Improved terminal functions.
This commit is contained in:
parent
4dec964cb7
commit
c9082aee42
4 changed files with 67 additions and 30 deletions
|
@ -10,6 +10,7 @@ Changes:
|
||||||
- comics: Removed the twisted and zope dependencies by adding
|
- comics: Removed the twisted and zope dependencies by adding
|
||||||
an internal plugin search mechanism.
|
an internal plugin search mechanism.
|
||||||
- testing: Refactored the test comic routine in proper unit tests.
|
- testing: Refactored the test comic routine in proper unit tests.
|
||||||
|
- cmdline: Improved terminal feature detection.
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
- comics: Adjusted Xkcd href values.
|
- comics: Adjusted Xkcd href values.
|
||||||
|
|
16
dosage
16
dosage
|
@ -22,7 +22,7 @@ import traceback
|
||||||
|
|
||||||
from dosagelib import events, scraper
|
from dosagelib import events, scraper
|
||||||
from dosagelib.output import out
|
from dosagelib.output import out
|
||||||
from dosagelib.util import getWindowSize, internal_error
|
from dosagelib.util import is_tty, get_columns, internal_error
|
||||||
from dosagelib.configuration import App, Freeware, Copyright
|
from dosagelib.configuration import App, Freeware, Copyright
|
||||||
|
|
||||||
def setupOptions():
|
def setupOptions():
|
||||||
|
@ -38,14 +38,7 @@ def setupOptions():
|
||||||
parser.add_option('-m', '--module-help', action='store_true', dest='modhelp', help='display help for comic modules')
|
parser.add_option('-m', '--module-help', action='store_true', dest='modhelp', help='display help for comic modules')
|
||||||
parser.add_option('-t', '--timestamps', action='store_true', dest='timestamps', default=False, help='print timestamps for all output at any info level')
|
parser.add_option('-t', '--timestamps', action='store_true', dest='timestamps', default=False, help='print timestamps for all output at any info level')
|
||||||
parser.add_option('-o', '--output', action='store', dest='output', choices=events.getHandlers(), help='output formatting for downloaded comics')
|
parser.add_option('-o', '--output', action='store', dest='output', choices=events.getHandlers(), help='output formatting for downloaded comics')
|
||||||
try:
|
if is_tty(sys.stdout):
|
||||||
getWindowSize()
|
|
||||||
except NotImplementedError:
|
|
||||||
progress = False
|
|
||||||
else:
|
|
||||||
progress = True
|
|
||||||
|
|
||||||
if progress:
|
|
||||||
parser.add_option('-p', '--progress', action='store_true', dest='progress', default=False, help='display progress bar while downloading comics')
|
parser.add_option('-p', '--progress', action='store_true', dest='progress', default=False, help='display progress bar while downloading comics')
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
@ -131,10 +124,7 @@ class Dosage(object):
|
||||||
print '\n'.join(scraper.get_name() for scraper in scrapers)
|
print '\n'.join(scraper.get_name() for scraper in scrapers)
|
||||||
|
|
||||||
def doColumnList(self, scrapers):
|
def doColumnList(self, scrapers):
|
||||||
try:
|
screenWidth = get_columns()
|
||||||
screenWidth = getWindowSize()
|
|
||||||
except NotImplementedError:
|
|
||||||
screenWidth = 80
|
|
||||||
names = [scraper.get_name() for scraper in scrapers]
|
names = [scraper.get_name() for scraper in scrapers]
|
||||||
maxlen = max([len(name) for name in names])
|
maxlen = max([len(name) for name in names])
|
||||||
namesPerLine = int(screenWidth / (maxlen + 1))
|
namesPerLine = int(screenWidth / (maxlen + 1))
|
||||||
|
|
22
dosagelib/fileutil.py
Normal file
22
dosagelib/fileutil.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# -*- coding: iso-8859-1 -*-
|
||||||
|
# Copyright (C) 2012 Bastian Kleineidam
|
||||||
|
"""
|
||||||
|
File and path utilities.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def has_module (name):
|
||||||
|
"""Test if given module can be imported.
|
||||||
|
@return: flag if import is successful
|
||||||
|
@rtype: bool
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
exec "import %s as _bla" % name
|
||||||
|
return True
|
||||||
|
except (OSError, ImportError):
|
||||||
|
# some modules (for example HTMLtidy) raise OSError
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def is_tty (fp):
|
||||||
|
"""Check if a file object is a TTY."""
|
||||||
|
return (hasattr(fp, "isatty") and fp.isatty())
|
|
@ -2,8 +2,6 @@ from __future__ import division
|
||||||
|
|
||||||
import urllib2, urlparse
|
import urllib2, urlparse
|
||||||
import sys
|
import sys
|
||||||
import struct
|
|
||||||
import array
|
|
||||||
import os
|
import os
|
||||||
import cgi
|
import cgi
|
||||||
import re
|
import re
|
||||||
|
@ -14,6 +12,12 @@ from math import log, floor
|
||||||
|
|
||||||
from .output import out
|
from .output import out
|
||||||
from .configuration import UserAgent, AppName, App, SupportUrl
|
from .configuration import UserAgent, AppName, App, SupportUrl
|
||||||
|
from .fileutil import has_module, is_tty
|
||||||
|
|
||||||
|
has_wconio = has_module("WConio")
|
||||||
|
has_curses = has_module("curses")
|
||||||
|
has_fcntl = has_module('fcntl')
|
||||||
|
has_termios = has_module('termios')
|
||||||
|
|
||||||
class NoMatchError(Exception): pass
|
class NoMatchError(Exception): pass
|
||||||
|
|
||||||
|
@ -148,21 +152,41 @@ def urlopen(url, referrer=None, retries=5):
|
||||||
|
|
||||||
return urlobj
|
return urlobj
|
||||||
|
|
||||||
def getWindowSize():
|
|
||||||
try:
|
def get_columns (fp):
|
||||||
from fcntl import ioctl
|
"""Return number of columns for given file."""
|
||||||
from termios import TIOCGWINSZ
|
if not is_tty(fp):
|
||||||
except ImportError:
|
return 80
|
||||||
raise NotImplementedError
|
if has_wconio:
|
||||||
st = 'HHHH'
|
import WConio
|
||||||
names = 'ws_row', 'ws_col', 'ws_xpixel', 'ws_ypixel'
|
# gettextinfo() returns a tuple
|
||||||
buf = array.array('b', ' ' * struct.calcsize(st))
|
# - left, top, right, bottom: window coordinates
|
||||||
try:
|
# - textattr, normattr: current attributes
|
||||||
ioctl(sys.stderr, TIOCGWINSZ, buf, True)
|
# - videomode: current video mode
|
||||||
except IOError:
|
# - height, width: screen size
|
||||||
raise NotImplementedError
|
# - curx, cury: current cursor position
|
||||||
winsize = dict(zip(names, struct.unpack(st, buf.tostring())))
|
# return the width:
|
||||||
return winsize['ws_col']
|
return WConio.gettextinfo()[8]
|
||||||
|
if has_curses:
|
||||||
|
import curses
|
||||||
|
try:
|
||||||
|
curses.setupterm()
|
||||||
|
return curses.tigetnum("cols")
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
|
if has_fcntl and has_termios:
|
||||||
|
import fcntl, termios, array, struct
|
||||||
|
st = 'HHHH'
|
||||||
|
names = 'ws_row', 'ws_col', 'ws_xpixel', 'ws_ypixel'
|
||||||
|
buf = array.array('b', ' ' * struct.calcsize(st))
|
||||||
|
try:
|
||||||
|
fcntl.ioctl(fp, termios.TIOCGWINSZ, buf, True)
|
||||||
|
winsize = dict(zip(names, struct.unpack(st, buf.tostring())))
|
||||||
|
return winsize['ws_col']
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
return 80
|
||||||
|
|
||||||
|
|
||||||
suffixes = ('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')
|
suffixes = ('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue