mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Basic GUI functionality for 505
This commit is contained in:
parent
e026890d9c
commit
d39c1a2130
@ -15,6 +15,12 @@
|
|||||||
'''
|
'''
|
||||||
Device drivers.
|
Device drivers.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
def devices():
|
||||||
|
from libprs500.devices.prs500.driver import PRS500
|
||||||
|
from libprs500.devices.prs505.driver import PRS505
|
||||||
|
return (PRS500, PRS505)
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
DAY_MAP = dict(Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6)
|
DAY_MAP = dict(Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6)
|
||||||
|
@ -29,11 +29,12 @@ if iswindows:
|
|||||||
_libusb_name = 'libusb0'
|
_libusb_name = 'libusb0'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_libusb = load_library(_libusb_name, cdll)
|
try:
|
||||||
except OSError:
|
_libusb = load_library(_libusb_name, cdll)
|
||||||
if iswindows or isosx:
|
except OSError:
|
||||||
raise
|
_libusb = cdll.LoadLibrary('libusb-0.1.so.4')
|
||||||
_libusb = cdll.LoadLibrary('libusb-0.1.so.4')
|
except:
|
||||||
|
_libusb = None
|
||||||
|
|
||||||
class DeviceDescriptor(Structure):
|
class DeviceDescriptor(Structure):
|
||||||
_fields_ = [\
|
_fields_ = [\
|
||||||
@ -308,25 +309,30 @@ Device._fields_ = [ \
|
|||||||
('children', POINTER(POINTER(Device)))
|
('children', POINTER(POINTER(Device)))
|
||||||
]
|
]
|
||||||
|
|
||||||
_libusb.usb_get_busses.restype = POINTER(Bus)
|
if _libusb is not None:
|
||||||
_libusb.usb_open.restype = POINTER(DeviceHandle)
|
_libusb.usb_get_busses.restype = POINTER(Bus)
|
||||||
_libusb.usb_open.argtypes = [POINTER(Device)]
|
_libusb.usb_open.restype = POINTER(DeviceHandle)
|
||||||
_libusb.usb_close.argtypes = [POINTER(DeviceHandle)]
|
_libusb.usb_open.argtypes = [POINTER(Device)]
|
||||||
_libusb.usb_claim_interface.argtypes = [POINTER(DeviceHandle), c_int]
|
_libusb.usb_close.argtypes = [POINTER(DeviceHandle)]
|
||||||
_libusb.usb_claim_interface.restype = c_int
|
_libusb.usb_claim_interface.argtypes = [POINTER(DeviceHandle), c_int]
|
||||||
_libusb.usb_release_interface.argtypes = [POINTER(DeviceHandle), c_int]
|
_libusb.usb_claim_interface.restype = c_int
|
||||||
_libusb.usb_release_interface.restype = c_int
|
_libusb.usb_release_interface.argtypes = [POINTER(DeviceHandle), c_int]
|
||||||
_libusb.usb_reset.argtypes = [POINTER(DeviceHandle)]
|
_libusb.usb_release_interface.restype = c_int
|
||||||
_libusb.usb_reset.restype = c_int
|
_libusb.usb_reset.argtypes = [POINTER(DeviceHandle)]
|
||||||
_libusb.usb_control_msg.restype = c_int
|
_libusb.usb_reset.restype = c_int
|
||||||
_libusb.usb_bulk_read.restype = c_int
|
_libusb.usb_control_msg.restype = c_int
|
||||||
_libusb.usb_bulk_write.restype = c_int
|
_libusb.usb_bulk_read.restype = c_int
|
||||||
_libusb.usb_set_configuration.argtypes = [POINTER(DeviceHandle), c_int]
|
_libusb.usb_bulk_write.restype = c_int
|
||||||
_libusb.usb_set_configuration.restype = c_int
|
_libusb.usb_set_configuration.argtypes = [POINTER(DeviceHandle), c_int]
|
||||||
_libusb.usb_init()
|
_libusb.usb_set_configuration.restype = c_int
|
||||||
|
_libusb.usb_init()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def busses():
|
def busses():
|
||||||
""" Get list of USB busses present on system """
|
""" Get list of USB busses present on system """
|
||||||
|
if _libusb is None:
|
||||||
|
raise Error('Could not find libusb.')
|
||||||
if _libusb.usb_find_busses() < 0:
|
if _libusb.usb_find_busses() < 0:
|
||||||
raise Error('Unable to search for USB busses')
|
raise Error('Unable to search for USB busses')
|
||||||
if _libusb.usb_find_devices() < 0:
|
if _libusb.usb_find_devices() < 0:
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
from libprs500.devices.prs505.driver import PRS505
|
from libprs500.devices.prs505.driver import PRS505
|
||||||
|
from libprs500.devices import devices
|
||||||
"""
|
"""
|
||||||
Provides a command-line and optional graphical interface to the SONY Reader PRS-500.
|
Provides a command-line and optional graphical interface to the SONY Reader PRS-500.
|
||||||
|
|
||||||
@ -208,9 +209,13 @@ def main():
|
|||||||
|
|
||||||
command = args[0]
|
command = args[0]
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
dev = PRS500(log_packets=options.log_packets)
|
dev = None
|
||||||
if not dev.is_connected():
|
for d in devices():
|
||||||
dev = PRS505()
|
if d.is_connected():
|
||||||
|
dev = d(log_packets=options.log_packets)
|
||||||
|
|
||||||
|
if dev is None:
|
||||||
|
print >>sys.stderr, 'Unable to find a connected ebook reader.'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dev.open()
|
dev.open()
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
## You should have received a copy of the GNU General Public License along
|
## You should have received a copy of the GNU General Public License along
|
||||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
from libprs500.devices import libusb
|
||||||
|
|
||||||
### End point description for PRS-500 procductId=667
|
### End point description for PRS-500 procductId=667
|
||||||
### Endpoint Descriptor:
|
### Endpoint Descriptor:
|
||||||
@ -224,7 +225,10 @@ class PRS500(Device):
|
|||||||
software connection. You may need to call L{reconnect} if you keep
|
software connection. You may need to call L{reconnect} if you keep
|
||||||
getting L{DeviceError}.
|
getting L{DeviceError}.
|
||||||
"""
|
"""
|
||||||
return get_device_by_id(cls.VENDOR_ID, cls.PRODUCT_ID) != None
|
try:
|
||||||
|
return get_device_by_id(cls.VENDOR_ID, cls.PRODUCT_ID) != None
|
||||||
|
except libusb.Error:
|
||||||
|
return False
|
||||||
|
|
||||||
def set_progress_reporter(self, report_progress):
|
def set_progress_reporter(self, report_progress):
|
||||||
self.report_progress = report_progress
|
self.report_progress = report_progress
|
||||||
|
@ -12,23 +12,19 @@
|
|||||||
## You should have received a copy of the GNU General Public License along
|
## You should have received a copy of the GNU General Public License along
|
||||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
import shutil
|
'''
|
||||||
''''''
|
Device driver for the SONY PRS-505
|
||||||
|
'''
|
||||||
|
import sys, os, shutil, time
|
||||||
|
from itertools import cycle
|
||||||
|
|
||||||
from libprs500.devices.interface import Device
|
from libprs500.devices.interface import Device
|
||||||
from libprs500.devices.errors import DeviceError, FreeSpaceError
|
from libprs500.devices.errors import DeviceError, FreeSpaceError
|
||||||
from libprs500.devices.prs500.books import BookList
|
from libprs500.devices.prs500.books import BookList, fix_ids
|
||||||
from libprs500 import iswindows, islinux, isosx
|
from libprs500 import iswindows, islinux, isosx
|
||||||
if not iswindows:
|
from libprs500.devices.libusb import get_device_by_id
|
||||||
from libprs500.devices.libusb import get_device_by_id
|
from libprs500.devices import libusb
|
||||||
|
from libprs500.devices.errors import PathError
|
||||||
|
|
||||||
import sys, os
|
|
||||||
|
|
||||||
try:
|
|
||||||
import _winreg
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class File(object):
|
class File(object):
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
@ -85,7 +81,7 @@ class PRS505(Device):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, log_packets=False):
|
||||||
self._main_prefix = self._card_prefix = None
|
self._main_prefix = self._card_prefix = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -119,7 +115,10 @@ class PRS505(Device):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return get_device_by_id(cls.VENDOR_ID, cls.PRODUCT_ID) != None
|
try:
|
||||||
|
return get_device_by_id(cls.VENDOR_ID, cls.PRODUCT_ID) != None
|
||||||
|
except libusb.Error:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def open_windows(self):
|
def open_windows(self):
|
||||||
@ -174,10 +173,14 @@ class PRS505(Device):
|
|||||||
self._card_prefix = conditional_mount(sc)+os.sep
|
self._card_prefix = conditional_mount(sc)+os.sep
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
if islinux:
|
try:
|
||||||
self.open_linux()
|
if islinux:
|
||||||
if iswindows:
|
self.open_linux()
|
||||||
self.open_windows()
|
if iswindows:
|
||||||
|
self.open_windows()
|
||||||
|
except DeviceError:
|
||||||
|
time.sleep(4)
|
||||||
|
return self.open()
|
||||||
|
|
||||||
def set_progress_reporter(self, pr):
|
def set_progress_reporter(self, pr):
|
||||||
self.report_progress = pr
|
self.report_progress = pr
|
||||||
@ -229,10 +232,12 @@ class PRS505(Device):
|
|||||||
return (msz, 0, csz)
|
return (msz, 0, csz)
|
||||||
|
|
||||||
def books(self, oncard=False, end_session=True):
|
def books(self, oncard=False, end_session=True):
|
||||||
|
if oncard and self._card_prefix is None:
|
||||||
|
return []
|
||||||
db = self.__class__.CACHE_XML if oncard else self.__class__.MEDIA_XML
|
db = self.__class__.CACHE_XML if oncard else self.__class__.MEDIA_XML
|
||||||
prefix = self._card_prefix if oncard else self._main_prefix
|
prefix = self._card_prefix if oncard else self._main_prefix
|
||||||
f = open(prefix + db, 'rb')
|
f = open(prefix + db, 'rb')
|
||||||
bl = BookList(root='', sfile=f)
|
bl = BookList(root=self._card_prefix if oncard else self._main_prefix, sfile=f)
|
||||||
paths = bl.purge_corrupted_files()
|
paths = bl.purge_corrupted_files()
|
||||||
for path in paths:
|
for path in paths:
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
@ -268,10 +273,12 @@ class PRS505(Device):
|
|||||||
src = open(path, 'rb')
|
src = open(path, 'rb')
|
||||||
shutil.copyfileobj(src, outfile, 10*1024*1024)
|
shutil.copyfileobj(src, outfile, 10*1024*1024)
|
||||||
|
|
||||||
def put_file(self, infile, path, end_session=True):
|
def put_file(self, infile, path, replace_file=False, end_session=True):
|
||||||
path = self.munge_path(path)
|
path = self.munge_path(path)
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
path = os.path.join(path, infile.name)
|
path = os.path.join(path, infile.name)
|
||||||
|
if not replace_file and os.path.exists(path):
|
||||||
|
raise PathError('File already exists: '+path)
|
||||||
dest = open(path, 'wb')
|
dest = open(path, 'wb')
|
||||||
shutil.copyfileobj(infile, dest, 10*1024*1024)
|
shutil.copyfileobj(infile, dest, 10*1024*1024)
|
||||||
|
|
||||||
@ -305,13 +312,49 @@ class PRS505(Device):
|
|||||||
|
|
||||||
paths, ctimes = [], []
|
paths, ctimes = [], []
|
||||||
|
|
||||||
|
names = iter(names)
|
||||||
for infile in infiles:
|
for infile in infiles:
|
||||||
infile.seek(0)
|
infile.seek(0)
|
||||||
name = names.next()
|
name = names.next()
|
||||||
paths.append(os.path.join(path, name))
|
paths.append(os.path.join(path, name))
|
||||||
self.put_file(infile, paths[-1], replace_file=True)
|
self.put_file(infile, paths[-1], replace_file=True)
|
||||||
ctimes.append(os.path.getctime(paths[-1]))
|
ctimes.append(os.path.getctime(paths[-1]))
|
||||||
return zip(paths, sizes, ctimes)
|
return zip(paths, sizes, ctimes, cycle([on_card]))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_books_to_metadata(cls, locations, metadata, booklists):
|
||||||
|
metadata = iter(metadata)
|
||||||
|
for location in locations:
|
||||||
|
info = metadata.next()
|
||||||
|
path = location[0]
|
||||||
|
on_card = 1 if location[3] else 0
|
||||||
|
name = path.rpartition('/')[2]
|
||||||
|
name = (cls.CARD_PATH_PREFIX+'/' if on_card else 'books/') + name
|
||||||
|
booklists[on_card].add_book(info, name, *location[1:-1])
|
||||||
|
fix_ids(*booklists)
|
||||||
|
|
||||||
|
def delete_books(self, paths, end_session=True):
|
||||||
|
for path in paths:
|
||||||
|
print path
|
||||||
|
os.unlink(path)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def remove_books_from_metadata(cls, paths, booklists):
|
||||||
|
for path in paths:
|
||||||
|
for bl in booklists:
|
||||||
|
bl.remove_book(path)
|
||||||
|
fix_ids(*booklists)
|
||||||
|
|
||||||
|
def sync_booklists(self, booklists, end_session=True):
|
||||||
|
fix_ids(*booklists)
|
||||||
|
f = open(self._main_prefix + self.__class__.MEDIA_XML, 'wb')
|
||||||
|
booklists[0].write(f)
|
||||||
|
f.close()
|
||||||
|
if self._card_prefix is not None and hasattr(booklists[1], 'write'):
|
||||||
|
f = open(self._card_prefix + self.__class__.CACHE_XML, 'wb')
|
||||||
|
booklists[1].write(f)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user