Refactor the device driver system to support devices from manufacturers that don't bother to assign unique ids to their devices. Preliminary drivers for CyBook Opus (windows/os x) and Cool-er (windows only)

This commit is contained in:
Kovid Goyal 2009-07-31 16:56:37 -06:00
parent 34c75d7aea
commit ab71d9f4cd
7 changed files with 104 additions and 32 deletions

View File

@ -354,8 +354,8 @@ from calibre.customize.profiles import input_profiles, output_profiles
from calibre.devices.bebook.driver import BEBOOK, BEBOOK_MINI from calibre.devices.bebook.driver import BEBOOK, BEBOOK_MINI
from calibre.devices.blackberry.driver import BLACKBERRY from calibre.devices.blackberry.driver import BLACKBERRY
from calibre.devices.cybookg3.driver import CYBOOKG3 from calibre.devices.cybookg3.driver import CYBOOKG3, CYBOOK_OPUS
from calibre.devices.eb600.driver import EB600 from calibre.devices.eb600.driver import EB600, COOL_ER
from calibre.devices.iliad.driver import ILIAD from calibre.devices.iliad.driver import ILIAD
from calibre.devices.irexdr.driver import IREXDR1000 from calibre.devices.irexdr.driver import IREXDR1000
from calibre.devices.jetbook.driver import JETBOOK from calibre.devices.jetbook.driver import JETBOOK
@ -412,6 +412,8 @@ plugins += [
PRS505, PRS505,
PRS700, PRS700,
ANDROID, ANDROID,
CYBOOK_OPUS,
COOL_ER
] ]
plugins += [x for x in list(locals().values()) if isinstance(x, type) and \ plugins += [x for x in list(locals().values()) if isinstance(x, type) and \
x.__name__.endswith('MetadataReader')] x.__name__.endswith('MetadataReader')]

View File

@ -114,16 +114,37 @@ def debug_device_driver():
raw = Device.run_ioreg() raw = Device.run_ioreg()
open('/tmp/ioreg.txt', 'wb').write(raw) open('/tmp/ioreg.txt', 'wb').write(raw)
print 'ioreg output saved to /tmp/ioreg.txt' print 'ioreg output saved to /tmp/ioreg.txt'
connected_devices = []
for dev in device_plugins(): for dev in device_plugins():
print 'Looking for', dev.__class__.__name__ print 'Looking for', dev.__class__.__name__
connected = s.is_device_connected(dev) connected = s.is_device_connected(dev)
if connected: if connected:
print 'Device Connected:', dev connected_devices.append(dev)
print 'Trying to open device...'
errors = {}
success = False
for dev in connected_devices:
print 'Device possibly connected:', dev
print 'Trying to open device...',
try:
dev.open() dev.open()
print 'OK'
except:
import traceback
errors[dev] = traceback.format_exc()
print 'failed'
continue
success = True
print 'Main memory:', repr(dev._main_prefix) print 'Main memory:', repr(dev._main_prefix)
print 'Total space:', dev.total_space() print 'Total space:', dev.total_space()
break break
if not success and errors:
print 'Opening of the following devices failed'
for dev,msg in errors.items():
print dev
print msg
print
def add_simple_plugin(path_to_plugin): def add_simple_plugin(path_to_plugin):
import tempfile, zipfile, shutil import tempfile, zipfile, shutil

View File

@ -124,3 +124,23 @@ class CYBOOKG3(USBMS):
except: except:
pass pass
self.report_progress(1.0, _('Removing books from device...')) self.report_progress(1.0, _('Removing books from device...'))
class CYBOOK_OPUS(CYBOOKG3):
FORMATS = ['epub', 'pdf', 'txt']
VENDOR_ID = [0x0bda]
PRODUCT_ID = [0x0703]
BCD = [0x110]
WINDOWS_MAIN_MEM = 'CYBOOK_OPUS__-FD'
WINDOWS_CARD_A_MEM = 'CYBOOK_OPUS__-SD'
OSX_MAIN_MEM = 'Bookeen Cybook Opus -FD Media'
OSX_CARD_A_MEM = 'Bookeen Cybook Opus -SD Media'
def upload_books(self, *args, **kwargs):
USBMS.upload_books(self, *args, **kwargs)
def delete_books(self, *args, **kwargs):
USBMS.delete_books(self, *args, **kwargs)

