From 449c1d57525736d52192767e8bb0e13fd2326bed Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 17 Dec 2012 18:36:23 +0530 Subject: [PATCH] MTP driver: UI for specifying top level folders to ignore on scan --- src/calibre/devices/mtp/driver.py | 15 +++ src/calibre/gui2/device_drivers/mtp_config.py | 27 ++++-- .../gui2/device_drivers/mtp_folder_browser.py | 95 +++++++++++++++++-- 3 files changed, 124 insertions(+), 13 deletions(-) diff --git a/src/calibre/devices/mtp/driver.py b/src/calibre/devices/mtp/driver.py index bc55654b1e..f62f06b23c 100644 --- a/src/calibre/devices/mtp/driver.py +++ b/src/calibre/devices/mtp/driver.py @@ -59,9 +59,24 @@ class MTP_DEVICE(BASE): p.defaults['blacklist'] = [] p.defaults['history'] = {} p.defaults['rules'] = [] + p.defaults['ignored_folders'] = {} return self._prefs + def is_folder_ignored(self, storage_or_storage_id, name, + ignored_folders=None): + storage_id = unicode(getattr(storage_or_storage_id, 'object_id', + storage_or_storage_id)) + name = icu_lower(name) + if ignored_folders is None: + ignored_folders = self.get_pref('ignored_folders') + if storage_id in ignored_folders: + return name in {icu_lower(x) for x in ignored_folders[storage_id]} + + return name in { + 'alarms', 'android', 'dcim', 'movies', 'music', 'notifications', + 'pictures', 'ringtones', 'samsung', 'sony', 'htc'} + def configure_for_kindle_app(self): proxy = self.prefs with proxy: diff --git a/src/calibre/gui2/device_drivers/mtp_config.py b/src/calibre/gui2/device_drivers/mtp_config.py index 5ab1dd692e..63002e90eb 100644 --- a/src/calibre/gui2/device_drivers/mtp_config.py +++ b/src/calibre/gui2/device_drivers/mtp_config.py @@ -19,7 +19,7 @@ from calibre.ebooks import BOOK_EXTENSIONS from calibre.gui2 import error_dialog from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.utils.date import parse_date -from calibre.gui2.device_drivers.mtp_folder_browser import Browser +from calibre.gui2.device_drivers.mtp_folder_browser import Browser, TopLevel class FormatsConfig(QWidget): # {{{ @@ -373,23 +373,29 @@ class MTPConfig(QTabWidget): _('&Ignore the %s in calibre')%device.current_friendly_name, self.base) b.clicked.connect(self.ignore_device) + self.config_ign_folders_button = cif = QPushButton( + QIcon(I('tb_folder.png')), _('Change scanned &folders')) self.show_debug_button = bd = QPushButton(QIcon(I('debug.png')), _('Show device information')) bd.clicked.connect(self.show_debug_info) + cif.clicked.connect(self.change_ignored_folders) l.addWidget(b, 0, 0, 1, 2) l.addWidget(la, 1, 0, 1, 1) - l.addWidget(self.formats, 2, 0, 4, 1) + l.addWidget(self.formats, 2, 0, 5, 1) l.addWidget(self.send_to, 2, 1, 1, 1) l.addWidget(self.template, 3, 1, 1, 1) - l.addWidget(self.show_debug_button, 4, 1, 1, 1) - l.setRowStretch(5, 10) - l.addWidget(r, 6, 0, 1, 2) - l.setRowStretch(6, 100) + l.addWidget(cif, 4, 1, 1, 1) + l.addWidget(self.show_debug_button, 5, 1, 1, 1) + l.setRowStretch(6, 10) + l.addWidget(r, 7, 0, 1, 2) + l.setRowStretch(7, 100) self.igntab = IgnoredDevices(self.device.prefs['history'], self.device.prefs['blacklist']) self.addTab(self.igntab, _('Ignored devices')) + self.current_ignored_folders = self.get_pref('ignored_folders') + self.initial_ignored_folders = self.current_ignored_folders self.setCurrentIndex(1 if msg else 0) @@ -413,6 +419,12 @@ class MTPConfig(QTabWidget): QApplication.clipboard().setText(v.toPlainText())) d.exec_() + def change_ignored_folders(self): + d = TopLevel(self.device, + self.current_ignored_folders, parent=self) + if d.exec_() == d.Accepted: + self.current_ignored_folders = d.ignored_folders + def ignore_device(self): self.igntab.ignore_device(self.device.current_serial_num) self.base.b.setEnabled(False) @@ -464,6 +476,9 @@ class MTPConfig(QTabWidget): if r and r != self.device.prefs['rules']: p['rules'] = r + if self.current_ignored_folders != self.initial_ignored_folders: + p['ignored_folders'] = self.current_ignored_folders + self.device.prefs[self.current_device_key] = p diff --git a/src/calibre/gui2/device_drivers/mtp_folder_browser.py b/src/calibre/gui2/device_drivers/mtp_folder_browser.py index 1e108ff117..6a54f65b38 100644 --- a/src/calibre/gui2/device_drivers/mtp_folder_browser.py +++ b/src/calibre/gui2/device_drivers/mtp_folder_browser.py @@ -10,7 +10,8 @@ __docformat__ = 'restructuredtext en' from operator import attrgetter from PyQt4.Qt import (QTabWidget, QTreeWidget, QTreeWidgetItem, Qt, QDialog, - QDialogButtonBox, QVBoxLayout, QSize, pyqtSignal, QIcon) + QDialogButtonBox, QVBoxLayout, QSize, pyqtSignal, QIcon, QLabel, + QListWidget, QListWidgetItem) from calibre.gui2 import file_icon_provider @@ -95,25 +96,105 @@ class Browser(QDialog): def current_item(self): return self.folders.current_item -def browse(): - from calibre.gui2 import Application +class TopLevel(QDialog): + + def __init__(self, dev, ignored_folders=None, parent=None): + QDialog.__init__(self, parent) + self.l = l = QVBoxLayout() + self.setLayout(l) + self.la = la = QLabel('

