From dd61e8eb879efa6039fe0749d458d67a433bc61a Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Mon, 28 Feb 2011 13:59:35 +0000 Subject: [PATCH] Implement driveinfo for devices. --- src/calibre/devices/apple/driver.py | 2 +- src/calibre/devices/bambook/driver.py | 2 +- src/calibre/devices/folder_device/driver.py | 4 +- src/calibre/devices/hanlin/driver.py | 1 + src/calibre/devices/interface.py | 2 +- src/calibre/devices/prs500/driver.py | 2 +- src/calibre/devices/prs505/driver.py | 3 -- src/calibre/devices/usbms/device.py | 3 +- src/calibre/devices/usbms/driver.py | 44 +++++++++++++++++++-- src/calibre/gui2/device.py | 17 +++++++- src/calibre/gui2/ui.py | 2 + 11 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/calibre/devices/apple/driver.py b/src/calibre/devices/apple/driver.py index aaa9382612..5ead675aab 100644 --- a/src/calibre/devices/apple/driver.py +++ b/src/calibre/devices/apple/driver.py @@ -701,7 +701,7 @@ class ITUNES(DriverBase): self.log.info("ITUNES.get_file(): exporting '%s'" % path) outfile.write(open(self.cached_books[path]['lib_book'].location().path).read()) - def open(self): + def open(self, library_uuid): ''' Perform any device specific initialization. Called after the device is detected but before any other functions that communicate with the device. diff --git a/src/calibre/devices/bambook/driver.py b/src/calibre/devices/bambook/driver.py index 3cc0245cf7..f251310d77 100644 --- a/src/calibre/devices/bambook/driver.py +++ b/src/calibre/devices/bambook/driver.py @@ -61,7 +61,7 @@ class BAMBOOK(DeviceConfig, DevicePlugin): detected_device=None) : self.open() - def open(self): + def open(self, library_uuid): # Make sure the Bambook library is ready if not is_bambook_lib_ready(): raise OpenFeedback(_("Unable to connect to Bambook, you need to install Bambook library first.")) diff --git a/src/calibre/devices/folder_device/driver.py b/src/calibre/devices/folder_device/driver.py index d75697a6cb..c08448051d 100644 --- a/src/calibre/devices/folder_device/driver.py +++ b/src/calibre/devices/folder_device/driver.py @@ -47,6 +47,7 @@ class FOLDER_DEVICE(USBMS): #: Icon for this device icon = I('devices/folder.png') METADATA_CACHE = '.metadata.calibre' + DRIVEINFO = '.driveinfo.calibre' _main_prefix = '' _card_a_prefix = None @@ -77,7 +78,8 @@ class FOLDER_DEVICE(USBMS): only_presence=False): return self.is_connected, self - def open(self): + def open(self, library_uuid): + self.current_library_uuid = library_uuid if not self._main_prefix: return False return True diff --git a/src/calibre/devices/hanlin/driver.py b/src/calibre/devices/hanlin/driver.py index 37f8430a66..ba0cca954d 100644 --- a/src/calibre/devices/hanlin/driver.py +++ b/src/calibre/devices/hanlin/driver.py @@ -116,6 +116,7 @@ class BOOX(HANLINV3): author = 'Jesus Manuel Marinho Valcarce' supported_platforms = ['windows', 'osx', 'linux'] METADATA_CACHE = '.metadata.calibre' + DRIVEINFO = '.driveinfo.calibre' # Ordered list of supported formats FORMATS = ['epub', 'fb2', 'djvu', 'pdf', 'html', 'txt', 'rtf', 'mobi', diff --git a/src/calibre/devices/interface.py b/src/calibre/devices/interface.py index bc442f5853..90da55a9db 100644 --- a/src/calibre/devices/interface.py +++ b/src/calibre/devices/interface.py @@ -215,7 +215,7 @@ class DevicePlugin(Plugin): return True - def open(self): + def open(self, library_uuid): ''' Perform any device specific initialization. Called after the device is detected but before any other functions that communicate with the device. diff --git a/src/calibre/devices/prs500/driver.py b/src/calibre/devices/prs500/driver.py index 445ddd757b..65ecc98a81 100644 --- a/src/calibre/devices/prs500/driver.py +++ b/src/calibre/devices/prs500/driver.py @@ -240,7 +240,7 @@ class PRS500(DeviceConfig, DevicePlugin): def set_progress_reporter(self, report_progress): self.report_progress = report_progress - def open(self) : + def open(self, library_uuid) : """ Claim an interface on the device for communication. Requires write privileges to the device file. diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 3768b8be62..9f17ea22a4 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -153,9 +153,6 @@ class PRS505(USBMS): # updated on every connect self.WANTS_UPDATED_THUMBNAILS = self.settings().extra_customization[2] - def get_device_information(self, end_session=True): - return (self.gui_name, '', '', '') - def filename_callback(self, fname, mi): if getattr(mi, 'application_id', None) is not None: base = fname.rpartition('.')[0] diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index b0857de909..37b2b061e5 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -700,7 +700,7 @@ class Device(DeviceConfig, DevicePlugin): - def open(self): + def open(self, library_uuid): time.sleep(5) self._main_prefix = self._card_a_prefix = self._card_b_prefix = None if islinux: @@ -722,6 +722,7 @@ class Device(DeviceConfig, DevicePlugin): time.sleep(7) self.open_osx() + self.current_library_uuid = library_uuid self.post_open_callback() def post_open_callback(self): diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index ef654ac428..37785612b5 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -10,17 +10,18 @@ driver. It is intended to be subclassed with the relevant parts implemented for a particular device. ''' -import os -import re -import time +import os, re, time, json, uuid from itertools import cycle +from calibre.constants import numeric_version from calibre import prints, isbytestring from calibre.constants import filesystem_encoding, DEBUG from calibre.devices.usbms.cli import CLI from calibre.devices.usbms.device import Device from calibre.devices.usbms.books import BookList, Book from calibre.ebooks.metadata.book.json_codec import JsonCodec +from calibre.utils.config import from_json, to_json +from calibre.utils.date import now BASE_TIME = None def debug_print(*args): @@ -52,10 +53,45 @@ class USBMS(CLI, Device): FORMATS = [] CAN_SET_METADATA = [] METADATA_CACHE = 'metadata.calibre' + DRIVEINFO = 'driveinfo.calibre' + + def _update_driveinfo_record(self, dinfo, prefix): + if not isinstance(dinfo, dict): + dinfo = {} + if dinfo.get('device_store_uuid', None) is None: + dinfo['device_store_uuid'] = unicode(uuid.uuid4()) + dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None) + dinfo['calibre_version'] = '.'.join([unicode(i) for i in numeric_version]) + dinfo['date_last_connected'] = unicode(now()) + dinfo['prefix'] = prefix.replace('\\', '/') + return dinfo + + def _update_driveinfo_file(self, prefix): + if os.path.exists(os.path.join(prefix, self.DRIVEINFO)): + with open(os.path.join(prefix, self.DRIVEINFO), 'rb') as f: + try: + driveinfo = json.loads(f.read(), object_hook=from_json) + except: + driveinfo = None + driveinfo = self._update_driveinfo_record(driveinfo, prefix) + with open(os.path.join(prefix, self.DRIVEINFO), 'wb') as f: + f.write(json.dumps(driveinfo, default=to_json)) + else: + driveinfo = self._update_driveinfo_record({}, prefix) + with open(os.path.join(prefix, self.DRIVEINFO), 'wb') as f: + f.write(json.dumps(driveinfo, default=to_json)) + return driveinfo def get_device_information(self, end_session=True): self.report_progress(1.0, _('Get device information...')) - return (self.get_gui_name(), '', '', '') + self.driveinfo = {} + if self._main_prefix is not None: + self.driveinfo['main'] = self._update_driveinfo_file(self._main_prefix) + if self._card_a_prefix is not None: + self.driveinfo['A'] = self._update_driveinfo_file(self._card_a_prefix) + if self._card_b_prefix is not None: + self.driveinfo['B'] = self._update_driveinfo_file(self._card_b_prefix) + return (self.get_gui_name(), '', '', '', self.driveinfo) def books(self, oncard=None, end_session=True): from calibre.ebooks.metadata.meta import path_to_ext diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index e4096f5761..972e02a6ab 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -140,6 +140,8 @@ class DeviceManager(Thread): # {{{ self.mount_connection_requests = Queue.Queue(0) self.open_feedback_slot = open_feedback_slot self.open_feedback_msg = open_feedback_msg + self._device_information = None + self.current_library_uuid = None def report_progress(self, *args): pass @@ -159,7 +161,7 @@ class DeviceManager(Thread): # {{{ try: dev.reset(detected_device=detected_device, report_progress=self.report_progress) - dev.open() + dev.open(self.current_library_uuid) except OpenFeedback, e: if dev not in self.ejected_devices: self.open_feedback_msg(dev.get_gui_name(), e.feedback_msg) @@ -194,6 +196,7 @@ class DeviceManager(Thread): # {{{ else: self.connected_slot(False, self.connected_device_kind) self.connected_device = None + self._device_information = None def detect_device(self): self.scanner.scan() @@ -292,9 +295,13 @@ class DeviceManager(Thread): # {{{ def _get_device_information(self): info = self.device.get_device_information(end_session=False) - info = [i.replace('\x00', '').replace('\x01', '') for i in info] + if len(info) < 5: + list(info).append({}) + info = [i.replace('\x00', '').replace('\x01', '') if isinstance(i, basestring) else i + for i in info] cp = self.device.card_prefix(end_session=False) fs = self.device.free_space() + self._device_information = {'info': info, 'prefixes': cp, 'freespace': fs} return info, cp, fs def get_device_information(self, done): @@ -302,6 +309,9 @@ class DeviceManager(Thread): # {{{ return self.create_job(self._get_device_information, done, description=_('Get device information')) + def get_current_device_information(self): + return self._device_information + def _books(self): '''Get metadata from device''' mainlist = self.device.books(oncard=None, end_session=False) @@ -417,6 +427,9 @@ class DeviceManager(Thread): # {{{ return self.create_job(self._view_book, done, args=[path, target], description=_('View book on device')) + def set_current_library_uuid(self, uuid): + self.current_library_uuid = uuid + # }}} class DeviceAction(QAction): # {{{ diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 8844446de6..bf672d43ca 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -296,6 +296,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ traceback.print_exc() if ac.plugin_path is None: raise + self.device_manager.set_current_library_uuid('THIS IS A UUID') if show_gui and self.gui_debug is not None: info_dialog(self, _('Debug mode'), '
' + @@ -461,6 +462,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ self.memory_view.reset() self.card_a_view.reset() self.card_b_view.reset() + self.device_manager.set_current_library_uuid('THIS IS A UUID') def set_window_title(self):