diff --git a/src/calibre/devices/__init__.py b/src/calibre/devices/__init__.py index dce04034c8..5c7da00861 100644 --- a/src/calibre/devices/__init__.py +++ b/src/calibre/devices/__init__.py @@ -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 diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 4c02574b77..4ecf18f836 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -3,7 +3,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' # 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) diff --git a/src/calibre/gui2/preferences/device_debug.py b/src/calibre/gui2/preferences/device_debug.py index 90927fe9b9..62cb5e4aaf 100644 --- a/src/calibre/gui2/preferences/device_debug.py +++ b/src/calibre/gui2/preferences/device_debug.py @@ -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()) diff --git a/src/calibre/gui2/preferences/misc.py b/src/calibre/gui2/preferences/misc.py index 796ff9d40f..1bf9db5a17 100644 --- a/src/calibre/gui2/preferences/misc.py +++ b/src/calibre/gui2/preferences/misc.py @@ -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):