mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
GUI skeleton
Added plumbing for PyPI
This commit is contained in:
parent
a44a2e578b
commit
87c82ab7d7
@ -1,4 +1,5 @@
|
|||||||
include libprs500 *.py
|
include libprs500 *.py
|
||||||
|
include libprs500/gui *.py
|
||||||
include scripts *.py
|
include scripts *.py
|
||||||
include README
|
include README
|
||||||
include docs/pdf/api.pdf
|
include docs/pdf/api.pdf
|
||||||
|
@ -1,3 +1,17 @@
|
|||||||
|
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## 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.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
"""
|
"""
|
||||||
This package provides an interface to the SONY Reader PRS-500 over USB.
|
This package provides an interface to the SONY Reader PRS-500 over USB.
|
||||||
|
|
||||||
|
@ -184,6 +184,7 @@ class PRS500Device(object):
|
|||||||
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.
|
||||||
|
|
||||||
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{USBConnect} 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}.
|
||||||
@ -192,15 +193,20 @@ class PRS500Device(object):
|
|||||||
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}.
|
||||||
"""
|
"""
|
||||||
def run_session(*args, **kwargs):
|
def run_session(*args, **kwargs):
|
||||||
dev = args[0]
|
dev = args[0]
|
||||||
res = None
|
res = None
|
||||||
try:
|
try:
|
||||||
|
if not dev.handle: dev.open()
|
||||||
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(USBConnect())
|
||||||
raise e
|
raise e
|
||||||
except usb.USBError, e:
|
except usb.USBError, e:
|
||||||
|
if "No such device" in str(e):
|
||||||
|
raise DeviceError()
|
||||||
|
elif "Connection timed out" in str(e):
|
||||||
|
raise TimeoutError(func.__name__)
|
||||||
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"]:
|
||||||
@ -214,8 +220,8 @@ class PRS500Device(object):
|
|||||||
self.device_descriptor = DeviceDescriptor(PRS500Device.SONY_VENDOR_ID,
|
self.device_descriptor = DeviceDescriptor(PRS500Device.SONY_VENDOR_ID,
|
||||||
PRS500Device.PRS500_PRODUCT_ID,
|
PRS500Device.PRS500_PRODUCT_ID,
|
||||||
PRS500Device.PRS500_INTERFACE_ID)
|
PRS500Device.PRS500_INTERFACE_ID)
|
||||||
self.device = self.device_descriptor.getDevice()
|
self.device = self.device_descriptor.getDevice() #: The actual device (PyUSB object)
|
||||||
self.handle = None
|
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
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -235,8 +241,7 @@ class PRS500Device(object):
|
|||||||
"""
|
"""
|
||||||
self.device = self.device_descriptor.getDevice()
|
self.device = self.device_descriptor.getDevice()
|
||||||
if not self.device:
|
if not self.device:
|
||||||
print >> sys.stderr, "Unable to find Sony Reader. Is it connected?"
|
raise DeviceError()
|
||||||
sys.exit(1)
|
|
||||||
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)
|
||||||
self.handle.reset()
|
self.handle.reset()
|
||||||
@ -492,11 +497,7 @@ class PRS500Device(object):
|
|||||||
|
|
||||||
@safe
|
@safe
|
||||||
def touch(self, path, end_session=True):
|
def touch(self, path, end_session=True):
|
||||||
"""
|
""" Create a file at path """
|
||||||
Create a file at path
|
|
||||||
|
|
||||||
@todo: Update file modification time if file already exists
|
|
||||||
"""
|
|
||||||
if path.endswith("/") and len(path) > 1: path = path[:-1]
|
if path.endswith("/") and len(path) > 1: path = path[:-1]
|
||||||
exists, file = self._exists(path)
|
exists, file = self._exists(path)
|
||||||
if exists and file.is_dir:
|
if exists and file.is_dir:
|
||||||
@ -505,11 +506,6 @@ class PRS500Device(object):
|
|||||||
res = self._send_validated_command(FileCreate(path))
|
res = self._send_validated_command(FileCreate(path))
|
||||||
if res.code != 0:
|
if res.code != 0:
|
||||||
raise PathError("Could not create file " + path + ". Response code: " + str(hex(res.code)))
|
raise PathError("Could not create file " + path + ". Response code: " + str(hex(res.code)))
|
||||||
## res = self._send_validated_command(SetFileInfo(path))
|
|
||||||
## if res.code != 0:
|
|
||||||
## raise ProtocolError("Unable to touch " + path + ". Response code: " + hex(res.code))
|
|
||||||
## file.wtime = int(time.time())
|
|
||||||
## self._bulk_write(file[16:])
|
|
||||||
|
|
||||||
|
|
||||||
@safe
|
@safe
|
||||||
@ -588,38 +584,38 @@ class PRS500Device(object):
|
|||||||
"""
|
"""
|
||||||
Return a list of all ebooks on the device
|
Return a list of all ebooks on the device
|
||||||
|
|
||||||
@return: A two element tuple. The first element is the books in the main memory and the second is the books on the storage card.
|
@return: A four element tuple. The first element is the books in the main memory and the second is the books on the storage card.
|
||||||
Each element is a list of dictionaries. Important fields in each dictionary are "title", "author", "path" and "thumbnail".
|
The first two elements are each a list of dictionaries. If there is no card the second list is empty.
|
||||||
|
Important fields in each dictionary are "title", "author", "path" and "thumbnail".
|
||||||
|
The third and fourth elements are the temporary files that hold main.xml and cache.xml
|
||||||
"""
|
"""
|
||||||
buffer = TemporaryFile()
|
main_xml = TemporaryFile()
|
||||||
media = self.get_file("/Data/database/cache/media.xml", buffer, end_session=False)
|
media = self.get_file("/Data/database/cache/media.xml", main_xml, end_session=False)
|
||||||
parser = make_parser()
|
parser = make_parser()
|
||||||
parser.setFeature(feature_namespaces, 0)
|
parser.setFeature(feature_namespaces, 0)
|
||||||
finder = FindBooks()
|
finder = FindBooks()
|
||||||
parser.setContentHandler(finder)
|
parser.setContentHandler(finder)
|
||||||
buffer.seek(0)
|
main_xml.seek(0)
|
||||||
parser.parse(buffer)
|
parser.parse(main_xml)
|
||||||
buffer.close()
|
|
||||||
books = finder.books
|
books = finder.books
|
||||||
root = "a:/"
|
root = "a:/"
|
||||||
buffer = TemporaryFile()
|
cache_xml = TemporaryFile()
|
||||||
cbooks = []
|
cbooks = []
|
||||||
try:
|
try:
|
||||||
self.get_file("a:/Sony Reader/database/cache.xml", buffer, end_session=False)
|
self.get_file("a:/Sony Reader/database/cache.xml", cache_xml, end_session=False)
|
||||||
except PathError:
|
except PathError:
|
||||||
try:
|
try:
|
||||||
self.get_file("b:/Sony Reader/database/cache.xml", buffer, end_session=False)
|
self.get_file("b:/Sony Reader/database/cache.xml", cache_xml, end_session=False)
|
||||||
root = "b:/"
|
root = "b:/"
|
||||||
except PathError:
|
except PathError:
|
||||||
pass
|
pass
|
||||||
if buffer.tell() > 0:
|
if cache_xml.tell() > 0:
|
||||||
finder = FindBooks(type="cache", root=root)
|
finder = FindBooks(type="cache", root=root)
|
||||||
buffer.seek(0)
|
cache_xml.seek(0)
|
||||||
parser.setContentHandler(finder)
|
parser.setContentHandler(finder)
|
||||||
parser.parse(buffer)
|
parser.parse(cache_xml)
|
||||||
buffer.close()
|
|
||||||
cbooks = finder.books
|
cbooks = finder.books
|
||||||
return books, cbooks
|
return books, cbooks, main_xml, cache_xml
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,6 +24,16 @@ class ProtocolError(Exception):
|
|||||||
def __init__(self, msg):
|
def __init__(self, msg):
|
||||||
Exception.__init__(self, msg)
|
Exception.__init__(self, msg)
|
||||||
|
|
||||||
|
class TimeoutError(ProtocolError):
|
||||||
|
""" There was a timeout during communication """
|
||||||
|
def __init__(self, func_name):
|
||||||
|
ProtocolError.__init__(self, "There was a timeout while communicating with the device in function: "+func_name)
|
||||||
|
|
||||||
|
class DeviceError(ProtocolError):
|
||||||
|
""" Raised when device is not found """
|
||||||
|
def __init__(self):
|
||||||
|
ProtocolError.__init__(self, "Unable to find SONY Reader. Is it connected?")
|
||||||
|
|
||||||
class PacketError(ProtocolError):
|
class PacketError(ProtocolError):
|
||||||
""" Errors with creating/interpreting packets """
|
""" Errors with creating/interpreting packets """
|
||||||
|
|
||||||
|
16
libprs500/gui/__init__.py
Normal file
16
libprs500/gui/__init__.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## 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.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
__docformat__ = "epytext"
|
||||||
|
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
88
libprs500/gui/main.py
Normal file
88
libprs500/gui/main.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## 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.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
from main_gui import Ui_MainWindow
|
||||||
|
from libprs500.communicate import PRS500Device as device
|
||||||
|
from libprs500.errors import *
|
||||||
|
from PyQt4.Qt import QThread
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceDetector(QThread):
|
||||||
|
def __init__(self, detected_slot):
|
||||||
|
QThread.__init__(self)
|
||||||
|
self.dev = None
|
||||||
|
self.detected_slot = detected_slot
|
||||||
|
self.removed = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
wait = 1
|
||||||
|
while None == self.msleep(wait):
|
||||||
|
wait = 1000
|
||||||
|
if self.removed or not self.dev:
|
||||||
|
self.dev = device()
|
||||||
|
self.removed = False
|
||||||
|
self.detected_slot()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MainWindow(Ui_MainWindow):
|
||||||
|
|
||||||
|
def safe(func):
|
||||||
|
def call_func(*args, **kwargs):
|
||||||
|
window = args[0]
|
||||||
|
res = None
|
||||||
|
try:
|
||||||
|
res = func(*args, **kwargs)
|
||||||
|
except DeviceError:
|
||||||
|
window.device_removed()
|
||||||
|
except TimeoutError, e:
|
||||||
|
print e
|
||||||
|
window.timeout_error()
|
||||||
|
return res
|
||||||
|
return call_func
|
||||||
|
|
||||||
|
@apply
|
||||||
|
def dev():
|
||||||
|
def fget(self):
|
||||||
|
return self.detector.dev
|
||||||
|
return property(**locals())
|
||||||
|
|
||||||
|
def __init__(self, window, log_packets):
|
||||||
|
Ui_MainWindow.__init__(self)
|
||||||
|
self.log_packets = log_packets
|
||||||
|
self.detector = DeviceDetector(self.establish_connection)
|
||||||
|
self.detector.start()
|
||||||
|
self.setupUi(window)
|
||||||
|
window.show()
|
||||||
|
|
||||||
|
def device_removed(self, timeout=False):
|
||||||
|
""" @todo: implement this """
|
||||||
|
self.detector.removed = True
|
||||||
|
|
||||||
|
def timeout_error(self):
|
||||||
|
""" @todo: update status bar """
|
||||||
|
self.detector.sleep(10)
|
||||||
|
self.device_removed(timeout=True)
|
||||||
|
|
||||||
|
@safe
|
||||||
|
def establish_connection(self):
|
||||||
|
mb, cb, mx, cx = self.dev.books()
|
||||||
|
self.main_books = mb
|
||||||
|
self.card_books = cb
|
||||||
|
self.main_xml = mx
|
||||||
|
self.cache_xml = cx
|
||||||
|
print self.main_books + self.card_books
|
||||||
|
|
||||||
|
|
||||||
|
|
136
libprs500/gui/main.ui
Normal file
136
libprs500/gui/main.ui
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## 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.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
<ui version="4.0" >
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>885</width>
|
||||||
|
<height>631</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>SONY Reader</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget" >
|
||||||
|
<layout class="QGridLayout" >
|
||||||
|
<property name="margin" >
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing" >
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="1" >
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<property name="margin" >
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing" >
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" >
|
||||||
|
<property name="margin" >
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing" >
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="clear" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="search" >
|
||||||
|
<property name="acceptDrops" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string>Search title and author</string>
|
||||||
|
</property>
|
||||||
|
<property name="frame" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListView" name="listView" >
|
||||||
|
<property name="sizePolicy" >
|
||||||
|
<sizepolicy>
|
||||||
|
<hsizetype>5</hsizetype>
|
||||||
|
<vsizetype>7</vsizetype>
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow" >
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="autoScroll" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" >
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<property name="margin" >
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing" >
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="treeView" >
|
||||||
|
<property name="frameShadow" >
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="df" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar" />
|
||||||
|
<widget class="QToolBar" name="toolBar" >
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea" >
|
||||||
|
<number>4</number>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
94
libprs500/gui/main_gui.py
Normal file
94
libprs500/gui/main_gui.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'main.ui'
|
||||||
|
#
|
||||||
|
# Created: Thu Nov 16 20:48:21 2006
|
||||||
|
# by: PyQt4 UI code generator 4-snapshot-20061112
|
||||||
|
#
|
||||||
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
class Ui_MainWindow(object):
|
||||||
|
def setupUi(self, MainWindow):
|
||||||
|
MainWindow.setObjectName("MainWindow")
|
||||||
|
MainWindow.resize(QtCore.QSize(QtCore.QRect(0,0,885,631).size()).expandedTo(MainWindow.minimumSizeHint()))
|
||||||
|
|
||||||
|
self.centralwidget = QtGui.QWidget(MainWindow)
|
||||||
|
self.centralwidget.setObjectName("centralwidget")
|
||||||
|
|
||||||
|
self.gridlayout = QtGui.QGridLayout(self.centralwidget)
|
||||||
|
self.gridlayout.setMargin(9)
|
||||||
|
self.gridlayout.setSpacing(6)
|
||||||
|
self.gridlayout.setObjectName("gridlayout")
|
||||||
|
|
||||||
|
self.vboxlayout = QtGui.QVBoxLayout()
|
||||||
|
self.vboxlayout.setMargin(0)
|
||||||
|
self.vboxlayout.setSpacing(6)
|
||||||
|
self.vboxlayout.setObjectName("vboxlayout")
|
||||||
|
|
||||||
|
self.hboxlayout = QtGui.QHBoxLayout()
|
||||||
|
self.hboxlayout.setMargin(0)
|
||||||
|
self.hboxlayout.setSpacing(6)
|
||||||
|
self.hboxlayout.setObjectName("hboxlayout")
|
||||||
|
|
||||||
|
self.clear = QtGui.QToolButton(self.centralwidget)
|
||||||
|
self.clear.setObjectName("clear")
|
||||||
|
self.hboxlayout.addWidget(self.clear)
|
||||||
|
|
||||||
|
self.search = QtGui.QLineEdit(self.centralwidget)
|
||||||
|
self.search.setAcceptDrops(False)
|
||||||
|
self.search.setAutoFillBackground(False)
|
||||||
|
self.search.setFrame(True)
|
||||||
|
self.search.setObjectName("search")
|
||||||
|
self.hboxlayout.addWidget(self.search)
|
||||||
|
self.vboxlayout.addLayout(self.hboxlayout)
|
||||||
|
|
||||||
|
self.listView = QtGui.QListView(self.centralwidget)
|
||||||
|
|
||||||
|
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(5),QtGui.QSizePolicy.Policy(7))
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.listView.sizePolicy().hasHeightForWidth())
|
||||||
|
self.listView.setSizePolicy(sizePolicy)
|
||||||
|
self.listView.setFrameShadow(QtGui.QFrame.Plain)
|
||||||
|
self.listView.setAutoScroll(False)
|
||||||
|
self.listView.setObjectName("listView")
|
||||||
|
self.vboxlayout.addWidget(self.listView)
|
||||||
|
self.gridlayout.addLayout(self.vboxlayout,0,1,1,1)
|
||||||
|
|
||||||
|
self.vboxlayout1 = QtGui.QVBoxLayout()
|
||||||
|
self.vboxlayout1.setMargin(0)
|
||||||
|
self.vboxlayout1.setSpacing(6)
|
||||||
|
self.vboxlayout1.setObjectName("vboxlayout1")
|
||||||
|
|
||||||
|
self.treeView = QtGui.QTreeView(self.centralwidget)
|
||||||
|
self.treeView.setFrameShadow(QtGui.QFrame.Plain)
|
||||||
|
self.treeView.setObjectName("treeView")
|
||||||
|
self.vboxlayout1.addWidget(self.treeView)
|
||||||
|
|
||||||
|
self.df = QtGui.QLabel(self.centralwidget)
|
||||||
|
self.df.setObjectName("df")
|
||||||
|
self.vboxlayout1.addWidget(self.df)
|
||||||
|
self.gridlayout.addLayout(self.vboxlayout1,0,0,1,1)
|
||||||
|
MainWindow.setCentralWidget(self.centralwidget)
|
||||||
|
|
||||||
|
self.statusbar = QtGui.QStatusBar(MainWindow)
|
||||||
|
self.statusbar.setObjectName("statusbar")
|
||||||
|
MainWindow.setStatusBar(self.statusbar)
|
||||||
|
|
||||||
|
self.toolBar = QtGui.QToolBar(MainWindow)
|
||||||
|
self.toolBar.setOrientation(QtCore.Qt.Horizontal)
|
||||||
|
self.toolBar.setObjectName("toolBar")
|
||||||
|
MainWindow.addToolBar(self.toolBar)
|
||||||
|
|
||||||
|
self.retranslateUi(MainWindow)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||||
|
|
||||||
|
def retranslateUi(self, MainWindow):
|
||||||
|
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.clear.setText(QtGui.QApplication.translate("MainWindow", "...", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.search.setText(QtGui.QApplication.translate("MainWindow", "Search title and author", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.df.setText(QtGui.QApplication.translate("MainWindow", "TextLabel", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
|
@ -1,3 +1,17 @@
|
|||||||
|
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## 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.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
import sys, re
|
import sys, re
|
||||||
|
|
||||||
class TerminalController:
|
class TerminalController:
|
||||||
|
@ -1,4 +1,18 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## 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.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
"""
|
"""
|
||||||
Provides a command-line interface to the SONY Reader PRS-500.
|
Provides a command-line interface to the SONY Reader PRS-500.
|
||||||
|
|
||||||
@ -11,7 +25,7 @@ from optparse import OptionParser
|
|||||||
from libprs500 import VERSION
|
from libprs500 import VERSION
|
||||||
from libprs500.communicate import PRS500Device
|
from libprs500.communicate import PRS500Device
|
||||||
from libprs500.terminfo import TerminalController
|
from libprs500.terminfo import TerminalController
|
||||||
from libprs500.errors import ArgumentError
|
from libprs500.errors import ArgumentError, DeviceError
|
||||||
|
|
||||||
|
|
||||||
MINIMUM_COL_WIDTH = 12 #: Minimum width of columns in ls output
|
MINIMUM_COL_WIDTH = 12 #: Minimum width of columns in ls output
|
||||||
@ -170,17 +184,29 @@ def main():
|
|||||||
parser.add_option("--log-packets", help="print out packet stream to stdout. "+\
|
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.",
|
"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)
|
dest="log_packets", action="store_true", default=False)
|
||||||
|
parser.add_option("--gui", help="Run a Graphical User Interface", dest="gui", action="store_true", default=False)
|
||||||
parser.remove_option("-h")
|
parser.remove_option("-h")
|
||||||
parser.disable_interspersed_args() # Allow unrecognized options
|
parser.disable_interspersed_args() # Allow unrecognized options
|
||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
|
if options.gui:
|
||||||
|
try:
|
||||||
|
from PyQt4.Qt import QApplication, QMainWindow
|
||||||
|
from libprs500.gui.main import MainWindow
|
||||||
|
app = QApplication(args)
|
||||||
|
window = QMainWindow()
|
||||||
|
mw = MainWindow(window, options.log_packets)
|
||||||
|
sys.exit(app.exec_())
|
||||||
|
except ImportError, e:
|
||||||
|
print >>sys.stderr, "You dont have PyQt4 installed:", e
|
||||||
|
sys.exit(1)
|
||||||
if len(args) < 1:
|
if len(args) < 1:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
command = args[0]
|
command = args[0]
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
dev = PRS500Device(log_packets=options.log_packets)
|
dev = PRS500Device(log_packets=options.log_packets)
|
||||||
dev.open()
|
|
||||||
try:
|
try:
|
||||||
if command == "df":
|
if command == "df":
|
||||||
data = dev.available_space()
|
data = dev.available_space()
|
||||||
@ -190,7 +216,9 @@ def main():
|
|||||||
str(0 if datum[2]==0 else int(100*(datum[2]-datum[1])/(datum[2]*1.)))+"%"
|
str(0 if datum[2]==0 else int(100*(datum[2]-datum[1])/(datum[2]*1.)))+"%"
|
||||||
print "%-10s\t%s\t%s\t%s\t%s"%(datum[0], total, used, free, percent)
|
print "%-10s\t%s\t%s\t%s\t%s"%(datum[0], total, used, free, percent)
|
||||||
elif command == "books":
|
elif command == "books":
|
||||||
main, card = dev.books()
|
main, card, d1, d2 = dev.books()
|
||||||
|
d1.close()
|
||||||
|
d2.close()
|
||||||
print "Books in main memory:"
|
print "Books in main memory:"
|
||||||
for book in main:
|
for book in main:
|
||||||
print book
|
print book
|
||||||
@ -215,7 +243,6 @@ def main():
|
|||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
dev.open()
|
|
||||||
print ls(dev, args[0], term, color=options.color, recurse=options.recurse, ll=options.ll, human_readable_size=options.hrs, cols=cols),
|
print ls(dev, args[0], term, color=options.color, recurse=options.recurse, ll=options.ll, human_readable_size=options.hrs, cols=cols),
|
||||||
elif command == "info":
|
elif command == "info":
|
||||||
info(dev)
|
info(dev)
|
||||||
@ -289,7 +316,7 @@ def main():
|
|||||||
parser.print_help()
|
parser.print_help()
|
||||||
if dev.handle: dev.close()
|
if dev.handle: dev.close()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except ArgumentError, e:
|
except (ArgumentError, DeviceError), e:
|
||||||
print >>sys.stderr, e
|
print >>sys.stderr, e
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
finally:
|
finally:
|
||||||
|
35
setup.py
35
setup.py
@ -1,3 +1,17 @@
|
|||||||
|
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## 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.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
from distutils.core import setup
|
from distutils.core import setup
|
||||||
from libprs500 import VERSION
|
from libprs500 import VERSION
|
||||||
@ -7,14 +21,27 @@ setup(name='libprs500',
|
|||||||
description='Library to interface with the Sony Portable Reader 500 over USB.',
|
description='Library to interface with the Sony Portable Reader 500 over USB.',
|
||||||
long_description =
|
long_description =
|
||||||
"""
|
"""
|
||||||
libprs500 is library to interface with the Sony Portable Reader 500 over USB.
|
libprs500 is library to interface with the _Sony Portable Reader:http://Sony.com/reader over USB.
|
||||||
It provides methods to list the contents of the file system on the device as well as
|
It provides methods to list the contents of the file system on the device as well as
|
||||||
copy files from and to the device. It also provides a command line interface via the script prs500.py.
|
copy files from and to the device. It also provides a command line and a graphical user interface via the script prs500.py.
|
||||||
""",
|
""",
|
||||||
author='Kovid Goyal',
|
author='Kovid Goyal',
|
||||||
author_email='kovid@kovidgoyal.net',
|
author_email='kovid@kovidgoyal.net',
|
||||||
provides=['libprs500'],
|
provides=['libprs500'],
|
||||||
requires=['pyusb'],
|
requires=['pyusb'],
|
||||||
packages = ['libprs500'],
|
packages = ['libprs500', 'libprs500.gui'],
|
||||||
scripts = ['scripts/prs500.py']
|
scripts = ['scripts/prs500.py'],
|
||||||
|
classifiers = [
|
||||||
|
'Development Status :: 3 - Alpha',
|
||||||
|
'Environment :: Console',
|
||||||
|
'Environment :: X11 Applications :: Qt',
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'Intended Audience :: End Users/Desktop',
|
||||||
|
'License :: OSI Approved :: GNU General Public License (GPL)',
|
||||||
|
'Natural Language :: English',
|
||||||
|
'Operating System :: POSIX :: Linux',
|
||||||
|
'Programming Language :: Python',
|
||||||
|
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||||
|
'Topic :: System :: Hardware :: Hardware Drivers'
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user