Run debug device detection on the gui thread, with proper handling of startup() and shutdown(). Also refuse to run if a device is already detected.

This commit is contained in:
Kovid Goyal 2012-08-09 10:27:40 +05:30
parent 5904626f3c
commit dfed990a65
4 changed files with 65 additions and 13 deletions

View File

@ -55,7 +55,7 @@ def get_connected_device():
break
return dev
def debug(ioreg_to_tmp=False, buf=None):
def debug(ioreg_to_tmp=False, buf=None, plugins=None):
import textwrap
from calibre.customize.ui import device_plugins
from calibre.devices.scanner import DeviceScanner, win_pnp_drives
@ -66,9 +66,19 @@ def debug(ioreg_to_tmp=False, buf=None):
if buf is None:
buf = StringIO()
sys.stdout = sys.stderr = buf
out = partial(prints, file=buf)
devplugins = device_plugins() if plugins is None else plugins
devplugins = list(sorted(devplugins, cmp=lambda
x,y:cmp(x.__class__.__name__, y.__class__.__name__)))
if plugins is None:
for d in devplugins:
try:
d.startup()
except:
out('Startup failed for device plugin: %s'%d)
try:
out = partial(prints, file=buf)
out('Version:', __version__)
s = DeviceScanner()
s.scan()
@ -96,8 +106,6 @@ def debug(ioreg_to_tmp=False, buf=None):
ioreg += 'Output from osx_get_usb_drives:\n'+drives+'\n\n'
ioreg += Device.run_ioreg()
connected_devices = []
devplugins = list(sorted(device_plugins(), cmp=lambda
x,y:cmp(x.__class__.__name__, y.__class__.__name__)))
out('Available plugins:', textwrap.fill(' '.join([x.__class__.__name__ for x in
devplugins])))
out(' ')
@ -155,6 +163,12 @@ def debug(ioreg_to_tmp=False, buf=None):
finally:
sys.stdout = oldo
sys.stderr = olde
if plugins is None:
for d in devplugins:
try:
d.shutdown()
except:
pass
def device_info(ioreg_to_tmp=False, buf=None):
from calibre.devices.scanner import DeviceScanner, win_pnp_drives

View File

@ -3,7 +3,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
# Imports {{{
import os, traceback, Queue, time, cStringIO, re, sys
import os, traceback, Queue, time, cStringIO, re, sys, weakref
from threading import Thread, Event
from PyQt4.Qt import (QMenu, QAction, QActionGroup, QIcon, SIGNAL,
@ -369,6 +369,18 @@ class DeviceManager(Thread): # {{{
except:
return False
def _debug_detection(self):
from calibre.devices import debug
raw = debug(plugins=self.devices)
return raw
def debug_detection(self, done):
if self.is_device_connected:
raise ValueError('Device is currently detected in calibre, cannot'
' debug device detection')
self.create_job(self._debug_detection, done,
_('Debug device detection'))
def _get_device_information(self):
info = self.device.get_device_information(end_session=False)
if len(info) < 5:
@ -771,6 +783,15 @@ class DeviceMixin(object): # {{{
if tweaks['auto_connect_to_folder']:
self.connect_to_folder_named(tweaks['auto_connect_to_folder'])
def debug_detection(self, done):
self.debug_detection_callback = weakref.ref(done)
self.device_manager.debug_detection(FunctionDispatcher(self.debug_detection_done))
def debug_detection_done(self, job):
d = self.debug_detection_callback()
if d is not None:
d(job)
def show_open_feedback(self, devname, e):
try:
self.__of_dev_mem__ = d = e.custom_dialog(self)

View File

@ -10,15 +10,18 @@ __docformat__ = 'restructuredtext en'
from PyQt4.Qt import QDialog, QVBoxLayout, QPlainTextEdit, QTimer, \
QDialogButtonBox, QPushButton, QApplication, QIcon
from calibre.gui2 import error_dialog
class DebugDevice(QDialog):
def __init__(self, parent=None):
def __init__(self, gui, parent=None):
QDialog.__init__(self, parent)
self.gui = gui
self._layout = QVBoxLayout(self)
self.setLayout(self._layout)
self.log = QPlainTextEdit(self)
self._layout.addWidget(self.log)
self.log.setPlainText(_('Getting debug information')+'...')
self.log.setPlainText(_('Getting debug information, please wait')+'...')
self.copy = QPushButton(_('Copy to &clipboard'))
self.copy.setDefault(True)
self.setWindowTitle(_('Debug device detection'))
@ -36,12 +39,26 @@ class DebugDevice(QDialog):
QTimer.singleShot(1000, self.debug)
def debug(self):
try:
from calibre.devices import debug
raw = debug()
self.log.setPlainText(raw)
finally:
if self.gui.device_manager.is_device_connected:
error_dialog(self, _('Device already detected'),
_('A device (%s) is already detected by calibre.'
' If you wish to debug the detection of another device'
', first disconnect this device.')%
self.gui.device_manager.connected_device.get_gui_name(),
show=True)
self.bbox.setEnabled(True)
return
self.gui.debug_detection(self)
def __call__(self, job):
if not self.isVisible(): return
self.bbox.setEnabled(True)
if job.failed:
return error_dialog(self, _('Debugging failed'),
_('Running debug device detection failed. Click Show '
'Details for more information.'), det_msg=job.details,
show=True)
self.log.setPlainText(job.result)
def copy_to_clipboard(self):
QApplication.clipboard().setText(self.log.toPlainText())

View File

@ -52,7 +52,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
def debug_device_detection(self, *args):
from calibre.gui2.preferences.device_debug import DebugDevice
d = DebugDevice(self)
d = DebugDevice(self.gui, self)
d.exec_()
def user_defined_device(self, *args):