Sync to trunk.

This commit is contained in:
John Schember 2009-08-28 22:31:47 -04:00
commit d6d268b92a
6 changed files with 49 additions and 34 deletions

View File

@ -9,6 +9,7 @@ from calibre.devices.usbms.driver import USBMS
class ANDROID(USBMS): class ANDROID(USBMS):
name = 'Android driver' name = 'Android driver'
gui_name = 'Android phone'
description = _('Communicate with Android phones.') description = _('Communicate with Android phones.')
author = 'Kovid Goyal' author = 'Kovid Goyal'
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']

View File

@ -15,6 +15,7 @@ from calibre.devices.usbms.driver import USBMS
class BEBOOK(USBMS): class BEBOOK(USBMS):
name = 'BeBook driver' name = 'BeBook driver'
gui_name = 'BeBook'
description = _('Communicate with the BeBook eBook reader.') description = _('Communicate with the BeBook eBook reader.')
author = 'Tijmen Ruizendaal' author = 'Tijmen Ruizendaal'
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']
@ -90,6 +91,7 @@ class BEBOOK(USBMS):
class BEBOOK_MINI(BEBOOK): class BEBOOK_MINI(BEBOOK):
name = 'BeBook Mini driver' name = 'BeBook Mini driver'
gui_name = 'BeBook Mini'
description = _('Communicate with the BeBook Mini eBook reader.') description = _('Communicate with the BeBook Mini eBook reader.')

View File

@ -17,6 +17,7 @@ import calibre.devices.cybookg3.t2b as t2b
class CYBOOKG3(USBMS): class CYBOOKG3(USBMS):
name = 'Cybook Gen 3 Device Interface' name = 'Cybook Gen 3 Device Interface'
gui_name = 'Cybook Gen 3'
description = _('Communicate with the Cybook Gen 3 eBook reader.') description = _('Communicate with the Cybook Gen 3 eBook reader.')
author = _('John Schember') author = _('John Schember')
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']
@ -81,6 +82,7 @@ class CYBOOKG3(USBMS):
class CYBOOK_OPUS(USBMS): class CYBOOK_OPUS(USBMS):
name = 'Cybook Opus Device Interface' name = 'Cybook Opus Device Interface'
gui_name = 'Cybook Opus'
description = _('Communicate with the Cybook Opus eBook reader.') description = _('Communicate with the Cybook Opus eBook reader.')
author = _('John Schember') author = _('John Schember')
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']

View File

