Implement driveinfo for devices.

This commit is contained in:
Charles Haley 2011-02-28 13:59:35 +00:00
parent 434e5caccf
commit dd61e8eb87
11 changed files with 67 additions and 15 deletions

View File

@ -701,7 +701,7 @@ class ITUNES(DriverBase):
self.log.info("ITUNES.get_file(): exporting '%s'" % path) self.log.info("ITUNES.get_file(): exporting '%s'" % path)
outfile.write(open(self.cached_books[path]['lib_book'].location().path).read()) 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 Perform any device specific initialization. Called after the device is
detected but before any other functions that communicate with the device. detected but before any other functions that communicate with the device.

View File

@ -61,7 +61,7 @@ class BAMBOOK(DeviceConfig, DevicePlugin):
detected_device=None) : detected_device=None) :
self.open() self.open()
def open(self): def open(self, library_uuid):
# Make sure the Bambook library is ready # Make sure the Bambook library is ready
if not is_bambook_lib_ready(): if not is_bambook_lib_ready():
raise OpenFeedback(_("Unable to connect to Bambook, you need to install Bambook library first.")) raise OpenFeedback(_("Unable to connect to Bambook, you need to install Bambook library first."))

View File

@ -47,6 +47,7 @@ class FOLDER_DEVICE(USBMS):
#: Icon for this device #: Icon for this device
icon = I('devices/folder.png') icon = I('devices/folder.png')
METADATA_CACHE = '.metadata.calibre' METADATA_CACHE = '.metadata.calibre'
DRIVEINFO = '.driveinfo.calibre'
_main_prefix = '' _main_prefix = ''
_card_a_prefix = None _card_a_prefix = None
@ -77,7 +78,8 @@ class FOLDER_DEVICE(USBMS):
only_presence=False): only_presence=False):
return self.is_connected, self return self.is_connected, self
def open(self): def open(self, library_uuid):
self.current_library_uuid = library_uuid
if not self._main_prefix: if not self._main_prefix:
return False return False
return True return True

View File

@ -116,6 +116,7 @@ class BOOX(HANLINV3):
author = 'Jesus Manuel Marinho Valcarce' author = 'Jesus Manuel Marinho Valcarce'
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']
METADATA_CACHE = '.metadata.calibre' METADATA_CACHE = '.metadata.calibre'
DRIVEINFO = '.driveinfo.calibre'
# Ordered list of supported formats # Ordered list of supported formats
FORMATS = ['epub', 'fb2', 'djvu', 'pdf', 'html', 'txt', 'rtf', 'mobi', FORMATS = ['epub', 'fb2', 'djvu', 'pdf', 'html', 'txt', 'rtf', 'mobi',

View File

@ -215,7 +215,7 @@ class DevicePlugin(Plugin):
return True return True
def open(self): def open(self, library_uuid):
''' '''
Perform any device specific initialization. Called after the device is Perform any device specific initialization. Called after the device is
detected but before any other functions that communicate with the device. detected but before any other functions that communicate with the device.

View File

@ -240,7 +240,7 @@ class PRS500(DeviceConfig, DevicePlugin):
def set_progress_reporter(self, report_progress): def set_progress_reporter(self, report_progress):
self.report_progress = report_progress self.report_progress = report_progress
def open(self) : def open(self, library_uuid) :
""" """
Claim an interface on the device for communication. Claim an interface on the device for communication.
Requires write privileges to the device file. Requires write privileges to the device file.

View File

@ -153,9 +153,6 @@ class PRS505(USBMS):
# updated on every connect # updated on every connect
self.WANTS_UPDATED_THUMBNAILS = self.settings().extra_customization[2] 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): def filename_callback(self, fname, mi):
if getattr(mi, 'application_id', None) is not None: if getattr(mi, 'application_id', None) is not None:
base = fname.rpartition('.')[0] base = fname.rpartition('.')[0]

View File

@ -700,7 +700,7 @@ class Device(DeviceConfig, DevicePlugin):
def open(self): def open(self, library_uuid):
time.sleep(5) time.sleep(5)
self._main_prefix = self._card_a_prefix = self._card_b_prefix = None self._main_prefix = self._card_a_prefix = self._card_b_prefix = None
if islinux: if islinux:
@ -722,6 +722,7 @@ class Device(DeviceConfig, DevicePlugin):
time.sleep(7) time.sleep(7)
self.open_osx() self.open_osx()
self.current_library_uuid = library_uuid
self.post_open_callback() self.post_open_callback()
def post_open_callback(self): def post_open_callback(self):

View File

@ -10,17 +10,18 @@ driver. It is intended to be subclassed with the relevant parts implemented
for a particular device. for a particular device.
''' '''
import os import os, re, time, json, uuid
import re
import time
from itertools import cycle from itertools import cycle
from calibre.constants import numeric_version
from calibre import prints, isbytestring from calibre import prints, isbytestring
from calibre.constants import filesystem_encoding, DEBUG from calibre.constants import filesystem_encoding, DEBUG
from calibre.devices.usbms.cli import CLI from calibre.devices.usbms.cli import CLI
from calibre.devices.usbms.device import Device from calibre.devices.usbms.device import Device
from calibre.devices.usbms.books import BookList, Book from calibre.devices.usbms.books import BookList, Book
from calibre.ebooks.metadata.book.json_codec import JsonCodec 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 BASE_TIME = None
def debug_print(*args): def debug_print(*args):
@ -52,10 +53,45 @@ class USBMS(CLI, Device):
FORMATS = [] FORMATS = []
CAN_SET_METADATA = [] CAN_SET_METADATA = []
METADATA_CACHE = 'metadata.calibre' 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): def get_device_information(self, end_session=True):
self.report_progress(1.0, _('Get device information...')) 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): def books(self, oncard=None, end_session=True):
from calibre.ebooks.metadata.meta import path_to_ext from calibre.ebooks.metadata.meta import path_to_ext

