Added detection of device busy condition

Added a lock file to ensure that only one instance of the GUI runs
This commit is contained in:
Kovid Goyal 2006-12-09 07:30:15 +00:00
parent 876f994a4a
commit 9962f95b31
6 changed files with 55 additions and 24 deletions

View File

@ -221,8 +221,12 @@ class PRS500Device(object):
self.device = self.device_descriptor.getDevice()
if not self.device:
raise DeviceError()
try:
self.handle = self.device.open()
self.handle.claimInterface(self.device_descriptor.interface_id)
except usb.USBError, e:
print >>sys.stderr, e
raise DeviceBusy()
res = self._send_validated_command(GetUSBProtocolVersion(), timeout=20000) # Large timeout as device may still be initializing
if res.code != 0: raise ProtocolError("Unable to get USB Protocol version.")
version = self._bulk_read(24, data_type=USBProtocolVersion)[0].version
@ -236,8 +240,10 @@ class PRS500Device(object):
def close(self):
""" Release device interface """
try:
self.handle.reset()
self.handle.releaseInterface()
except: pass
self.handle, self.device = None, None
def _send_command(self, command, response_type=Response, timeout=1000):

View File

@ -34,6 +34,11 @@ class DeviceError(ProtocolError):
def __init__(self):
ProtocolError.__init__(self, "Unable to find SONY Reader. Is it connected?")
class DeviceBusy(ProtocolError):
""" Raised when device is busy """
def __init__(self):
ProtocolError.__init__(self, "Device is in use by another application")
class PacketError(ProtocolError):
""" Errors with creating/interpreting packets """

View File

@ -14,6 +14,7 @@
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
__docformat__ = "epytext"
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
APP_TITLE = "libprs500"
import pkg_resources, sys, os, re, StringIO, traceback
from PyQt4 import QtCore, QtGui # Needed for classes imported with import_ui
@ -28,7 +29,7 @@ def installErrorHandler(dialog):
global error_dialog
error_dialog = dialog
error_dialog.resize(600, 400)
error_dialog.setWindowTitle("SONY Reader - Error")
error_dialog.setWindowTitle(APP_TITLE + " - Error")
error_dialog.setModal(True)

View File

