mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
MTP: Implement prepare_addable_books and refactor the GUI to run prepare_addable_books in the device thread
This commit is contained in:
parent
b9737b9659
commit
2e66bd1aa5
@ -7,13 +7,13 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import json, traceback, posixpath, importlib
|
||||
import json, traceback, posixpath, importlib, os
|
||||
from io import BytesIO
|
||||
|
||||
from calibre import prints
|
||||
from calibre.constants import iswindows, numeric_version
|
||||
from calibre.devices.mtp.base import debug
|
||||
from calibre.ptempfile import SpooledTemporaryFile
|
||||
from calibre.ptempfile import SpooledTemporaryFile, PersistentTemporaryDirectory
|
||||
from calibre.utils.config import from_json, to_json
|
||||
from calibre.utils.date import now, isoformat
|
||||
|
||||
@ -199,10 +199,32 @@ class MTP_DEVICE(BASE):
|
||||
|
||||
# }}}
|
||||
|
||||
# Get files from the device {{{
|
||||
def get_file(self, path, outfile, end_session=True):
|
||||
f = self.filesystem_cache.resolve_mtp_id_path(path)
|
||||
self.get_mtp_file(f, outfile)
|
||||
|
||||
def prepare_addable_books(self, paths):
|
||||
tdir = PersistentTemporaryDirectory('_prepare_mtp')
|
||||
ans = []
|
||||
for path in paths:
|
||||
try:
|
||||
f = self.filesystem_cache.resolve_mtp_id_path(path)
|
||||
except Exception as e:
|
||||
ans.append((path, e, traceback.format_exc()))
|
||||
continue
|
||||
base = os.path.join(tdir, '%s'%f.object_id)
|
||||
os.mkdir(base)
|
||||
with open(os.path.join(base, f.name), 'wb') as out:
|
||||
try:
|
||||
self.get_mtp_file(f, out)
|
||||
except Exception as e:
|
||||
ans.append((path, e, traceback.format_exc()))
|
||||
else:
|
||||
ans.append(out.name)
|
||||
return ans
|
||||
# }}}
|
||||
|
||||
def create_upload_path(self, path, mdata, fname):
|
||||
from calibre.devices import create_upload_path
|
||||
from calibre.utils.filenames import ascii_filename as sanitize
|
||||
|
@ -10,9 +10,9 @@ from functools import partial
|
||||
|
||||
from PyQt4.Qt import QPixmap, QTimer
|
||||
|
||||
|
||||
from calibre.gui2 import error_dialog, choose_files, \
|
||||
choose_dir, warning_dialog, info_dialog
|
||||
from calibre import as_unicode
|
||||
from calibre.gui2 import (error_dialog, choose_files, choose_dir,
|
||||
warning_dialog, info_dialog)
|
||||
from calibre.gui2.dialogs.add_empty_book import AddEmptyBookDialog
|
||||
from calibre.gui2.dialogs.progress import ProgressDialog
|
||||
from calibre.gui2.widgets import IMAGE_EXTENSIONS
|
||||
@ -400,12 +400,45 @@ class AddAction(InterfaceAction):
|
||||
d = error_dialog(self.gui, _('Add to library'), _('No book files found'))
|
||||
d.exec_()
|
||||
return
|
||||
paths = self.gui.device_manager.device.prepare_addable_books(paths)
|
||||
from calibre.gui2.add import Adder
|
||||
self.__adder_func = partial(self._add_from_device_adder, on_card=None,
|
||||
model=view.model())
|
||||
self._adder = Adder(self.gui, self.gui.library_view.model().db,
|
||||
self.Dispatcher(self.__adder_func), spare_server=self.gui.spare_server)
|
||||
self._adder.add(paths)
|
||||
|
||||
self.gui.device_manager.prepare_addable_books(self.Dispatcher(partial(
|
||||
self.books_prepared, view)), paths)
|
||||
self.bpd = ProgressDialog(_('Downloading books'),
|
||||
msg=_('Downloading books from device'), parent=self.gui,
|
||||
cancelable=False)
|
||||
QTimer.singleShot(1000, self.show_bpd)
|
||||
|
||||
def show_bpd(self):
|
||||
if self.bpd is not None:
|
||||
self.bpd.show()
|
||||
|
||||
def books_prepared(self, view, job):
|
||||
self.bpd.hide()
|
||||
self.bpd = None
|
||||
if job.exception is not None:
|
||||
self.gui.device_job_exception(job)
|
||||
return
|
||||
paths = job.result
|
||||
ok_paths = [x for x in paths if isinstance(x, basestring)]
|
||||
failed_paths = [x for x in paths if isinstance(x, tuple)]
|
||||
if failed_paths:
|
||||
if not ok_paths:
|
||||
msg = _('Could not download files from the device')
|
||||
typ = error_dialog
|
||||
else:
|
||||
msg = _('Could not download some files from the device')
|
||||
typ = warning_dialog
|
||||
det_msg = [x[0]+ '\n ' + as_unicode(x[1]) for x in failed_paths]
|
||||
det_msg = '\n\n'.join(det_msg)
|
||||
typ(self.gui, _('Could not download files'), msg, det_msg=det_msg,
|
||||
show=True)
|
||||
|
||||
if ok_paths:
|
||||
from calibre.gui2.add import Adder
|
||||
self.__adder_func = partial(self._add_from_device_adder, on_card=None,
|
||||
model=view.model())
|
||||
self._adder = Adder(self.gui, self.gui.library_view.model().db,
|
||||
self.Dispatcher(self.__adder_func), spare_server=self.gui.spare_server)
|
||||
self._adder.add(ok_paths)
|
||||
|
||||
|
||||
|
@ -443,6 +443,14 @@ class DeviceManager(Thread): # {{{
|
||||
return self.create_job_step(self._books, done,
|
||||
description=_('Get list of books on device'), to_job=add_as_step_to_job)
|
||||
|
||||
def _prepare_addable_books(self, paths):
|
||||
return self.device.prepare_addable_books(paths)
|
||||
|
||||
def prepare_addable_books(self, done, paths, add_as_step_to_job=None):
|
||||
return self.create_job_step(self._prepare_addable_books, done, args=[paths],
|
||||
description=_('Prepare files for transfer from device'),
|
||||
to_job=add_as_step_to_job)
|
||||
|
||||
def _annotations(self, path_map):
|
||||
return self.device.get_annotations(path_map)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user