~ubuntu-branches/ubuntu/karmic/calibre/karmic

« back to all changes in this revision

Viewing changes to src/calibre/utils/complete.py

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-30 12:49:41 UTC
  • mfrom: (1.3.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730124941-qjdsmri25zt8zocn
Tags: 0.6.3+dfsg-0ubuntu1
* New upstream release. Please see http://calibre.kovidgoyal.net/new_in_6/
  for the list of new features and changes.
* remove_postinstall.patch: Update for new version.
* build_debug.patch: Does not apply any more, disable for now. Might not be
  necessary any more.
* debian/copyright: Fix reference to versionless GPL.
* debian/rules: Drop obsolete dh_desktop call.
* debian/rules: Add workaround for weird Python 2.6 setuptools behaviour of
  putting compiled .so files into src/calibre/plugins/calibre/plugins
  instead of src/calibre/plugins.
* debian/rules: Drop hal fdi moving, new upstream version does not use hal
  any more. Drop hal dependency, too.
* debian/rules: Install udev rules into /lib/udev/rules.d.
* Add debian/calibre.preinst: Remove unmodified
  /etc/udev/rules.d/95-calibre.rules on upgrade.
* debian/control: Bump Python dependencies to 2.6, since upstream needs
  it now.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
 
3
from __future__ import with_statement
 
4
 
 
5
__license__   = 'GPL v3'
 
6
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
 
7
__docformat__ = 'restructuredtext en'
 
8
 
 
9
 
 
10
'''
 
11
BASH completion for calibre commands that are too complex for simple
 
12
completion.
 
13
'''
 
14
 
 
15
import sys, os, shlex, glob, re
 
16
from functools import partial
 
17
 
 
18
from calibre import prints
 
19
 
 
20
debug = partial(prints, file=sys.stderr)
 
21
 
 
22
def split(src):
 
23
    try:
 
24
        return shlex.split(src)
 
25
    except ValueError:
 
26
        try:
 
27
            return shlex.split(src+'"')
 
28
        except ValueError:
 
29
            return shlex.split(src+"'")
 
30
 
 
31
 
 
32
def files_and_dirs(prefix, allowed_exts=[]):
 
33
    for i in glob.iglob(prefix+'*'):
 
34
        _, ext = os.path.splitext(i)
 
35
        ext = ext.lower().replace('.', '')
 
36
        if os.path.isdir(i):
 
37
            yield i+os.sep
 
38
        elif allowed_exts is None or ext in allowed_exts:
 
39
            yield i+' '
 
40
 
 
41
def get_opts_from_parser(parser, prefix):
 
42
    def do_opt(opt):
 
43
        for x in opt._long_opts:
 
44
            if x.startswith(prefix):
 
45
                yield x
 
46
        for x in opt._short_opts:
 
47
            if x.startswith(prefix):
 
48
                yield x
 
49
    for o in parser.option_list:
 
50
        for x in do_opt(o): yield x
 
51
    for g in parser.option_groups:
 
52
        for o in g.option_list:
 
53
            for x in do_opt(o): yield x
 
54
 
 
55
def send(ans):
 
56
    pat = re.compile('([^0-9a-zA-Z_./-])')
 
57
    for x in sorted(set(ans)):
 
58
        x = pat.sub(lambda m : '\\'+m.group(1), x)
 
59
        if x.endswith('\\ '):
 
60
            x = x[:-2]+' '
 
61
        prints(x)
 
62
 
 
63
 
 
64
 
 
65
class EbookConvert(object):
 
66
 
 
67
    def __init__(self, comp_line, pos):
 
68
        words = split(comp_line[:pos])
 
69
        char_before = comp_line[pos-1]
 
70
        prefix = words[-1] if words[-1].endswith(char_before) else ''
 
71
        wc = len(words)
 
72
        if not prefix:
 
73
            wc += 1
 
74
        self.words = words
 
75
        self.prefix = prefix
 
76
        self.previous = words[-2 if prefix else -1]
 
77
        self.complete(wc)
 
78
 
 
79
    def complete(self, wc):
 
80
        if wc == 2:
 
81
            self.complete_input()
 
82
        elif wc == 3:
 
83
            self.complete_output()
 
84
        else:
 
85
            from calibre.ebooks.conversion.cli import create_option_parser
 
86
            from calibre.utils.logging import Log
 
87
            log = Log()
 
88
            log.outputs = []
 
89
            ans = []
 
90
            if not self.prefix or self.prefix.startswith('-'):
 
91
                try:
 
92
                    parser, _ = create_option_parser(self.words[:3], log)
 
93
                    ans += list(get_opts_from_parser(parser, self.prefix))
 
94
                except:
 
95
                    pass
 
96
            if self.previous.startswith('-'):
 
97
                ans += list(files_and_dirs(self.prefix, None))
 
98
            send(ans)
 
99
 
 
100
    def complete_input(self):
 
101
        from calibre.ebooks.conversion.plumber import supported_input_formats
 
102
        ans = list(files_and_dirs(self.prefix, supported_input_formats()))
 
103
        from calibre.web.feeds.recipes import recipes
 
104
        ans += [t.title+'.recipe ' for t in recipes if
 
105
                (t.title+'.recipe').startswith(self.prefix)]
 
106
        send(ans)
 
107
 
 
108
    def complete_output(self):
 
109
        from calibre.customize.ui import available_output_formats
 
110
        fmts = available_output_formats()
 
111
        ans = list(files_and_dirs(self.prefix, fmts))
 
112
        ans += ['.'+x+' ' for x in fmts if ('.'+x).startswith(self.prefix)]
 
113
        send(ans)
 
114
 
 
115
 
 
116
 
 
117
 
 
118
 
 
119
 
 
120
def main(args=sys.argv):
 
121
    comp_line, pos = os.environ['COMP_LINE'], int(os.environ['COMP_POINT'])
 
122
    module = split(comp_line)[0].split(os.sep)[-1]
 
123
    if module == 'ebook-convert':
 
124
        EbookConvert(comp_line, pos)
 
125
 
 
126
    return 0
 
127
 
 
128
 
 
129
if __name__ == '__main__':
 
130
    raise sys.exit(main())