From 509fdf081b9adbe540618e116decb51689558afd Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 30 Jan 2007 02:26:50 +0000 Subject: [PATCH] Added support for unlocking the reader in both CLI and GUI. Version bump. --- setup.py | 1 + src/libprs500/__init__.py | 2 +- src/libprs500/cli/main.py | 8 ++++++-- src/libprs500/communicate.py | 12 +++++++++--- src/libprs500/errors.py | 5 +++++ src/libprs500/gui/database.py | 3 +++ src/libprs500/gui/main.py | 20 +++++++++++++++++--- src/libprs500/prstypes.py | 13 +++++++++---- 8 files changed, 51 insertions(+), 13 deletions(-) diff --git a/setup.py b/setup.py index c5dc750913..e4875b1ed8 100644 --- a/setup.py +++ b/setup.py @@ -65,6 +65,7 @@ setup( 'console_scripts': [ \ 'prs500 = libprs500.cli.main:main', \ 'lrf-meta = libprs500.lrf.meta:main', \ + 'rtf-meta = libprs500.metadata.rtf:main', \ 'makelrf = libprs500.lrf.makelrf:main'\ ], 'gui_scripts' : [ 'prs500-gui = libprs500.gui.main:main'] diff --git a/src/libprs500/__init__.py b/src/libprs500/__init__.py index 85ba74fdd4..5f9d52e201 100644 --- a/src/libprs500/__init__.py +++ b/src/libprs500/__init__.py @@ -37,7 +37,7 @@ You may have to adjust the GROUP and the location of the rules file to suit your distribution. """ -__version__ = "0.3.7" +__version__ = "0.3.8" __docformat__ = "epytext" __author__ = "Kovid Goyal " diff --git a/src/libprs500/cli/main.py b/src/libprs500/cli/main.py index 9477fb1052..1a8da87b88 100755 --- a/src/libprs500/cli/main.py +++ b/src/libprs500/cli/main.py @@ -24,7 +24,7 @@ from optparse import OptionParser from libprs500 import __version__ as VERSION from libprs500.communicate import PRS500Device from terminfo import TerminalController -from libprs500.errors import ArgumentError, DeviceError +from libprs500.errors import ArgumentError, DeviceError, DeviceLocked MINIMUM_COL_WIDTH = 12 #: Minimum width of columns in ls output @@ -185,6 +185,8 @@ def main(): 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) + parser.add_option("--unlock", help="Unlock device with KEY. For e.g. --unlock=1234", \ + dest='key', default='-1') parser.remove_option("-h") parser.disable_interspersed_args() # Allow unrecognized options options, args = parser.parse_args() @@ -195,7 +197,7 @@ def main(): command = args[0] args = args[1:] - dev = PRS500Device(log_packets=options.log_packets) + dev = PRS500Device(key=options.key, log_packets=options.log_packets) try: if command == "df": total = dev.total_space(end_session=False) @@ -301,6 +303,8 @@ def main(): parser.print_help() if dev.handle: dev.close() return 1 + except DeviceLocked: + print >> sys.stderr, "The device is locked. Use the --unlock option" except (ArgumentError, DeviceError), e: print >>sys.stderr, e return 1 diff --git a/src/libprs500/communicate.py b/src/libprs500/communicate.py index 2653a454fe..5725b725d5 100755 --- a/src/libprs500/communicate.py +++ b/src/libprs500/communicate.py @@ -188,8 +188,9 @@ class PRS500Device(Device): return run_session - def __init__(self, log_packets=False, report_progress=None) : + def __init__(self, key='-1', log_packets=False, report_progress=None) : """ + @param key: The key to unlock the device @param log_packets: If true the packet stream to/from the device is logged @param report_progress: Function that is called with a % progress (number between 0 and 100) for various tasks @@ -202,6 +203,11 @@ class PRS500Device(Device): self.handle = None self.log_packets = log_packets self.report_progress = report_progress + if len(key) > 8: + key = key[:8] + elif len(key) < 8: + key += ''.join(['\0' for i in xrange(8 - len(key))]) + self.key = key def reconnect(self): """ Only recreates the device node and deleted the connection handle """ @@ -265,9 +271,9 @@ class PRS500Device(Device): unknown = 2)) if res.code != 0: raise ProtocolError("Unable to set bulk size.") - self.send_validated_command(UnlockDevice(key=0x312d)) + res = self.send_validated_command(UnlockDevice(key=self.key))#0x312d)) if res.code != 0: - raise ProtocolError("Unlocking of device not implemented. Remove locking and retry.") + raise DeviceLocked() res = self.send_validated_command(SetTime()) if res.code != 0: raise ProtocolError("Could not set time on device") diff --git a/src/libprs500/errors.py b/src/libprs500/errors.py index a239ccb984..88cdc3dc97 100644 --- a/src/libprs500/errors.py +++ b/src/libprs500/errors.py @@ -42,6 +42,11 @@ class DeviceBusy(ProtocolError): ProtocolError.__init__(self, "Device is in use by another application:"\ "\nUnderlying error:" + str(uerr)) +class DeviceLocked(ProtocolError): + """ Raised when device has been locked """ + def __init__(self): + ProtocolError.__init__(self, "Device is locked") + class PacketError(ProtocolError): """ Errors with creating/interpreting packets """ diff --git a/src/libprs500/gui/database.py b/src/libprs500/gui/database.py index 889be76eb0..83690e61dd 100644 --- a/src/libprs500/gui/database.py +++ b/src/libprs500/gui/database.py @@ -12,6 +12,9 @@ ## 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. +""" +Backend that implements storage of ebooks in an sqlite database. +""" import sqlite3 as sqlite import os from zlib import compress, decompress diff --git a/src/libprs500/gui/main.py b/src/libprs500/gui/main.py index fc203c5876..d8ee1ad362 100644 --- a/src/libprs500/gui/main.py +++ b/src/libprs500/gui/main.py @@ -22,8 +22,8 @@ import tempfile from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, \ QSettings, QVariant, QSize, QEventLoop, QString, \ QBuffer, QIODevice, QModelIndex -from PyQt4.QtGui import QPixmap, QErrorMessage, \ - QMessageBox, QFileDialog, QIcon, QDialog +from PyQt4.QtGui import QPixmap, QErrorMessage, QLineEdit, \ + QMessageBox, QFileDialog, QIcon, QDialog, QInputDialog from PyQt4.Qt import qDebug, qFatal, qWarning, qCritical from libprs500.communicate import PRS500Device as device @@ -404,7 +404,10 @@ class Main(QObject, Ui_MainWindow): QObject.__init__(self) Ui_MainWindow.__init__(self) - self.dev = device(report_progress=self.progress, log_packets=log_packets) + self.key = '-1' + self.log_packets = log_packets + self.dev = device(key=self.key, report_progress=self.progress, \ + log_packets=self.log_packets) self.setupUi(window) self.card = None self.window = window @@ -532,6 +535,17 @@ class Main(QObject, Ui_MainWindow): self.dev.reconnect() self.thread().msleep(100) return self.establish_connection() + except DeviceLocked: + key, ok = QInputDialog.getText(self.window, 'Unlock device', \ + 'Key to unlock device:', QLineEdit.Password) + self.key = str(key) + if not ok: + self.status('Device locked') + self.window.setCursor(Qt.ArrowCursor) + return + else: + self.dev.key = key + return self.establish_connection() except ProtocolError, e: traceback.print_exc(e) qFatal("Unable to connect to device. Please try unplugging and"+\ diff --git a/src/libprs500/prstypes.py b/src/libprs500/prstypes.py index 39cecc3fe8..8faf377e5f 100755 --- a/src/libprs500/prstypes.py +++ b/src/libprs500/prstypes.py @@ -415,12 +415,17 @@ class SetBulkSize(Command): self.chunk_size = chunk_size self.unknown = unknown -class UnlockDevice(ShortCommand): +class UnlockDevice(Command): """ Unlock the device """ NUMBER = 0x106 #: Command number - def __init__(self, key=0x312d): - ShortCommand.__init__(self, \ - number=UnlockDevice.NUMBER, type=0x01, command=key) + key = stringfield(8, start=16) #: The key defaults to -1 + + def __init__(self, key='-1\0\0\0\0\0\0'): + Command.__init__(self, 24) + self.number = UnlockDevice.NUMBER + self.type = 0x01 + self.length = 8 + self.key = key class LongCommand(Command):