diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 1686f66b22..00f636a30f 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -40,6 +40,46 @@ entry_points = { ], } +class PreserveMIMEDefaults(object): + + def __init__(self): + self.initial_values = {} + + def __enter__(self): + def_data_dirs = '/usr/local/share:/usr/share' + paths = os.environ.get('XDG_DATA_DIRS', def_data_dirs) + paths = paths.split(':') + paths.append(os.environ.get('XDG_DATA_HOME', os.path.expanduser( + '~/.local/share'))) + paths = list(filter(os.path.isdir, paths)) + if not paths: + # Env var had garbage in it, ignore it + paths = def_data_dirs.split(':') + paths = list(filter(os.path.isdir, paths)) + self.paths = {os.path.join(x, 'applications/defaults.list') for x in + paths} + self.initial_values = {} + for x in self.paths: + try: + with open(x, 'rb') as f: + self.initial_values[x] = f.read() + except: + self.initial_values[x] = None + + def __exit__(self, *args): + for path, val in self.initial_values.iteritems(): + if val is None: + try: + os.remove(path) + except: + pass + elif os.path.exists(path): + with open(path, 'r+b') as f: + if f.read() != val: + f.seek(0) + f.truncate() + f.write(val) + # Uninstall script {{{ UNINSTALL = '''\ #!{python} @@ -333,57 +373,55 @@ class PostInstall: def setup_desktop_integration(self): # {{{ try: - self.info('Setting up desktop integration...') + with TemporaryDirectory() as tdir, CurrentDir(tdir), \ + PreserveMIMEDefaults(): + render_img('mimetypes/lrf.png', 'calibre-lrf.png') + check_call('xdg-icon-resource install --noupdate --context mimetypes --size 128 calibre-lrf.png application-lrf', shell=True) + self.icon_resources.append(('mimetypes', 'application-lrf', '128')) + check_call('xdg-icon-resource install --noupdate --context mimetypes --size 128 calibre-lrf.png text-lrs', shell=True) + self.icon_resources.append(('mimetypes', 'application-lrs', + '128')) + render_img('lt.png', 'calibre-gui.png') + check_call('xdg-icon-resource install --noupdate --size 128 calibre-gui.png calibre-gui', shell=True) + self.icon_resources.append(('apps', 'calibre-gui', '128')) + render_img('viewer.png', 'calibre-viewer.png') + check_call('xdg-icon-resource install --size 128 calibre-viewer.png calibre-viewer', shell=True) + self.icon_resources.append(('apps', 'calibre-viewer', '128')) - with TemporaryDirectory() as tdir: - with CurrentDir(tdir): - render_img('mimetypes/lrf.png', 'calibre-lrf.png') - check_call('xdg-icon-resource install --noupdate --context mimetypes --size 128 calibre-lrf.png application-lrf', shell=True) - self.icon_resources.append(('mimetypes', 'application-lrf', '128')) - check_call('xdg-icon-resource install --noupdate --context mimetypes --size 128 calibre-lrf.png text-lrs', shell=True) - self.icon_resources.append(('mimetypes', 'application-lrs', - '128')) - render_img('lt.png', 'calibre-gui.png') - check_call('xdg-icon-resource install --noupdate --size 128 calibre-gui.png calibre-gui', shell=True) - self.icon_resources.append(('apps', 'calibre-gui', '128')) - render_img('viewer.png', 'calibre-viewer.png') - check_call('xdg-icon-resource install --size 128 calibre-viewer.png calibre-viewer', shell=True) - self.icon_resources.append(('apps', 'calibre-viewer', '128')) + mimetypes = set([]) + for x in all_input_formats(): + mt = guess_type('dummy.'+x)[0] + if mt and 'chemical' not in mt and 'ctc-posml' not in mt: + mimetypes.add(mt) - mimetypes = set([]) - for x in all_input_formats(): - mt = guess_type('dummy.'+x)[0] - if mt and 'chemical' not in mt and 'ctc-posml' not in mt: - mimetypes.add(mt) + def write_mimetypes(f): + f.write('MimeType=%s;\n'%';'.join(mimetypes)) - def write_mimetypes(f): - f.write('MimeType=%s;\n'%';'.join(mimetypes)) - - f = open('calibre-lrfviewer.desktop', 'wb') - f.write(VIEWER) - f.close() - f = open('calibre-ebook-viewer.desktop', 'wb') - f.write(EVIEWER) - write_mimetypes(f) - f.close() - f = open('calibre-gui.desktop', 'wb') - f.write(GUI) - write_mimetypes(f) - f.close() - des = ('calibre-gui.desktop', 'calibre-lrfviewer.desktop', - 'calibre-ebook-viewer.desktop') - for x in des: - cmd = ['xdg-desktop-menu', 'install', '--noupdate', './'+x] - check_call(' '.join(cmd), shell=True) - self.menu_resources.append(x) - check_call(['xdg-desktop-menu', 'forceupdate']) - f = open('calibre-mimetypes', 'wb') - f.write(MIME) - f.close() - self.mime_resources.append('calibre-mimetypes') - check_call('xdg-mime install ./calibre-mimetypes', shell=True) + f = open('calibre-lrfviewer.desktop', 'wb') + f.write(VIEWER) + f.close() + f = open('calibre-ebook-viewer.desktop', 'wb') + f.write(EVIEWER) + write_mimetypes(f) + f.close() + f = open('calibre-gui.desktop', 'wb') + f.write(GUI) + write_mimetypes(f) + f.close() + des = ('calibre-gui.desktop', 'calibre-lrfviewer.desktop', + 'calibre-ebook-viewer.desktop') + for x in des: + cmd = ['xdg-desktop-menu', 'install', '--noupdate', './'+x] + check_call(' '.join(cmd), shell=True) + self.menu_resources.append(x) + check_call(['xdg-desktop-menu', 'forceupdate']) + f = open('calibre-mimetypes', 'wb') + f.write(MIME) + f.close() + self.mime_resources.append('calibre-mimetypes') + check_call('xdg-mime install ./calibre-mimetypes', shell=True) except Exception: if self.opts.fatal_errors: raise