diff --git a/src/calibre/devices/cybookg3/driver.py b/src/calibre/devices/cybookg3/driver.py index 4ab6dc297b..495a7f1b81 100644 --- a/src/calibre/devices/cybookg3/driver.py +++ b/src/calibre/devices/cybookg3/driver.py @@ -7,6 +7,7 @@ Device driver for Bookeen's Cybook Gen 3 import os, shutil from itertools import cycle +from calibre.devices.errors import FreeSpaceError from calibre.devices.usbms.driver import USBMS import calibre.devices.cybookg3.t2b as t2b from calibre.devices.errors import FreeSpaceError diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index d85fdef29a..1d3aba37de 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -18,21 +18,21 @@ class Device(_Device): as USB Mass Storage devices. If you are writing such a driver, inherit from this class. ''' - + VENDOR_ID = 0x0 PRODUCT_ID = 0x0 BCD = None - + VENDOR_NAME = None WINDOWS_MAIN_MEM = None WINDOWS_CARD_MEM = None - + OSX_MAIN_MEM = None OSX_CARD_MEM = None - + MAIN_MEMORY_VOLUME_LABEL = '' STORAGE_CARD_VOLUME_LABEL = '' - + FDI_TEMPLATE = \ ''' @@ -65,15 +65,15 @@ class Device(_Device): ''' FDI_BCD_TEMPLATE = '' - - + + def __init__(self, key='-1', log_packets=False, report_progress=None) : self._main_prefix = self._card_prefix = None - + @classmethod def get_fdi(cls): fdi = '' - + fdi_base_values = dict( app=__appname__, deviceclass=cls.__name__, @@ -92,12 +92,12 @@ class Device(_Device): fdi_bcd_values['BCD_start'] = cls.FDI_BCD_TEMPLATE % dict(bcd=hex(bcd)) fdi_bcd_values['BCD_end'] = '' fdi += cls.FDI_TEMPLATE % fdi_bcd_values - + return fdi - + def set_progress_reporter(self, report_progress): self.report_progress = report_progress - + def card_prefix(self, end_session=True): return self._card_prefix @@ -117,7 +117,7 @@ class Device(_Device): else: raise mult = sectors_per_cluster * bytes_per_sector return total_clusters * mult, free_clusters * mult - + def total_space(self, end_session=True): msz = csz = 0 print self._main_prefix @@ -131,9 +131,9 @@ class Device(_Device): else: msz = self._windows_space(self._main_prefix)[0] csz = self._windows_space(self._card_prefix)[0] - + return (msz, 0, csz) - + def free_space(self, end_session=True): msz = csz = 0 if not iswindows: @@ -146,15 +146,15 @@ class Device(_Device): else: msz = self._windows_space(self._main_prefix)[1] csz = self._windows_space(self._card_prefix)[1] - + return (msz, 0, csz) def windows_match_device(self, pnp_id, device_id): pnp_id = pnp_id.upper() - + if device_id and pnp_id is not None: device_id = device_id.upper() - + if 'VEN_' + self.VENDOR_NAME in pnp_id and 'PROD_' + device_id in pnp_id: return True @@ -162,32 +162,32 @@ class Device(_Device): def windows_get_drive_prefix(self, drive): prefix = None - + try: partition = drive.associators("Win32_DiskDriveToDiskPartition")[0] logical_disk = partition.associators('Win32_LogicalDiskToPartition')[0] prefix = logical_disk.DeviceID + os.sep except IndexError: pass - + return prefix def open_windows(self): drives = {} - wmi = __import__('wmi', globals(), locals(), [], -1) + wmi = __import__('wmi', globals(), locals(), [], -1) c = wmi.WMI() for drive in c.Win32_DiskDrive(): if self.windows_match_device(str(drive.PNPDeviceID), self.WINDOWS_MAIN_MEM): drives['main'] = self.windows_get_drive_prefix(drive) elif self.windows_match_device(str(drive.PNPDeviceID), self.WINDOWS_CARD_MEM): drives['card'] = self.windows_get_drive_prefix(drive) - + if 'main' and 'card' in drives.keys(): break - + if not drives: raise DeviceError(_('Unable to detect the %s disk drive. Try rebooting.') % self.__class__.__name__) - + self._main_prefix = drives.get('main', None) self._card_prefix = drives.get('card', None) @@ -197,11 +197,11 @@ class Device(_Device): ioreg = '/usr/sbin/ioreg' if not os.access(ioreg, os.X_OK): ioreg = 'ioreg' - raw = subprocess.Popen((ioreg+' -w 0 -S -c IOMedia').split(), + raw = subprocess.Popen((ioreg+' -w 0 -S -c IOMedia').split(), stdout=subprocess.PIPE).stdout.read() lines = raw.splitlines() names = {} - + def get_dev_node(lines, loc): for line in lines: line = line.strip() @@ -211,7 +211,7 @@ class Device(_Device): if match is not None: names[loc] = match.group(1) break - + for i, line in enumerate(lines): if self.OSX_MAIN_MEM is not None and line.strip().endswith('') and self.OSX_MAIN_MEM in line: get_dev_node(lines[i+1:], 'main') @@ -220,7 +220,7 @@ class Device(_Device): if len(names.keys()) == 2: break return names - + def open_osx(self): mount = subprocess.Popen('mount', shell=True, stdout=subprocess.PIPE).stdout.read() names = self.get_osx_mountpoints() @@ -233,12 +233,12 @@ class Device(_Device): if card_pat is not None: card_pat = dev_pat%card_pat self._card_prefix = re.search(card_pat, mount).group(2) + os.sep - + def open_linux(self): import dbus - bus = dbus.SystemBus() + bus = dbus.SystemBus() hm = dbus.Interface(bus.get_object("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager"), "org.freedesktop.Hal.Manager") - + def conditional_mount(dev): mmo = bus.get_object("org.freedesktop.Hal", dev) label = mmo.GetPropertyString('volume.label', dbus_interface='org.freedesktop.Hal.Device') @@ -247,10 +247,10 @@ class Device(_Device): fstype = mmo.GetPropertyString('volume.fstype', dbus_interface='org.freedesktop.Hal.Device') if is_mounted: return str(mount_point) - mmo.Mount(label, fstype, ['umask=077', 'uid='+str(os.getuid()), 'sync'], + mmo.Mount(label, fstype, ['umask=077', 'uid='+str(os.getuid()), 'sync'], dbus_interface='org.freedesktop.Hal.Device.Volume') return os.path.normpath('/media/'+label)+'/' - + mm = hm.FindDeviceStringMatch(__appname__+'.mainvolume', self.__class__.__name__) if not mm: raise DeviceError(_('Unable to detect the %s disk drive. Try rebooting.')%(self.__class__.__name__,)) @@ -261,13 +261,13 @@ class Device(_Device): break except dbus.exceptions.DBusException: continue - + if not self._main_prefix: raise DeviceError('Could not open device for reading. Try a reboot.') - + self._card_prefix = None cards = hm.FindDeviceStringMatch(__appname__+'.cardvolume', self.__class__.__name__) - + for dev in cards: try: self._card_prefix = conditional_mount(dev)+os.sep diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index eb02408aef..10e655ac39 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -27,7 +27,6 @@ class File(object): self.path = path self.name = os.path.basename(path) - class USBMS(Device): FORMATS = [] EBOOK_DIR_MAIN = '' @@ -36,38 +35,38 @@ class USBMS(Device): def __init__(self, key='-1', log_packets=False, report_progress=None): pass - + def get_device_information(self, end_session=True): - """ - Ask device for device information. See L{DeviceInfoQuery}. + """ + Ask device for device information. See L{DeviceInfoQuery}. @return: (device name, device version, software version on device, mime type) """ return (self.__class__.__name__, '', '', '') - + def books(self, oncard=False, end_session=True): bl = BookList() - - if oncard and self._card_prefix is None: - return bl + + if oncard and self._card_prefix is None: + return bl prefix = self._card_prefix if oncard else self._main_prefix ebook_dir = self.EBOOK_DIR_CARD if oncard else self.EBOOK_DIR_MAIN - + # Get all books in all directories under the root ebook_dir directory for path, dirs, files in os.walk(os.path.join(prefix, ebook_dir)): # Filter out anything that isn't in the list of supported ebook types for book_type in self.FORMATS: for filename in fnmatch.filter(files, '*.%s' % (book_type)): title, author, mime = self.__class__.extract_book_metadata_by_filename(filename) - - bl.append(Book(os.path.join(path, filename), title, author, mime)) + + bl.append(Book(os.path.join(path, filename), title, author, mime)) return bl - - def upload_books(self, files, names, on_card=False, end_session=True, + + def upload_books(self, files, names, on_card=False, end_session=True, metadata=None): if on_card and not self._card_prefix: raise ValueError(_('The reader has no storage card connected.')) - + if not on_card: path = os.path.join(self._main_prefix, self.EBOOK_DIR_MAIN) else: @@ -84,21 +83,21 @@ class USBMS(Device): sizes = map(get_size, files) size = sum(sizes) - if on_card and size > self.free_space()[2] - 1024*1024: + if on_card and size > self.free_space()[2] - 1024*1024: raise FreeSpaceError(_("There is insufficient free space on the storage card")) - if not on_card and size > self.free_space()[0] - 2*1024*1024: + if not on_card and size > self.free_space()[0] - 2*1024*1024: raise FreeSpaceError(_("There is insufficient free space in main memory")) paths = [] names = iter(names) metadata = iter(metadata) - + for infile in files: newpath = path - + if self.SUPPORTS_SUB_DIRS: mdata = metadata.next() - + if 'tags' in mdata.keys(): for tag in mdata['tags']: if tag.startswith('/'): @@ -108,32 +107,32 @@ class USBMS(Device): if not os.path.exists(newpath): os.makedirs(newpath) - - filepath = os.path.join(newpath, names.next()) + + filepath = os.path.join(newpath, names.next()) paths.append(filepath) - + if hasattr(infile, 'read'): infile.seek(0) - + dest = open(filepath, 'wb') shutil.copyfileobj(infile, dest, 10*1024*1024) - dest.flush() + dest.flush() dest.close() else: shutil.copy2(infile, filepath) - + return zip(paths, cycle([on_card])) - + @classmethod - def add_books_to_metadata(cls, locations, metadata, booklists): + def add_books_to_metadata(cls, locations, metadata, booklists): for location in locations: path = location[0] on_card = 1 if location[1] else 0 - + title, author, mime = cls.extract_book_metadata_by_filename(os.path.basename(path)) booklists[on_card].append(Book(path, title, author, mime)) - + def delete_books(self, paths, end_session=True): for path in paths: if os.path.exists(path): @@ -144,7 +143,7 @@ class USBMS(Device): os.removedirs(os.path.dirname(path)) except: pass - + @classmethod def remove_books_from_metadata(cls, paths, booklists): for path in paths: @@ -152,14 +151,14 @@ class USBMS(Device): for book in bl: if path.endswith(book.path): bl.remove(book) - + def sync_booklists(self, booklists, end_session=True): # There is no meta data on the device to update. The device is treated # as a mass storage device and does not use a meta data xml file like # the Sony Readers. pass - - def get_file(self, path, outfile, end_session=True): + + def get_file(self, path, outfile, end_session=True): path = self.munge_path(path) src = open(path, 'rb') shutil.copyfileobj(src, outfile, 10*1024*1024) @@ -229,7 +228,7 @@ class USBMS(Device): # the filename without the extension else: book_title = os.path.splitext(filename)[0].replace('_', ' ') - + fileext = os.path.splitext(filename)[1][1:] if fileext in cls.FORMATS: