mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
MTP: only populate driveinfo during the fetching of the book lists so that the get_device_information() job is not slow
This commit is contained in:
parent
c0aee6772d
commit
5008cc5d92
@ -95,6 +95,10 @@ class DevicePlugin(Plugin):
|
||||
#: call post_yank_cleanup().
|
||||
MANAGES_DEVICE_PRESENCE = False
|
||||
|
||||
#: If set the True, calibre will call the :method:`get_driveinfo()` method
|
||||
#: after the books lists have been loaded to get the driveinfo.
|
||||
SLOW_DRIVEINFO = False
|
||||
|
||||
@classmethod
|
||||
def get_gui_name(cls):
|
||||
if hasattr(cls, 'gui_name'):
|
||||
@ -352,6 +356,18 @@ class DevicePlugin(Plugin):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_driveinfo(self):
|
||||
'''
|
||||
Return the driveinfo dictionary. Usually called from
|
||||
get_device_information(), but if loading the driveinfo is slow for this
|
||||
driver, then it should set SLOW_DRIVEINFO. In this case, this method
|
||||
will be called by calibre after the book lists have been loaded. Note
|
||||
that it is not called on the device thread, so the driver should cache
|
||||
the drive info in the books() method and this function should return
|
||||
the cached data.
|
||||
'''
|
||||
return {}
|
||||
|
||||
def card_prefix(self, end_session=True):
|
||||
'''
|
||||
Return a 2 element list of the prefix to paths on the cards.
|
||||
|
@ -35,6 +35,7 @@ class MTP_DEVICE(BASE):
|
||||
MANAGES_DEVICE_PRESENCE = True
|
||||
FORMATS = ['epub', 'azw3', 'mobi', 'pdf']
|
||||
DEVICE_PLUGBOARD_NAME = 'MTP_DEVICE'
|
||||
SLOW_DRIVEINFO = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
BASE.__init__(self, *args, **kwargs)
|
||||
@ -76,6 +77,7 @@ class MTP_DEVICE(BASE):
|
||||
def open(self, devices, library_uuid):
|
||||
self.current_library_uuid = library_uuid
|
||||
self.location_paths = None
|
||||
self.driveinfo = {}
|
||||
BASE.open(self, devices, library_uuid)
|
||||
h = self.prefs['history']
|
||||
if self.current_serial_num:
|
||||
@ -109,13 +111,17 @@ class MTP_DEVICE(BASE):
|
||||
self.put_file(storage, self.DRIVEINFO, BytesIO(raw), len(raw))
|
||||
self.driveinfo[location_code] = dinfo
|
||||
|
||||
def get_driveinfo(self):
|
||||
if not self.driveinfo:
|
||||
self.driveinfo = {}
|
||||
for sid, location_code in ( (self._main_id, 'main'), (self._carda_id,
|
||||
'A'), (self._cardb_id, 'B')):
|
||||
if sid is None: continue
|
||||
self._update_drive_info(self.filesystem_cache.storage(sid), location_code)
|
||||
return self.driveinfo
|
||||
|
||||
def get_device_information(self, end_session=True):
|
||||
self.report_progress(1.0, _('Get device information...'))
|
||||
self.driveinfo = {}
|
||||
for sid, location_code in ( (self._main_id, 'main'), (self._carda_id,
|
||||
'A'), (self._cardb_id, 'B')):
|
||||
if sid is None: continue
|
||||
self._update_drive_info(self.filesystem_cache.storage(sid), location_code)
|
||||
dinfo = self.get_basic_device_information()
|
||||
return tuple( list(dinfo) + [self.driveinfo] )
|
||||
|
||||
@ -135,6 +141,7 @@ class MTP_DEVICE(BASE):
|
||||
def books(self, oncard=None, end_session=True):
|
||||
from calibre.devices.mtp.books import JSONCodec
|
||||
from calibre.devices.mtp.books import BookList, Book
|
||||
self.get_driveinfo() # Ensure driveinfo is loaded
|
||||
sid = {'carda':self._carda_id, 'cardb':self._cardb_id}.get(oncard,
|
||||
self._main_id)
|
||||
if sid is None:
|
||||
|
@ -230,6 +230,9 @@ class FilesystemCache(object):
|
||||
continue # Ignore .txt files in the root
|
||||
yield x
|
||||
|
||||
def __len__(self):
|
||||
return len(self.id_map)
|
||||
|
||||
def resolve_mtp_id_path(self, path):
|
||||
if not path.startswith('mtp:::'):
|
||||
raise ValueError('%s is not a valid MTP path'%path)
|
||||
|
@ -222,7 +222,8 @@ class MTP_DEVICE(MTPDeviceBase):
|
||||
self.current_friendly_name,
|
||||
self.format_errorstack(all_errs)))
|
||||
self._filesystem_cache = FilesystemCache(storage, all_items)
|
||||
debug('Filesystem metadata loaded in %g seconds'%(time.time()-st))
|
||||
debug('Filesystem metadata loaded in %g seconds (%d objects)'%(
|
||||
time.time()-st, len(self._filesystem_cache)))
|
||||
return self._filesystem_cache
|
||||
|
||||
@synchronous
|
||||
|
@ -220,7 +220,8 @@ class MTP_DEVICE(MTPDeviceBase):
|
||||
all_storage.append(storage)
|
||||
items.append(id_map.itervalues())
|
||||
self._filesystem_cache = FilesystemCache(all_storage, chain(*items))
|
||||
debug('Filesystem metadata loaded in %g seconds'%(time.time()-st))
|
||||
debug('Filesystem metadata loaded in %g seconds (%d objects)'%(
|
||||
time.time()-st, len(self._filesystem_cache)))
|
||||
return self._filesystem_cache
|
||||
|
||||
@same_thread
|
||||
|
@ -433,6 +433,15 @@ class DeviceManager(Thread): # {{{
|
||||
return self.create_job_step(self._get_device_information, done,
|
||||
description=_('Get device information'), to_job=add_as_step_to_job)
|
||||
|
||||
def slow_driveinfo(self):
|
||||
''' Update the stored device information with the driveinfo if the
|
||||
device indicates that getting driveinfo is slow '''
|
||||
info = self._device_information['info']
|
||||
if (not info[4] and self.device.SLOW_DRIVEINFO):
|
||||
info = list(info)
|
||||
info[4] = self.device.get_driveinfo()
|
||||
self._device_information['info'] = tuple(info)
|
||||
|
||||
def get_current_device_information(self):
|
||||
return self._device_information
|
||||
|
||||
@ -1023,6 +1032,7 @@ class DeviceMixin(object): # {{{
|
||||
if job.failed:
|
||||
self.device_job_exception(job)
|
||||
return
|
||||
self.device_manager.slow_driveinfo()
|
||||
# set_books_in_library might schedule a sync_booklists job
|
||||
self.set_books_in_library(job.result, reset=True, add_as_step_to_job=job)
|
||||
mainlist, cardalist, cardblist = job.result
|
||||
|
Loading…
x
Reference in New Issue
Block a user