@ -1,7 +1,7 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
""" """
This module provides a thin ctypes based wrapper around libusb. This module provides a thin ctypes based wrapper around libusb.
""" """
from ctypes import cdll, POINTER, byref, pointer, Structure as _Structure, \ from ctypes import cdll, POINTER, byref, pointer, Structure as _Structure, \
@ -24,8 +24,10 @@ try:
_libusb = load_library(_libusb_name, cdll) _libusb = load_library(_libusb_name, cdll)
except OSError: except OSError:
_libusb = cdll.LoadLibrary('libusb-0.1.so.4') _libusb = cdll.LoadLibrary('libusb-0.1.so.4')
has_library = True
except: except:
_libusb = None _libusb = None
has_library = False
class DeviceDescriptor(Structure): class DeviceDescriptor(Structure):
_fields_ = [\ _fields_ = [\
@ -81,7 +83,7 @@ class Interface(Structure):
('num_altsetting', c_int)\ ('num_altsetting', c_int)\
] ]
class ConfigDescriptor(Structure): class ConfigDescriptor(Structure):
_fields_ = [\ _fields_ = [\
('Length', c_ubyte), \ ('Length', c_ubyte), \
('DescriptorType', c_ubyte), \ ('DescriptorType', c_ubyte), \
@ -95,27 +97,27 @@ class ConfigDescriptor(Structure):
('extra', POINTER(c_ubyte)), \ ('extra', POINTER(c_ubyte)), \
('extralen', c_int) \ ('extralen', c_int) \
] ]
def __str__(self): def __str__(self):
ans = "" ans = ""
for field in self._fields_: for field in self._fields_:
ans += field[0] + ": " + str(eval('self.'+field[0])) + '\n' ans += field[0] + ": " + str(eval('self.'+field[0])) + '\n'
return ans.strip() return ans.strip()
class Error(Exception): class Error(Exception):
pass pass
class Device(Structure): class Device(Structure):
def open(self): def open(self):
""" Open device for use. Return a DeviceHandle. """ """ Open device for use. Return a DeviceHandle. """
handle = _libusb.usb_open(byref(self)) handle = _libusb.usb_open(byref(self))
if not handle: if not handle:
raise Error("Cannot open device") raise Error("Cannot open device")
return handle.contents return handle.contents
@dynamic_property @dynamic_property
def configurations(self): def configurations(self):
doc = """ List of device configurations. See L{ConfigDescriptor} """ doc = """ List of device configurations. See L{ConfigDescriptor} """
@ -130,9 +132,9 @@ class Bus(Structure):
@dynamic_property @dynamic_property
def device_list(self): def device_list(self):
doc = \ doc = \
""" """
Flat list of devices on this bus. Flat list of devices on this bus.
Note: children are not explored Note: children are not explored
TODO: Check if exploring children is neccessary (e.g. with an external hub) TODO: Check if exploring children is neccessary (e.g. with an external hub)
""" """
def fget(self): def fget(self):
@ -145,7 +147,7 @@ class Bus(Structure):
while ndev: while ndev:
dev = ndev.contents dev = ndev.contents
ans.append(dev) ans.append(dev)
ndev = dev.next ndev = dev.next
return ans return ans
return property(doc=doc, fget=fget) return property(doc=doc, fget=fget)
@ -159,14 +161,14 @@ class DeviceHandle(Structure):
('altsetting', c_int), \ ('altsetting', c_int), \
('impl_info', c_void_p) ('impl_info', c_void_p)
] ]
def close(self): def close(self):
""" Close this DeviceHandle """ """ Close this DeviceHandle """
_libusb.usb_close(byref(self)) _libusb.usb_close(byref(self))
def set_configuration(self, config): def set_configuration(self, config):
""" """
Set device configuration. This has to be called on windows before Set device configuration. This has to be called on windows before
trying to claim an interface. trying to claim an interface.
@param config: A L{ConfigDescriptor} or a integer (the ConfigurationValue) @param config: A L{ConfigDescriptor} or a integer (the ConfigurationValue)
""" """
@ -178,14 +180,14 @@ class DeviceHandle(Structure):
if ret < 0: if ret < 0:
raise Error('Failed to set device configuration to: ' + str(num) + \ raise Error('Failed to set device configuration to: ' + str(num) + \
'. Error code: ' + str(ret)) '. Error code: ' + str(ret))
def claim_interface(self, num): def claim_interface(self, num):
""" """
Claim interface C{num} on device. Claim interface C{num} on device.
Must be called before doing anything witht the device. Must be called before doing anything witht the device.
""" """
ret = _libusb.usb_claim_interface(byref(self), num) ret = _libusb.usb_claim_interface(byref(self), num)
if -ret == ENOMEM: if -ret == ENOMEM:
raise Error("Insufficient memory to claim interface") raise Error("Insufficient memory to claim interface")
elif -ret == EBUSY: elif -ret == EBUSY:
@ -193,7 +195,7 @@ class DeviceHandle(Structure):
elif ret < 0: elif ret < 0:
raise Error('Unknown error occurred while trying to claim USB'\ raise Error('Unknown error occurred while trying to claim USB'\
' interface: ' + str(ret)) ' interface: ' + str(ret))
def control_msg(self, rtype, request, bytes, value=0, index=0, timeout=100): def control_msg(self, rtype, request, bytes, value=0, index=0, timeout=100):
""" """
Perform a control request to the default control pipe on the device. Perform a control request to the default control pipe on the device.
@ -210,7 +212,7 @@ class DeviceHandle(Structure):
try: try:
size = len(bytes) size = len(bytes)
except TypeError: except TypeError:
size = bytes size = bytes
ArrayType = c_byte * size ArrayType = c_byte * size
_libusb.usb_control_msg.argtypes = [POINTER(DeviceHandle), c_int, \ _libusb.usb_control_msg.argtypes = [POINTER(DeviceHandle), c_int, \
c_int, c_int, c_int, \ c_int, c_int, c_int, \
@ -234,7 +236,7 @@ class DeviceHandle(Structure):
return _libusb.usb_control_msg(byref(self), rtype, request, \ return _libusb.usb_control_msg(byref(self), rtype, request, \
value, index, byref(arr), \ value, index, byref(arr), \
size, timeout) size, timeout)
def bulk_read(self, endpoint, size, timeout=100): def bulk_read(self, endpoint, size, timeout=100):
""" """
Read C{size} bytes via a bulk transfer from the device. Read C{size} bytes via a bulk transfer from the device.
@ -254,7 +256,7 @@ class DeviceHandle(Structure):
if rsize < size: if rsize < size:
arr = arr[:rsize] arr = arr[:rsize]
return arr return arr
def bulk_write(self, endpoint, bytes, timeout=100): def bulk_write(self, endpoint, bytes, timeout=100):
""" """
Send C{bytes} to device via a bulk transfer. Send C{bytes} to device via a bulk transfer.
@ -266,13 +268,13 @@ class DeviceHandle(Structure):
POINTER(ArrayType), c_int, c_int POINTER(ArrayType), c_int, c_int
] ]
_libusb.usb_bulk_write(byref(self), endpoint, byref(arr), size, timeout) _libusb.usb_bulk_write(byref(self), endpoint, byref(arr), size, timeout)
def release_interface(self, num): def release_interface(self, num):
ret = _libusb.usb_release_interface(pointer(self), num) ret = _libusb.usb_release_interface(pointer(self), num)
if ret < 0: if ret < 0:
raise Error('Unknown error occurred while trying to release USB'\ raise Error('Unknown error occurred while trying to release USB'\
' interface: ' + str(ret)) ' interface: ' + str(ret))
def reset(self): def reset(self):
ret = _libusb.usb_reset(pointer(self)) ret = _libusb.usb_reset(pointer(self))
if ret < 0: if ret < 0:
@ -300,7 +302,7 @@ Device._fields_ = [ \
('devnum', c_ubyte), \ ('devnum', c_ubyte), \
('num_children', c_ubyte), \ ('num_children', c_ubyte), \
('children', POINTER(POINTER(Device))) ('children', POINTER(POINTER(Device)))
] ]
if _libusb is not None: if _libusb is not None:
_libusb.usb_get_busses.restype = POINTER(Bus) _libusb.usb_get_busses.restype = POINTER(Bus)
@ -337,7 +339,7 @@ def busses():
ans.append(bus) ans.append(bus)
nbus = bus.next nbus = bus.next
return ans return ans
def get_device_by_id(idVendor, idProduct): def get_device_by_id(idVendor, idProduct):
""" Return a L{Device} by vendor and prduct ids """ """ Return a L{Device} by vendor and prduct ids """
@ -348,7 +350,7 @@ def get_device_by_id(idVendor, idProduct):
if dev.device_descriptor.idVendor == idVendor and \ if dev.device_descriptor.idVendor == idVendor and \
dev.device_descriptor.idProduct == idProduct: dev.device_descriptor.idProduct == idProduct:
return dev return dev
def has_library(): def has_library():
return _libusb is not None return _libusb is not None
@ -360,4 +362,4 @@ def get_devices():
for dev in devices: for dev in devices:
device = (dev.device_descriptor.idVendor, dev.device_descriptor.idProduct, dev.device_descriptor.bcdDevice) device = (dev.device_descriptor.idVendor, dev.device_descriptor.idProduct, dev.device_descriptor.bcdDevice)
ans.append(device) ans.append(device)
return ans return ans

