py3: Port linux.py

All literals are now unicode and converted to bytes only at write time.
This commit is contained in:
Kovid Goyal 2019-04-10 10:18:59 +05:30
parent d9cd1884af
commit d3e42a4cf3
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -1,6 +1,8 @@
from __future__ import print_function #!/usr/bin/env python2
__license__ = 'GPL v3' # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' # License: GPLv3 Copyright: 2008, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import absolute_import, division, print_function, unicode_literals
''' Post installation script for linux ''' ''' Post installation script for linux '''
@ -44,7 +46,17 @@ entry_points = {
} }
class PreserveMIMEDefaults(object): def polyglot_write(stream):
stream_write = stream.write
def write(x):
if not isinstance(x, bytes):
x = x.encode('utf-8')
return stream_write(x)
return write
class PreserveMIMEDefaults(object): # {{{
def __init__(self): def __init__(self):
self.initial_values = {} self.initial_values = {}
@ -87,12 +99,14 @@ class PreserveMIMEDefaults(object):
except EnvironmentError as e: except EnvironmentError as e:
if e.errno != errno.EACCES: if e.errno != errno.EACCES:
raise raise
# }}}
# Uninstall script {{{ # Uninstall script {{{
UNINSTALL = '''\ UNINSTALL = '''\
#!{python} #!{python}
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import print_function, unicode_literals from __future__ import print_function, unicode_literals
euid = {euid} euid = {euid}
@ -267,7 +281,7 @@ class ZshCompleter(object): # {{{
output_fmts = set(available_output_formats()) output_fmts = set(available_output_formats())
iexts = {x.upper() for x in input_fmts}.union(input_fmts) iexts = {x.upper() for x in input_fmts}.union(input_fmts)
oexts = {x.upper() for x in output_fmts}.union(output_fmts) oexts = {x.upper() for x in output_fmts}.union(output_fmts)
w = lambda x: f.write(x if isinstance(x, bytes) else x.encode('utf-8')) w = polyglot_write(f)
# Arg 1 # Arg 1
w('\n_ebc_input_args() {') w('\n_ebc_input_args() {')
w('\n local extras; extras=(') w('\n local extras; extras=(')
@ -374,7 +388,7 @@ class ZshCompleter(object): # {{{
opt_lines.append(ostrings + help_txt + ' \\') opt_lines.append(ostrings + help_txt + ' \\')
opt_lines = ('\n' + (' ' * 8)).join(opt_lines) opt_lines = ('\n' + (' ' * 8)).join(opt_lines)
f.write((u''' polyglot_write(f)((u'''
_ebook_edit() { _ebook_edit() {
local curcontext="$curcontext" state line ebookfile expl local curcontext="$curcontext" state line ebookfile expl
typeset -A opt_args typeset -A opt_args
@ -401,7 +415,7 @@ _ebook_edit() {
return 1 return 1
} }
''' % (opt_lines, '|'.join(tweakable_fmts)) + '\n\n').encode('utf-8')) ''' % (opt_lines, '|'.join(tweakable_fmts)) + '\n\n'))
def do_calibredb(self, f): def do_calibredb(self, f):
from calibre.db.cli.main import COMMANDS, option_parser_for from calibre.db.cli.main import COMMANDS, option_parser_for
@ -414,13 +428,14 @@ _ebook_edit() {
not x.strip().startswith('%prog')] not x.strip().startswith('%prog')]
descs[command] = lines[0] descs[command] = lines[0]
f.write('\n_calibredb_cmds() {\n local commands; commands=(\n') w = polyglot_write(f)
f.write(' {-h,--help}":Show help"\n') w('\n_calibredb_cmds() {\n local commands; commands=(\n')
f.write(' "--version:Show version"\n') w(' {-h,--help}":Show help"\n')
w(' "--version:Show version"\n')
for command, desc in iteritems(descs): for command, desc in iteritems(descs):
f.write(' "%s:%s"\n'%( w(' "%s:%s"\n'%(
command, desc.replace(':', '\\:').replace('"', '\''))) command, desc.replace(':', '\\:').replace('"', '\'')))
f.write(' )\n _describe -t commands "calibredb command" commands \n}\n') w(' )\n _describe -t commands "calibredb command" commands \n}\n')
subcommands = [] subcommands = []
for command, parser in iteritems(parsers): for command, parser in iteritems(parsers):
@ -441,8 +456,8 @@ _ebook_edit() {
subcommands.append(txt) subcommands.append(txt)
subcommands.append(';;') subcommands.append(';;')
f.write('\n_calibredb() {') w('\n_calibredb() {')
f.write(( w((
r''' r'''
local state line state_descr context local state line state_descr context
typeset -A opt_args typeset -A opt_args
@ -465,26 +480,24 @@ _ebook_edit() {
esac esac
return ret return ret
'''%'\n '.join(subcommands)).encode('utf-8')) '''%'\n '.join(subcommands)))
f.write('\n}\n\n') w('\n}\n\n')
def write(self): def write(self):
if self.dest: if self.dest:
for c in ('calibredb', 'ebook-convert', 'ebook-edit'): for c in ('calibredb', 'ebook-convert', 'ebook-edit'):
self.commands[c] = ' _%s "$@"' % c.replace('-', '_') self.commands[c] = ' _%s "$@"' % c.replace('-', '_')
with open(self.dest, 'wb') as f: with open(self.dest, 'wb') as f:
f.write('#compdef ' + ' '.join(self.commands)+'\n') w = polyglot_write(f)
w('#compdef ' + ' '.join(self.commands)+'\n')
self.do_ebook_convert(f) self.do_ebook_convert(f)
self.do_calibredb(f) self.do_calibredb(f)
self.do_ebook_edit(f) self.do_ebook_edit(f)
f.write('case $service in\n') w('case $service in\n')
for c, txt in iteritems(self.commands): for c, txt in iteritems(self.commands):
if isinstance(txt, unicode_type): w('%s)\n%s\n;;\n'%(c, txt))
txt = txt.encode('utf-8') w('esac\n')
if isinstance(c, unicode_type):
c = c.encode('utf-8')
f.write(b'%s)\n%s\n;;\n'%(c, txt))
f.write('esac\n')
# }}} # }}}
@ -493,7 +506,7 @@ def get_bash_completion_path(root, share, info):
# Try to get the system bash completion dir since we are installing to # Try to get the system bash completion dir since we are installing to
# /usr # /usr
try: try:
path = check_output('pkg-config --variable=completionsdir bash-completion'.split()).strip().partition(os.pathsep)[0] path = check_output('pkg-config --variable=completionsdir bash-completion'.split()).decode('utf-8').strip().partition(os.pathsep)[0]
except Exception: except Exception:
info('Failed to find directory to install bash completions, using default.') info('Failed to find directory to install bash completions, using default.')
path = '/usr/share/bash-completion/completions' path = '/usr/share/bash-completion/completions'
@ -530,15 +543,17 @@ def write_completion(bash_comp_dest, zsh):
complete = os.path.join(getattr(sys, 'frozen_path'), complete) complete = os.path.join(getattr(sys, 'frozen_path'), complete)
with open(bash_comp_dest or os.devnull, 'wb') as f: with open(bash_comp_dest or os.devnull, 'wb') as f:
w = polyglot_write(f)
def o_and_e(*args, **kwargs): def o_and_e(*args, **kwargs):
f.write(opts_and_exts(*args, **kwargs)) w(opts_and_exts(*args, **kwargs))
zsh.opts_and_exts(*args, **kwargs) zsh.opts_and_exts(*args, **kwargs)
def o_and_w(*args, **kwargs): def o_and_w(*args, **kwargs):
f.write(opts_and_words(*args, **kwargs)) w(opts_and_words(*args, **kwargs))
zsh.opts_and_words(*args, **kwargs) zsh.opts_and_words(*args, **kwargs)
f.write('# calibre Bash Shell Completion\n') w('# calibre Bash Shell Completion\n')
o_and_e('calibre', guiop, BOOK_EXTENSIONS) o_and_e('calibre', guiop, BOOK_EXTENSIONS)
o_and_e('lrf2lrs', lrf2lrsop, ['lrf'], file_map={'--output':['lrs']}) o_and_e('lrf2lrs', lrf2lrsop, ['lrf'], file_map={'--output':['lrs']})
o_and_e('ebook-meta', metaop, o_and_e('ebook-meta', metaop,
@ -561,7 +576,7 @@ def write_completion(bash_comp_dest, zsh):
'--inspect-mobi':['mobi', 'azw', 'azw3'], '--inspect-mobi':['mobi', 'azw', 'azw3'],
'--viewer':sorted(available_input_formats()), '--viewer':sorted(available_input_formats()),
}) })
f.write(textwrap.dedent(''' w(textwrap.dedent('''
_ebook_device_ls() _ebook_device_ls()
{ {
local pattern search listing prefix local pattern search listing prefix
@ -733,7 +748,7 @@ class PostInstall:
appdata_resources=self.appdata_resources, frozen_path=getattr(sys, 'frozen_path', None)) appdata_resources=self.appdata_resources, frozen_path=getattr(sys, 'frozen_path', None))
try: try:
with open(dest, 'wb') as f: with open(dest, 'wb') as f:
f.write(raw) polyglot_write(f)(raw)
os.chmod(dest, stat.S_IRWXU|stat.S_IRGRP|stat.S_IROTH) os.chmod(dest, stat.S_IRWXU|stat.S_IRGRP|stat.S_IROTH)
if os.geteuid() == 0: if os.geteuid() == 0:
os.chown(dest, 0, 0) os.chown(dest, 0, 0)
@ -800,7 +815,7 @@ class PostInstall:
for size in sizes: for size in sizes:
install_single_icon(iconsrc, basename, size, context, is_last_icon and size is sizes[-1]) install_single_icon(iconsrc, basename, size, context, is_last_icon and size is sizes[-1])
icons = filter(None, [x.strip() for x in '''\ icons = list(filter(None, [x.strip() for x in '''\
mimetypes/lrf.png application-lrf mimetypes mimetypes/lrf.png application-lrf mimetypes
mimetypes/lrf.png text-lrs mimetypes mimetypes/lrf.png text-lrs mimetypes
mimetypes/mobi.png application-x-mobipocket-ebook mimetypes mimetypes/mobi.png application-x-mobipocket-ebook mimetypes
@ -810,7 +825,7 @@ class PostInstall:
lt.png calibre-gui apps lt.png calibre-gui apps
viewer.png calibre-viewer apps viewer.png calibre-viewer apps
tweak.png calibre-ebook-edit apps tweak.png calibre-ebook-edit apps
'''.splitlines()]) '''.splitlines()]))
for line in icons: for line in icons:
iconsrc, basename, context = line.split() iconsrc, basename, context = line.split()
install_icons(iconsrc, basename, context, is_last_icon=line is icons[-1]) install_icons(iconsrc, basename, context, is_last_icon=line is icons[-1])
@ -823,25 +838,22 @@ class PostInstall:
mimetypes.discard('application/octet-stream') mimetypes.discard('application/octet-stream')
def write_mimetypes(f): def write_mimetypes(f):
f.write('MimeType=%s;\n'%';'.join(mimetypes)) polyglot_write(f)('MimeType=%s;\n'%';'.join(mimetypes))
from calibre.ebooks.oeb.polish.main import SUPPORTED from calibre.ebooks.oeb.polish.main import SUPPORTED
from calibre.ebooks.oeb.polish.import_book import IMPORTABLE from calibre.ebooks.oeb.polish.import_book import IMPORTABLE
f = open('calibre-lrfviewer.desktop', 'wb') with open('calibre-lrfviewer.desktop', 'wb') as f:
f.write(VIEWER) polyglot_write(f)(VIEWER)
f.close() with open('calibre-ebook-viewer.desktop', 'wb') as f:
f = open('calibre-ebook-viewer.desktop', 'wb') polyglot_write(f)(EVIEWER)
f.write(EVIEWER) write_mimetypes(f)
write_mimetypes(f) with open('calibre-ebook-edit.desktop', 'wb') as f:
f = open('calibre-ebook-edit.desktop', 'wb') polyglot_write(f)(ETWEAK)
f.write(ETWEAK) mt = {guess_type('a.' + x.lower())[0] for x in (SUPPORTED|IMPORTABLE)} - {None, 'application/octet-stream'}
mt = {guess_type('a.' + x.lower())[0] for x in (SUPPORTED|IMPORTABLE)} - {None, 'application/octet-stream'} polyglot_write(f)('MimeType=%s;\n'%';'.join(mt))
f.write('MimeType=%s;\n'%';'.join(mt)) with open('calibre-gui.desktop', 'wb') as f:
f.close() polyglot_write(f)(GUI)
f = open('calibre-gui.desktop', 'wb') write_mimetypes(f)
f.write(GUI)
write_mimetypes(f)
f.close()
des = ('calibre-gui.desktop', 'calibre-lrfviewer.desktop', des = ('calibre-gui.desktop', 'calibre-lrfviewer.desktop',
'calibre-ebook-viewer.desktop', 'calibre-ebook-edit.desktop') 'calibre-ebook-viewer.desktop', 'calibre-ebook-edit.desktop')
appdata = os.path.join(os.path.dirname(self.opts.staging_sharedir), 'metainfo') appdata = os.path.join(os.path.dirname(self.opts.staging_sharedir), 'metainfo')
@ -931,7 +943,7 @@ def opts_and_words(name, op, words, takes_files=False):
esac esac
} }
complete -F _'''%(opts, words) + fname + ' ' + name +"\n\n").encode('utf-8') complete -F _'''%(opts, words) + fname + ' ' + name +"\n\n")
pics = {'jpg', 'jpeg', 'gif', 'png', 'bmp'} pics = {'jpg', 'jpeg', 'gif', 'png', 'bmp'}