diff --git a/src/calibre/devices/__init__.py b/src/calibre/devices/__init__.py index e67c17c063..89d0e4e026 100644 --- a/src/calibre/devices/__init__.py +++ b/src/calibre/devices/__init__.py @@ -221,54 +221,65 @@ def debug(ioreg_to_tmp=False, buf=None, plugins=None): out('Available plugins:', textwrap.fill(' '.join([x.__class__.__name__ for x in devplugins]))) out(' ') - out('Looking for devices...') + found_dev = False for dev in devplugins: - connected, det = s.is_device_connected(dev, debug=True) - if connected: - out('\t\tDetected possible device', dev.__class__.__name__) - connected_devices.append((dev, det)) - - out(' ') - errors = {} - success = False - out('Devices possibly connected:', end=' ') - for dev, det in connected_devices: - out(dev.name, end=', ') - if not connected_devices: - out('None', end='') - out(' ') - for dev, det in connected_devices: - out('Trying to open', dev.name, '...', end=' ') - try: - dev.reset(detected_device=det) - dev.open(det, None) - out('OK') - except: - import traceback - errors[dev] = traceback.format_exc() - out('failed') - continue - success = True - if hasattr(dev, '_main_prefix'): - out('Main memory:', repr(dev._main_prefix)) - out('Total space:', dev.total_space()) - break - if not success and errors: - out('Opening of the following devices failed') - for dev,msg in errors.items(): - out(dev) - out(msg) - out(' ') - - if ioreg is not None: - ioreg = 'IOREG Output\n'+ioreg + if not dev.MANAGES_DEVICE_PRESENCE: continue + out('Looking for devices of type:', dev.__class__.__name__) + if dev.debug_managed_device_detection(s.devices, buf): + found_dev = True + break out(' ') - if ioreg_to_tmp: - open('/tmp/ioreg.txt', 'wb').write(ioreg) - out('Dont forget to send the contents of /tmp/ioreg.txt') - out('You can open it with the command: open /tmp/ioreg.txt') - else: - out(ioreg) + + if not found_dev: + out('Looking for devices...') + for dev in devplugins: + if dev.MANAGES_DEVICE_PRESENCE: continue + connected, det = s.is_device_connected(dev, debug=True) + if connected: + out('\t\tDetected possible device', dev.__class__.__name__) + connected_devices.append((dev, det)) + + out(' ') + errors = {} + success = False + out('Devices possibly connected:', end=' ') + for dev, det in connected_devices: + out(dev.name, end=', ') + if not connected_devices: + out('None', end='') + out(' ') + for dev, det in connected_devices: + out('Trying to open', dev.name, '...', end=' ') + try: + dev.reset(detected_device=det) + dev.open(det, None) + out('OK') + except: + import traceback + errors[dev] = traceback.format_exc() + out('failed') + continue + success = True + if hasattr(dev, '_main_prefix'): + out('Main memory:', repr(dev._main_prefix)) + out('Total space:', dev.total_space()) + break + if not success and errors: + out('Opening of the following devices failed') + for dev,msg in errors.items(): + out(dev) + out(msg) + out(' ') + + if ioreg is not None: + ioreg = 'IOREG Output\n'+ioreg + out(' ') + if ioreg_to_tmp: + open('/tmp/ioreg.txt', 'wb').write(ioreg) + out('Dont forget to send the contents of /tmp/ioreg.txt') + out('You can open it with the command: open /tmp/ioreg.txt') + else: + out(ioreg) if hasattr(buf, 'getvalue'): return buf.getvalue().decode('utf-8') diff --git a/src/calibre/devices/mtp/unix/driver.py b/src/calibre/devices/mtp/unix/driver.py index 9244ac198c..b4e8b44407 100644 --- a/src/calibre/devices/mtp/unix/driver.py +++ b/src/calibre/devices/mtp/unix/driver.py @@ -82,6 +82,8 @@ class MTP_DEVICE(MTPDeviceBase): @synchronous def debug_managed_device_detection(self, devices_on_system, output): + if self.currently_connected_dev is not None: + return True p = partial(prints, file=output) if self.libmtp is None: err = plugins['libmtp'][1] diff --git a/src/calibre/devices/mtp/windows/driver.py b/src/calibre/devices/mtp/windows/driver.py index 191d69560d..abe38e5f7c 100644 --- a/src/calibre/devices/mtp/windows/driver.py +++ b/src/calibre/devices/mtp/windows/driver.py @@ -7,8 +7,8 @@ __license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import time, threading -from functools import wraps +import time, threading, traceback +from functools import wraps, partial from future_builtins import zip from itertools import chain @@ -123,6 +123,54 @@ class MTP_DEVICE(MTPDeviceBase): return None + @same_thread + def debug_managed_device_detection(self, devices_on_system, output): + import pprint + p = partial(prints, file=output) + if self.currently_connected_pnp_id is not None: + return True + if self.wpd_error: + p('Cannot detect MTP devices') + p(self.wpd_error) + return False + try: + pnp_ids = frozenset(self.wpd.enumerate_devices()) + except: + p("Failed to get list of PNP ids on system") + p(traceback.format_exc()) + return False + + for pnp_id in pnp_ids: + try: + data = self.wpd.device_info(pnp_id) + except: + p('Failed to get data for device:', pnp_id) + p(traceback.format_exc()) + continue + protocol = data.get('protocol', '').lower() + if not protocol.startswith('mtp:'): continue + p('MTP device:', pnp_id) + p(pprint.pformat(data)) + if not self.is_suitable_wpd_device(data): + p('Not a suitable MTP device, ignoring\n') + continue + p('\nTrying to open:', pnp_id) + try: + self.open(pnp_id, 'debug-detection') + except: + p('Open failed:') + p(traceback.format_exc()) + continue + break + if self.currently_connected_pnp_id: + p('Opened', self.current_friendly_name, 'successfully') + p('Device info:') + p(pprint.pformat(self.dev.data)) + self.eject() + return True + p('No suitable MTP devices found') + return False + def is_suitable_wpd_device(self, devdata): # Check that protocol is MTP protocol = devdata.get('protocol', '').lower()