diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py index b43b242fd8..0e6bad8d2e 100644 --- a/src/calibre/customize/__init__.py +++ b/src/calibre/customize/__init__.py @@ -221,5 +221,4 @@ class MetadataWriterPlugin(Plugin): ''' pass - - \ No newline at end of file + diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index dcbffade92..0b5a0295ea 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -295,9 +295,19 @@ from calibre.ebooks.pdf.output import PDFOutput from calibre.ebooks.pdb.ereader.output import EREADEROutput from calibre.customize.profiles import input_profiles, output_profiles +from calibre.devices.prs500.driver import PRS500 +from calibre.devices.prs505.driver import PRS505 +from calibre.devices.prs700.driver import PRS700 +from calibre.devices.cybookg3.driver import CYBOOKG3 +from calibre.devices.kindle.driver import KINDLE +from calibre.devices.kindle.driver import KINDLE2 +from calibre.devices.blackberry.driver import BLACKBERRY +from calibre.devices.eb600.driver import EB600 + plugins = [HTML2ZIP, EPUBInput, MOBIInput, PDBInput, PDFInput, HTMLInput, TXTInput, OEBOutput, TXTOutput, PDFOutput, LITInput, ComicInput, FB2Input, ODTInput, RTFInput, EPUBOutput, EREADEROutput, RecipeInput] +plugins += [PRS505, PRS700, CYBOOKG3, KINDLE, KINDLE2, BLACKBERRY, EB600] plugins += [x for x in list(locals().values()) if isinstance(x, type) and \ x.__name__.endswith('MetadataReader')] plugins += [x for x in list(locals().values()) if isinstance(x, type) and \ diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py index 4bd5c9b284..ad321a1f83 100644 --- a/src/calibre/customize/ui.py +++ b/src/calibre/customize/ui.py @@ -10,6 +10,7 @@ from calibre.customize.conversion import InputFormatPlugin, OutputFormatPlugin from calibre.customize.profiles import InputProfile, OutputProfile from calibre.customize.builtins import plugins as builtin_plugins from calibre.constants import __version__, iswindows, isosx +from calibre.devices.interface import DevicePlugin from calibre.ebooks.metadata import MetaInformation from calibre.utils.config import make_config_dir, Config, ConfigProxy, \ plugin_dir, OptionParser @@ -286,6 +287,12 @@ def available_output_formats(): formats.add(plugin.file_type) return formats +def device_plugins(): + for plugin in _initialized_plugins: + if isinstance(plugin, DevicePlugin): + if not is_disabled(plugin): + yield plugin + def disable_plugin(plugin_or_name): x = getattr(plugin_or_name, 'name', plugin_or_name) plugin = find_plugin(x) diff --git a/src/calibre/devices/__init__.py b/src/calibre/devices/__init__.py index 9c515c07fd..874de7c070 100644 --- a/src/calibre/devices/__init__.py +++ b/src/calibre/devices/__init__.py @@ -5,18 +5,6 @@ __copyright__ = '2008, Kovid Goyal ' Device drivers. ''' -def devices(): - from calibre.devices.prs500.driver import PRS500 - from calibre.devices.prs505.driver import PRS505 - from calibre.devices.prs700.driver import PRS700 - from calibre.devices.cybookg3.driver import CYBOOKG3 - from calibre.devices.kindle.driver import KINDLE - from calibre.devices.kindle.driver import KINDLE2 - from calibre.devices.blackberry.driver import BLACKBERRY - from calibre.devices.eb600.driver import EB600 - return (PRS500, PRS505, PRS700, CYBOOKG3, KINDLE, KINDLE2, - BLACKBERRY, EB600) - import time DAY_MAP = dict(Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6) diff --git a/src/calibre/devices/blackberry/driver.py b/src/calibre/devices/blackberry/driver.py index f6c615b0de..da2328419a 100644 --- a/src/calibre/devices/blackberry/driver.py +++ b/src/calibre/devices/blackberry/driver.py @@ -7,6 +7,12 @@ __docformat__ = 'restructuredtext en' from calibre.devices.usbms.driver import USBMS class BLACKBERRY(USBMS): + + name = 'Blackberry Device Interface' + description = _('Communicate with the Blackberry smart phone.') + author = _('Kovid Goyal') + supported_platforms = ['windows', 'linux'] + # Ordered list of supported formats FORMATS = ['mobi', 'prc'] @@ -16,15 +22,11 @@ class BLACKBERRY(USBMS): VENDOR_NAME = 'RIM' WINDOWS_MAIN_MEM = 'BLACKBERRY_SD' - #WINDOWS_CARD_MEM = 'CARD_STORAGE' #OSX_MAIN_MEM = 'Kindle Internal Storage Media' - #OSX_CARD_MEM = 'Kindle Card Storage Media' MAIN_MEMORY_VOLUME_LABEL = 'Blackberry Main Memory' - #STORAGE_CARD_VOLUME_LABEL = 'Kindle Storage Card' EBOOK_DIR_MAIN = 'ebooks' - #EBOOK_DIR_CARD = "documents" SUPPORTS_SUB_DIRS = True diff --git a/src/calibre/devices/cybookg3/driver.py b/src/calibre/devices/cybookg3/driver.py index 1cdf9863b4..7f3e5a82f4 100644 --- a/src/calibre/devices/cybookg3/driver.py +++ b/src/calibre/devices/cybookg3/driver.py @@ -12,6 +12,12 @@ from calibre.devices.usbms.driver import USBMS import calibre.devices.cybookg3.t2b as t2b class CYBOOKG3(USBMS): + name = 'Cybook Gen 3 Device Interface' + description = _('Communicate with the Cybook eBook reader.') + author = _('John Schember') + supported_platforms = ['windows', 'osx', 'linux'] + + # Ordered list of supported formats # Be sure these have an entry in calibre.devices.mime FORMATS = ['mobi', 'prc', 'html', 'pdf', 'rtf', 'txt'] diff --git a/src/calibre/devices/eb600/driver.py b/src/calibre/devices/eb600/driver.py index cb2f25d2f9..638dea42ba 100644 --- a/src/calibre/devices/eb600/driver.py +++ b/src/calibre/devices/eb600/driver.py @@ -7,6 +7,11 @@ Device driver for the Netronix EB600 from calibre.devices.usbms.driver import USBMS class EB600(USBMS): + name = 'Netronix EB600 Device Interface' + description = _('Communicate with the EB600 eBook reader.') + author = _('Kovid Goyal') + supported_platforms = ['windows', 'osx', 'linux'] + # Ordered list of supported formats FORMATS = ['epub', 'prc', 'chm', 'djvu', 'html', 'rtf', 'txt', 'pdf'] DRM_FORMATS = ['prc', 'mobi', 'html', 'pdf', 'txt'] diff --git a/src/calibre/devices/interface.py b/src/calibre/devices/interface.py index 0ad01e7493..94cecd65b6 100644 --- a/src/calibre/devices/interface.py +++ b/src/calibre/devices/interface.py @@ -6,8 +6,9 @@ the GUI. A device backend must subclass the L{Device} class. See prs500.py for a backend that implement the Device interface for the SONY PRS500 Reader. """ +from calibre.customize import Plugin -class Device(object): +class DevicePlugin(Plugin): """ Defines the interface that should be implemented by backends that communicate with an ebook reader. @@ -16,6 +17,8 @@ class Device(object): the front-end needs to call several methods one after another, in which case the USB session should not be closed after each method call. """ + type = _('Device Interface') + # Ordered list of supported formats FORMATS = ["lrf", "rtf", "pdf", "txt"] VENDOR_ID = 0x0000 @@ -27,8 +30,8 @@ class Device(object): # Whether the metadata on books can be set via the GUI. CAN_SET_METADATA = True - def __init__(self, key='-1', log_packets=False, report_progress=None) : - """ + def reset(self, key='-1', log_packets=False, report_progress=None) : + """ @param key: The key to unlock the device @param log_packets: If true the packet stream to/from the device is logged @param report_progress: Function that is called with a % progress diff --git a/src/calibre/devices/kindle/driver.py b/src/calibre/devices/kindle/driver.py index d598e2a503..6f17cd335a 100644 --- a/src/calibre/devices/kindle/driver.py +++ b/src/calibre/devices/kindle/driver.py @@ -6,9 +6,14 @@ Device driver for Amazon's Kindle import os, re, sys -from calibre.devices.usbms.driver import USBMS, metadata_from_formats +from calibre.devices.usbms.driver import USBMS class KINDLE(USBMS): + name = 'Kindle Device Interface' + description = _('Communicate with the Kindle eBook reader.') + author = _('John Schember') + supported_platforms = ['windows', 'osx', 'linux'] + # Ordered list of supported formats FORMATS = ['azw', 'mobi', 'prc', 'azw1', 'tpz', 'txt'] @@ -46,6 +51,7 @@ class KINDLE(USBMS): @classmethod def metadata_from_path(cls, path): + from calibre.devices.usbms.driver import metadata_from_formats mi = metadata_from_formats([path]) if mi.title == _('Unknown') or ('-asin' in mi.title and '-type' in mi.title): match = cls.WIRELESS_FILE_NAME_PATTERN.match(os.path.basename(path)) @@ -58,6 +64,10 @@ class KINDLE(USBMS): class KINDLE2(KINDLE): + name = 'Kindle 2 Device Interface' + description = _('Communicate with the Kindle 2 eBook reader.') + author = _('John Schember') + supported_platforms = ['windows', 'osx', 'linux'] PRODUCT_ID = [0x0002] BCD = [0x0100] diff --git a/src/calibre/devices/prs500/driver.py b/src/calibre/devices/prs500/driver.py index a905a314ae..874ed494e4 100644 --- a/src/calibre/devices/prs500/driver.py +++ b/src/calibre/devices/prs500/driver.py @@ -40,7 +40,7 @@ from array import array from functools import wraps from StringIO import StringIO -from calibre.devices.interface import Device +from calibre.devices.interface import DevicePlugin from calibre.devices.libusb import Error as USBError from calibre.devices.libusb import get_device_by_id from calibre.devices.prs500.prstypes import * @@ -76,12 +76,16 @@ class File(object): return self.name -class PRS500(Device): +class PRS500(DevicePlugin): """ Implements the backend for communication with the SONY Reader. Each method decorated by C{safe} performs a task. """ + name = 'PRS-500 Device Interface' + description = _('Communicate with the Sony PRS-500 eBook reader.') + author = _('Kovid Goyal') + supported_platforms = ['windows', 'osx', 'linux'] VENDOR_ID = 0x054c #: SONY Vendor Id PRODUCT_ID = 0x029b #: Product Id for the PRS-500 @@ -181,7 +185,7 @@ class PRS500(Device): return run_session - def __init__(self, key='-1', log_packets=False, report_progress=None) : + def reset(self, key='-1', log_packets=False, report_progress=None) : """ @param key: The key to unlock the device @param log_packets: If true the packet stream to/from the device is logged diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index a704eb1ec3..f569667ba1 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -1,5 +1,6 @@ __license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal ' +__copyright__ = '2008, Kovid Goyal ' \ + '2009, John Schember ' ''' Device driver for the SONY PRS-505 ''' @@ -14,6 +15,12 @@ from calibre import iswindows, islinux, isosx, __appname__ from calibre.devices.errors import PathError class PRS505(CLI, Device): + + name = 'PRS-505 Device Interface' + description = _('Communicate with the Sony PRS-505 eBook reader.') + author = _('Kovid Goyal and John Schember') + supported_platforms = ['windows', 'osx', 'linux'] + FORMATS = ['epub', 'lrf', 'lrx', 'rtf', 'pdf', 'txt'] VENDOR_ID = [0x054c] #: SONY Vendor Id diff --git a/src/calibre/devices/prs700/driver.py b/src/calibre/devices/prs700/driver.py index 2b82eb3e34..a79902fe10 100644 --- a/src/calibre/devices/prs700/driver.py +++ b/src/calibre/devices/prs700/driver.py @@ -8,6 +8,11 @@ Device driver for the SONY PRS-700 from calibre.devices.prs505.driver import PRS505 class PRS700(PRS505): + + name = 'PRS-700 Device Interface' + description = _('Communicate with the Sony PRS-700 eBook reader.') + author = _('Kovid Goyal and John Schember') + supported_platforms = ['windows', 'osx', 'linux'] BCD = [0x31a] diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index 8f2755d3fa..c4bbe7839f 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -8,11 +8,11 @@ device. This class handles device detection. import os, subprocess, time, re -from calibre.devices.interface import Device as _Device +from calibre.devices.interface import DevicePlugin as Device from calibre.devices.errors import DeviceError from calibre import iswindows, islinux, isosx, __appname__ -class Device(_Device): +class Device(Device): ''' This class provides logic common to all drivers for devices that export themselves as USB Mass Storage devices. If you are writing such a driver, inherit from this @@ -83,7 +83,7 @@ class Device(_Device): FDI_BCD_TEMPLATE = '' - def __init__(self, key='-1', log_packets=False, report_progress=None) : + def reset(self, key='-1', log_packets=False, report_progress=None) : self._main_prefix = self._card_a_prefix = self._card_b_prefix = None @classmethod diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index aa40f90c25..156e3a5eb5 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -10,7 +10,6 @@ for a particular device. import os, fnmatch, shutil from itertools import cycle -from calibre.ebooks.metadata.meta import metadata_from_formats, path_to_ext from calibre.ebooks.metadata import authors_to_string from calibre.devices.usbms.cli import CLI from calibre.devices.usbms.device import Device @@ -21,6 +20,12 @@ from calibre.devices.mime import mime_type_ext # CLI must come before Device as it implments the CLI functions that # are inherited from the device interface in Device. class USBMS(CLI, Device): + + name = 'USBMS Base Device Interface' + description = _('Communicate with an eBook reader.') + author = _('John Schember') + supported_platforms = ['windows', 'osx', 'linux'] + FORMATS = [] EBOOK_DIR_MAIN = '' EBOOK_DIR_CARD_A = '' @@ -28,8 +33,8 @@ class USBMS(CLI, Device): SUPPORTS_SUB_DIRS = False CAN_SET_METADATA = False - def __init__(self, key='-1', log_packets=False, report_progress=None): - Device.__init__(self, key=key, log_packets=log_packets, + def reset(self, key='-1', log_packets=False, report_progress=None): + Device.reset(self, key=key, log_packets=log_packets, report_progress=report_progress) def get_device_information(self, end_session=True): @@ -40,6 +45,7 @@ class USBMS(CLI, Device): return (self.__class__.__name__, '', '', '') def books(self, oncard=None, end_session=True): + from calibre.ebooks.metadata.meta import path_to_ext bl = BookList() if oncard == 'carda' and not self._card_a_prefix: @@ -185,10 +191,12 @@ class USBMS(CLI, Device): @classmethod def metadata_from_path(cls, path): + from calibre.ebooks.metadata.meta import metadata_from_formats return metadata_from_formats([path]) @classmethod def book_from_path(cls, path): + from calibre.ebooks.metadata.meta import path_to_ext fileext = path_to_ext(path) mi = cls.metadata_from_path(path) mime = mime_type_ext(fileext) diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 239fd4d37d..bbdc62746f 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -10,8 +10,8 @@ from binascii import unhexlify from PyQt4.Qt import QMenu, QAction, QActionGroup, QIcon, SIGNAL, QPixmap, \ Qt -from calibre.customize.ui import available_input_formats, available_output_formats -from calibre.devices import devices +from calibre.customize.ui import available_input_formats, available_output_formats, \ + device_plugins from calibre.constants import iswindows from calibre.gui2.dialogs.choose_format import ChooseFormatDialog from calibre.parallel import Job @@ -21,7 +21,6 @@ from calibre.gui2 import config, error_dialog, Dispatcher, dynamic, \ info_dialog from calibre.ebooks.metadata import authors_to_string from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog -from calibre.devices.interface import Device from calibre import sanitize_file_name, preferred_encoding from calibre.utils.filenames import ascii_filename from calibre.devices.errors import FreeSpaceError @@ -54,7 +53,7 @@ class DeviceManager(Thread): ''' Thread.__init__(self) self.setDaemon(True) - self.devices = [[d, False] for d in devices()] + self.devices = [[d, False] for d in device_plugins()] self.device = None self.device_class = None self.sleep_time = sleep_time @@ -71,7 +70,8 @@ class DeviceManager(Thread): connected = self.scanner.is_device_connected(device[0]) if connected and not device[1]: try: - dev = device[0]() + dev = device[0] + dev.reset() if iswindows: import pythoncom pythoncom.CoInitialize()