From 3af918bb3f824eec6683e7e2d55add9c472d6ec3 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Fri, 6 Jul 2012 00:17:39 -0300 Subject: [PATCH 1/5] Allow the user to override unsupported database --- src/calibre/devices/kobo/driver.py | 47 +++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 1384ec0810..fff08e878c 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -23,10 +23,11 @@ class KOBO(USBMS): gui_name = 'Kobo Reader' description = _('Communicate with the Kobo Reader') author = 'Timothy Legge' - version = (1, 0, 12) + version = (1, 0, 13) dbversion = 0 fwversion = 0 + supported_dbversion = 33 has_kepubs = False supported_platforms = ['windows', 'osx', 'linux'] @@ -73,6 +74,12 @@ class KOBO(USBMS): ':::'+_('Kobo now shows recommendations on the device. In some case these have ' 'files but in other cases they are just pointers to the web site to buy. ' 'Enable if you wish to see/delete them.'), + _('Attempt to support newer firmware') + + ':::'+_('Kobo routinely updates the firmware and the ' + 'database version. With this option Calibre will attempt ' + 'to perform full read-write functionality - Here be Dragons!! ' + 'Enable only if you are comfortable with restoring your kobo ' + 'to factory defaults and testing software'), ] EXTRA_CUSTOMIZATION_DEFAULT = [ @@ -81,6 +88,7 @@ class KOBO(USBMS): True, True, False, + False, False ] @@ -90,6 +98,7 @@ class KOBO(USBMS): OPT_SHOW_EXPIRED_BOOK_RECORDS = 3 OPT_SHOW_PREVIEWS = 4 OPT_SHOW_RECOMMENDATIONS = 5 + OPT_SUPPORT_NEWER_FIRMWARE = 6 def initialize(self): USBMS.initialize(self) @@ -238,15 +247,6 @@ class KOBO(USBMS): cursor = connection.cursor() - #query = 'select count(distinct volumeId) from volume_shortcovers' - #cursor.execute(query) - #for row in (cursor): - # numrows = row[0] - #cursor.close() - - # Determine the database version - # 4 - Bluetooth Kobo Rev 2 (1.4) - # 8 - WIFI KOBO Rev 1 cursor.execute('select version from dbversion') result = cursor.fetchone() self.dbversion = result[0] @@ -422,6 +422,9 @@ class KOBO(USBMS): os.unlink(fpath) def delete_books(self, paths, end_session=True): + if self.modify_database_check("delete_books") == False: + return + for i, path in enumerate(paths): self.report_progress((i+1) / float(len(paths)), _('Removing books from device...')) path = self.normalize_path(path) @@ -458,6 +461,9 @@ class KOBO(USBMS): self.report_progress(1.0, _('Removing books from device...')) def remove_books_from_metadata(self, paths, booklists): + if self.modify_datbase_check("remove_books_from_metatata") == False: + return + for i, path in enumerate(paths): self.report_progress((i+1) / float(len(paths)), _('Removing books from device metadata listing...')) for bl in booklists: @@ -588,6 +594,24 @@ class KOBO(USBMS): return path + def modify_database_check(self, function): + # Checks to see whether the database version is supported + # and whether the user has chosen to support the firmware version + if self.dbversion > self.supported_dbversion: + # Unsupported database + opts = self.settings() + if not opts.extra_customization[self.OPT_SUPPORT_NEWER_FIRMWARE]: + debug_print('The database has been upgraded past supported version') + debug_print('The database has been upgraded past supported version') + self.report_progress(1.0, _('Removing books from device...')) + return False + else: + # The user chose to edit the database anyway + return True + else: + # Supported database version + return True + def get_file(self, path, *args, **kwargs): tpath = self.munge_path(path) extension = os.path.splitext(tpath)[1] @@ -706,6 +730,9 @@ class KOBO(USBMS): # debug_print(' Commit: Set FavouritesIndex') def update_device_database_collections(self, booklists, collections_attributes, oncard): + if self.modify_database_check("update_device_database_collections") == False: + return + # Only process categories in this list supportedcategories = { "Im_Reading":1, From 714141b896a2b00d9da869fa9c2c68bf3cf3832a Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Fri, 6 Jul 2012 19:02:12 -0300 Subject: [PATCH 2/5] Provide user information on unsupported database options --- src/calibre/devices/kobo/driver.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index fff08e878c..6f2358ade1 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -604,6 +604,16 @@ class KOBO(USBMS): debug_print('The database has been upgraded past supported version') debug_print('The database has been upgraded past supported version') self.report_progress(1.0, _('Removing books from device...')) + from calibre.devices.errors import UserFeedback + raise UserFeedback(_("Kobo database version unsupported - See details"), + _('Your Kobo is running an updated firmware/database version ' + 'As Calibre has not been updated, database editing is disabled. ' + 'You can enable support for your Kobo in plugin preferences. ' + 'Doing so may require you to perform a factory reset. ' + 'before selecting the "Attempt to support newer firmware" option ' + 'you should be familiar with restoring your Kobo to factory defaults.'), + UserFeedback.WARN) + return False else: # The user chose to edit the database anyway From e7e0aea6958b1419a5e72c85da0e0f920d36fb53 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Jul 2012 09:44:48 +0530 Subject: [PATCH 3/5] Set WM_CLASS for the viewers as well --- src/calibre/gui2/__init__.py | 8 ++++---- src/calibre/gui2/lrf_renderer/main.py | 3 ++- src/calibre/gui2/main.py | 5 +++-- src/calibre/gui2/viewer/main.py | 3 ++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 8aa4caf574..cd75f3bb00 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -734,11 +734,11 @@ gui_thread = None qt_app = None class Application(QApplication): - def __init__(self, args, force_calibre_style=False): + def __init__(self, args, force_calibre_style=False, + override_program_name=None): self.file_event_hook = None - if islinux and args[0].endswith(u'calibre'): - args = list(args) - args[0] += '-gui' + if override_program_name: + args = [override_program_name] + args[1:] qargs = [i.encode('utf-8') if isinstance(i, unicode) else i for i in args] QApplication.__init__(self, qargs) global gui_thread, qt_app diff --git a/src/calibre/gui2/lrf_renderer/main.py b/src/calibre/gui2/lrf_renderer/main.py index 0575d106f4..741f6a620d 100644 --- a/src/calibre/gui2/lrf_renderer/main.py +++ b/src/calibre/gui2/lrf_renderer/main.py @@ -309,7 +309,8 @@ def main(args=sys.argv, logger=None): return 1 pid = os.fork() if (islinux or isbsd) else -1 if pid <= 0: - app = Application(args) + override = 'calibre-lrf-viewer' if islinux else None + app = Application(args, override_program_name=override) app.setWindowIcon(QIcon(I('viewer.png'))) QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setApplicationName(APP_UID) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 9b80b7bddc..94a82989ab 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -8,7 +8,7 @@ from PyQt4.Qt import (QCoreApplication, QIcon, QObject, QTimer, QPixmap, QSplashScreen, QApplication) from calibre import prints, plugins, force_unicode -from calibre.constants import (iswindows, __appname__, isosx, DEBUG, +from calibre.constants import (iswindows, __appname__, isosx, DEBUG, islinux, filesystem_encoding) from calibre.utils.ipc import gui_socket_address, RC from calibre.gui2 import (ORG_NAME, APP_UID, initialize_file_icon_provider, @@ -58,7 +58,8 @@ def init_qt(args): prints('Using library at', prefs['library_path']) QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setApplicationName(APP_UID) - app = Application(args) + override = 'calibre-gui' if islinux else None + app = Application(args, override_program_name=override) actions = tuple(Main.create_application_menubar()) app.setWindowIcon(QIcon(I('lt.png'))) return app, opts, args, actions diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index 4a39a6ae8d..b08262d707 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -1006,7 +1006,8 @@ def main(args=sys.argv): except: open_at = None if pid <= 0: - app = Application(args) + override = 'calibre-ebook-viewer' if islinux else None + app = Application(args, override_program_name=override) app.setWindowIcon(QIcon(I('viewer.png'))) QApplication.setOrganizationName(ORG_NAME) QApplication.setApplicationName(APP_UID) From 93545002ced5562c05135d730198a7ae24635ea2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Jul 2012 10:11:18 +0530 Subject: [PATCH 4/5] Linux installer: When calling the xdg utilities use system libraries rather than the libraries bundled with calibre --- src/calibre/linux.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 90cacd0180..2613c168fd 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -5,6 +5,7 @@ __copyright__ = '2008, Kovid Goyal ' import sys, os, cPickle, textwrap, stat from subprocess import check_call +from functools import partial from calibre import __appname__, prints, guess_type from calibre.constants import islinux, isnetbsd, isbsd @@ -346,19 +347,28 @@ class PostInstall: try: self.info('Setting up desktop integration...') + env = os.environ.copy() + cc = check_call + if getattr(sys, 'frozen_path', False) and 'LD_LIBRARY_PATH' in env: + paths = env.get('LD_LIBRARY_PATH', '').split(os.pathsep) + paths = [x for x in paths if x] + npaths = [x for x in paths if x != sys.frozen_path+'/lib'] + env['LD_LIBRARY_PATH'] = os.pathsep.join(npaths) + cc = partial(check_call, env=env) + 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) + cc('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) + cc('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', width=256, height=256) - check_call('xdg-icon-resource install --noupdate --size 256 calibre-gui.png calibre-gui', shell=True) + cc('xdg-icon-resource install --noupdate --size 256 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) + cc('xdg-icon-resource install --size 128 calibre-viewer.png calibre-viewer', shell=True) self.icon_resources.append(('apps', 'calibre-viewer', '128')) mimetypes = set([]) @@ -385,14 +395,14 @@ class PostInstall: 'calibre-ebook-viewer.desktop') for x in des: cmd = ['xdg-desktop-menu', 'install', '--noupdate', './'+x] - check_call(' '.join(cmd), shell=True) + cc(' '.join(cmd), shell=True) self.menu_resources.append(x) - check_call(['xdg-desktop-menu', 'forceupdate']) + cc(['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) + cc('xdg-mime install ./calibre-mimetypes', shell=True) except Exception: if self.opts.fatal_errors: raise From 7c2bdb800d9178494f7eae8b960d8f89e830a682 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 7 Jul 2012 10:40:28 +0530 Subject: [PATCH 5/5] ... --- setup/installer/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/installer/__init__.py b/setup/installer/__init__.py index 55f7486c19..3d891281b7 100644 --- a/setup/installer/__init__.py +++ b/setup/installer/__init__.py @@ -11,7 +11,7 @@ import subprocess, tempfile, os, time from setup import Command, installer_name from setup.build_environment import HOST, PROJECT -BASE_RSYNC = ['rsync', '-avz', '--delete'] +BASE_RSYNC = ['rsync', '-avz', '--delete', '--force'] EXCLUDES = [] for x in [ 'src/calibre/plugins', 'src/calibre/manual', 'src/calibre/trac',