mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Fixed connection errors due to timeouts in the GUI (Basically, increased the timeout in PRS500Device.open to 10s to allow device to initialize USB handler.
Refactored device display code to work with changed implementation of book list parsing in libprs500
This commit is contained in:
parent
a591a6d788
commit
ddc2e5bbdd
@ -16,6 +16,7 @@
|
|||||||
from xml.dom.ext import PrettyPrint as PrettyPrint
|
from xml.dom.ext import PrettyPrint as PrettyPrint
|
||||||
import xml.dom.minidom as dom
|
import xml.dom.minidom as dom
|
||||||
from base64 import b64decode as decode
|
from base64 import b64decode as decode
|
||||||
|
import time
|
||||||
|
|
||||||
class book_metadata_field(object):
|
class book_metadata_field(object):
|
||||||
def __init__(self, attr, formatter=None):
|
def __init__(self, attr, formatter=None):
|
||||||
@ -27,7 +28,7 @@ class book_metadata_field(object):
|
|||||||
|
|
||||||
class Book(object):
|
class Book(object):
|
||||||
title = book_metadata_field("title")
|
title = book_metadata_field("title")
|
||||||
author = book_metadata_field("author")
|
author = book_metadata_field("author", formatter=lambda x: x if x.strip() else "Unknown")
|
||||||
mime = book_metadata_field("mime")
|
mime = book_metadata_field("mime")
|
||||||
rpath = book_metadata_field("path")
|
rpath = book_metadata_field("path")
|
||||||
id = book_metadata_field("id", formatter=int)
|
id = book_metadata_field("id", formatter=int)
|
||||||
|
@ -134,16 +134,21 @@ class PRS500Device(object):
|
|||||||
MEDIA_XML = "/Data/database/cache/media.xml" #: Location of media.xml file on device
|
MEDIA_XML = "/Data/database/cache/media.xml" #: Location of media.xml file on device
|
||||||
CACHE_XML = "/Sony Reader/database/cache.xml" #: Location of cache.xml on storage card in device
|
CACHE_XML = "/Sony Reader/database/cache.xml" #: Location of cache.xml on storage card in device
|
||||||
|
|
||||||
|
device_descriptor = DeviceDescriptor(SONY_VENDOR_ID, PRS500_PRODUCT_ID, PRS500_INTERFACE_ID)
|
||||||
|
|
||||||
|
|
||||||
def safe(func):
|
def safe(func):
|
||||||
"""
|
"""
|
||||||
Decorator that wraps a call to C{func} to ensure that exceptions are handled correctly.
|
Decorator that wraps a call to C{func} to ensure that exceptions are handled correctly.
|
||||||
It also calls L{open} to claim the interface and initialize the Reader if needed.
|
It also calls L{open} to claim the interface and initialize the Reader if needed.
|
||||||
|
|
||||||
As a convenience, C{safe} automatically sends the a L{USBConnect} after calling func, unless func has
|
As a convenience, C{safe} automatically sends the a L{EndSession} after calling func, unless func has
|
||||||
a keyword argument named C{end_session} set to C{False}.
|
a keyword argument named C{end_session} set to C{False}.
|
||||||
|
|
||||||
An L{ArgumentError} will cause the L{USBConnect} command to be sent to the device, unless end_session is set to C{False}.
|
An L{ArgumentError} will cause the L{EndSession} command to be sent to the device, unless end_session is set to C{False}.
|
||||||
An L{usb.USBError} will cause the library to release control of the USB interface via a call to L{close}.
|
An L{usb.USBError} will cause the library to release control of the USB interface via a call to L{close}.
|
||||||
|
|
||||||
|
@todo: Fix handling of timeout errors
|
||||||
"""
|
"""
|
||||||
def run_session(*args, **kwargs):
|
def run_session(*args, **kwargs):
|
||||||
dev = args[0]
|
dev = args[0]
|
||||||
@ -153,17 +158,21 @@ class PRS500Device(object):
|
|||||||
res = func(*args, **kwargs)
|
res = func(*args, **kwargs)
|
||||||
except ArgumentError, e:
|
except ArgumentError, e:
|
||||||
if not kwargs.has_key("end_session") or kwargs["end_session"]:
|
if not kwargs.has_key("end_session") or kwargs["end_session"]:
|
||||||
dev._send_validated_command(USBConnect())
|
dev._send_validated_command(EndSession())
|
||||||
raise e
|
raise e
|
||||||
except usb.USBError, e:
|
except usb.USBError, e:
|
||||||
if "No such device" in str(e):
|
if "No such device" in str(e):
|
||||||
raise DeviceError()
|
raise DeviceError()
|
||||||
elif "Connection timed out" in str(e):
|
elif "Connection timed out" in str(e):
|
||||||
|
dev.close()
|
||||||
raise TimeoutError(func.__name__)
|
raise TimeoutError(func.__name__)
|
||||||
|
elif "Protocol error" in str(e):
|
||||||
|
dev.close()
|
||||||
|
raise ProtocolError("There was an unknown error in the protocol. Contact the developer.")
|
||||||
dev.close()
|
dev.close()
|
||||||
raise e
|
raise e
|
||||||
if not kwargs.has_key("end_session") or kwargs["end_session"]:
|
if not kwargs.has_key("end_session") or kwargs["end_session"]:
|
||||||
dev._send_validated_command(USBConnect())
|
dev._send_validated_command(EndSession())
|
||||||
return res
|
return res
|
||||||
|
|
||||||
return run_session
|
return run_session
|
||||||
@ -174,16 +183,23 @@ class PRS500Device(object):
|
|||||||
@param: report_progress: Function that is called with a % progress (number between 0 and 100) for various tasks
|
@param: report_progress: Function that is called with a % progress (number between 0 and 100) for various tasks
|
||||||
If it is called with -1 that means that the task does not have any progress information
|
If it is called with -1 that means that the task does not have any progress information
|
||||||
"""
|
"""
|
||||||
self.device_descriptor = DeviceDescriptor(PRS500Device.SONY_VENDOR_ID,
|
|
||||||
PRS500Device.PRS500_PRODUCT_ID,
|
|
||||||
PRS500Device.PRS500_INTERFACE_ID)
|
|
||||||
self.device = self.device_descriptor.getDevice() #: The actual device (PyUSB object)
|
self.device = self.device_descriptor.getDevice() #: The actual device (PyUSB object)
|
||||||
self.handle = None #: Handle that is used to communicate with device. Setup in L{open}
|
self.handle = None #: Handle that is used to communicate with device. Setup in L{open}
|
||||||
self._log_packets = log_packets
|
self._log_packets = log_packets
|
||||||
self.report_progress = report_progress
|
self.report_progress = report_progress
|
||||||
|
|
||||||
def is_connected(self):
|
def reconnect(self):
|
||||||
return self.device_descriptor.getDevice() != None
|
self.device = self.device_descriptor.getDevice()
|
||||||
|
self.handle = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_connected(cls):
|
||||||
|
"""
|
||||||
|
This method checks to see whether the device is physically connected.
|
||||||
|
It does not return any information about the validity of the software connection. You may need to call L{reconnect} if you keep
|
||||||
|
getting L{DeviceError}.
|
||||||
|
"""
|
||||||
|
return cls.device_descriptor.getDevice() != None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _validate_response(cls, res, type=0x00, number=0x00):
|
def _validate_response(cls, res, type=0x00, number=0x00):
|
||||||
@ -205,7 +221,7 @@ class PRS500Device(object):
|
|||||||
raise DeviceError()
|
raise DeviceError()
|
||||||
self.handle = self.device.open()
|
self.handle = self.device.open()
|
||||||
self.handle.claimInterface(self.device_descriptor.interface_id)
|
self.handle.claimInterface(self.device_descriptor.interface_id)
|
||||||
res = self._send_validated_command(GetUSBProtocolVersion())
|
res = self._send_validated_command(GetUSBProtocolVersion(), timeout=10000) # Large timeout as device mat still be initializing
|
||||||
if res.code != 0: raise ProtocolError("Unable to get USB Protocol version.")
|
if res.code != 0: raise ProtocolError("Unable to get USB Protocol version.")
|
||||||
version = self._bulk_read(24, data_type=USBProtocolVersion)[0].version
|
version = self._bulk_read(24, data_type=USBProtocolVersion)[0].version
|
||||||
if version not in KNOWN_USB_PROTOCOL_VERSIONS:
|
if version not in KNOWN_USB_PROTOCOL_VERSIONS:
|
||||||
@ -216,9 +232,9 @@ class PRS500Device(object):
|
|||||||
if res.code != 0:
|
if res.code != 0:
|
||||||
raise ProtocolError("Unlocking of device not implemented. Remove locking and retry.")
|
raise ProtocolError("Unlocking of device not implemented. Remove locking and retry.")
|
||||||
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
""" Release device interface """
|
""" Release device interface """
|
||||||
|
self.handle.reset()
|
||||||
self.handle.releaseInterface()
|
self.handle.releaseInterface()
|
||||||
self.handle, self.device = None, None
|
self.handle, self.device = None, None
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<file alias="default_cover">images/cherubs.jpg</file>
|
<file alias="default_cover">images/cherubs.jpg</file>
|
||||||
<file alias="library">images/mycomputer.png</file>
|
<file alias="library">images/mycomputer.png</file>
|
||||||
<file alias="reader">images/reader.png</file>
|
<file alias="reader">images/reader.png</file>
|
||||||
|
<file alias="card">images/memory_stick_unmount.png</file>
|
||||||
<file>images/clear.png</file>
|
<file>images/clear.png</file>
|
||||||
<file>images/minus.png</file>
|
<file>images/minus.png</file>
|
||||||
<file>images/plus.png</file>
|
<file>images/plus.png</file>
|
||||||
|
BIN
libprs500/gui/images/memory_stick_unmount.png
Normal file
BIN
libprs500/gui/images/memory_stick_unmount.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
@ -1,6 +1,6 @@
|
|||||||
# Resource object code
|
# Resource object code
|
||||||
#
|
#
|
||||||
# Created: Fri Nov 24 20:24:55 2006
|
# Created: Sun Dec 3 17:57:59 2006
|
||||||
# by: The Resource Compiler for PyQt (Qt v4.1.4)
|
# by: The Resource Compiler for PyQt (Qt v4.1.4)
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
@ -8,6 +8,298 @@
|
|||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
qt_resource_data = "\
|
qt_resource_data = "\
|
||||||
|
\x00\x00\x12\x16\
|
||||||
|
\x89\
|
||||||
|
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||||
|
\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\
|
||||||
|
\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
|
||||||
|
\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\x61\x72\x65\
|
||||||
|
\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\
|
||||||
|
\x67\x9b\xee\x3c\x1a\x00\x00\x11\xa8\x49\x44\x41\x54\x78\x9c\xed\
|
||||||
|
\x9a\x79\x70\x5c\x47\x9d\xc7\x3f\xfd\xde\xdc\x33\xd2\xe8\x96\x2d\
|
||||||
|
\xf9\x92\x7c\x61\x72\x40\x0c\x09\xc4\xd9\x84\x6c\x2a\x50\x40\x41\
|
||||||
|
\x0c\x0b\x01\xb6\x08\x47\xc1\xd6\x2e\x57\xb1\xbb\x50\x5b\x0b\x45\
|
||||||
|
\xed\x16\xd9\x9b\x64\xc3\x86\x2c\x09\x6c\x0e\x08\x39\x21\x4e\x48\
|
||||||
|
\x70\x5c\xb1\xc9\x69\x12\x5b\x8b\x15\x47\x2b\x5f\xf2\x25\xd9\x3a\
|
||||||
|
\xac\x6b\x66\xa4\x39\xde\x5c\xef\xe8\xee\xfd\x63\x24\xd9\x96\x95\
|
||||||
|
\xd8\x49\x9c\xc8\x14\xf9\x4d\xa9\x66\x9e\xde\xf4\xaf\x7f\xdf\x6f\
|
||||||
|
\xff\xae\xd7\x3d\x42\x6b\xcd\x1f\xb3\x18\xf3\x6d\xc0\x7c\xcb\x5b\
|
||||||
|
\x04\xcc\xb7\x01\xf3\x2d\x6f\x11\x30\xdf\x06\xcc\xb7\xbc\x45\xc0\
|
||||||
|
\x7c\x1b\xf0\x7a\x64\xe3\xc6\x8d\x17\x6e\xde\xbc\x39\xf8\x7a\x74\
|
||||||
|
\x88\x3f\xc4\x3e\x60\xcb\x96\x2d\xcb\x94\x52\x77\xbb\xae\xbb\xce\
|
||||||
|
\xf3\x3c\x03\xb7\xf0\x8b\x4f\x7c\xe6\xf3\x5f\x7e\x2d\xba\xfe\xa0\
|
||||||
|
\x3c\xe0\xfa\xeb\xaf\x37\x9e\x7c\xf2\xc9\x6f\x2a\xa5\xf6\x29\xa5\
|
||||||
|
\x2e\xa9\x31\x52\xfe\x4b\x0b\xb7\x9a\xae\xa7\xbe\x70\xd3\x4d\x37\
|
||||||
|
\xbd\xfd\xb5\xe8\xf4\x9d\x6d\x23\xdf\x28\xd9\xba\x75\xeb\xdb\x2e\
|
||||||
|
\xbd\xf4\xd2\xfb\xa4\x94\xab\x0c\x43\x47\x96\x5b\x1b\x59\x91\x7b\
|
||||||
|
\x84\xb1\xbc\x9f\x70\xe0\x25\xb3\x2a\xb4\xf4\x3f\x80\x6b\x00\x84\
|
||||||
|
\x10\x7e\xad\xb5\x7b\x26\x7a\xcf\xf9\x10\xd8\xba\x75\xab\x4f\x29\
|
||||||
|
\xf5\x1d\x29\xe5\xf7\xa4\x94\x46\xdc\xed\x0f\x9c\x37\x71\x2b\x66\
|
||||||
|
\x71\x98\xe1\x42\x94\xe6\x98\x47\xd2\x6b\xe4\x59\xff\x5f\xc9\xd1\
|
||||||
|
\xf1\xd4\x92\xef\x7f\xff\xfb\x35\xc0\x32\xe0\xb7\x5a\x6b\x79\x3a\
|
||||||
|
\xfd\xe7\xb4\x07\xbc\xf0\xc2\x0b\x6b\xb5\xd6\xf7\x2b\xa5\x5a\x85\
|
||||||
|
\x76\x42\xab\x33\xbf\x64\x49\x6e\x13\x23\x85\x30\x4e\x3e\x46\x55\
|
||||||
|
\x59\x12\xab\x55\x94\x64\x1a\x7f\xbe\xcf\xb0\x0b\xea\x0e\xe0\xce\
|
||||||
|
\xa9\xe1\xcb\x80\xbe\xd3\xcd\x71\x4e\x12\xb0\x75\xeb\xd6\x90\x69\
|
||||||
|
\x9a\xff\xe4\x79\xde\x37\xa5\x94\x66\xbc\x7c\xd0\xb7\x3a\x75\x07\
|
||||||
|
\xba\x30\x42\xaf\x15\x83\x01\x81\x90\x50\xbf\x56\x22\x0c\x41\xa6\
|
||||||
|
\x1c\x60\xa1\xf3\xa2\x98\x6c\xf8\xf0\x07\x6a\x6b\x6b\xef\x4b\xa7\
|
||||||
|
\xd3\x65\x60\x85\x10\xe2\x88\x3e\x8d\x8b\x9f\x73\x49\xb0\xb3\xb3\
|
||||||
|
\xf3\x72\xbf\xdf\x7f\x40\x29\xf5\x15\xbc\x72\xb0\x7d\xf2\x61\xdf\
|
||||||
|
\x79\xe3\x3f\x26\x99\xb1\x99\x48\x47\xa1\xcf\xa0\x2a\xae\x58\xf1\
|
||||||
|
\x5e\x07\x5f\x50\xe0\x28\x93\xbc\x6b\x50\x2f\x12\x84\xd4\xa4\xf1\
|
||||||
|
\xa9\x4f\x7e\xfc\x63\x53\xaa\x22\x40\xeb\xe9\xe6\x3b\x67\x3c\x60\
|
||||||
|
\xfb\xf6\xed\x55\x3e\x9f\xef\x46\xd7\x75\xbf\xe0\xba\x6e\xa0\xaa\
|
||||||
|
\x78\xd8\x58\x36\xb9\x11\x3b\x9f\xa2\xaf\x14\xa3\x6a\xc2\xc2\xa7\
|
||||||
|
\x05\x4b\x2e\x95\x08\x3c\x32\xe3\x26\x13\x83\x3e\xec\x2a\x1f\xd4\
|
||||||
|
\x9a\xe8\x96\x3f\xa5\xbd\xfa\x42\xa3\xc8\xc0\x35\x81\x40\x60\x83\
|
||||||
|
\xe3\x38\x12\x58\x09\x1c\x7b\xa5\x79\xcf\x09\x0f\xe8\xea\xea\xfa\
|
||||||
|
\xa0\xcf\xe7\x3b\xec\xba\xee\x67\xb5\x9d\x0f\x2d\x9a\x78\xca\x58\
|
||||||
|
\x9a\x7c\x9c\x91\xb4\x4b\x59\x47\x08\x1c\xc9\x93\xea\xb1\x31\x43\
|
||||||
|
\x7e\x86\xf7\x07\xd8\xfb\x74\x88\x23\x9d\x01\x32\x09\x41\xb1\xb6\
|
||||||
|
\x09\x75\xd1\x77\xd0\x6f\xfb\x22\x75\x2d\xab\x88\x04\xcd\xc0\xa7\
|
||||||
|
\xae\xfd\xc4\xd5\x53\xaa\x6b\x84\x10\x8d\xaf\x34\xf7\xbc\x7a\x40\
|
||||||
|
\x4f\x4f\x4f\x5d\xb1\x58\xbc\xd5\xf3\xbc\xf5\xae\xeb\x86\x22\xd6\
|
||||||
|
\x11\xb1\x20\xdb\x49\xde\x4a\x33\x50\x0a\xb0\x28\x2e\xc8\xed\x1a\
|
||||||
|
\xc7\x1a\x2e\x03\x30\xd2\xed\x50\xb5\xc0\x04\x2a\x61\xed\xff\x93\
|
||||||
|
\x75\xb8\xeb\xbe\x06\x46\x10\xb4\x46\x6b\xcd\xd2\xa5\x6d\x46\xb1\
|
||||||
|
\x64\x7f\x1a\xf8\xed\xd4\x34\x2b\x81\xe4\xcb\xd9\x30\x6f\x1e\xb0\
|
||||||
|
\x67\xcf\x9e\x6b\xcb\xe5\x72\x9f\xe7\x79\xd7\xc8\xa2\x15\x6e\x4c\
|
||||||
|
\xed\x14\xf5\x93\xdd\x0c\x4d\xd8\xd8\x83\x29\x9a\x95\x8b\x70\x0d\
|
||||||
|
\x72\xfd\x59\x7c\x11\x1f\xf5\xab\xab\x59\xfe\x81\x7a\x5a\x2e\x8e\
|
||||||
|
\x60\x86\x43\x34\x7e\xee\xeb\xc8\x2b\xbe\x8d\x30\x43\x00\x08\x21\
|
||||||
|
\x30\x0c\x83\xc6\xd6\x36\x02\xa1\x70\xf5\xfa\xf5\xeb\x2f\x99\x9a\
|
||||||
|
\xaa\x59\x08\x11\x7f\x39\x3b\xde\xf4\x3e\x60\xff\xfe\xfd\x0b\x5d\
|
||||||
|
\xd7\xbd\xd3\xf3\xbc\xf7\x95\xcb\xe5\x68\x20\x37\x4a\x6d\xee\x28\
|
||||||
|
\xd9\xdc\x24\x65\xbb\x48\x7c\x60\x1f\xa5\xc3\xbd\xc4\x56\x2e\xa6\
|
||||||
|
\xfe\x9d\x4b\xd0\x25\x0b\x33\xe0\x61\x62\x53\x1c\xb5\x28\x7b\xad\
|
||||||
|
\x54\xff\xd9\xf7\x18\x75\x03\x38\x8e\x73\x92\x6e\xa5\x14\x42\x08\
|
||||||
|
\x86\x8e\x1e\xe4\xe0\x81\x9e\x91\xef\xfe\xe3\xbf\x7d\x63\xea\xd6\
|
||||||
|
\x90\xd6\x7a\xe7\x5c\xf6\xbc\xa9\x1e\xd0\xd3\xd3\xf3\x25\xcf\xf3\
|
||||||
|
\x0e\xd9\xb6\x7d\x55\xd9\xca\x45\x63\xc9\x41\xc2\xe9\x51\x06\x27\
|
||||||
|
\x0a\x98\xfe\x10\xd5\x7d\x7b\x29\x1d\xee\x05\xa0\x38\x38\x86\xeb\
|
||||||
|
\x00\xa1\x08\x4a\xf9\x18\xdf\x53\xa6\x14\xbc\x84\xa6\xaf\xdc\x4e\
|
||||||
|
\x8a\x28\x9e\xe7\x61\x18\x06\x42\x88\xe3\x60\x8c\x0a\x9c\x96\x25\
|
||||||
|
\x2b\x08\x46\xe2\x0b\xae\xbc\xf2\xca\xd5\x53\xb7\x16\x09\x21\xc2\
|
||||||
|
\x73\xd9\xf4\xa6\x10\x70\xf0\xe0\xc1\xb6\xfd\xfb\xf7\x3f\xef\x79\
|
||||||
|
\xde\x2d\x85\x42\x21\xa6\xd3\xb9\x50\xd5\xc4\x24\x99\x89\x0c\x89\
|
||||||
|
\xbc\x43\x4b\x63\x03\x11\x21\xb0\x8f\x0d\xce\x8c\x51\xb6\x4b\xea\
|
||||||
|
\x85\x3d\xd8\x59\x49\xc1\x5a\xc8\xc2\xaf\xdd\x49\xcb\x5f\xde\x40\
|
||||||
|
\x22\x93\xa3\x5c\x2e\xcf\x80\x15\x42\xcc\x90\xa0\xb5\x46\x08\x81\
|
||||||
|
\x69\x9a\x2c\x6a\x69\x36\xae\xba\xfc\x92\x2f\x4e\xa9\x13\xc0\x8a\
|
||||||
|
\xb9\x6c\x7b\xa3\x09\x30\x7a\x7b\x7b\xff\x46\x6b\xbd\xaf\x5c\x2e\
|
||||||
|
\x5f\x52\x48\x17\xa2\xfe\x94\x44\x67\xca\x0c\x25\xd3\x84\xc3\x31\
|
||||||
|
\x16\xd4\x37\x81\x08\x52\xdc\xf9\x3c\xcc\x0a\xc7\x50\xfb\x6a\x6a\
|
||||||
|
\xae\xb9\x9e\x05\x7f\x71\x33\xbe\xa6\x25\x8c\x8c\x8c\x60\x59\x16\
|
||||||
|
\x70\x1c\x2c\x1c\x8f\xff\x13\x49\x59\xdc\xb6\x9a\x68\xbc\x61\xd5\
|
||||||
|
\xda\xb5\x6b\xa7\x7b\x81\x65\x42\x08\xff\x29\x06\xbe\x51\xc8\x07\
|
||||||
|
\x06\x06\xd6\xf4\xf6\xf6\xee\x74\x1c\xe7\x9f\x73\xb9\x5c\xd8\x4b\
|
||||||
|
\x7b\xc1\x80\x15\x20\x91\xca\x90\x29\xda\xb4\x36\x2f\x22\x1c\xae\
|
||||||
|
\x46\x0b\x3f\xde\xf0\x51\xbc\x91\x7e\x22\x57\x7c\x14\xb3\xb6\x11\
|
||||||
|
\x21\x0c\x1a\xd6\x7f\x9e\x25\xdf\xba\x1b\x7f\x43\x1b\x9e\xe7\x31\
|
||||||
|
\x3c\x3c\x4c\xb1\x58\x9c\x59\xe1\xe9\x95\x9f\x0d\x7c\xfa\xda\x74\
|
||||||
|
\xd3\x34\x18\x29\xf1\xe1\xf7\xbf\xef\xba\x29\x93\x7c\x40\xdb\x6c\
|
||||||
|
\x3b\xcf\x7a\x19\x7c\xe9\xa5\x97\xfc\xf5\xf5\xf5\xdf\x95\x52\x7e\
|
||||||
|
\xb7\x50\x28\xf8\xec\xbc\xed\x0b\x96\x83\x14\xad\x22\xa9\x74\x8a\
|
||||||
|
\xba\xea\x3a\xc2\x01\x03\xad\xcb\x68\xe5\x21\xf3\x59\x9c\xae\xa7\
|
||||||
|
\x08\xbd\xff\xf3\x18\xf5\xf5\xd4\x2e\x5d\x45\xb8\xba\x99\xf8\x7b\
|
||||||
|
\x3f\x04\x80\xeb\xba\x8c\x8e\x8e\xe2\xba\xee\x0c\xe8\xe9\x64\x37\
|
||||||
|
\xfd\x19\x2a\xf1\xaf\xb5\x46\x4b\x49\xb9\x77\x13\xf9\xfd\x8f\x50\
|
||||||
|
\x27\x22\xc4\xeb\x3f\x76\x71\x7b\x7b\x7b\xcd\x91\x23\x47\x32\xc0\
|
||||||
|
\x72\x21\x44\xaf\xd6\x5a\x4d\xdb\x7b\x56\xab\xc0\xe8\xe8\xe8\xbb\
|
||||||
|
\x6c\xdb\x7e\xc0\x71\x9c\x16\x2b\x67\xc5\x7c\x8e\x0f\xd3\x36\x19\
|
||||||
|
\x4b\x8e\x21\xb4\xa6\x76\xe4\x25\x74\xa2\x0f\xac\x14\x58\xa3\x68\
|
||||||
|
\x2b\x05\xa6\x89\xff\x8a\xeb\xf0\x2f\x6e\xa7\x7e\xd5\x1a\xe2\x6d\
|
||||||
|
\x6b\x60\x0a\x5c\xb9\x5c\x66\x7c\x7c\x1c\x29\x25\xd3\x76\xea\xa9\
|
||||||
|
\x7a\x3f\xdb\x6e\xa5\x14\xde\xe4\x21\xb2\xbf\xff\x09\xe5\xb1\x61\
|
||||||
|
\x3c\x17\x30\x04\xe3\x8b\x3e\xa0\x0e\x8c\xa9\x27\x7f\xf8\xa3\x5b\
|
||||||
|
\x6f\x9f\xfa\xea\xff\x69\xad\xfb\xa7\xc7\x9d\x15\x0f\xe8\xef\xef\
|
||||||
|
\x0f\x05\x83\xc1\x7f\x71\x5d\xf7\xeb\x96\x65\x05\xbc\x92\x67\xc4\
|
||||||
|
\x88\x61\x15\x2c\xc6\x27\xc7\x69\x88\x45\x61\xcb\x8d\xa8\x63\xbb\
|
||||||
|
\x4e\x1e\x18\x88\x60\x5c\xfd\x55\x22\xab\x2e\x60\xc1\x05\xe7\xe3\
|
||||||
|
\x8f\x44\x67\xe2\x3a\x9f\xcf\x33\x31\x31\x31\x03\xf4\xc4\x6c\x2f\
|
||||||
|
\x84\x98\xf9\xbf\x52\x0a\xe5\x96\xc8\xbc\xf0\x53\x26\x3b\xb6\xe3\
|
||||||
|
\x15\x05\x20\x40\x54\xde\x6b\xc3\xbb\x8c\x85\x2d\x1f\xba\xba\xa1\
|
||||||
|
\xa1\xe1\xde\x54\x2a\x55\xa2\x92\x0c\x67\x08\x78\xdd\x1e\x90\x4c\
|
||||||
|
\x26\xaf\x70\x1c\xe7\x7e\xdb\xb6\x6b\x73\xd9\x5c\x34\x44\x08\x9f\
|
||||||
|
\xf4\x31\x32\x36\x82\xdf\xf4\x13\x37\x15\xe5\x87\xff\x01\x95\x3c\
|
||||||
|
\x5a\x99\xb0\xf5\x02\x88\x35\xa3\x63\x0d\x88\x65\x6b\x59\x78\xc9\
|
||||||
|
\xbb\xa9\x5b\xb2\xf0\xa4\x4c\x9e\xcd\x66\xc9\xe5\x72\x33\xd7\xd3\
|
||||||
|
\xef\x27\xae\xfc\xf4\xe7\xd2\xb1\x9d\x24\x1e\xbf\x15\xd7\xca\x61\
|
||||||
|
\x84\x40\x18\x0a\x27\x0b\xaa\x64\xe0\x6f\xd5\x44\x9a\xab\xe9\x0f\
|
||||||
|
\x5e\x2e\xbb\xfa\x72\x0f\xfc\xf4\xf6\xbb\x1e\x9d\x32\xfb\xf7\x5a\
|
||||||
|
\xeb\x51\x78\x1d\x1e\x90\x4a\xa5\xaa\xb4\xd6\x3f\x74\x1c\xe7\xba\
|
||||||
|
\x6c\x36\x1b\x54\xae\x12\x75\xc1\x3a\x32\x99\x0c\xe3\xe9\x71\x9a\
|
||||||
|
\x1a\x9b\x30\x9d\x12\xd6\x9d\x5f\x45\xe7\x12\x33\xe3\x44\xdb\x25\
|
||||||
|
\xe8\x35\x1f\x22\x56\x1b\xa5\x75\x4d\x0b\x81\xf0\xf1\x3d\x4d\xd7\
|
||||||
|
\x75\x49\xa7\xd3\xa7\xc4\xfb\x34\x60\xc3\x30\x66\xae\xbd\x62\x9a\
|
||||||
|
\x89\xae\x5f\x92\xed\xd8\x8a\xca\x39\x04\xd7\x84\xd0\xca\x41\x39\
|
||||||
|
\x12\x03\x08\x2e\x31\x89\xc6\x63\x04\x83\x21\x5c\x1d\xa7\xa9\x56\
|
||||||
|
\x2e\x3d\xc1\xfc\x95\xc0\x6b\x27\x20\x9d\x4e\x7f\x58\x29\x75\x77\
|
||||||
|
\xb1\x58\x8c\x5a\x39\x2b\x54\x15\xaa\xc2\x30\x0c\x8e\x1d\x3b\x46\
|
||||||
|
\x24\x1c\x61\xc9\xe2\x25\x28\xa9\xd0\xa6\x1f\x73\xd1\x79\x78\x3d\
|
||||||
|
\xc7\x09\x50\x3b\xee\xa7\xe5\x83\xd7\x52\xb7\x7c\xe9\x49\x6e\x5d\
|
||||||
|
\x2c\x16\xc9\xe5\x72\x33\x09\x6e\x3a\xa9\x4d\x7f\xe7\xf8\x35\x64\
|
||||||
|
\x0e\x6d\x63\x62\xef\x26\xbc\xc3\x43\xc8\x44\x09\xfc\x02\x7b\xd8\
|
||||||
|
\x05\x34\x46\xcc\x47\x55\x4b\x98\x70\xc0\x20\x11\x58\xa3\x8f\x7a\
|
||||||
|
\x2b\xdc\xee\xee\xee\x9f\xdc\xf3\xc0\x23\xbf\x3b\x01\x42\xbd\x10\
|
||||||
|
\xa2\x4e\x6b\x3d\xf9\xaa\x08\xb0\x2c\xab\xde\xf3\xbc\xdb\x1c\xc7\
|
||||||
|
\xf9\xe8\xe4\xe4\x64\xd8\x14\x26\xcd\x75\xcd\xa4\x92\x29\x72\xd9\
|
||||||
|
\x1c\x2d\x2d\x2d\x98\x86\x89\xf4\x24\x42\x0b\x94\x54\x04\xaf\xfa\
|
||||||
|
\x32\xde\xe1\x0e\x70\x6d\x44\xb8\x8a\x25\xdf\xbe\x95\xea\x15\xcb\
|
||||||
|
\x8e\x13\xa2\x14\xb9\x5c\x0e\xdb\xb6\x4f\x02\x0a\x9c\xe2\x01\x4e\
|
||||||
|
\x76\x9c\xe1\x8e\x0d\xd8\x89\x23\x08\xe1\xa1\x52\x16\x42\x80\x36\
|
||||||
|
\x05\x98\x06\xfe\xe6\x28\xb1\x58\x00\x33\x10\xa4\x8b\x2b\xa5\x95\
|
||||||
|
\x49\xef\xf9\xe9\xdd\x77\xdc\x3c\x38\x38\x98\x9b\x05\x45\x03\x55\
|
||||||
|
\xc0\xe4\x19\xe7\x80\x7c\x3e\xff\x29\xcf\xf3\x6e\xcf\xe5\x72\xc1\
|
||||||
|
\x7c\x3e\x1f\xaa\x8b\xd7\x81\x82\xa1\xa1\x21\xe2\xd5\x71\xaa\x22\
|
||||||
|
\x55\x48\x29\x51\x52\xa1\xa4\x42\x7a\x95\xcf\xd2\x95\x78\x7b\x9e\
|
||||||
|
\xc4\xeb\x78\x80\xb6\xef\xdd\x45\x68\xd1\x8a\x19\x70\x8e\xe3\x60\
|
||||||
|
\x59\x16\x4a\xa9\x99\x98\x3e\x11\xf0\x34\x41\x5a\xba\x8c\xee\xfa\
|
||||||
|
\x1d\x93\xcf\x3d\x8c\x1e\x3c\x8a\x00\xbc\x0b\x56\x62\x28\x1b\x59\
|
||||||
|
\x2e\x21\xa2\x3e\xa2\xd1\x30\x11\xbf\x64\xd4\xb7\x4a\x0f\x7b\x2d\
|
||||||
|
\xe5\x8e\x1d\x3b\x6f\x79\xf8\x91\xdf\xec\x98\x03\x4a\x16\xe8\xd2\
|
||||||
|
\x5a\x67\xe0\x0c\x92\x60\xb1\x58\x6c\x51\x4a\xfd\xcc\xb6\xed\xcb\
|
||||||
|
\x53\xa9\x54\x24\x1c\x0e\x53\x53\x5d\xc3\xe8\xc8\x28\xa5\x52\x89\
|
||||||
|
\x85\xcd\x0b\x2b\x86\xba\x0a\xad\x34\x9e\xeb\xa1\x95\x46\xba\x12\
|
||||||
|
\x29\x25\xe1\x58\x98\xba\xd6\x3a\x70\xcb\x98\xe1\xe8\x89\x7a\x29\
|
||||||
|
\x97\xcb\xa7\x24\xb5\x13\x09\xd0\x5a\x93\x1d\x19\x60\xe8\x99\x5f\
|
||||||
|
\xc1\x9e\xed\xe8\x82\x85\x16\x06\xb2\xb1\x01\x1d\xf4\x21\xe3\x61\
|
||||||
|
\x82\xb1\x30\xb1\x88\x0f\x65\x86\xe8\x91\x17\xc8\xcc\xe4\xf8\x8b\
|
||||||
|
\xb7\xde\xf9\xe0\x8f\x13\x89\x44\x71\x16\x14\x05\x1c\x00\x0e\x9d\
|
||||||
|
\xb8\x4d\xf6\x8a\x21\x50\x2e\x97\xbf\xac\xb5\xfe\x51\x36\x9b\xf5\
|
||||||
|
\x17\x0a\x85\x40\x73\x73\x33\x4a\x29\x8e\xf6\x1f\xa5\xa1\xae\x81\
|
||||||
|
\xa6\xc6\xa6\x99\x55\x17\x42\xa0\x50\x95\xae\x5b\x80\x16\x9a\x68\
|
||||||
|
\x6d\x94\xfa\x96\xfa\xa9\x99\x2a\x25\xce\xf3\x3c\x8a\xc5\x22\x52\
|
||||||
|
\xca\x99\xa4\x36\xbb\xad\x05\xf0\x6c\x9b\xfe\x97\x3a\xb0\x5e\x78\
|
||||||
|
\x14\x23\x3d\x82\x76\xbd\x4a\xdb\xaa\x15\x48\x8d\x6c\x68\xa2\xaa\
|
||||||
|
\x26\x46\xd0\xf4\x18\x62\x89\x9a\xb0\x63\xc5\xad\xdb\xb6\xdd\xb4\
|
||||||
|
\x71\xd3\x13\xbb\xe6\x80\x32\x41\xa5\xfe\x5b\xb3\x6f\xbc\x9c\x07\
|
||||||
|
\xb4\x95\x4a\xa5\xfb\x1c\xc7\x79\x47\x22\x91\x88\x46\xa3\x51\x6a\
|
||||||
|
\x6a\x6a\x18\x19\x19\x41\x4a\xc9\x82\xe6\x05\x08\x04\x9e\xeb\x4d\
|
||||||
|
\xd5\x61\x35\x43\x84\xf4\xe4\x8c\xfb\x6b\xa5\x69\x5d\xd5\x8a\x69\
|
||||||
|
\x9a\x00\xd8\xb6\x8d\xe3\x38\x73\xae\xf4\x74\xf2\x53\x4a\x31\xda\
|
||||||
|
\x77\x84\x81\xee\x9d\xf8\xbb\x1e\xc7\x9f\x3c\x8a\xbd\x70\x25\xfe\
|
||||||
|
\xd1\x5e\x64\x20\x88\xdd\xda\x8e\x7f\x51\x0b\xb1\xb0\x89\x2d\x02\
|
||||||
|
\x1c\x76\x5b\x65\x2a\x31\xfa\xfc\x6d\x77\xdc\x73\xc7\xd4\x66\xe8\
|
||||||
|
\x89\xe2\x01\xfb\xb4\xd6\x47\x5e\x6e\x91\x4f\x21\x40\x4a\xf9\xe7\
|
||||||
|
\x9e\xe7\xfd\x2c\x9d\x4e\x9b\x85\x42\xc1\xdf\xd8\xd8\x88\xe3\x38\
|
||||||
|
\x8c\x8e\x8e\xd2\xd4\xd4\x44\x2c\x16\xab\x80\x9e\x8a\x75\xcf\xf3\
|
||||||
|
\x2a\x04\x94\x0a\x58\x2f\x6e\x21\x7c\xf1\x47\x2a\x71\xef\x79\x68\
|
||||||
|
\xa9\x89\x37\xc6\x89\x37\xc4\x71\x1c\xa7\x32\xee\x84\x78\x3f\xb1\
|
||||||
|
\xae\x2b\xa5\xc8\x67\xf3\x1c\xde\xb9\x97\xcc\xf8\x08\xd1\x3d\x8f\
|
||||||
|
\xe1\x4f\x1c\x02\x04\x1a\x28\x2d\x5a\x83\xbd\xa8\x9d\x78\x75\x84\
|
||||||
|
\x80\xe9\x31\xe4\xd5\xca\xb4\x6d\xe4\x36\x3f\xf5\xdc\x8d\xcf\x3c\
|
||||||
|
\xf3\xcc\x81\x39\xb0\x8d\x03\xdd\x5a\xeb\xd9\xa1\x70\x92\x9c\x12\
|
||||||
|
\x02\x52\xca\x92\x6d\xdb\xd2\xb2\xac\xd0\xe2\xc5\x8b\x19\x1c\x1c\
|
||||||
|
\x44\x08\x41\x5b\x5b\xdb\x8c\xa1\x15\xea\xc0\xcd\xa7\xb1\x3a\x36\
|
||||||
|
\x81\x08\x50\xe8\xdc\x8c\xb9\x60\x19\xea\x5d\x1f\x44\x4f\x85\x81\
|
||||||
|
\x42\x91\x1a\x4f\x11\x8a\x85\xa6\x9a\xb3\xe3\xe5\x6d\x7a\xc5\xb5\
|
||||||
|
\xd6\x48\x4f\xd2\xdf\xd3\x4f\xff\xfe\x7e\xa4\xeb\x10\x3b\xf4\x0c\
|
||||||
|
\xa1\xe4\x61\x14\xa0\x4c\x3f\xd6\x92\x77\xe0\x6b\x7f\x3b\x75\x41\
|
||||||
|
\x83\xa2\x86\x43\x76\x44\x8e\x8d\x0c\xff\xf6\xb6\xdb\xef\xfa\x45\
|
||||||
|
\x3e\x9f\x9f\x7d\x02\xe4\x00\x7b\xb4\xd6\x83\x9c\x81\x9c\x42\x40\
|
||||||
|
\x20\x10\xd8\x58\x2a\x95\xd2\x5a\xeb\xe8\x74\x69\xaa\xad\xad\x3d\
|
||||||
|
\x09\xbc\x52\x0a\x55\xb4\x28\x74\x3c\x4e\xf8\x82\xcb\x71\xc6\x87\
|
||||||
|
\x11\xa6\x41\xf8\x3d\x1f\xc5\xda\xf0\x03\x22\x1f\xfb\xbb\x0a\x30\
|
||||||
|
\x25\x71\xca\x0e\x99\x54\x86\xba\xe6\xba\x93\xfa\xf7\x69\x22\xd2\
|
||||||
|
\xa9\x34\x87\x3b\xf7\x20\xbb\x37\x53\x95\x3e\x86\xb5\x78\x1d\x32\
|
||||||
|
\x50\x85\x36\x0c\x9c\x68\x13\xd6\xea\x2b\xa9\x6e\x6a\xc6\x34\x5c\
|
||||||
|
\xfa\x4b\x48\xab\xec\x4e\x6e\xda\xb2\xe9\x86\xe7\x9f\x7f\x7e\xae\
|
||||||
|
\x43\x8f\x61\x60\x97\xd6\xda\x3e\x13\xf0\xf0\x32\x39\x20\x9d\x4e\
|
||||||
|
\x7f\xb5\x50\x28\xdc\x50\x2e\x97\x63\x4d\x4d\x4d\x0c\x0f\x0f\xd3\
|
||||||
|
\xda\xda\x7a\x92\xdb\x66\x9f\x7e\x10\x59\xca\x63\x0f\x1c\xa2\xb4\
|
||||||
|
\x77\x3b\xb1\xab\x3f\x87\x6f\xd9\xf9\x78\xe5\x22\xce\xbe\xdf\x23\
|
||||||
|
\x96\x5d\x88\x5e\x71\x31\x9e\xe3\x01\xb0\xfc\xbc\xe5\x08\xe3\x78\
|
||||||
|
\xbb\xeb\xd8\x0e\x7d\x7b\xfb\x48\x6d\xdf\x42\x68\xf7\xa3\x18\xa5\
|
||||||
|
\x2c\x4e\x75\x0b\xe3\x6b\xbf\x84\x2b\x35\x3e\x7b\x82\x68\x5d\x2d\
|
||||||
|
\x61\xbf\x81\xe5\x95\x18\x29\xda\x72\x68\x70\xe0\x37\xff\x73\xe7\
|
||||||
|
\x5d\x0f\x96\x4a\xa5\xd9\x47\x5e\x65\x2a\xee\x3e\x7a\xa6\xc0\xa7\
|
||||||
|
\x65\xce\x2a\x50\x28\x14\xee\x16\x42\xfc\x20\x97\xcb\xd1\xdc\xdc\
|
||||||
|
\x8c\x61\x18\xb8\xae\x3b\xb3\x6a\xe5\xc3\xdd\xf8\x16\xb6\x31\x71\
|
||||||
|
\xcb\xdf\x62\xd6\x35\xe3\x5b\xb0\x0c\x55\xb6\xc8\xde\xf7\x4f\xa8\
|
||||||
|
\xdc\x04\x00\xe1\x0b\xaf\x42\x53\x71\x7b\xd7\x71\x99\x4c\x4c\xd2\
|
||||||
|
\xd8\xd2\x88\x52\x8a\xe4\x48\x92\x23\xdd\xbb\x11\xdb\xee\x21\x3a\
|
||||||
|
\xdc\x83\xf6\x6c\xca\x0b\xce\x67\x72\xf5\x47\x90\xc2\xc0\xf4\x0b\
|
||||||
|
\xe2\x75\xed\x18\x86\xc7\xd1\xec\xb8\x57\x28\x15\x13\x8f\x6e\xdc\
|
||||||
|
\x78\xc3\x8e\x1d\x3b\xe6\x72\xeb\x7e\x60\xef\x99\x1e\x86\x9e\x11\
|
||||||
|
\x01\x8b\x16\x2d\x2a\x0d\x0d\x0d\xdd\x1c\x0a\x85\xbe\x35\x36\x36\
|
||||||
|
\x16\x6d\x6a\x6a\x22\x95\x4a\x51\x5f\x5f\x8f\x52\x0a\x67\x62\x0c\
|
||||||
|
\xff\xe2\x55\x68\xd7\xc6\x1b\xaf\xd8\xe4\x0e\x56\xf2\x90\x08\x86\
|
||||||
|
\xf1\x5d\x78\x15\x46\xeb\x4a\xa4\xeb\xa2\xb4\x42\x69\x45\x62\x38\
|
||||||
|
\x41\xb4\x2a\x4a\xff\xe1\x7e\x26\xf7\x77\x13\x79\xf6\x36\x8a\x6d\
|
||||||
|
\xef\x81\xfa\x3c\xd6\xe2\xcb\x28\x34\xac\x40\x79\x8a\x78\x55\x8c\
|
||||||
|
\xa0\x2f\xc8\x44\x61\x82\x64\x21\xe9\xf5\x1d\xe9\x7b\xe8\xae\xbb\
|
||||||
|
\xee\xfa\xb5\xe3\x38\x6a\x96\x99\x05\x2a\xa5\xed\x65\xb7\xbc\x5f\
|
||||||
|
\x33\x01\x00\x8e\xe3\xfc\xd8\x34\xcd\xbf\x4f\x24\x12\xb4\xb4\xb4\
|
||||||
|
\x20\x65\x25\xb3\xcf\x3c\x8a\x06\x2b\x7b\x8c\xc2\x30\xf1\xb5\x9d\
|
||||||
|
\x87\x88\xd5\x10\xbc\xfc\x93\xc8\xc9\x04\xe2\x6d\xeb\x2a\xa5\x50\
|
||||||
|
\x29\xf4\xd4\xcb\x75\x5d\xf6\x74\xed\x81\xe4\x10\xd1\xa7\x6e\x06\
|
||||||
|
\xbb\x40\xb8\xff\x45\x26\x2f\xbe\x0e\x3b\xb6\x90\x90\xe9\x23\x16\
|
||||||
|
\x8d\xa1\xa4\xa2\x37\xd1\xeb\xe5\x8b\xf9\x63\x1b\x1e\xde\x70\x63\
|
||||||
|
\x77\x77\xf7\x6c\xb7\xd6\x40\x2f\xb0\xff\x4c\x4e\x7f\x5f\x33\x01\
|
||||||
|
\xcb\x97\x2f\x4f\xec\xdd\xbb\xf7\x7e\x9f\xcf\xf7\x99\xb1\xb1\xb1\
|
||||||
|
\x70\x63\x63\x23\x99\x4c\x86\x68\x34\x8a\x51\x5d\x8f\xd3\xbf\x1f\
|
||||||
|
\x84\xa0\xea\xd3\xdf\xc6\x5c\xd8\x8e\x3b\x39\x8e\xb2\x26\x31\xda\
|
||||||
|
\xdf\x89\xd2\x1a\xa5\x4f\x68\x6f\x75\x85\x08\x23\x3b\x8e\x7f\xf3\
|
||||||
|
\x7f\x22\xec\x02\x1a\x50\xca\xc3\xf0\x6c\x6a\x6b\x6b\x09\xfa\x83\
|
||||||
|
\x0c\x4f\x0c\xab\xb1\xf4\x98\x3c\x70\xf0\xc0\x3d\x3f\xff\xf9\xcf\
|
||||||
|
\x9f\x90\x52\xce\x4e\x50\x39\x2a\x6d\x6c\xfa\xf5\x02\x3f\x2d\x01\
|
||||||
|
\x00\x4a\xa9\x1f\xf8\x7c\xbe\xcf\x0e\x0d\x0d\xd1\xd2\xd2\x42\x32\
|
||||||
|
\x99\x44\x4a\x89\xd9\x76\x3e\x99\x5b\xfe\x9a\xd8\xc7\xbf\x81\xa8\
|
||||||
|
\x69\x46\x79\x0e\x66\x4b\x3b\xce\xc1\x2e\x44\x30\x7c\xd2\xea\x4b\
|
||||||
|
\x55\x59\x24\x85\xc2\xdf\xf9\x6b\xcc\x92\x85\x12\x50\x5e\xfa\x6e\
|
||||||
|
\xec\xf7\x7c\x86\xba\xfa\x05\x94\xcb\x65\x76\xf7\xef\x76\x2d\xcb\
|
||||||
|
\xea\x7b\xf0\x57\x0f\xfe\xd7\xbe\x7d\xfb\x66\xbb\xb5\x02\x0e\x52\
|
||||||
|
\x69\x63\x67\x87\xc2\xeb\x92\xd3\x3e\x0b\x74\x76\x76\x6e\xb1\x2c\
|
||||||
|
\xeb\xaa\xf6\xf6\x76\x7f\x34\x1a\xc5\xb2\x2c\xfc\x7e\x3f\x85\xa7\
|
||||||
|
\x1f\x00\xc3\x44\xfb\xfc\x68\x61\x60\x54\xd5\x21\x56\xbe\xbb\xd2\
|
||||||
|
\x18\x79\x0a\xd7\x75\x2b\x8d\x92\xeb\x21\x3d\x89\xe7\x7a\xb8\xe5\
|
||||||
|
\x12\xbe\xae\x4d\x78\xf1\x16\xc2\xe7\xbf\x8f\x80\x3f\x40\xdf\x60\
|
||||||
|
\x9f\x1c\x4e\x0e\xcb\xdd\xbb\x77\xdf\x71\xef\xbd\xf7\x3e\x33\x87\
|
||||||
|
\x09\x93\x54\x56\xfd\x94\x36\xf6\x4d\x21\xa0\xa3\xa3\xe3\x0a\xd7\
|
||||||
|
\x75\x37\xbb\xae\x1b\xb9\xec\xb2\xcb\x18\x18\x18\x20\x18\x0c\xa2\
|
||||||
|
\x95\x44\x69\x90\xae\x06\xa1\x51\xba\xb2\x6f\x37\x03\xf8\x04\x22\
|
||||||
|
\x66\x08\x70\x5c\x22\xe1\x08\x55\xb1\x2a\xf2\xf9\x3c\x5d\x3d\x5d\
|
||||||
|
\x6e\x26\x93\xd9\x7f\xdf\xfd\xf7\xfd\xa8\xb7\xb7\x77\xb6\x5b\x4b\
|
||||||
|
\x60\x1f\x70\xda\x33\xfe\x37\x94\x00\x80\x67\x9f\x7d\x76\x97\x65\
|
||||||
|
\x59\x17\x5c\x74\xd1\x45\xc2\xef\xf7\x63\x59\xd6\x4c\x32\x9c\xd8\
|
||||||
|
\xd6\x83\xeb\x4a\xea\x2e\x5b\x8d\x52\xc7\x9f\x09\x5c\xd7\x45\xba\
|
||||||
|
\xb2\xe2\x09\x9e\x42\x20\xa8\xa9\xa9\x21\xe4\x0f\xb1\xab\x67\x97\
|
||||||
|
\x37\x3c\x36\xec\x76\xbe\xd8\x79\xdb\x43\x0f\x3d\xb4\x7d\x8e\x29\
|
||||||
|
\x13\x54\x32\xfc\x2b\xb6\xb1\x67\x43\xce\x68\x43\x44\x29\xf5\xaf\
|
||||||
|
\x3e\x9f\xef\x8e\x43\x87\x0e\x55\xaf\x5b\xb7\x6e\x66\xe7\x46\x29\
|
||||||
|
\x85\xb3\xaf\x03\x99\xcb\xa2\x2e\x5d\x59\x01\xaf\x14\xae\xe7\xce\
|
||||||
|
\xdc\x47\x43\x3c\x1e\x27\x16\x8b\x91\xc9\x64\xd8\xda\xb1\xd5\xcb\
|
||||||
|
\xa4\x33\x2f\xdd\xfd\x8b\xbb\x7f\x32\xc7\x46\x85\x0b\xec\x3e\xd3\
|
||||||
|
\x36\xf6\x6c\xc8\x19\x11\x90\x4e\xa7\x1f\x09\x06\x83\x37\x27\x12\
|
||||||
|
\x89\xea\x6c\x36\x4b\x24\x12\xa9\xec\xe2\x58\x0e\x66\xff\xff\x12\
|
||||||
|
\x92\xe3\x4c\x76\x7d\x84\xe8\x79\x0b\x66\x1e\x76\xa4\x94\x18\xa6\
|
||||||
|
\x41\x43\x43\x03\xe1\x60\x98\x8e\x1d\x1d\xee\xe8\xd8\xa8\xbd\x6d\
|
||||||
|
\xfb\xb6\xff\x7e\xec\xb1\xc7\x5e\x9c\x63\x9a\x57\xdd\xc6\x9e\x0d\
|
||||||
|
\x39\xa3\x93\xa1\x6b\xaf\xbd\x56\x2a\xa5\x7e\x60\x9a\x66\xba\xa7\
|
||||||
|
\xa7\x87\xba\xba\x3a\x4c\xd3\x24\xbd\x63\x3f\x41\x35\x8c\x29\x5c\
|
||||||
|
\xdc\xce\xa7\xf1\x3c\x0f\xcf\xf3\x90\x52\x12\xaf\x89\xb3\x78\xc9\
|
||||||
|
\x62\xf2\x85\x3c\x8f\x6e\x7a\xd4\xdb\xdb\xb3\xb7\xe3\x86\x1b\x6f\
|
||||||
|
\xf8\xca\x1c\xe0\xcb\xc0\x0e\xad\x75\xe7\x9b\x0d\x1e\x5e\xc5\xb6\
|
||||||
|
\xf8\x86\x0d\x1b\x62\x9e\xe7\x8d\x16\x8b\xc5\xd8\xfa\xf5\xeb\x29\
|
||||||
|
\x16\x8b\x24\xc6\x93\x58\x7d\x29\xe4\xc8\x00\x85\xb1\x71\xe4\xda\
|
||||||
|
\x0b\x21\x50\x09\x83\x42\xa1\xe0\x64\xb3\x59\x1c\xc7\x29\x3e\xf7\
|
||||||
|
\xdc\x73\x37\x3f\xf1\xc4\x13\xbb\xe7\x50\x3b\x40\xe5\xc9\xed\x35\
|
||||||
|
\xb5\xb1\x67\x43\x5e\xd5\xb9\xc0\xbd\xf7\xde\xfb\xef\xae\xeb\x7e\
|
||||||
|
\xa9\xb1\xb1\x31\x57\x53\x53\xb3\x62\x78\x78\x58\x67\x32\x19\xaf\
|
||||||
|
\x58\x2c\xfa\xa6\xea\x73\xce\xb6\xed\xd1\xf1\xf1\xf1\xfd\xc9\x64\
|
||||||
|
\x72\x68\x64\x64\x64\xa4\xbb\xbb\x7b\x30\x9b\xcd\x3a\xb3\x54\x9d\
|
||||||
|
\x95\x36\xf6\x6c\xc8\xab\xda\x15\xb6\x6d\xfb\x66\x80\x91\x91\x91\
|
||||||
|
\x45\xc9\x64\x72\x5b\x2e\x97\xdb\x27\xa5\xdc\xb7\x61\xc3\x06\x6f\
|
||||||
|
\xc7\x8e\x1d\xb1\xd3\x0c\x97\x54\x3a\xb9\x24\x70\xe0\x6c\xb4\xb1\
|
||||||
|
\x67\x43\xce\xca\xd9\xa0\x10\x22\x0a\xbc\x9f\xca\x8e\xa0\x0b\x58\
|
||||||
|
\x27\xfc\xe5\x00\xeb\xcd\x28\x69\xaf\x45\xce\xda\xe1\xa8\x10\xa2\
|
||||||
|
\x16\x28\x6b\xad\x4b\x67\x45\xe1\x9b\x24\xe7\xfc\x6f\x85\xdf\x68\
|
||||||
|
\x39\x27\x7e\x27\x38\x9f\xf2\x16\x01\xf3\x6d\xc0\x7c\xcb\x5b\x04\
|
||||||
|
\xcc\xb7\x01\xf3\x2d\x6f\x11\x30\xdf\x06\xcc\xb7\xfc\xd1\x13\xf0\
|
||||||
|
\xff\xdb\x1a\x8f\x55\x76\x8a\x2b\x80\x00\x00\x00\x00\x49\x45\x4e\
|
||||||
|
\x44\xae\x42\x60\x82\
|
||||||
\x00\x00\x07\x8d\
|
\x00\x00\x07\x8d\
|
||||||
\x89\
|
\x89\
|
||||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||||
@ -1778,6 +2070,10 @@ qt_resource_data = "\
|
|||||||
"
|
"
|
||||||
|
|
||||||
qt_resource_name = "\
|
qt_resource_name = "\
|
||||||
|
\x00\x04\
|
||||||
|
\x00\x06\x98\x84\
|
||||||
|
\x00\x63\
|
||||||
|
\x00\x61\x00\x72\x00\x64\
|
||||||
\x00\x06\
|
\x00\x06\
|
||||||
\x07\x8b\x7a\xc2\
|
\x07\x8b\x7a\xc2\
|
||||||
\x00\x72\
|
\x00\x72\
|
||||||
@ -1817,16 +2113,17 @@ qt_resource_name = "\
|
|||||||
"
|
"
|
||||||
|
|
||||||
qt_resource_struct = "\
|
qt_resource_struct = "\
|
||||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x01\
|
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x01\
|
||||||
\x00\x00\x00\x24\x00\x00\x00\x00\x00\x01\x00\x00\x07\x91\
|
|
||||||
\x00\x00\x00\x12\x00\x02\x00\x00\x00\x05\x00\x00\x00\x05\
|
|
||||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||||
\x00\x00\x00\x38\x00\x00\x00\x00\x00\x01\x00\x00\x0d\xd8\
|
\x00\x00\x00\x32\x00\x00\x00\x00\x00\x01\x00\x00\x19\xab\
|
||||||
\x00\x00\x00\xbc\x00\x00\x00\x00\x00\x01\x00\x00\x68\xd3\
|
\x00\x00\x00\x20\x00\x02\x00\x00\x00\x05\x00\x00\x00\x06\
|
||||||
\x00\x00\x00\x58\x00\x00\x00\x00\x00\x01\x00\x00\x59\x89\
|
\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x12\x1a\
|
||||||
\x00\x00\x00\xa6\x00\x00\x00\x00\x00\x01\x00\x00\x68\x02\
|
\x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x1f\xf2\
|
||||||
\x00\x00\x00\x70\x00\x00\x00\x00\x00\x01\x00\x00\x5b\xa1\
|
\x00\x00\x00\xca\x00\x00\x00\x00\x00\x01\x00\x00\x7a\xed\
|
||||||
\x00\x00\x00\x8e\x00\x00\x00\x00\x00\x01\x00\x00\x64\x5d\
|
\x00\x00\x00\x66\x00\x00\x00\x00\x00\x01\x00\x00\x6b\xa3\
|
||||||
|
\x00\x00\x00\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x7a\x1c\
|
||||||
|
\x00\x00\x00\x7e\x00\x00\x00\x00\x00\x01\x00\x00\x6d\xbb\
|
||||||
|
\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x76\x77\
|
||||||
"
|
"
|
||||||
|
|
||||||
def qInitResources():
|
def qInitResources():
|
||||||
|
@ -20,7 +20,7 @@ from database import LibraryDatabase
|
|||||||
from editbook import EditBookDialog
|
from editbook import EditBookDialog
|
||||||
|
|
||||||
from PyQt4.QtCore import Qt, SIGNAL
|
from PyQt4.QtCore import Qt, SIGNAL
|
||||||
from PyQt4.Qt import QObject, QThread, QCoreApplication, QEventLoop, QString, QStandardItem, QStandardItemModel, QStatusBar, QVariant, QAbstractTableModel, \
|
from PyQt4.Qt import QObject, QThread, QCoreApplication, QEventLoop, QString, QTreeWidgetItem, QStandardItemModel, QStatusBar, QVariant, QAbstractTableModel, \
|
||||||
QAbstractItemView, QImage, QPixmap, QIcon, QSize, QMessageBox, QSettings, QFileDialog, QErrorMessage, QDialog, QSpinBox,\
|
QAbstractItemView, QImage, QPixmap, QIcon, QSize, QMessageBox, QSettings, QFileDialog, QErrorMessage, QDialog, QSpinBox,\
|
||||||
QPainterPath, QItemDelegate, QPainter, QPen, QColor, QLinearGradient, QBrush, QStyle,\
|
QPainterPath, QItemDelegate, QPainter, QPen, QColor, QLinearGradient, QBrush, QStyle,\
|
||||||
qInstallMsgHandler, qDebug, qFatal, qWarning, qCritical
|
qInstallMsgHandler, qDebug, qFatal, qWarning, qCritical
|
||||||
@ -31,7 +31,7 @@ from tempfile import TemporaryFile, NamedTemporaryFile
|
|||||||
from exceptions import Exception as Exception
|
from exceptions import Exception as Exception
|
||||||
import xml.dom.minidom as dom
|
import xml.dom.minidom as dom
|
||||||
from xml.dom.ext import PrettyPrint as PrettyPrint
|
from xml.dom.ext import PrettyPrint as PrettyPrint
|
||||||
from operator import itemgetter
|
from operator import itemgetter, attrgetter
|
||||||
from math import sin, cos, pi
|
from math import sin, cos, pi
|
||||||
|
|
||||||
DEFAULT_BOOK_COVER = None
|
DEFAULT_BOOK_COVER = None
|
||||||
@ -309,18 +309,15 @@ class LibraryBooksModel(QAbstractTableModel):
|
|||||||
self.db.commit()
|
self.db.commit()
|
||||||
|
|
||||||
class DeviceBooksModel(QAbstractTableModel):
|
class DeviceBooksModel(QAbstractTableModel):
|
||||||
TIME_READ_FMT = "%a, %d %b %Y %H:%M:%S %Z"
|
def __init__(self, parent):
|
||||||
def __init__(self, parent, data):
|
|
||||||
QAbstractTableModel.__init__(self, parent)
|
QAbstractTableModel.__init__(self, parent)
|
||||||
self._data = data
|
self._data = []
|
||||||
self._orig_data = data
|
self._orig_data = []
|
||||||
self.image_file = None
|
|
||||||
|
|
||||||
def set_data(self, data):
|
def set_data(self, book_list):
|
||||||
self.emit(SIGNAL("layoutAboutToBeChanged()"))
|
self.emit(SIGNAL("layoutAboutToBeChanged()"))
|
||||||
self._data = data
|
self._data = book_list
|
||||||
self._orig_data = data
|
self._orig_data = book_list
|
||||||
self.sort(0, Qt.DescendingOrder)
|
|
||||||
|
|
||||||
def rowCount(self, parent): return len(self._data)
|
def rowCount(self, parent): return len(self._data)
|
||||||
def columnCount(self, parent): return 4
|
def columnCount(self, parent): return 4
|
||||||
@ -341,10 +338,10 @@ class DeviceBooksModel(QAbstractTableModel):
|
|||||||
if role == Qt.DisplayRole:
|
if role == Qt.DisplayRole:
|
||||||
row, col = index.row(), index.column()
|
row, col = index.row(), index.column()
|
||||||
book = self._data[row]
|
book = self._data[row]
|
||||||
if col == 0: text = book["title"]
|
if col == 0: text = wrap(book.title, width=40)
|
||||||
elif col == 1: text = book["author"]
|
elif col == 1: text = re.sub("&\s*","\n", book.author)
|
||||||
elif col == 2: text = human_readable(int(book["size"]))
|
elif col == 2: text = human_readable(book.size)
|
||||||
elif col == 3: text = time.strftime(TIME_WRITE_FMT, time.strptime(book["date"], self.TIME_READ_FMT))
|
elif col == 3: text = time.strftime(TIME_WRITE_FMT, book.datetime)
|
||||||
return QVariant(text)
|
return QVariant(text)
|
||||||
elif role == Qt.TextAlignmentRole and index.column() in [2,3]:
|
elif role == Qt.TextAlignmentRole and index.column() in [2,3]:
|
||||||
return QVariant(Qt.AlignRight)
|
return QVariant(Qt.AlignRight)
|
||||||
@ -353,7 +350,7 @@ class DeviceBooksModel(QAbstractTableModel):
|
|||||||
def info(self, row):
|
def info(self, row):
|
||||||
row = self._data[row]
|
row = self._data[row]
|
||||||
try:
|
try:
|
||||||
cover = row["thumbnail"]
|
cover = row.thumbnail
|
||||||
pix = QPixmap()
|
pix = QPixmap()
|
||||||
self.image_file = NamedTemporaryFile()
|
self.image_file = NamedTemporaryFile()
|
||||||
self.image_file.write(cover)
|
self.image_file.write(cover)
|
||||||
@ -363,14 +360,14 @@ class DeviceBooksModel(QAbstractTableModel):
|
|||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.image_file = None
|
self.image_file = None
|
||||||
cover = DEFAULT_BOOK_COVER
|
cover = DEFAULT_BOOK_COVER
|
||||||
return row["title"], row["author"], human_readable(int(row["size"])), row["mime"], cover
|
return row.title, row.author, human_readable(row.size), row.mime, cover
|
||||||
|
|
||||||
def sort(self, col, order):
|
def sort(self, col, order):
|
||||||
def getter(key, func): return lambda x : func(itemgetter(key)(x))
|
def getter(key, func): return lambda x : func(attrgetter(key)(x))
|
||||||
if col == 0: key, func = "title", string.lower
|
if col == 0: key, func = "title", string.lower
|
||||||
if col == 1: key, func = "author", lambda x : x.split()[-1:][0].lower()
|
if col == 1: key, func = "author", lambda x : x.split()[-1:][0].lower()
|
||||||
if col == 2: key, func = "size", int
|
if col == 2: key, func = "size", int
|
||||||
if col == 3: key, func = "date", lambda x: time.mktime(time.strptime(x, self.TIME_READ_FMT))
|
if col == 3: key, func = "datetime", lambda x: x
|
||||||
descending = order != Qt.AscendingOrder
|
descending = order != Qt.AscendingOrder
|
||||||
self.emit(SIGNAL("layoutAboutToBeChanged()"))
|
self.emit(SIGNAL("layoutAboutToBeChanged()"))
|
||||||
self._data.sort(key=getter(key, func))
|
self._data.sort(key=getter(key, func))
|
||||||
@ -385,7 +382,7 @@ class DeviceBooksModel(QAbstractTableModel):
|
|||||||
for book in self._orig_data:
|
for book in self._orig_data:
|
||||||
match = True
|
match = True
|
||||||
for q in queries:
|
for q in queries:
|
||||||
if q in book["title"].lower() or q in book["author"].lower(): continue
|
if q in book.title.lower() or q in book.author.lower(): continue
|
||||||
else:
|
else:
|
||||||
match = False
|
match = False
|
||||||
break
|
break
|
||||||
@ -425,37 +422,28 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
self.current_view = self.device_view
|
self.current_view = self.device_view
|
||||||
else:
|
else:
|
||||||
self.device_view.hide(), self.library_view.show()
|
self.device_view.hide(), self.library_view.show()
|
||||||
self.current_view = self.device_view
|
self.current_view = self.library_view
|
||||||
|
self.current_view.sortByColumn(3, Qt.DescendingOrder)
|
||||||
|
|
||||||
|
|
||||||
def tree_clicked(self, index):
|
def tree_clicked(self, item, col):
|
||||||
show_device = self.show_device
|
if item:
|
||||||
item = self.tree.itemFromIndex(index)
|
text = str(item.text(0))
|
||||||
text = str(item.text())
|
if text == "Books": text = str(item.parent().text(0))
|
||||||
if text == "Library":
|
if "Library" in text:
|
||||||
show_device(False)
|
self.show_device(False)
|
||||||
elif text == "SONY Reader":
|
elif "SONY Reader" in text:
|
||||||
show_device(True)
|
self.device_view.setModel(self.reader_model)
|
||||||
self.set_device_data(self.main_books + self.card_books)
|
QObject.connect(self.device_view.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.show_book)
|
||||||
elif text == "Main Memory":
|
self.show_device(True)
|
||||||
show_device(True)
|
elif "Storage Card" in text:
|
||||||
self.set_device_data(self.main_books)
|
self.device_view.setModel(self.card_model)
|
||||||
elif text == "Storage Card":
|
QObject.connect(self.device_view.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.show_book)
|
||||||
show_device(True)
|
self.show_device(True)
|
||||||
self.set_device_data(self.card_books)
|
|
||||||
elif text == "Books":
|
|
||||||
text = str(item.parent().text())
|
|
||||||
if text == "Library":
|
|
||||||
show_device(False)
|
|
||||||
elif text == "Main Memory":
|
|
||||||
show_device(True)
|
|
||||||
self.set_device_data(self.main_books)
|
|
||||||
elif text == "Storage Card":
|
|
||||||
show_device(True)
|
|
||||||
self.set_data(self.card_books)
|
|
||||||
|
|
||||||
def set_device_data(self, data):
|
def set_device_data(self, data):
|
||||||
self.device_model.set_data(data)
|
model.set_data(data)
|
||||||
self.device_view.resizeColumnsToContents()
|
self.device_view.resizeColumnsToContents()
|
||||||
|
|
||||||
def model_modified(self):
|
def model_modified(self):
|
||||||
@ -518,7 +506,7 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
else: self.cache_xml = file
|
else: self.cache_xml = file
|
||||||
for path in paths:
|
for path in paths:
|
||||||
self.dev.del_file(path)
|
self.dev.del_file(path)
|
||||||
self.device_model.delete_by_path(path)
|
model.delete_by_path(path)
|
||||||
self.cache_xml.seek(0)
|
self.cache_xml.seek(0)
|
||||||
self.main_xml.seek(0)
|
self.main_xml.seek(0)
|
||||||
self.status("Files deleted. Updating media list on device")
|
self.status("Files deleted. Updating media list on device")
|
||||||
@ -588,11 +576,11 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
def show_error(self, e, msg):
|
def show_error(self, e, msg):
|
||||||
QErrorMessage(self.window).showMessage(msg+"<br><b>Error: </b>"+str(e)+"<br><br>Traceback:<br>"+traceback.format_exc(e))
|
QErrorMessage(self.window).showMessage(msg+"<br><b>Error: </b>"+str(e)+"<br><br>Traceback:<br>"+traceback.format_exc(e))
|
||||||
|
|
||||||
def __init__(self, window):
|
def __init__(self, window, log_packets):
|
||||||
QObject.__init__(self)
|
QObject.__init__(self)
|
||||||
Ui_MainWindow.__init__(self)
|
Ui_MainWindow.__init__(self)
|
||||||
|
|
||||||
self.dev = device(report_progress=self.progress)
|
self.dev = device(report_progress=self.progress, log_packets=log_packets)
|
||||||
self.is_connected = False
|
self.is_connected = False
|
||||||
self.setupUi(window)
|
self.setupUi(window)
|
||||||
self.card = None
|
self.card = None
|
||||||
@ -618,52 +606,58 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
QObject.connect(self.library_model, SIGNAL("dataChanged(QModelIndex, QModelIndex)"), self.resize_columns)
|
QObject.connect(self.library_model, SIGNAL("dataChanged(QModelIndex, QModelIndex)"), self.resize_columns)
|
||||||
self.library_view.resizeColumnsToContents()
|
self.library_view.resizeColumnsToContents()
|
||||||
|
|
||||||
# Create Device list
|
# Create Device tree
|
||||||
self.tree = QStandardItemModel()
|
QObject.connect(self.device_tree, SIGNAL("itemClicked ( QTreeWidgetItem *, int )"), self.tree_clicked)
|
||||||
library = QStandardItem(QString("Library"))
|
QObject.connect(self.device_tree, SIGNAL("itemActivated ( QTreeWidgetItem *, int )"), self.tree_clicked)
|
||||||
library.setIcon(QIcon(":/library"))
|
self.device_tree.header().hide()
|
||||||
font = library.font()
|
library = QTreeWidgetItem(self.device_tree, QTreeWidgetItem.Type)
|
||||||
font.setBold(True)
|
library.setData(0, Qt.DisplayRole, QVariant("Library"))
|
||||||
self.tree.appendRow(library)
|
library.setData(0, Qt.DecorationRole, QVariant(QIcon(":/library")))
|
||||||
library.setFont(font)
|
books =QTreeWidgetItem(library, QTreeWidgetItem.Type)
|
||||||
library.appendRow(QStandardItem(QString("Books")))
|
books.setData(0, Qt.DisplayRole, QVariant("Books"))
|
||||||
blank = QStandardItem(" ")
|
self.device_tree.expandItem(library)
|
||||||
blank.setEnabled(False)
|
buffer = QTreeWidgetItem(self.device_tree, QTreeWidgetItem.Type)
|
||||||
self.tree.appendRow(blank)
|
buffer.setFlags(Qt.ItemFlags())
|
||||||
self.reader = QStandardItem(QString("SONY Reader"))
|
library = QTreeWidgetItem(self.device_tree, QTreeWidgetItem.Type)
|
||||||
mm = QStandardItem(QString("Main Memory"))
|
library.setData(0, Qt.DisplayRole, QVariant("SONY Reader"))
|
||||||
mm.appendRow(QStandardItem(QString("Books")))
|
library.setData(0, Qt.DecorationRole, QVariant(QIcon(":/reader")))
|
||||||
self.reader.appendRow(mm)
|
books =QTreeWidgetItem(library, QTreeWidgetItem.Type)
|
||||||
mc = QStandardItem(QString("Storage Card"))
|
books.setData(0, Qt.DisplayRole, QVariant("Books"))
|
||||||
mc.appendRow(QStandardItem(QString("Books")))
|
self.device_tree.expandItem(library)
|
||||||
self.reader.appendRow(mc)
|
buffer = QTreeWidgetItem(self.device_tree, QTreeWidgetItem.Type)
|
||||||
self.reader.setIcon(QIcon(":/reader"))
|
buffer.setFlags(Qt.ItemFlags())
|
||||||
self.tree.appendRow(self.reader)
|
library = QTreeWidgetItem(self.device_tree, QTreeWidgetItem.Type)
|
||||||
self.reader.setFont(font)
|
library.setData(0, Qt.DisplayRole, QVariant("Storage Card"))
|
||||||
self.treeView.setModel(self.tree)
|
library.setData(0, Qt.DecorationRole, QVariant(QIcon(":/card")))
|
||||||
self.treeView.header().hide()
|
books =QTreeWidgetItem(library, QTreeWidgetItem.Type)
|
||||||
self.treeView.setExpanded(library.index(), True)
|
books.setData(0, Qt.DisplayRole, QVariant("Books"))
|
||||||
self.treeView.setExpanded(self.reader.index(), True)
|
self.device_tree.expandItem(library)
|
||||||
self.treeView.setExpanded(mm.index(), True)
|
self.device_tree.reader = self.device_tree.topLevelItem(2)
|
||||||
self.treeView.setExpanded(mc.index(), True)
|
self.device_tree.card = self.device_tree.topLevelItem(4)
|
||||||
self.treeView.setRowHidden(2, self.tree.invisibleRootItem().index(), True)
|
def hider(i):
|
||||||
QObject.connect(self.treeView, SIGNAL("activated(QModelIndex)"), self.tree_clicked)
|
def do(s, x): s.topLevelItem(i).setHidden(x), s.topLevelItem(i+1).setHidden(x)
|
||||||
QObject.connect(self.treeView, SIGNAL("clicked(QModelIndex)"), self.tree_clicked)
|
return do
|
||||||
|
self.device_tree.hide_reader = hider(1)
|
||||||
|
self.device_tree.hide_card = hider(3)
|
||||||
|
self.device_tree.hide_reader(self.device_tree, True)
|
||||||
|
self.device_tree.hide_card(self.device_tree, True)
|
||||||
|
|
||||||
|
|
||||||
# Create Device Book list
|
# Create Device Book list
|
||||||
self.device_model = DeviceBooksModel(window, [])
|
self.reader_model = DeviceBooksModel(window)
|
||||||
self.device_view.setModel(self.device_model)
|
self.card_model = DeviceBooksModel(window)
|
||||||
|
self.device_view.setModel(self.reader_model)
|
||||||
self.device_view.setSelectionBehavior(QAbstractItemView.SelectRows)
|
self.device_view.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
self.device_view.setSortingEnabled(True)
|
self.device_view.setSortingEnabled(True)
|
||||||
self.device_view.contextMenuEvent = self.list_context_event
|
self.device_view.contextMenuEvent = self.list_context_event
|
||||||
QObject.connect(self.device_model, SIGNAL("layoutChanged()"), self.device_view.resizeRowsToContents)
|
|
||||||
QObject.connect(self.device_view.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.show_book)
|
QObject.connect(self.device_view.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.show_book)
|
||||||
QObject.connect(self.search, SIGNAL("textChanged(QString)"), self.device_model.search)
|
for model in (self.reader_model, self. card_model):
|
||||||
QObject.connect(self.device_model, SIGNAL("sorted()"), self.model_modified)
|
QObject.connect(model, SIGNAL("layoutChanged()"), self.device_view.resizeRowsToContents)
|
||||||
QObject.connect(self.device_model, SIGNAL("searched()"), self.model_modified)
|
QObject.connect(self.search, SIGNAL("textChanged(QString)"), model.search)
|
||||||
QObject.connect(self.device_model, SIGNAL("deleted()"), self.model_modified)
|
QObject.connect(model, SIGNAL("sorted()"), self.model_modified)
|
||||||
QObject.connect(self.device_model, SIGNAL("dataChanged(QModelIndex, QModelIndex)"), self.resize_columns)
|
QObject.connect(model, SIGNAL("searched()"), self.model_modified)
|
||||||
self.device_view.hide()
|
QObject.connect(model, SIGNAL("deleted()"), self.model_modified)
|
||||||
|
QObject.connect(model, SIGNAL("dataChanged(QModelIndex, QModelIndex)"), self.resize_columns)
|
||||||
|
|
||||||
# Setup book display
|
# Setup book display
|
||||||
self.BOOK_TEMPLATE = self.book_info.text()
|
self.BOOK_TEMPLATE = self.book_info.text()
|
||||||
@ -679,6 +673,7 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
self.device_detector = self.startTimer(1000)
|
self.device_detector = self.startTimer(1000)
|
||||||
self.splitter.setStretchFactor(1,100)
|
self.splitter.setStretchFactor(1,100)
|
||||||
self.search.setFocus(Qt.OtherFocusReason)
|
self.search.setFocus(Qt.OtherFocusReason)
|
||||||
|
self.show_device(False)
|
||||||
window.show()
|
window.show()
|
||||||
|
|
||||||
def timerEvent(self, e):
|
def timerEvent(self, e):
|
||||||
@ -692,13 +687,13 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
def device_removed(self, timeout=False):
|
def device_removed(self, timeout=False):
|
||||||
""" @todo: only reset stuff if library is not shown """
|
""" @todo: only reset stuff if library is not shown """
|
||||||
self.is_connected = False
|
self.is_connected = False
|
||||||
self.df.setText("Main memory: <br><br>Storage card:")
|
self.df.setText("SONY Reader: <br><br>Storage card:")
|
||||||
self.card = None
|
self.device_tree.hide_reader(self.device_tree, True)
|
||||||
self.treeView.setRowHidden(2, self.tree.invisibleRootItem().index(), True)
|
self.device_tree.hide_card(self.device_tree, True)
|
||||||
self.device_model.set_data([])
|
|
||||||
self.book_cover.hide()
|
self.book_cover.hide()
|
||||||
self.book_info.hide()
|
self.book_info.hide()
|
||||||
self.device_view.hide()
|
self.device_view.hide()
|
||||||
|
self.library_view.show()
|
||||||
|
|
||||||
|
|
||||||
def timeout_error(self):
|
def timeout_error(self):
|
||||||
@ -715,6 +710,7 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
self.progress_bar.setMaximum(100)
|
self.progress_bar.setMaximum(100)
|
||||||
self.progress_bar.reset()
|
self.progress_bar.reset()
|
||||||
self.progress_bar.setFormat(msg + ": %p%")
|
self.progress_bar.setFormat(msg + ": %p%")
|
||||||
|
self.progress(0)
|
||||||
QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
|
QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
|
||||||
|
|
||||||
def establish_connection(self):
|
def establish_connection(self):
|
||||||
@ -722,39 +718,38 @@ class MainWindow(QObject, Ui_MainWindow):
|
|||||||
self.status("Connecting to device")
|
self.status("Connecting to device")
|
||||||
try:
|
try:
|
||||||
space = self.dev.available_space()
|
space = self.dev.available_space()
|
||||||
except TimeoutError:
|
except DeviceError:
|
||||||
c = 0
|
self.dev.reconnect()
|
||||||
self.status("Waiting for device to initialize")
|
return
|
||||||
while c < 100: # Delay for 10s while device is initializing
|
except ProtocolError, e:
|
||||||
if c % 10 == c/10:
|
traceback.print_exc(e)
|
||||||
self.progress(c)
|
print >> sys.stderr, "Unable to connect device. Please try unplugiing and reconnecting it"
|
||||||
QThread.currentThread().msleep(100)
|
qFatal("Unable to connect device. Please try unplugiing and reconnecting it")
|
||||||
c += 1
|
|
||||||
space = self.dev.available_space()
|
|
||||||
sc = space[1][1] if space[1][1] else space[2][1]
|
sc = space[1][1] if space[1][1] else space[2][1]
|
||||||
self.df.setText("Main memory: " + human_readable(space[0][1]) + "<br><br>Storage card: " + human_readable(sc))
|
self.df.setText("SONY Reader: " + human_readable(space[0][1]) + "<br><br>Storage card: " + human_readable(sc))
|
||||||
self.is_connected = True
|
self.is_connected = True
|
||||||
if space[1][2] > 0: self.card = "a:"
|
if space[1][2] > 0: card = "a:"
|
||||||
elif space[2][2] > 0: self.card = "b:"
|
elif space[2][2] > 0: card = "b:"
|
||||||
else: self.card = None
|
else: card = None
|
||||||
if self.card: self.treeView.setRowHidden(1, self.reader.index(), False)
|
if card: self.device_tree.hide_card(self.device_tree, False)
|
||||||
else: self.treeView.setRowHidden(1, self.reader.index(), True)
|
else: self.device_tree.hide_card(self.device_tree, True)
|
||||||
self.treeView.setRowHidden(2, self.tree.invisibleRootItem().index(), False)
|
self.device_tree.hide_reader(self.device_tree, False)
|
||||||
self.status("Loading media list from device")
|
self.status("Loading media list from SONY Reader")
|
||||||
mb, cb, mx, cx = self.dev.books()
|
self.reader_model.set_data(self.dev.books())
|
||||||
|
if card: self.status("Loading media list from Storage Card")
|
||||||
for x in (mb, cb):
|
self.card_model.set_data(self.dev.books(oncard=True))
|
||||||
for book in x:
|
self.progress(100)
|
||||||
if "&" in book["author"]:
|
|
||||||
book["author"] = re.sub(r"&\s*", r"\n", book["author"])
|
|
||||||
|
|
||||||
self.main_books = mb
|
|
||||||
self.card_books = cb
|
|
||||||
self.main_xml = mx
|
|
||||||
self.cache_xml = cx
|
|
||||||
self.window.setCursor(Qt.ArrowCursor)
|
self.window.setCursor(Qt.ArrowCursor)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
from optparse import OptionParser
|
||||||
|
from libprs500 import __version__ as VERSION
|
||||||
|
parser = OptionParser(usage="usage: %prog [options]", version=VERSION)
|
||||||
|
parser.add_option("--log-packets", help="print out packet stream to stdout. "+\
|
||||||
|
"The numbers in the left column are byte offsets that allow the packet size to be read off easily.", \
|
||||||
|
dest="log_packets", action="store_true", default=False)
|
||||||
|
options, args = parser.parse_args()
|
||||||
from PyQt4.Qt import QApplication, QMainWindow
|
from PyQt4.Qt import QApplication, QMainWindow
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
global DEFAULT_BOOK_COVER
|
global DEFAULT_BOOK_COVER
|
||||||
@ -771,7 +766,7 @@ def main():
|
|||||||
handler = QErrorMessage.qtHandler()
|
handler = QErrorMessage.qtHandler()
|
||||||
handler.resize(600, 400)
|
handler.resize(600, 400)
|
||||||
handler.setModal(True)
|
handler.setModal(True)
|
||||||
gui = MainWindow(window)
|
gui = MainWindow(window, options.log_packets)
|
||||||
ret = app.exec_()
|
ret = app.exec_()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -53,36 +53,30 @@
|
|||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeView" name="treeView" >
|
<widget class="QTreeWidget" name="device_tree" >
|
||||||
<property name="sizePolicy" >
|
<property name="dragDropMode" >
|
||||||
<sizepolicy>
|
<enum>QAbstractItemView::DropOnly</enum>
|
||||||
<hsizetype>1</hsizetype>
|
|
||||||
<vsizetype>7</vsizetype>
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="acceptDrops" >
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow" >
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollBarPolicy" >
|
|
||||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
|
||||||
</property>
|
|
||||||
<property name="autoScroll" >
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="alternatingRowColors" >
|
<property name="alternatingRowColors" >
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="indentation" >
|
<property name="rootIsDecorated" >
|
||||||
<number>15</number>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="uniformRowHeights" >
|
<property name="animated" >
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="allColumnsShowFocus" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="columnCount" >
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<column>
|
||||||
|
<property name="text" >
|
||||||
|
<string>1</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@ -299,7 +293,7 @@
|
|||||||
<string>Add files to Library</string>
|
<string>Add files to Library</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut" >
|
<property name="shortcut" >
|
||||||
<string>a</string>
|
<string>A</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoRepeat" >
|
<property name="autoRepeat" >
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
@ -313,7 +307,7 @@
|
|||||||
<string>Delete selected items</string>
|
<string>Delete selected items</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut" >
|
<property name="shortcut" >
|
||||||
<string>Delete</string>
|
<string>Del</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="action_edit" >
|
<action name="action_edit" >
|
||||||
@ -324,7 +318,7 @@
|
|||||||
<string>Edit meta-information for the currently selected items</string>
|
<string>Edit meta-information for the currently selected items</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut" >
|
<property name="shortcut" >
|
||||||
<string>e</string>
|
<string>E</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoRepeat" >
|
<property name="autoRepeat" >
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
|
@ -204,7 +204,7 @@ class Command(TransferBuffer):
|
|||||||
|
|
||||||
Command numbers are:
|
Command numbers are:
|
||||||
0 GetUsbProtocolVersion
|
0 GetUsbProtocolVersion
|
||||||
1 ReqUsbConnect
|
1 ReqEndSession
|
||||||
|
|
||||||
10 FskFileOpen
|
10 FskFileOpen
|
||||||
11 FskFileClose
|
11 FskFileClose
|
||||||
@ -343,11 +343,11 @@ class DirClose(ShortCommand):
|
|||||||
""" @param id: The identifier returned as a result of a L{DirOpen} command """
|
""" @param id: The identifier returned as a result of a L{DirOpen} command """
|
||||||
ShortCommand.__init__(self, number=DirClose.NUMBER, type=0x01, command=id)
|
ShortCommand.__init__(self, number=DirClose.NUMBER, type=0x01, command=id)
|
||||||
|
|
||||||
class USBConnect(ShortCommand):
|
class EndSession(ShortCommand):
|
||||||
""" Ask device to change status to 'USB connected' i.e., tell the device that the present sequence of commands is complete """
|
""" Ask device to change status to 'USB connected' i.e., tell the device that the present sequence of commands is complete """
|
||||||
NUMBER=0x1 #: Command number
|
NUMBER=0x1 #: Command number
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
ShortCommand.__init__(self, number=USBConnect.NUMBER, type=0x01, command=0x00)
|
ShortCommand.__init__(self, number=EndSession.NUMBER, type=0x01, command=0x00)
|
||||||
|
|
||||||
class GetUSBProtocolVersion(ShortCommand):
|
class GetUSBProtocolVersion(ShortCommand):
|
||||||
""" Get USB Protocol version used by device """
|
""" Get USB Protocol version used by device """
|
||||||
|
Loading…
x
Reference in New Issue
Block a user