diff --git a/src/calibre/devices/__init__.py b/src/calibre/devices/__init__.py
index 3fead7b75f..4f71d39651 100644
--- a/src/calibre/devices/__init__.py
+++ b/src/calibre/devices/__init__.py
@@ -37,6 +37,10 @@ def debug(ioreg_to_tmp=False, buf=None):
if buf is None:
buf = StringIO()
sys.stdout = sys.stderr = buf
+ if iswindows:
+ import pythoncom
+ pythoncom.CoInitialize()
+
try:
out = partial(prints, file=buf)
out('Version:', __version__)
@@ -50,29 +54,25 @@ def debug(ioreg_to_tmp=False, buf=None):
d[i] = hex(d[i])
out('USB devices on system:')
out(pprint.pformat(devices))
+ wmi = Wmi =None
if iswindows:
- if iswindows:
- import pythoncom
- pythoncom.CoInitialize()
+ wmi = __import__('wmi', globals(), locals(), [], -1)
+ Wmi = wmi.WMI(find_classes=False)
+ drives = []
+ out('Drives detected:')
+ out('\t', '(ID, Partitions, Drive letter)')
+ for drive in Wmi.Win32_DiskDrive():
+ if drive.Partitions == 0:
+ continue
try:
- wmi = __import__('wmi', globals(), locals(), [], -1)
- drives = []
- out('Drives detected:')
- out('\t', '(ID, Partitions, Drive letter)')
- for drive in wmi.WMI(find_classes=False).Win32_DiskDrive():
- if drive.Partitions == 0:
- continue
- try:
- partition = drive.associators("Win32_DiskDriveToDiskPartition")[0]
- logical_disk = partition.associators('Win32_LogicalDiskToPartition')[0]
- prefix = logical_disk.DeviceID+os.sep
- drives.append((str(drive.PNPDeviceID), drive.Index, prefix))
- except IndexError:
- drives.append((str(drive.PNPDeviceID), 'No mount points found'))
- for drive in drives:
- out('\t', drive)
- finally:
- pythoncom.CoUninitialize()
+ partition = drive.associators("Win32_DiskDriveToDiskPartition")[0]
+ logical_disk = partition.associators('Win32_LogicalDiskToPartition')[0]
+ prefix = logical_disk.DeviceID+os.sep
+ drives.append((str(drive.PNPDeviceID), drive.Index, prefix))
+ except IndexError:
+ drives.append((str(drive.PNPDeviceID), 'No mount points found'))
+ for drive in drives:
+ out('\t', drive)
ioreg = None
if isosx:
@@ -81,17 +81,26 @@ def debug(ioreg_to_tmp=False, buf=None):
ioreg = Device.run_ioreg()
ioreg = 'Output from mount:\n\n'+mount+'\n\n'+ioreg
connected_devices = []
+ s.wmi = Wmi
for dev in device_plugins():
+ owmi = getattr(dev, 'wmi', None)
+ dev.wmi = Wmi
out('Looking for', dev.__class__.__name__)
connected, det = s.is_device_connected(dev, debug=True)
if connected:
connected_devices.append((dev, det))
+ dev.wmi = owmi
errors = {}
success = False
+ out('Devices possibly connected:', end=' ')
for dev, det in connected_devices:
- out('Device possibly connected:', dev.__class__.name)
- out('Trying to open device...', end=' ')
+ out(dev.name, end=', ')
+ out(' ')
+ for dev, det in connected_devices:
+ out('Trying to open', dev.name, '...', end=' ')
+ owmi = getattr(dev, 'wmi', None)
+ dev.wmi = Wmi
try:
dev.reset(detected_device=det)
dev.open()
@@ -101,6 +110,8 @@ def debug(ioreg_to_tmp=False, buf=None):
errors[dev] = traceback.format_exc()
out('failed')
continue
+ finally:
+ dev.wmi = owmi
success = True
if hasattr(dev, '_main_prefix'):
out('Main memory:', repr(dev._main_prefix))
@@ -128,4 +139,7 @@ def debug(ioreg_to_tmp=False, buf=None):
finally:
sys.stdout = oldo
sys.stderr = olde
+ if iswindows:
+ import pythoncom
+ pythoncom.CoUninitialize()
diff --git a/src/calibre/devices/interface.py b/src/calibre/devices/interface.py
index dec3f0304a..128a0bf45e 100644
--- a/src/calibre/devices/interface.py
+++ b/src/calibre/devices/interface.py
@@ -43,8 +43,7 @@ class DevicePlugin(Plugin):
#: Icon for this device
icon = I('reader.svg')
- @classmethod
- def test_bcd_windows(cls, device_id, bcd):
+ def test_bcd_windows(self, device_id, bcd):
if bcd is None or len(bcd) == 0:
return True
for c in bcd:
@@ -54,30 +53,28 @@ class DevicePlugin(Plugin):
return True
return False
- @classmethod
- def print_usb_device_info(cls, info):
+ def print_usb_device_info(self, info):
try:
print '\t', repr(info)
except:
import traceback
traceback.print_exc()
- @classmethod
- def is_usb_connected_windows(cls, devices_on_system, debug=False):
+ def is_usb_connected_windows(self, devices_on_system, pnp_id_iterator, debug=False):
def id_iterator():
- if hasattr(cls.VENDOR_ID, 'keys'):
- for vid in cls.VENDOR_ID:
- vend = cls.VENDOR_ID[vid]
+ if hasattr(self.VENDOR_ID, 'keys'):
+ for vid in self.VENDOR_ID:
+ vend = self.VENDOR_ID[vid]
for pid in vend:
bcd = vend[pid]
yield vid, pid, bcd
else:
- vendors = cls.VENDOR_ID if hasattr(cls.VENDOR_ID, '__len__') else [cls.VENDOR_ID]
- products = cls.PRODUCT_ID if hasattr(cls.PRODUCT_ID, '__len__') else [cls.PRODUCT_ID]
+ vendors = self.VENDOR_ID if hasattr(self.VENDOR_ID, '__len__') else [self.VENDOR_ID]
+ products = self.PRODUCT_ID if hasattr(self.PRODUCT_ID, '__len__') else [self.PRODUCT_ID]
for vid in vendors:
for pid in products:
- yield vid, pid, cls.BCD
+ yield vid, pid, self.BCD
for vendor_id, product_id, bcd in id_iterator():
vid, pid = 'vid_%4.4x'%vendor_id, 'pid_%4.4x'%product_id
@@ -85,15 +82,14 @@ class DevicePlugin(Plugin):
for device_id in devices_on_system:
if (vid in device_id or vidd in device_id) and \
(pid in device_id or pidd in device_id) and \
- cls.test_bcd_windows(device_id, bcd):
+ self.test_bcd_windows(device_id, bcd):
if debug:
- cls.print_usb_device_info(device_id)
- if cls.can_handle(device_id):
+ self.print_usb_device_info(device_id)
+ if self.can_handle_windows(device_id, pnp_id_iterator, debug=debug):
return True
return False
- @classmethod
- def test_bcd(cls, bcdDevice, bcd):
+ def test_bcd(self, bcdDevice, bcd):
if bcd is None or len(bcd) == 0:
return True
for c in bcd:
@@ -101,24 +97,24 @@ class DevicePlugin(Plugin):
return True
return False
- @classmethod
- def is_usb_connected(cls, devices_on_system, debug=False):
+ def is_usb_connected(self, devices_on_system, pnp_id_iterator, debug=False):
'''
Return True, device_info if a device handled by this plugin is currently connected.
:param devices_on_system: List of devices currently connected
'''
if iswindows:
- return cls.is_usb_connected_windows(devices_on_system, debug=debug), None
+ return self.is_usb_connected_windows(devices_on_system,
+ pnp_id_iterator, debug=debug), None
vendors_on_system = set([x[0] for x in devices_on_system])
- vendors = cls.VENDOR_ID if hasattr(cls.VENDOR_ID, '__len__') else [cls.VENDOR_ID]
- if hasattr(cls.VENDOR_ID, 'keys'):
+ vendors = self.VENDOR_ID if hasattr(self.VENDOR_ID, '__len__') else [self.VENDOR_ID]
+ if hasattr(self.VENDOR_ID, 'keys'):
products = []
- for ven in cls.VENDOR_ID:
- products.extend(cls.VENDOR_ID[ven].keys())
+ for ven in self.VENDOR_ID:
+ products.extend(self.VENDOR_ID[ven].keys())
else:
- products = cls.PRODUCT_ID if hasattr(cls.PRODUCT_ID, '__len__') else [cls.PRODUCT_ID]
+ products = self.PRODUCT_ID if hasattr(self.PRODUCT_ID, '__len__') else [self.PRODUCT_ID]
for vid in vendors:
if vid in vendors_on_system:
@@ -126,14 +122,14 @@ class DevicePlugin(Plugin):
cvid, pid, bcd = dev[:3]
if cvid == vid:
if pid in products:
- if hasattr(cls.VENDOR_ID, 'keys'):
- cbcd = cls.VENDOR_ID[vid][pid]
+ if hasattr(self.VENDOR_ID, 'keys'):
+ cbcd = self.VENDOR_ID[vid][pid]
else:
- cbcd = cls.BCD
- if cls.test_bcd(bcd, cbcd):
+ cbcd = self.BCD
+ if self.test_bcd(bcd, cbcd):
if debug:
- cls.print_usb_device_info(dev)
- if cls.can_handle(dev, debug=debug):
+ self.print_usb_device_info(dev)
+ if self.can_handle(dev, debug=debug):
return True, dev
return False, None
@@ -151,25 +147,30 @@ class DevicePlugin(Plugin):
"""
raise NotImplementedError()
- @classmethod
- def get_fdi(cls):
- '''Return the FDI description of this device for HAL on linux.'''
- return ''
-
- @classmethod
- def can_handle(cls, device_info, debug=False):
+ def can_handle_windows(self, device_id, pnp_id_iterator, debug=False):
'''
Optional method to perform further checks on a device to see if this driver
is capable of handling it. If it is not it should return False. This method
is only called after the vendor, product ids and the bcd have matched, so
it can do some relatively time intensive checks. The default implementation
- returns True.
+ returns True. This method is called only on windows. See also
+ :method:`can_handle`.
:param device_info: On windows a device ID string. On Unix a tuple of
``(vendor_id, product_id, bcd)``.
'''
return True
+ def can_handle(self, device_info, debug=False):
+ '''
+ Unix version of :method:`can_handle_windows`
+
+ :param device_info: Is a tupe of (vid, pid, bcd, manufacturer, product,
+ serial number)
+ '''
+
+ return True
+
def open(self):
'''
Perform any device specific initialization. Called after the device is
diff --git a/src/calibre/devices/prs500/cli/main.py b/src/calibre/devices/prs500/cli/main.py
index a49bca4794..2b942d4cfc 100755
--- a/src/calibre/devices/prs500/cli/main.py
+++ b/src/calibre/devices/prs500/cli/main.py
@@ -197,15 +197,15 @@ def main():
command = args[0]
args = args[1:]
dev = None
- _wmi = None
+ scanner = DeviceScanner()
if iswindows:
import wmi, pythoncom
pythoncom.CoInitialize()
- _wmi = wmi.WMI()
- scanner = DeviceScanner(_wmi)
+ scanner.wmi = wmi.WMI(find_classes=False)
scanner.scan()
connected_devices = []
for d in device_plugins():
+ d.wmi = scanner.wmi
ok, det = scanner.is_device_connected(d)
if ok:
dev = d
diff --git a/src/calibre/devices/scanner.py b/src/calibre/devices/scanner.py
index ef83659fe3..839552e9a7 100644
--- a/src/calibre/devices/scanner.py
+++ b/src/calibre/devices/scanner.py
@@ -85,13 +85,26 @@ class DeviceScanner(object):
raise RuntimeError('DeviceScanner requires the /sys filesystem to work.')
self.scanner = win_scanner if iswindows else osx_scanner if isosx else linux_scanner
self.devices = []
+ self.wmi = None
+ self.pnp_ids = set([])
+ self.rescan_pnp_ids = True
def scan(self):
'''Fetch list of connected USB devices from operating system'''
self.devices = self.scanner()
+ if self.rescan_pnp_ids:
+ self.pnp_ids = set([])
+
+ def pnp_id_iterator(self):
+ if self.wmi is not None and not self.pnp_ids:
+ for drive in self.wmi.Win32_DiskDrive():
+ if drive.Partitions > 0:
+ self.pnp_ids.add(str(drive.PNPDeviceID))
+ for x in self.pnp_ids:
+ yield x
def is_device_connected(self, device, debug=False):
- return device.is_usb_connected(self.devices, debug=debug)
+ return device.is_usb_connected(self.devices, self.pnp_id_iterator, debug=debug)
def main(args=sys.argv):
diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py
index 5d09d3821f..88f7cb3f19 100644
--- a/src/calibre/devices/usbms/device.py
+++ b/src/calibre/devices/usbms/device.py
@@ -22,7 +22,7 @@ from itertools import repeat
from calibre.devices.interface import DevicePlugin
from calibre.devices.errors import DeviceError, FreeSpaceError
from calibre.devices.usbms.deviceconfig import DeviceConfig
-from calibre.constants import iswindows, islinux, isosx, __appname__, plugins
+from calibre.constants import iswindows, islinux, isosx, plugins
from calibre.utils.filenames import ascii_filename as sanitize, shorten_components_to
if isosx:
@@ -83,53 +83,6 @@ class Device(DeviceConfig, DevicePlugin):
EBOOK_DIR_CARD_B = ''
DELETE_EXTS = []
- FDI_TEMPLATE = \
-'''
-
-
-
-
- %(BCD_start)s
-
- %(main_memory)s
- %(deviceclass)s
-
- %(BCD_end)s
-
-
-
-
-
-
-
-
- %(BCD_start)s
-
- %(storage_card)s
- %(deviceclass)s
-
- %(BCD_end)s
-
-
-
-
-
-
-
-
- %(BCD_start)s
-
- %(storage_card)s
- %(deviceclass)s
-
- %(BCD_end)s
-
-
-
-
-'''
- FDI_LUNS = {'lun0':0, 'lun1':1, 'lun2':2}
- FDI_BCD_TEMPLATE = ''
def reset(self, key='-1', log_packets=False, report_progress=None,
detected_device=None):
@@ -138,6 +91,7 @@ class Device(DeviceConfig, DevicePlugin):
self.detected_device = USBDevice(detected_device)
except: # On windows detected_device is None
self.detected_device = None
+ self.set_progress_reporter(report_progress)
@classmethod
def get_gui_name(cls):
@@ -146,37 +100,11 @@ class Device(DeviceConfig, DevicePlugin):
x = cls.__name__
return x
-
- @classmethod
- def get_fdi(cls):
- fdi = ''
- for vid in cls.VENDOR_ID:
- for pid in cls.PRODUCT_ID:
- fdi_base_values = dict(
- app=__appname__,
- deviceclass=cls.__name__,
- vendor_id=hex(vid),
- product_id=hex(pid),
- main_memory=cls.MAIN_MEMORY_VOLUME_LABEL,
- storage_card=cls.STORAGE_CARD_VOLUME_LABEL,
- )
- fdi_base_values.update(cls.FDI_LUNS)
-
- if cls.BCD is None:
- fdi_base_values['BCD_start'] = ''
- fdi_base_values['BCD_end'] = ''
- fdi += cls.FDI_TEMPLATE % fdi_base_values
- else:
- for bcd in cls.BCD:
- fdi_bcd_values = fdi_base_values
- fdi_bcd_values['BCD_start'] = cls.FDI_BCD_TEMPLATE % dict(bcd=hex(bcd))
- fdi_bcd_values['BCD_end'] = ''
- fdi += cls.FDI_TEMPLATE % fdi_bcd_values
-
- return fdi
-
def set_progress_reporter(self, report_progress):
self.report_progress = report_progress
+ self.report_progress = report_progress
+ if self.report_progress is None:
+ self.report_progress = lambda x, y: x
def card_prefix(self, end_session=True):
return (self._card_a_prefix, self._card_b_prefix)
@@ -239,9 +167,7 @@ class Device(DeviceConfig, DevicePlugin):
def windows_filter_pnp_id(self, pnp_id):
return False
- def windows_match_device(self, drive, attr):
- pnp_id = (str(drive.PNPDeviceID) if not isinstance(drive, basestring)
- else str(drive)).upper()
+ def windows_match_device(self, pnp_id, attr):
device_id = getattr(self, attr)
def test_vendor():
@@ -292,6 +218,12 @@ class Device(DeviceConfig, DevicePlugin):
'''
return drives
+ def can_handle_windows(self, device_id, pnp_id_iterator, debug=False):
+ for pnp_id in pnp_id_iterator():
+ if self.windows_match_device(pnp_id, 'WINDOWS_MAIN_MEM'):
+ return True
+ return False
+
def open_windows(self):
def matches_q(drive, attr):
@@ -307,14 +239,14 @@ class Device(DeviceConfig, DevicePlugin):
time.sleep(8)
drives = {}
- wmi = __import__('wmi', globals(), locals(), [], -1)
- c = wmi.WMI(find_classes=False)
+ c = self.wmi
for drive in c.Win32_DiskDrive():
- if self.windows_match_device(drive, 'WINDOWS_CARD_A_MEM') and not drives.get('carda', None):
+ pnp_id = str(drive.PNPDeviceID)
+ if self.windows_match_device(pnp_id, 'WINDOWS_CARD_A_MEM') and not drives.get('carda', None):
drives['carda'] = self.windows_get_drive_prefix(drive)
- elif self.windows_match_device(drive, 'WINDOWS_CARD_B_MEM') and not drives.get('cardb', None):
+ elif self.windows_match_device(pnp_id, 'WINDOWS_CARD_B_MEM') and not drives.get('cardb', None):
drives['cardb'] = self.windows_get_drive_prefix(drive)
- elif self.windows_match_device(drive, 'WINDOWS_MAIN_MEM') and not drives.get('main', None):
+ elif self.windows_match_device(pnp_id, 'WINDOWS_MAIN_MEM') and not drives.get('main', None):
drives['main'] = self.windows_get_drive_prefix(drive)
if 'main' in drives.keys() and 'carda' in drives.keys() and \
diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py
index ec91e70257..d302c10d09 100644
--- a/src/calibre/gui2/device.py
+++ b/src/calibre/gui2/device.py
@@ -72,15 +72,12 @@ class DeviceManager(Thread):
def __init__(self, connected_slot, job_manager, sleep_time=2):
'''
- @param sleep_time: Time to sleep between device probes in secs
- @type sleep_time: integer
+ :sleep_time: Time to sleep between device probes in secs
'''
Thread.__init__(self)
self.setDaemon(True)
# [Device driver, Showing in GUI, Ejected]
- self.devices = [[d, False, False] for d in device_plugins()]
- self.device = None
- self.device_class = None
+ self.devices = list(device_plugins())
self.sleep_time = sleep_time
self.connected_slot = connected_slot
self.jobs = Queue.Queue(0)
@@ -88,75 +85,83 @@ class DeviceManager(Thread):
self.job_manager = job_manager
self.current_job = None
self.scanner = DeviceScanner()
+ self.wmi = None
+ self.connected_device = None
+ self.ejected_devices = set([])
+
+ def report_progress(self, *args):
+ pass
+
+ @property
+ def is_device_connected(self):
+ return self.connected_device is not None
+
+ @property
+ def device(self):
+ return self.connected_device
def do_connect(self, connected_devices):
- if iswindows:
- import pythoncom
- pythoncom.CoInitialize()
- try:
- for dev, detected_device in connected_devices:
- dev.reset(detected_device=detected_device)
- try:
- dev.open()
- except:
- print 'Unable to open device', dev
- traceback.print_exc()
- continue
- self.device = dev
- self.device_class = dev.__class__
- self.connected_slot(True)
- return True
- finally:
- if iswindows:
- pythoncom.CoUninitialize()
+ for dev, detected_device in connected_devices:
+ dev.reset(detected_device=detected_device,
+ report_progress=self.report_progress)
+ try:
+ dev.open()
+ except:
+ print 'Unable to open device', dev
+ traceback.print_exc()
+ continue
+ self.connected_device = dev
+ self.connected_slot(True)
+ return True
return False
+ def connected_device_removed(self):
+ while True:
+ try:
+ job = self.jobs.get_nowait()
+ job.abort(Exception(_('Device no longer connected.')))
+ except Queue.Empty:
+ break
+ try:
+ self.connected_device.post_yank_cleanup()
+ except:
+ pass
+ if self.connected_device in self.ejected_devices:
+ self.ejected_devices.remove(self.connected_device)
+ else:
+ self.connected_slot(False)
+ self.connected_device = None
def detect_device(self):
+ self.scanner.rescan_pnp_ids = not self.is_device_connected
self.scanner.scan()
- connected_devices = []
- for device in self.devices:
- connected, detected_device = self.scanner.is_device_connected(device[0])
- if connected and not device[1] and not device[2]:
- # If connected and not showing in GUI and not ejected
- connected_devices.append((device[0], detected_device))
- device[1] = True
- elif not connected and device[1]:
- # Disconnected but showing in GUI
- while True:
- try:
- job = self.jobs.get_nowait()
- job.abort(Exception(_('Device no longer connected.')))
- except Queue.Empty:
- break
- try:
- self.device.post_yank_cleanup()
- except:
- pass
- device[2] = False
- self.device = None
- self.connected_slot(False)
- device[1] ^= True
- if connected_devices:
- if not self.do_connect(connected_devices):
- print 'Connect to device failed, retying in 5 seconds...'
- time.sleep(5)
- if not self.do_connect(connected_devices):
- print 'Device connect failed again, giving up'
+ if self.is_device_connected:
+ connected, detected_device = \
+ self.scanner.is_device_connected(self.connected_device)
+ if not connected:
+ self.connected_device_removed()
+ else:
+ possibly_connected_devices = []
+ for device in self.devices:
+ if device in self.ejected_devices:
+ continue
+ possibly_connected, detected_device = \
+ self.scanner.is_device_connected(device)
+ if possibly_connected:
+ possibly_connected_devices.append((device, detected_device))
+ if possibly_connected_devices:
+ if not self.do_connect(possibly_connected_devices):
+ print 'Connect to device failed, retying in 5 seconds...'
+ time.sleep(5)
+ if not self.do_connect(possibly_connected_devices):
+ print 'Device connect failed again, giving up'
def umount_device(self):
- if self.device is not None:
- self.device.eject()
- dev = None
- for x in self.devices:
- if x[0] is self.device:
- dev = x
- break
- if dev is not None:
- dev[2] = True
+ if self.is_device_connected:
+ self.connected_device.eject()
+ self.ejected_devices.add(self.connected_device)
self.connected_slot(False)
-
def next(self):
if not self.jobs.empty():
try:
@@ -165,18 +170,31 @@ class DeviceManager(Thread):
pass
def run(self):
- while self.keep_going:
- self.detect_device()
- while True:
- job = self.next()
- if job is not None:
- self.current_job = job
- self.device.set_progress_reporter(job.report_progress)
- self.current_job.run()
- self.current_job = None
- else:
- break
- time.sleep(self.sleep_time)
+ if iswindows:
+ import pythoncom
+ pythoncom.CoInitialize()
+ wmi = __import__('wmi', globals(), locals(), [], -1)
+ self.wmi = wmi.WMI(find_classes=False)
+ self.scanner.wmi = self.wmi
+ for x in self.devices:
+ x[0].wmi = self.wmi
+ try:
+ while self.keep_going:
+ self.detect_device()
+ while True:
+ job = self.next()
+ if job is not None:
+ self.current_job = job
+ self.device.set_progress_reporter(job.report_progress)
+ self.current_job.run()
+ self.current_job = None
+ else:
+ break
+ time.sleep(self.sleep_time)
+ finally:
+ if iswindows:
+ pythoncom.CoUninitialize()
+
def create_job(self, func, done, description, args=[], kwargs={}):
job = DeviceJob(func, done, self.job_manager,
@@ -495,7 +513,7 @@ class DeviceGUI(object):
fmt = None
if specific:
d = ChooseFormatDialog(self, _('Choose format to send to device'),
- self.device_manager.device_class.settings().format_map)
+ self.device_manager.device.settings().format_map)
d.exec_()
fmt = d.format().lower()
dest, sub_dest = dest.split(':')
@@ -637,7 +655,7 @@ class DeviceGUI(object):
p = QPixmap()
p.loadFromData(data)
if not p.isNull():
- ht = self.device_manager.device_class.THUMBNAIL_HEIGHT \
+ ht = self.device_manager.device.THUMBNAIL_HEIGHT \
if self.device_manager else DevicePlugin.THUMBNAIL_HEIGHT
p = p.scaledToHeight(ht, Qt.SmoothTransformation)
return (p.width(), p.height(), pixmap_to_data(p))
@@ -675,10 +693,11 @@ class DeviceGUI(object):
def sync_news(self, send_ids=None, do_auto_convert=True):
if self.device_connected:
+ settings = self.device_manager.device.settings()
ids = list(dynamic.get('news_to_be_synced', set([]))) if send_ids is None else send_ids
ids = [id for id in ids if self.library_view.model().db.has_id(id)]
files, _auto_ids = self.library_view.model().get_preferred_formats_from_ids(
- ids, self.device_manager.device_class.settings().format_map,
+ ids, settings.format_map,
exclude_auto=do_auto_convert)
auto = []
if do_auto_convert and _auto_ids:
@@ -687,12 +706,12 @@ class DeviceGUI(object):
formats = [] if dbfmts is None else \
[f.lower() for f in dbfmts.split(',')]
if set(formats).intersection(available_input_formats()) \
- and set(self.device_manager.device_class.settings().format_map).intersection(available_output_formats()):
+ and set(settings.format_map).intersection(available_output_formats()):
auto.append(id)
if auto:
format = None
- for fmt in self.device_manager.device_class.settings().format_map:
- if fmt in list(set(self.device_manager.device_class.settings().format_map).intersection(set(available_output_formats()))):
+ for fmt in settings.format_map:
+ if fmt in list(set(settings.format_map).intersection(set(available_output_formats()))):
format = fmt
break
if format is not None:
@@ -738,8 +757,10 @@ class DeviceGUI(object):
if not self.device_manager or not ids or len(ids) == 0:
return
+ settings = self.device_manager.device.settings()
+
_files, _auto_ids = self.library_view.model().get_preferred_formats_from_ids(ids,
- self.device_manager.device_class.settings().format_map,
+ settings.format_map,
paths=True, set_metadata=True,
specific_format=specific_format,
exclude_auto=do_auto_convert)
@@ -790,21 +811,21 @@ class DeviceGUI(object):
formats = self.library_view.model().db.formats(id, index_is_id=True)
formats = formats.split(',') if formats is not None else []
formats = [f.lower().strip() for f in formats]
- if list(set(formats).intersection(available_input_formats())) != [] and list(set(self.device_manager.device_class.settings().format_map).intersection(available_output_formats())) != []:
+ if list(set(formats).intersection(available_input_formats())) != [] and list(set(settings.format_map).intersection(available_output_formats())) != []:
auto.append(id)
else:
bad.append(self.library_view.model().db.title(id, index_is_id=True))
else:
- if specific_format in list(set(self.device_manager.device_class.settings().format_map).intersection(set(available_output_formats()))):
+ if specific_format in list(set(settings.format_map).intersection(set(available_output_formats()))):
auto.append(id)
else:
bad.append(self.library_view.model().db.title(id, index_is_id=True))
if auto != []:
- format = specific_format if specific_format in list(set(self.device_manager.device_class.settings().format_map).intersection(set(available_output_formats()))) else None
+ format = specific_format if specific_format in list(set(settings.format_map).intersection(set(available_output_formats()))) else None
if not format:
- for fmt in self.device_manager.device_class.settings().format_map:
- if fmt in list(set(self.device_manager.device_class.settings().format_map).intersection(set(available_output_formats()))):
+ for fmt in settings.format_map:
+ if fmt in list(set(settings.format_map).intersection(set(available_output_formats()))):
format = fmt
break
if not format:
diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py
index f9fbcbae3a..c90a70f4d3 100644
--- a/src/calibre/gui2/ui.py
+++ b/src/calibre/gui2/ui.py
@@ -840,11 +840,11 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
return
mainlist, cardalist, cardblist = job.result
self.memory_view.set_database(mainlist)
- self.memory_view.set_editable(self.device_manager.device_class.CAN_SET_METADATA)
+ self.memory_view.set_editable(self.device_manager.device.CAN_SET_METADATA)
self.card_a_view.set_database(cardalist)
- self.card_a_view.set_editable(self.device_manager.device_class.CAN_SET_METADATA)
+ self.card_a_view.set_editable(self.device_manager.device.CAN_SET_METADATA)
self.card_b_view.set_database(cardblist)
- self.card_b_view.set_editable(self.device_manager.device_class.CAN_SET_METADATA)
+ self.card_b_view.set_editable(self.device_manager.device.CAN_SET_METADATA)
for view in (self.memory_view, self.card_a_view, self.card_b_view):
view.sortByColumn(3, Qt.DescendingOrder)
view.read_settings()