Basic GUI functionality for 505

This commit is contained in:
Kovid Goyal 2007-10-23 02:35:25 +00:00
parent e026890d9c
commit d39c1a2130
5 changed files with 111 additions and 47 deletions

View File

@ -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)

View File

@ -28,12 +28,13 @@ if iswindows:
Structure._pack_ = 1 Structure._pack_ = 1
_libusb_name = 'libusb0' _libusb_name = 'libusb0'
try:
try: try:
_libusb = load_library(_libusb_name, cdll) _libusb = load_library(_libusb_name, cdll)
except OSError: except OSError:
if iswindows or isosx:
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,6 +309,7 @@ Device._fields_ = [ \
('children', POINTER(POINTER(Device))) ('children', POINTER(POINTER(Device)))
] ]
if _libusb is not None:
_libusb.usb_get_busses.restype = POINTER(Bus) _libusb.usb_get_busses.restype = POINTER(Bus)
_libusb.usb_open.restype = POINTER(DeviceHandle) _libusb.usb_open.restype = POINTER(DeviceHandle)
_libusb.usb_open.argtypes = [POINTER(Device)] _libusb.usb_open.argtypes = [POINTER(Device)]
@ -325,8 +327,12 @@ _libusb.usb_set_configuration.argtypes = [POINTER(DeviceHandle), c_int]
_libusb.usb_set_configuration.restype = c_int _libusb.usb_set_configuration.restype = c_int
_libusb.usb_init() _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:

View File

@ -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()

View File

@ -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}.
""" """
try:
return get_device_by_id(cls.VENDOR_ID, cls.PRODUCT_ID) != None 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

View File

@ -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:
try:
return get_device_by_id(cls.VENDOR_ID, cls.PRODUCT_ID) != None 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):
try:
if islinux: if islinux:
self.open_linux() self.open_linux()
if iswindows: if iswindows:
self.open_windows() 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()