diff --git a/src/calibre/devices/mtp/filesystem_cache.py b/src/calibre/devices/mtp/filesystem_cache.py index cf259893e6..99c961a228 100644 --- a/src/calibre/devices/mtp/filesystem_cache.py +++ b/src/calibre/devices/mtp/filesystem_cache.py @@ -8,6 +8,7 @@ __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' import weakref, sys +from collections import deque from operator import attrgetter from future_builtins import map @@ -50,6 +51,16 @@ class FileOrFolder(object): def parent(self): return None if self.parent_id is None else self.id_map[self.parent_id] + @property + def full_path(self): + parts = deque() + parts.append(self.name) + p = self.parent + while p is not None: + parts.appendleft(p.name) + p = p.parent + return tuple(parts) + def __iter__(self): for e in self.folders: yield e diff --git a/src/calibre/devices/mtp/windows/driver.py b/src/calibre/devices/mtp/windows/driver.py index d079a0f71a..f5c999760a 100644 --- a/src/calibre/devices/mtp/windows/driver.py +++ b/src/calibre/devices/mtp/windows/driver.py @@ -15,7 +15,7 @@ from itertools import chain from calibre import as_unicode, prints from calibre.constants import plugins, __appname__, numeric_version from calibre.ptempfile import SpooledTemporaryFile -from calibre.devices.errors import OpenFailed +from calibre.devices.errors import OpenFailed, DeviceError from calibre.devices.mtp.base import MTPDeviceBase from calibre.devices.mtp.filesystem_cache import FilesystemCache @@ -245,13 +245,20 @@ class MTP_DEVICE(MTPDeviceBase): @same_thread def get_file(self, object_id, stream=None, callback=None): + f = self.filesystem_cache.id_map[object_id] + if f.is_folder: + raise ValueError('%s is a folder on the device'%f.full_path) if stream is None: stream = SpooledTemporaryFile(5*1024*1024, '_wpd_receive_file.dat') try: - self.dev.get_file(object_id, stream, callback) - except self.wpd.WPDFileBusy: - time.sleep(2) - self.dev.get_file(object_id, stream, callback) + try: + self.dev.get_file(object_id, stream, callback) + except self.wpd.WPDFileBusy: + time.sleep(2) + self.dev.get_file(object_id, stream, callback) + except Exception as e: + raise DeviceError('Failed to fetch the file %s with error: %s'% + f.full_path, as_unicode(e)) return stream @same_thread