mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
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:
parent
34c75d7aea
commit
ab71d9f4cd
@ -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')]
|
||||||
|
@ -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 'Main memory:', repr(dev._main_prefix)
|
print 'OK'
|
||||||
print 'Total space:', dev.total_space()
|
except:
|
||||||
break
|
import traceback
|
||||||
|
errors[dev] = traceback.format_exc()
|
||||||
|
print 'failed'
|
||||||
|
continue
|
||||||
|
success = True
|
||||||
|
print 'Main memory:', repr(dev._main_prefix)
|
||||||
|
print 'Total space:', dev.total_space()
|
||||||
|
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
|
||||||
|
@ -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)
|
||||||
|
@ -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'
|
||||||
|
|
||||||
|
@ -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":
|
||||||
|
@ -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:
|
||||||
|
@ -89,33 +89,39 @@ class DeviceManager(Thread):
|
|||||||
self.current_job = None
|
self.current_job = None
|
||||||
self.scanner = DeviceScanner()
|
self.scanner = DeviceScanner()
|
||||||
|
|
||||||
|
def do_connect(self, connected_devices):
|
||||||
|
if iswindows:
|
||||||
|
import pythoncom
|
||||||
|
pythoncom.CoInitialize()
|
||||||
|
try:
|
||||||
|
for dev in connected_devices:
|
||||||
|
dev.reset()
|
||||||
|
try:
|
||||||
|
dev.open()
|
||||||
|
except:
|
||||||
|
print 'Unable to open device', dev
|
||||||
|
traceback.print_exc()
|
||||||
|
continue
|
||||||
|
self.device = dev
|
||||||
|
self.device_class = dev.__class__
|
||||||
|
self.connected_slot(True)
|
||||||
|
break
|
||||||
|
finally:
|
||||||
|
if iswindows:
|
||||||
|
pythoncom.CoUninitialize()
|
||||||
|
|
||||||
|
|
||||||
def detect_device(self):
|
def detect_device(self):
|
||||||
self.scanner.scan()
|
self.scanner.scan()
|
||||||
|
connected_devices = []
|
||||||
for device in self.devices:
|
for device in self.devices:
|
||||||
connected = self.scanner.is_device_connected(device[0])
|
connected = self.scanner.is_device_connected(device[0])
|
||||||
if connected and not device[1]:
|
if connected and not device[1] and not device[2]:
|
||||||
if device[2]:
|
# If connected and not showing in GUI and not ejected
|
||||||
continue
|
connected_devices.append(device[0])
|
||||||
try:
|
device[1] = True
|
||||||
dev = device[0]
|
|
||||||
dev.reset()
|
|
||||||
if iswindows:
|
|
||||||
import pythoncom
|
|
||||||
pythoncom.CoInitialize()
|
|
||||||
try:
|
|
||||||
dev.open()
|
|
||||||
finally:
|
|
||||||
if iswindows:
|
|
||||||
pythoncom.CoUninitialize()
|
|
||||||
self.device = dev
|
|
||||||
self.device_class = dev.__class__
|
|
||||||
self.connected_slot(True)
|
|
||||||
except:
|
|
||||||
print 'Unable to open device'
|
|
||||||
traceback.print_exc()
|
|
||||||
finally:
|
|
||||||
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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user