mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Sync to trunk.
This commit is contained in:
commit
d6d268b92a
@ -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']
|
||||||
|
@ -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.')
|
||||||
|
|
||||||
|
|
||||||
|
@ -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']
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user