View File

@ -20,7 +20,7 @@ class EB600(USBMS):
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']
# Ordered list of supported formats # Ordered list of supported formats
FORMATS = ['epub', 'prc', 'chm', 'djvu', 'html', 'rtf', 'txt', 'pdf'] FORMATS = ['epub', 'mobi', 'prc', 'chm', 'djvu', 'html', 'rtf', 'txt', 'pdf']
DRM_FORMATS = ['prc', 'mobi', 'html', 'pdf', 'txt'] DRM_FORMATS = ['prc', 'mobi', 'html', 'pdf', 'txt']
VENDOR_ID = [0x1f85] VENDOR_ID = [0x1f85]
@ -51,3 +51,12 @@ class EB600(USBMS):
return drives return drives
class COOL_ER(EB600):
FORMATS = ['epub', 'mobi', 'prc', 'pdf', 'txt']
VENDOR_NAME = 'COOL-ER'
WINDOWS_MAIN_MEM = 'EREADER'
EBOOK_DIR_MAIN = 'my docs'

View File

@ -204,15 +204,27 @@ def main():
_wmi = wmi.WMI() _wmi = wmi.WMI()
scanner = DeviceScanner(_wmi) scanner = DeviceScanner(_wmi)
scanner.scan() scanner.scan()
connected_devices = []
for d in device_plugins(): for d in device_plugins():
if scanner.is_device_connected(d): if scanner.is_device_connected(d):
dev = d dev = d
dev.reset(log_packets=options.log_packets) dev.reset(log_packets=options.log_packets)
connected_devices.append(dev)
if dev is None: if dev is None:
print >>sys.stderr, 'Unable to find a connected ebook reader.' print >>sys.stderr, 'Unable to find a connected ebook reader.'
return 1 return 1
for d in connected_devices:
try:
d.open()
except:
continue
else:
dev = d
break
try: try:
dev.open() dev.open()
if command == "df": if command == "df":

View File

@ -16,7 +16,7 @@ def get_metadata(stream, extract_cover=True):
mdata = u'' mdata = u''
for x in range(0, 4): for x in range(0, 4):
line = stream.readline().decode('utf-8') line = stream.readline().decode('utf-8', 'replace')
if line == '': if line == '':
break break
else: else:

View File

@ -89,33 +89,39 @@ class DeviceManager(Thread):
self.current_job = None self.current_job = None
self.scanner = DeviceScanner() self.scanner = DeviceScanner()
def detect_device(self): def do_connect(self, connected_devices):
self.scanner.scan()
for device in self.devices:
connected = self.scanner.is_device_connected(device[0])
if connected and not device[1]:
if device[2]:
continue
try:
dev = device[0]
dev.reset()
if iswindows: if iswindows:
import pythoncom import pythoncom
pythoncom.CoInitialize() pythoncom.CoInitialize()
try:
for dev in connected_devices:
dev.reset()
try: try:
dev.open() dev.open()
finally: except:
if iswindows: print 'Unable to open device', dev
pythoncom.CoUninitialize() traceback.print_exc()
continue
self.device = dev self.device = dev
self.device_class = dev.__class__ self.device_class = dev.__class__
self.connected_slot(True) self.connected_slot(True)
except: break
print 'Unable to open device'
traceback.print_exc()
finally: finally:
if iswindows:
pythoncom.CoUninitialize()
def detect_device(self):
self.scanner.scan()
connected_devices = []
for device in self.devices:
connected = self.scanner.is_device_connected(device[0])
if connected and not device[1] and not device[2]:
# If connected and not showing in GUI and not ejected
connected_devices.append(device[0])
device[1] = True device[1] = True
elif not connected and device[1]: elif not connected and device[1]:
# Disconnected but showing in GUI
while True: while True:
try: try:
job = self.jobs.get_nowait() job = self.jobs.get_nowait()
@ -126,6 +132,8 @@ class DeviceManager(Thread):
self.device = None self.device = None
self.connected_slot(False) self.connected_slot(False)
device[1] ^= True device[1] ^= True
if connected_devices:
self.do_connect(connected_devices)
def umount_device(self): def umount_device(self):
if self.device is not None: if self.device is not None: