diff --git a/setup.py b/setup.py index 1de2535937..9abe2a1d66 100644 --- a/setup.py +++ b/setup.py @@ -313,6 +313,9 @@ setup( **py2exe_options ) +if '--uninstall' in ' '.join(sys.argv[1:]): + sys.exit(0) + try: import PyQt4 except ImportError: @@ -324,6 +327,150 @@ else: print "WARNING: The GUI needs PyQt >= 4.1.1" import os +def options(parse_options): + options, args, parser = parse_options(['dummy'], cli=False) + options = parser.option_list + for group in parser.option_groups: + options += group.option_list + opts = [] + for opt in options: + opts.extend(opt._short_opts) + opts.extend(opt._long_opts) + return opts + +def opts_and_exts(name, op, exts): + opts = ' '.join(options(op)) + exts.extend([i.upper() for i in exts]) + exts='|'.join(exts) + return '_'+name+'()'+\ +''' +{ + local cur prev opts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + opts="%s" + pics="@(jpg|jpeg|png|gif|bmp|JPG|JPEG|PNG|GIF|BMP)" + + case "${prev}" in + --cover ) + _filedir "${pics}" + return 0 + ;; + esac + + case "${cur}" in + --cover ) + _filedir "${pics}" + return 0 + ;; + -* ) + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; + * ) + _filedir '@(%s)' + return 0 + ;; + esac + +} +complete -o filenames -F _'''%(opts,exts) + name + ' ' + name +"\n\n" + + + +if os.access('/etc/bash_completion.d', os.W_OK): + try: + print 'Setting up bash completion...', + sys.stdout.flush() + from libprs500.lrf.html.convert_from import parse_options as htmlop + from libprs500.lrf.txt.convert_from import parse_options as txtop + from libprs500.lrf.meta import parse_options as metaop + f = open('/etc/bash_completion.d/libprs500', 'wb') + f.write('# libprs500 Bash Shell Completion\n') + f.write(opts_and_exts('html2lrf', htmlop, + ['htm', 'html', 'xhtml', 'xhtm', 'rar', 'zip'])) + f.write(opts_and_exts('txt2lrf', txtop, ['txt'])) + f.write(opts_and_exts('lrf-meta', metaop, ['lrf'])) + f.write(''' +_prs500_ls() +{ + local pattern search listing prefix + pattern="$1" + search="$1" + if [[ -n "{$pattern}" ]]; then + if [[ "${pattern:(-1)}" == "/" ]]; then + pattern="" + else + pattern="$(basename ${pattern} 2> /dev/null)" + search="$(dirname ${search} 2> /dev/null)" + fi + fi + + if [[ "x${search}" == "x" || "x${search}" == "x." ]]; then + search="/" + fi + + listing="$(prs500 ls ${search} 2>/dev/null)" + + prefix="${search}" + if [[ "x${prefix:(-1)}" != "x/" ]]; then + prefix="${prefix}/" + fi + + echo $(compgen -P "${prefix}" -W "${listing}" "${pattern}") +} + +_prs500() +{ + local cur prev + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + COMPREPLY=() + case "${prev}" in + ls|rm|mkdir|touch|cat ) + COMPREPLY=( $(_prs500_ls "${cur}") ) + return 0 + ;; + cp ) + if [[ ${cur} == prs500:* ]]; then + COMPREPLY=( $(_prs500_ls "${cur:7}") ) + return 0 + else + _filedir + return 0 + fi + ;; + prs500 ) + COMPREPLY=( $(compgen -W "cp ls rm mkdir touch cat info books df" "${cur}") ) + return 0 + ;; + * ) + if [[ ${cur} == prs500:* ]]; then + COMPREPLY=( $(_prs500_ls "${cur:7}") ) + return 0 + else + if [[ ${prev} == prs500:* ]]; then + _filedir + return 0 + else + COMPREPLY=( $(compgen -W "prs500:" "${cur}") ) + return 0 + fi + return 0 + fi + ;; + esac +} +complete -o nospace -F _prs500 prs500 + +''') + f.close() + print 'done' + except: + print 'failed' + + if os.access('/etc/udev/rules.d', os.W_OK): from subprocess import check_call print 'Trying to setup udev rules...', diff --git a/src/libprs500/__init__.py b/src/libprs500/__init__.py index ebf9717551..b738899546 100644 --- a/src/libprs500/__init__.py +++ b/src/libprs500/__init__.py @@ -33,7 +33,7 @@ You may have to adjust the GROUP and the location of the rules file to suit your distribution. """ -__version__ = "0.3.26" +__version__ = "0.3.27" __docformat__ = "epytext" __author__ = "Kovid Goyal " diff --git a/src/libprs500/cli/main.py b/src/libprs500/cli/main.py index 03e73cb606..10ef8e4ccd 100755 --- a/src/libprs500/cli/main.py +++ b/src/libprs500/cli/main.py @@ -61,6 +61,17 @@ class FileFormatter(object): return mode return property(doc=doc, fget=fget) + @apply + def isdir_name(): + doc='''Return self.name + '/' if self is a directory''' + def fget(self): + name = self.name + if self.is_dir: + name += '/' + return name + return property(doc=doc, fget=fget) + + @apply def name_in_color(): doc=""" The name in ANSI text. Directories are blue, ebooks are green """ @@ -140,7 +151,7 @@ def ls(dev, path, term, recurse=False, color=False, human_readable_size=False, l if size > maxlen: maxlen = size for file in files: file = FileFormatter(file, term) - name = file.name + name = file.name if ll else file.isdir_name lsoutput.append(name) if color: name = file.name_in_color lscoloutput.append(name) diff --git a/src/libprs500/lrf/__init__.py b/src/libprs500/lrf/__init__.py index 0dbf9b0144..7305de89ca 100644 --- a/src/libprs500/lrf/__init__.py +++ b/src/libprs500/lrf/__init__.py @@ -44,7 +44,7 @@ class ConversionError(Exception): def option_parser(usage): parser = OptionParser(usage=usage, version='libprs500 '+VERSION, - epilog='html2lrf created by Kovid Goyal') + epilog='Created by Kovid Goyal') metadata = parser.add_option_group('METADATA OPTIONS') metadata.add_option('--header', action='store_true', default=False, dest='header', help='Add a header to all the pages with title and author.') diff --git a/src/libprs500/lrf/html/convert_from.py b/src/libprs500/lrf/html/convert_from.py index 808e5b155c..1e91c5599a 100644 --- a/src/libprs500/lrf/html/convert_from.py +++ b/src/libprs500/lrf/html/convert_from.py @@ -22,7 +22,7 @@ and to Falstaff for pylrs. """ import os, re, sys, shutil, traceback, copy from htmlentitydefs import name2codepoint -from urllib import urlopen, unquote +from urllib import unquote from urlparse import urlparse from tempfile import mkdtemp from operator import itemgetter @@ -1121,12 +1121,12 @@ def parse_options(argv=None, cli=True): raise ConversionError, 'no filename specified' if options.title == None: options.title = filename_to_utf8(os.path.splitext(os.path.basename(args[0]))[0]) - return options, args + return options, args, parser def main(): try: - options, args = parse_options() + options, args, parser = parse_options() src = args[0] except: sys.exit(1) diff --git a/src/libprs500/lrf/meta.py b/src/libprs500/lrf/meta.py index 077fa2ff7d..602efb96df 100644 --- a/src/libprs500/lrf/meta.py +++ b/src/libprs500/lrf/meta.py @@ -24,8 +24,7 @@ to get and set meta information. For example: >>> lrf.category = "History" """ -import struct -import zlib +import struct, zlib, sys from shutil import copyfileobj from cStringIO import StringIO import xml.dom.minidom as dom @@ -538,10 +537,11 @@ class LRFMetaFile(object): self._file.write(val) -def main(): - import sys, os.path +def parse_options(argv=None, cli=True): from optparse import OptionParser from libprs500 import __version__ as VERSION + if not argv: + argv = sys.argv[1:] parser = OptionParser(usage = \ """%prog [options] mybook.lrf @@ -574,7 +574,16 @@ def main(): dest="page", help="Don't know what this is for") options, args = parser.parse_args() if len(args) != 1: - parser.print_help() + if cli: + parser.print_help() + raise LRFException, 'no filename specified' + return options, args, parser + +def main(): + import os.path + try: + options, args, parser = parse_options() + except: sys.exit(1) lrf = LRFMetaFile(open(args[0], "r+b")) if options.title: diff --git a/src/libprs500/lrf/txt/convert_from.py b/src/libprs500/lrf/txt/convert_from.py index 34b3136122..8cc00a6a5a 100644 --- a/src/libprs500/lrf/txt/convert_from.py +++ b/src/libprs500/lrf/txt/convert_from.py @@ -21,33 +21,39 @@ from libprs500.lrf import ConversionError, option_parser from libprs500.lrf import Book from libprs500.lrf.pylrs.pylrs import Paragraph, Italic, Bold, BookSetting from libprs500 import filename_to_utf8 +from libprs500 import iswindows -def main(): +def parse_options(argv=None, cli=True): """ CLI for txt -> lrf conversions """ - parser = option_parser(\ + if not argv: + argv = sys.argv[1:] + parser = option_parser( """usage: %prog [options] mybook.txt %prog converts mybook.txt to mybook.lrf - """\ + """ ) - - defenc = 'cp1252' + defenc = 'cp1252' if iswindows else 'utf8' enchelp = 'Set the encoding used to decode ' + \ - 'the text in mybook.txt. Default encoding is ' + defenc + 'the text in mybook.txt. Default encoding is %default' parser.add_option('-e', '--encoding', action='store', type='string', \ dest='encoding', help=enchelp, default=defenc) options, args = parser.parse_args() if len(args) != 1: - parser.print_help() - sys.exit(1) - src = os.path.abspath(os.path.expanduser(args[0])) + if cli: + parser.print_help() + raise ConversionError, 'no filename specified' if options.title == None: - options.title = filename_to_utf8(os.path.splitext(os.path.basename(src))[0]) + options.title = filename_to_utf8(os.path.splitext(os.path.basename(args[0]))[0]) + return options, args, parser + +def main(): try: - convert_txt(src, options) - except ConversionError, err: - print >>sys.stderr, err - sys.exit(1) + options, args, parser = parse_options() + src = os.path.abspath(os.path.expanduser(args[0])) + except: + sys.exit(1) + convert_txt(src, options) def convert_txt(path, options):