@ -20,12 +20,12 @@ from PyQt4 import uic
from libprs500.communicate import PRS500Device as device
from libprs500.errors import *
from libprs500.lrf.meta import LRFMetaFile, LRFException
from libprs500.gui import import_ui, installErrorHandler, Error, Warning, extension
from libprs500.gui import import_ui, installErrorHandler, Error, Warning, extension, APP_TITLE
from libprs500.gui.widgets import LibraryBooksModel, DeviceBooksModel, DeviceModel, TableView
from database import LibraryDatabase
from editbook import EditBookDialog
import sys, re, os, traceback
import sys, re, os, traceback, tempfile
DEFAULT_BOOK_COVER = None
LIBRARY_BOOK_TEMPLATE = QString("<table><tr><td><b>Formats:</b> %1 </td><td><b>Tags:</b> %2</td></tr><tr><td><b>Comments:</b>%3</td></tr></table>")
@ -102,7 +102,7 @@ class MainWindow(QObject, Ui_MainWindow):
def delete(self, action):
count = str(len(self.current_view.selectionModel().selectedRows()))
ret = QMessageBox.question(self.window, self.trUtf8("SONY Reader - confirm"), self.trUtf8("Are you sure you want to <b>permanently delete</b> these ") +count+self.trUtf8(" item(s)?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
ret = QMessageBox.question(self.window, self.trUtf8(APP_TITLE + " - confirm"), self.trUtf8("Are you sure you want to <b>permanently delete</b> these ") +count+self.trUtf8(" item(s)?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if ret != QMessageBox.Yes: return
self.window.setCursor(Qt.WaitCursor)
if self.library_view.isVisible():
@ -342,7 +342,7 @@ class MainWindow(QObject, Ui_MainWindow):
def device_removed(self, timeout=False):
""" @todo: only reset stuff if library is not shown """
self.is_connected = False
self.df.setText("SONY Reader: <br><br>Storage card:")
self.df.setText(self.df_template.arg("").arg("").arg(""))
self.device_tree.hide_reader(True)
self.device_tree.hide_card(True)
self.book_cover.hide()
@ -368,13 +368,15 @@ class MainWindow(QObject, Ui_MainWindow):
self.status("Connecting to device")
try:
info = self.dev.get_device_information(end_session=False)
except DeviceBusy, e:
qFatal(str(e))
except DeviceError:
self.dev.reconnect()
return
except ProtocolError, e:
traceback.print_exc(e)
qFatal("Unable to connect to device. Please try unplugging and reconnecting it")
self.df.setText(self.df_template.arg(info[0]).arg(info[1]).arg(info[2]))
self.df.setText(self.df_template.arg("Connected: "+info[0]).arg(info[1]).arg(info[2]))
space = self.dev.available_space(end_session=False)
sc = space[1][1] if space[1][1] else space[2][1]
self.device_tree.model().update_free_space(space[0][1], sc)
@ -395,6 +397,11 @@ class MainWindow(QObject, Ui_MainWindow):
def main():
from optparse import OptionParser
from libprs500 import __version__ as VERSION
lock = os.path.join(tempfile.gettempdir(),"libprs500_gui_lock")
if os.access(lock, os.F_OK):
print >>sys.stderr, "Another instance of", APP_TITLE, "is running"
print >>sys.stderr, "If you are sure this is not the case then manually delete the file", lock
sys.exit(1)
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.", \
@ -405,12 +412,17 @@ def main():
global DEFAULT_BOOK_COVER
DEFAULT_BOOK_COVER = QPixmap(":/default_cover")
window = QMainWindow()
window.setWindowTitle(APP_TITLE)
window.setWindowIcon(QIcon(":/icon"))
installErrorHandler(QErrorMessage(window))
QCoreApplication.setOrganizationName("KovidsBrain")
QCoreApplication.setApplicationName("SONY Reader")
QCoreApplication.setApplicationName(APP_TITLE)
gui = MainWindow(window, options.log_packets)
f = open(lock, "w")
f.close()
try:
ret = app.exec_()
finally: os.remove(lock)
return ret
if __name__ == "__main__": main()

View File

@ -19,7 +19,10 @@
</sizepolicy>
</property>
<property name="windowTitle" >
<string>SONY Reader</string>
<string/>
</property>
<property name="windowIcon" >
<iconset resource="images.qrc" >:/images/library.png</iconset>
</property>
<widget class="QWidget" name="centralwidget" >
<layout class="QVBoxLayout" >
@ -60,7 +63,7 @@
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="dragDropMode" >
<enum>QAbstractItemView::DropOnly</enum>
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="flow" >
<enum>QListView::TopToBottom</enum>
@ -84,11 +87,14 @@
</sizepolicy>
</property>
<property name="text" >
<string>&lt;b>libprs500&lt;/b> was created by &lt;b>Kovid Goyal&lt;/b> &amp;copy; 2006&lt;br>&lt;br>%1 %2 %3</string>
<string>For help visit &lt;a href="http://libprs500.kovidgoyal.net">http://libprs500.kovidgoyal.net&lt;/a>&lt;br>&lt;br>&lt;b>libprs500&lt;/b> was created by &lt;b>Kovid Goyal&lt;/b> &amp;copy; 2006&lt;br>%1 %2 %3</string>
</property>
<property name="textFormat" >
<enum>Qt::RichText</enum>
</property>
<property name="openExternalLinks" >
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -275,8 +281,8 @@
<widget class="QToolBar" name="tool_bar" >
<property name="minimumSize" >
<size>
<width>49</width>
<height>37</height>
<width>163</width>
<height>58</height>
</size>
</property>
<property name="movable" >
@ -291,6 +297,9 @@
<height>22</height>
</size>
</property>
<property name="toolButtonStyle" >
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<attribute name="toolBarArea" >
<number>4</number>
</attribute>
@ -303,7 +312,7 @@
<iconset resource="images.qrc" >:/images/plus.png</iconset>
</property>
<property name="text" >
<string>Add files to Library</string>
<string>Add books to Library</string>
</property>
<property name="shortcut" >
<string>A</string>
@ -317,7 +326,7 @@
<iconset resource="images.qrc" >:/images/minus.png</iconset>
</property>
<property name="text" >
<string>Delete selected items</string>
<string>Delete books</string>
</property>
<property name="shortcut" >
<string>Del</string>
@ -328,7 +337,7 @@
<iconset resource="images.qrc" >:/images/edit.png</iconset>
</property>
<property name="text" >
<string>Edit meta-information for the currently selected items</string>
<string>Edit meta-information</string>
</property>
<property name="shortcut" >
<string>E</string>

View File

@ -116,9 +116,7 @@ class FileDragAndDrop(object):
urls.append(urlunparse(('file', quote(gethostname()), quote(str(file.name)), '','','')))
self._dragged_files.append(file)
mime_data.setData("text/uri-list", QByteArray("\n".join(urls)))
user = None
try: user = os.environ['USER']
except: pass
user = os.getenv['USER']
if user: mime_data.setData("text/x-xdnd-username", QByteArray(user))
drag.setMimeData(mime_data)
return drag