%PDF- %PDF-
| Direktori : /lib/calibre/calibre/utils/ |
| Current File : //lib/calibre/calibre/utils/complete.py |
#!/usr/bin/env python3
__license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
'''
BASH completion for calibre commands that are too complex for simple
completion.
'''
import sys, os, shlex, glob, re
prints = print
def split(src):
try:
return shlex.split(src)
except ValueError:
try:
return shlex.split(src+'"')
except ValueError:
return shlex.split(src+"'")
def files_and_dirs(prefix, allowed_exts=[]):
prefix = os.path.expanduser(prefix)
for i in glob.iglob(prefix+'*'):
_, ext = os.path.splitext(i)
ext = ext.lower().replace('.', '')
if os.path.isdir(i):
yield i+os.sep
elif allowed_exts is None or ext in allowed_exts:
yield i+' '
def get_opts_from_parser(parser, prefix):
def do_opt(opt):
for x in opt._long_opts:
if x.startswith(prefix):
yield x
for x in opt._short_opts:
if x.startswith(prefix):
yield x
for o in parser.option_list:
for x in do_opt(o):
yield x+' '
for g in parser.option_groups:
for o in g.option_list:
for x in do_opt(o):
yield x+' '
def send(ans):
pat = re.compile('([^0-9a-zA-Z_./-])')
for x in sorted(set(ans)):
x = pat.sub(lambda m : '\\'+m.group(1), x)
if x.endswith('\\ '):
x = x[:-2]+' '
prints(x)
class EbookConvert:
def __init__(self, comp_line, pos):
words = split(comp_line[:pos])
char_before = comp_line[pos-1]
prefix = words[-1] if words[-1].endswith(char_before) else ''
wc = len(words)
if not prefix:
wc += 1
self.words = words
self.prefix = prefix
self.previous = words[-2 if prefix else -1]
from calibre.utils.serialize import msgpack_loads
self.cache = msgpack_loads(open(os.path.join(sys.resources_location,
'ebook-convert-complete.calibre_msgpack'), 'rb').read(), use_list=False)
self.complete(wc)
def complete(self, wc):
if wc == 2:
self.complete_input()
elif wc == 3:
self.complete_output()
else:
q = list(self.words[1:3])
q = [os.path.splitext(x)[0 if x.startswith('.') else 1].partition('.')[-1].lower() for x in q]
if not q[1]:
q[1] = 'oeb'
q = tuple(q)
if q in self.cache:
ans = [x for x in self.cache[q] if x.startswith(self.prefix)]
else:
from calibre.ebooks.conversion.cli import create_option_parser
from calibre.utils.logging import Log
log = Log()
log.outputs = []
ans = []
if not self.prefix or self.prefix.startswith('-'):
try:
parser, _ = create_option_parser(self.words[:3], log)
ans += list(get_opts_from_parser(parser, self.prefix))
except:
pass
if self.previous.startswith('-'):
ans += list(files_and_dirs(self.prefix, None))
send(ans)
def complete_input(self):
ans = list(files_and_dirs(self.prefix, self.cache['input_fmts']))
ans += [t for t in self.cache['input_recipes'] if
t.startswith(self.prefix)]
send(ans)
def complete_output(self):
fmts = self.cache['output']
ans = list(files_and_dirs(self.prefix, fmts))
ans += ['.'+x+' ' for x in fmts if ('.'+x).startswith(self.prefix)]
send(ans)
def main(args=sys.argv):
comp_line, pos = os.environ['COMP_LINE'], int(os.environ['COMP_POINT'])
module = split(comp_line)[0].split(os.sep)[-1]
if module == 'ebook-convert':
EbookConvert(comp_line, pos)
return 0
if __name__ == '__main__':
raise sys.exit(main())