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().
|
#: call post_yank_cleanup().
|
||||||
MANAGES_DEVICE_PRESENCE = False
|
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
|
@classmethod
|
||||||
def get_gui_name(cls):
|
def get_gui_name(cls):
|
||||||
if hasattr(cls, 'gui_name'):
|
if hasattr(cls, 'gui_name'):
|
||||||
@ -352,6 +356,18 @@ class DevicePlugin(Plugin):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
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):
|
def card_prefix(self, end_session=True):
|
||||||
'''
|
'''
|
||||||
Return a 2 element list of the prefix to paths on the cards.
|
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
|
MANAGES_DEVICE_PRESENCE = True
|
||||||
FORMATS = ['epub', 'azw3', 'mobi', 'pdf']
|
FORMATS = ['epub', 'azw3', 'mobi', 'pdf']
|
||||||
DEVICE_PLUGBOARD_NAME = 'MTP_DEVICE'
|
DEVICE_PLUGBOARD_NAME = 'MTP_DEVICE'
|
||||||
|
SLOW_DRIVEINFO = True
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
BASE.__init__(self, *args, **kwargs)
|
BASE.__init__(self, *args, **kwargs)
|
||||||
@ -76,6 +77,7 @@ class MTP_DEVICE(BASE):
|
|||||||
def open(self, devices, library_uuid):
|
def open(self, devices, library_uuid):
|
||||||
self.current_library_uuid = library_uuid
|
self.current_library_uuid = library_uuid
|
||||||
self.location_paths = None
|
self.location_paths = None
|
||||||
|
self.driveinfo = {}
|
||||||
BASE.open(self, devices, library_uuid)
|
BASE.open(self, devices, library_uuid)
|
||||||
h = self.prefs['history']
|
h = self.prefs['history']
|
||||||
if self.current_serial_num:
|
if self.current_serial_num:
|
||||||
@ -109,13 +111,17 @@ class MTP_DEVICE(BASE):
|
|||||||
self.put_file(storage, self.DRIVEINFO, BytesIO(raw), len(raw))
|
self.put_file(storage, self.DRIVEINFO, BytesIO(raw), len(raw))
|
||||||
self.driveinfo[location_code] = dinfo
|
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):
|
def get_device_information(self, end_session=True):
|
||||||
self.report_progress(1.0, _('Get device information...'))
|
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()
|
dinfo = self.get_basic_device_information()
|
||||||
return tuple( list(dinfo) + [self.driveinfo] )
|
return tuple( list(dinfo) + [self.driveinfo] )
|
||||||
|
|
||||||
@ -135,6 +141,7 @@ class MTP_DEVICE(BASE):
|
|||||||
def books(self, oncard=None, end_session=True):
|
def books(self, oncard=None, end_session=True):
|
||||||
from calibre.devices.mtp.books import JSONCodec
|
from calibre.devices.mtp.books import JSONCodec
|
||||||
from calibre.devices.mtp.books import BookList, Book
|
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,
|
sid = {'carda':self._carda_id, 'cardb':self._cardb_id}.get(oncard,
|
||||||
self._main_id)
|
self._main_id)
|
||||||
if sid is None:
|
if sid is None:
|
||||||
|
@ -230,6 +230,9 @@ class FilesystemCache(object):
|
|||||||
continue # Ignore .txt files in the root
|
continue # Ignore .txt files in the root
|
||||||
yield x
|
yield x
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.id_map)
|
||||||
|
|
||||||
def resolve_mtp_id_path(self, path):
|
def resolve_mtp_id_path(self, path):
|
||||||
if not path.startswith('mtp:::'):
|
if not path.startswith('mtp:::'):
|
||||||
raise ValueError('%s is not a valid MTP path'%path)
|
raise ValueError('%s is not a valid MTP path'%path)
|
||||||
|
@ -222,7 +222,8 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
self.current_friendly_name,
|
self.current_friendly_name,
|
||||||
self.format_errorstack(all_errs)))
|
self.format_errorstack(all_errs)))
|
||||||
self._filesystem_cache = FilesystemCache(storage, all_items)
|
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
|
return self._filesystem_cache
|
||||||
|
|
||||||
@synchronous
|
@synchronous
|
||||||
|
@ -220,7 +220,8 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
all_storage.append(storage)
|
all_storage.append(storage)
|
||||||
items.append(id_map.itervalues())
|
items.append(id_map.itervalues())
|
||||||
self._filesystem_cache = FilesystemCache(all_storage, chain(*items))
|
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
|
return self._filesystem_cache
|
||||||
|
|
||||||
@same_thread
|
@same_thread
|
||||||
|
@ -433,6 +433,15 @@ class DeviceManager(Thread): # {{{
|
|||||||
return self.create_job_step(self._get_device_information, done,
|
return self.create_job_step(self._get_device_information, done,
|
||||||
description=_('Get device information'), to_job=add_as_step_to_job)
|
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):
|
def get_current_device_information(self):
|
||||||
return self._device_information
|
return self._device_information
|
||||||
|
|
||||||
@ -1023,6 +1032,7 @@ class DeviceMixin(object): # {{{
|
|||||||
if job.failed:
|
if job.failed:
|
||||||
self.device_job_exception(job)
|
self.device_job_exception(job)
|
||||||
return
|
return
|
||||||
|
self.device_manager.slow_driveinfo()
|
||||||
# set_books_in_library might schedule a sync_booklists job
|
# 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)
|
self.set_books_in_library(job.result, reset=True, add_as_step_to_job=job)
|
||||||
mainlist, cardalist, cardblist = job.result
|
mainlist, cardalist, cardblist = job.result
|
||||||
|
Loading…
x
Reference in New Issue
Block a user