From 7a79a9307deefa6bb98ab59da98975b5cc8b193b Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Wed, 3 Oct 2012 10:09:48 +0200 Subject: [PATCH] Add global device preferences. Add interface to override device preferences. Add override to smartapp to force metadata management to automatic for the device. Make changes everywhere else reference device_prefs instead of prefs for metadata management. --- src/calibre/devices/interface.py | 16 ++++++++++++++ .../devices/smart_device_app/driver.py | 10 ++++++++- src/calibre/devices/usbms/books.py | 10 ++++----- src/calibre/gui2/device.py | 8 +++++-- src/calibre/gui2/dialogs/smartdevice.py | 22 ------------------- src/calibre/gui2/library/models.py | 6 ++--- src/calibre/utils/config.py | 15 +++++++++++-- 7 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/calibre/devices/interface.py b/src/calibre/devices/interface.py index 7ce6968eee..bde882bd70 100644 --- a/src/calibre/devices/interface.py +++ b/src/calibre/devices/interface.py @@ -5,6 +5,7 @@ from collections import namedtuple from calibre.customize import Plugin from calibre.constants import iswindows +from calibre.utils.config import prefs class DevicePlugin(Plugin): """ @@ -626,6 +627,21 @@ class DevicePlugin(Plugin): ''' pass + def specialize_global_preferences(self, device_prefs, add_specializations): + ''' + Implement this method if your device wants to override a particular + preference. You must ensure that all call sites that want a preference + that can be overridden use device_prefs['something'] instead + of prefs['something']. If add_specializations is True, then your + method should call device_prefs.set_overrides(pref=val, pref=val, ...). + If add_specializations is False, then your method should call + device_prefs.set_overrides() to remove any previous specialization. + Currently used for: + metadata management (prefs['manage_device_metadata']) + ''' + pass + + # Dynamic control interface. # The following methods are probably called on the GUI thread. Any driver # that implements these methods must take pains to be thread safe, because diff --git a/src/calibre/devices/smart_device_app/driver.py b/src/calibre/devices/smart_device_app/driver.py index 4d189d8365..a604441750 100644 --- a/src/calibre/devices/smart_device_app/driver.py +++ b/src/calibre/devices/smart_device_app/driver.py @@ -34,7 +34,7 @@ from calibre.library import current_library_name from calibre.library.server import server_config as content_server_config from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.ipc import eintr_retry_call -from calibre.utils.config import from_json, tweaks +from calibre.utils.config import from_json, tweaks, prefs from calibre.utils.date import isoformat, now from calibre.utils.filenames import ascii_filename as sanitize, shorten_components_to from calibre.utils.mdns import (publish as publish_zeroconf, unpublish as @@ -1197,6 +1197,14 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): self.plugboards = plugboards self.plugboard_func = pb_func + @synchronous('sync_lock') + def specialize_global_preferences(self, device_prefs, add_specializations): + self._debug('add', add_specializations) + if add_specializations: + device_prefs.set_overrides(manage_device_metadata='on_connect') + else: + device_prefs.set_overrides() + @synchronous('sync_lock') def startup(self): self.listen_socket = None diff --git a/src/calibre/devices/usbms/books.py b/src/calibre/devices/usbms/books.py index 4d726e5bde..7d6377ca96 100644 --- a/src/calibre/devices/usbms/books.py +++ b/src/calibre/devices/usbms/books.py @@ -12,7 +12,7 @@ from calibre.devices.mime import mime_type_ext from calibre.devices.interface import BookList as _BookList from calibre.constants import preferred_encoding from calibre import isbytestring, force_unicode -from calibre.utils.config import prefs, tweaks +from calibre.utils.config import device_prefs, tweaks from calibre.utils.icu import strcmp from calibre.utils.formatter import EvalFormatter @@ -124,7 +124,7 @@ class CollectionsBookList(BookList): def get_collections(self, collection_attributes): from calibre.devices.usbms.driver import debug_print - debug_print('Starting get_collections:', prefs['manage_device_metadata']) + debug_print('Starting get_collections:', device_prefs['manage_device_metadata']) debug_print('Renaming rules:', tweaks['sony_collection_renaming_rules']) debug_print('Formatting template:', tweaks['sony_collection_name_template']) debug_print('Sorting rules:', tweaks['sony_collection_sorting_rules']) @@ -132,7 +132,7 @@ class CollectionsBookList(BookList): # Complexity: we can use renaming rules only when using automatic # management. Otherwise we don't always have the metadata to make the # right decisions - use_renaming_rules = prefs['manage_device_metadata'] == 'on_connect' + use_renaming_rules = device_prefs['manage_device_metadata'] == 'on_connect' collections = {} @@ -169,7 +169,7 @@ class CollectionsBookList(BookList): # book in all existing collections. Do not add any new ones. attrs = ['device_collections'] if getattr(book, '_new_book', False): - if prefs['manage_device_metadata'] == 'manual': + if device_prefs['manage_device_metadata'] == 'manual': # Ensure that the book is in all the book's existing # collections plus all metadata collections attrs += collection_attributes @@ -178,7 +178,7 @@ class CollectionsBookList(BookList): # thing. The book's existing collections are ignored. Put # the book in collections defined by its metadata. attrs = collection_attributes - elif prefs['manage_device_metadata'] == 'on_connect': + elif device_prefs['manage_device_metadata'] == 'on_connect': # For existing books, modify the collections only if the user # specified 'on_connect' attrs = collection_attributes diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index b56c40d402..915eb15776 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -30,7 +30,7 @@ from calibre.devices.apple.driver import ITUNES_ASYNC from calibre.devices.folder_device.driver import FOLDER_DEVICE from calibre.devices.bambook.driver import BAMBOOK, BAMBOOKWifi from calibre.constants import DEBUG -from calibre.utils.config import prefs, tweaks +from calibre.utils.config import tweaks, device_prefs from calibre.utils.magick.draw import thumbnail from calibre.library.save_to_disk import find_plugboard # }}} @@ -210,6 +210,8 @@ class DeviceManager(Thread): # {{{ return self.connected_device = dev + self.connected_device.specialize_global_preferences(device_prefs, + add_specializations=True) self.connected_device_kind = device_kind self.connected_slot(True, device_kind) @@ -235,6 +237,8 @@ class DeviceManager(Thread): # {{{ # is being shut down. self.connected_device.shutdown() self.call_shutdown_on_disconnect = False + self.connected_device.specialize_global_preferences(device_prefs, + add_specializations=False) self.connected_device = None self._device_information = None @@ -1648,7 +1652,7 @@ class DeviceMixin(object): # {{{ x = x.lower() if x else '' return string_pat.sub('', x) - update_metadata = prefs['manage_device_metadata'] == 'on_connect' + update_metadata = device_prefs['manage_device_metadata'] == 'on_connect' get_covers = False if update_metadata and self.device_manager.is_device_connected: diff --git a/src/calibre/gui2/dialogs/smartdevice.py b/src/calibre/gui2/dialogs/smartdevice.py index 745125d409..8efe9bb41e 100644 --- a/src/calibre/gui2/dialogs/smartdevice.py +++ b/src/calibre/gui2/dialogs/smartdevice.py @@ -98,23 +98,6 @@ class SmartdeviceDialog(QDialog, Ui_Dialog): if pw: self.password_box.setText(pw) - self.auto_mgmt_button = QPushButton(_('Enable automatic metadata management')) - self.auto_mgmt_button.clicked.connect(self.auto_mgmt_button_clicked) - self.auto_mgmt_button.setToolTip('
' + - _('Enabling automatic metadata management tells calibre to send any ' - 'changes you made to books\' metadata when your device is ' - 'connected, which is the most useful setting when using the wireless ' - 'device interface. If automatic metadata management is not ' - 'enabled, changes are sent only when you re-send the book. You can ' - 'get more information or change this preference to some other ' - 'choice at Preferences -> Sending books to devices -> ' - 'Metadata management') - + '
') - self.buttonBox.addButton(self.auto_mgmt_button, QDialogButtonBox.ActionRole) - if prefs['manage_device_metadata'] == 'on_connect': - self.auto_mgmt_button.setText(_('Automatic metadata management is enabled')) - self.auto_mgmt_button.setEnabled(False) - forced_ip = self.device_manager.get_option('smartdevice', 'force_ip_address') if forced_ip: self.ip_addresses.setText(forced_ip) @@ -123,11 +106,6 @@ class SmartdeviceDialog(QDialog, Ui_Dialog): self.resize(self.sizeHint()) - def auto_mgmt_button_clicked(self): - self.auto_mgmt_button.setText(_('Automatic metadata management is enabled')) - self.auto_mgmt_button.setEnabled(False) - prefs.set('manage_device_metadata', 'on_connect') - def use_fixed_port_changed(self, state): self.fixed_port.setEnabled(state == Qt.Checked) diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index 246b0835a5..9d24ef7974 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -16,7 +16,7 @@ from calibre.utils.pyparsing import ParseException from calibre.ebooks.metadata import fmt_sidx, authors_to_string, string_to_authors from calibre.ebooks.metadata.book.base import SafeFormat from calibre.ptempfile import PersistentTemporaryFile -from calibre.utils.config import tweaks, prefs +from calibre.utils.config import tweaks, prefs, device_prefs from calibre.utils.date import dt_factory, qt_to_dt, as_local_time from calibre.utils.icu import sort_key from calibre.utils.search_query_parser import SearchQueryParser @@ -1152,7 +1152,7 @@ class DeviceBooksModel(BooksModel): # {{{ (cname != 'collections' or \ (callable(getattr(self.db, 'supports_collections', None)) and \ self.db.supports_collections() and \ - prefs['manage_device_metadata']=='manual')): + device_prefs['manage_device_metadata']=='manual')): flags |= Qt.ItemIsEditable return flags @@ -1447,7 +1447,7 @@ class DeviceBooksModel(BooksModel): # {{{ self.editable = ['title', 'authors', 'collections'] else: self.editable = [] - if prefs['manage_device_metadata']=='on_connect': + if device_prefs['manage_device_metadata']=='on_connect': self.editable = [] # }}} diff --git a/src/calibre/utils/config.py b/src/calibre/utils/config.py index 734be6c1a4..e79affb2f4 100644 --- a/src/calibre/utils/config.py +++ b/src/calibre/utils/config.py @@ -368,7 +368,18 @@ class JSONConfig(XMLConfig): dict.__setitem__(self, key, val) self.commit() - - +class DevicePrefs: + + def __init__(self, global_prefs): + self.global_prefs = global_prefs + self.overrides = {} + + def set_overrides(self, **kwargs): + self.overrides = kwargs.copy() + + def __getitem__(self, key): + return self.overrides.get(key, self.global_prefs[key]) + +device_prefs = DevicePrefs(prefs)