View File

@ -140,6 +140,8 @@ class DeviceManager(Thread): # {{{
self.mount_connection_requests = Queue.Queue(0) self.mount_connection_requests = Queue.Queue(0)
self.open_feedback_slot = open_feedback_slot self.open_feedback_slot = open_feedback_slot
self.open_feedback_msg = open_feedback_msg self.open_feedback_msg = open_feedback_msg
self._device_information = None
self.current_library_uuid = None
def report_progress(self, *args): def report_progress(self, *args):
pass pass
@ -159,7 +161,7 @@ class DeviceManager(Thread): # {{{
try: try:
dev.reset(detected_device=detected_device, dev.reset(detected_device=detected_device,
report_progress=self.report_progress) report_progress=self.report_progress)
dev.open() dev.open(self.current_library_uuid)
except OpenFeedback, e: except OpenFeedback, e:
if dev not in self.ejected_devices: if dev not in self.ejected_devices:
self.open_feedback_msg(dev.get_gui_name(), e.feedback_msg) self.open_feedback_msg(dev.get_gui_name(), e.feedback_msg)
@ -194,6 +196,7 @@ class DeviceManager(Thread): # {{{
else: else:
self.connected_slot(False, self.connected_device_kind) self.connected_slot(False, self.connected_device_kind)
self.connected_device = None self.connected_device = None
self._device_information = None
def detect_device(self): def detect_device(self):
self.scanner.scan() self.scanner.scan()
@ -292,9 +295,13 @@ class DeviceManager(Thread): # {{{
def _get_device_information(self): def _get_device_information(self):
info = self.device.get_device_information(end_session=False) 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) cp = self.device.card_prefix(end_session=False)
fs = self.device.free_space() fs = self.device.free_space()
self._device_information = {'info': info, 'prefixes': cp, 'freespace': fs}
return info, cp, fs return info, cp, fs
def get_device_information(self, done): def get_device_information(self, done):
@ -302,6 +309,9 @@ class DeviceManager(Thread): # {{{
return self.create_job(self._get_device_information, done, return self.create_job(self._get_device_information, done,
description=_('Get device information')) description=_('Get device information'))
def get_current_device_information(self):
return self._device_information
def _books(self): def _books(self):
'''Get metadata from device''' '''Get metadata from device'''
mainlist = self.device.books(oncard=None, end_session=False) 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], return self.create_job(self._view_book, done, args=[path, target],
description=_('View book on device')) description=_('View book on device'))
def set_current_library_uuid(self, uuid):
self.current_library_uuid = uuid
# }}} # }}}
class DeviceAction(QAction): # {{{ class DeviceAction(QAction): # {{{

View File

@ -296,6 +296,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
traceback.print_exc() traceback.print_exc()
if ac.plugin_path is None: if ac.plugin_path is None:
raise raise
self.device_manager.set_current_library_uuid('THIS IS A UUID')
if show_gui and self.gui_debug is not None: if show_gui and self.gui_debug is not None:
info_dialog(self, _('Debug mode'), '<p>' + info_dialog(self, _('Debug mode'), '<p>' +
@ -461,6 +462,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
self.memory_view.reset() self.memory_view.reset()
self.card_a_view.reset() self.card_a_view.reset()
self.card_b_view.reset() self.card_b_view.reset()
self.device_manager.set_current_library_uuid('THIS IS A UUID')
def set_window_title(self): def set_window_title(self):