'+ _('Scanned folders:') + ' ' + + _('You can select which top level folders calibre will ' + 'scan when searching this device for books.')) + la.setWordWrap(True) + l.addWidget(la) + self.tabs = QTabWidget(self) + l.addWidget(self.tabs) + self.widgets = [] + + for storage in dev.filesystem_cache.entries: + w = QListWidget(self) + w.storage = storage + self.tabs.addTab(w, storage.name) + self.widgets.append(w) + for child in sorted(storage.folders, key=attrgetter('name')): + i = QListWidgetItem(child.name) + i.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) + i.setCheckState(Qt.Unchecked if + dev.is_folder_ignored(storage, child.name, + ignored_folders=ignored_folders) else Qt.Checked) + w.addItem(i) + + self.bb = QDialogButtonBox(QDialogButtonBox.Ok | + QDialogButtonBox.Cancel) + self.bb.accepted.connect(self.accept) + self.bb.rejected.connect(self.reject) + self.sab = self.bb.addButton(_('Select &All'), self.bb.ActionRole) + self.sab.clicked.connect(self.select_all) + self.snb = self.bb.addButton(_('Select &None'), self.bb.ActionRole) + self.snb.clicked.connect(self.select_none) + l.addWidget(self.bb) + self.setWindowTitle(_('Choose folders to scan')) + self.setWindowIcon(QIcon(I('devices/tablet.png'))) + + self.resize(500, 500) + + def select_all(self): + w = self.tabs.currentWidget() + for i in xrange(w.count()): + x = w.item(i) + x.setCheckState(Qt.Checked) + + def select_none(self): + w = self.tabs.currentWidget() + for i in xrange(w.count()): + x = w.item(i) + x.setCheckState(Qt.Unchecked) + + @property + def ignored_folders(self): + ans = {} + for w in self.widgets: + ans[unicode(w.storage.object_id)] = folders = [] + for i in xrange(w.count()): + x = w.item(i) + if x.checkState() != Qt.Checked: + folders.append(unicode(x.text())) + return ans + +def setup_device(): from calibre.devices.mtp.driver import MTP_DEVICE from calibre.devices.scanner import DeviceScanner s = DeviceScanner() s.scan() - app = Application([]) - app dev = MTP_DEVICE(None) dev.startup() cd = dev.detect_managed_devices(s.devices) if cd is None: raise ValueError('No MTP device found') dev.open(cd, 'test') + return dev + +def browse(): + from calibre.gui2 import Application + app = Application([]) + app + dev = setup_device() d = Browser(dev.filesystem_cache) d.exec_() dev.shutdown() return d.current_item -if __name__ == '__main__': - print (browse()) +def top_level(): + from calibre.gui2 import Application + app = Application([]) + app + dev = setup_device() + d = TopLevel(dev, None) + d.exec_() + dev.shutdown() + return d.ignored_folders + +if __name__ == '__main__': + # print (browse()) + print ('Ignored:', top_level())