View File

@ -8,6 +8,7 @@ manner.
import sys, re, os import sys, re, os
from calibre import iswindows, isosx, plugins from calibre import iswindows, isosx, plugins
from calibre.devices import libusb
osx_scanner = win_scanner = linux_scanner = None osx_scanner = win_scanner = linux_scanner = None
@ -22,11 +23,12 @@ elif isosx:
except: except:
raise RuntimeError('Failed to load the usbobserver plugin: %s'%plugins['usbobserver'][1]) raise RuntimeError('Failed to load the usbobserver plugin: %s'%plugins['usbobserver'][1])
_usb_re = re.compile(r'Vendor\s*=\s*([0-9a-fA-F]+)\s+ProdID\s*=\s*([0-9a-fA-F]+)\s+Rev\s*=\s*([0-9a-fA-f.]+)') _usb_re = re.compile(r'Vendor\s*=\s*([0-9a-fA-F]+)\s+ProdID\s*=\s*([0-9a-fA-F]+)\s+Rev\s*=\s*([0-9a-fA-f.]+)')
_DEVICES = '/proc/bus/usb/devices' _DEVICES = '/proc/bus/usb/devices'
def linux_scanner(): def _linux_scanner():
raw = open(_DEVICES).read() raw = open(_DEVICES).read()
devices = [] devices = []
device = None device = None
@ -46,6 +48,11 @@ def linux_scanner():
devices.append(device) devices.append(device)
return devices return devices
if libusb.has_library:
linux_scanner = libusb.get_devices
else:
linux_scanner = _linux_scanner
class DeviceScanner(object): class DeviceScanner(object):
def __init__(self, *args): def __init__(self, *args):

View File

@ -1421,15 +1421,16 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
for row in rows: for row in rows:
row = row.row() row = row.row()
formats = self.library_view.model().db.formats(row).upper() formats = self.library_view.model().db.formats(row)
formats = formats.split(',')
title = self.library_view.model().db.title(row) title = self.library_view.model().db.title(row)
if not formats: if not formats:
error_dialog(self, _('Cannot view'), error_dialog(self, _('Cannot view'),
_('%s has no available formats.')%(title,), show=True) _('%s has no available formats.')%(title,), show=True)
continue continue
formats = formats.upper().split(',')
in_prefs = False in_prefs = False
for format in prefs['input_format_order']: for format in prefs['input_format_order']:
if format in formats: if format in formats: