From 07978111915e03ab7fd522a83c89211f9d4f8a6a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 18 Dec 2012 17:30:58 +0530 Subject: [PATCH] MTP driver: Prevent sending books into an ignored folder --- src/calibre/devices/mtp/driver.py | 12 +++++- src/calibre/gui2/device.py | 6 +++ src/calibre/gui2/device_drivers/mtp_config.py | 43 +++++++++++++++++-- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/calibre/devices/mtp/driver.py b/src/calibre/devices/mtp/driver.py index b9643af1b2..b1850c9e49 100644 --- a/src/calibre/devices/mtp/driver.py +++ b/src/calibre/devices/mtp/driver.py @@ -13,6 +13,7 @@ from itertools import izip from calibre import prints from calibre.constants import iswindows, numeric_version +from calibre.devices.errors import PathError from calibre.devices.mtp.base import debug from calibre.devices.mtp.defaults import DeviceDefaults from calibre.ptempfile import SpooledTemporaryFile, PersistentTemporaryDirectory @@ -23,6 +24,12 @@ from calibre.utils.filenames import shorten_components_to BASE = importlib.import_module('calibre.devices.mtp.%s.driver'%( 'windows' if iswindows else 'unix')).MTP_DEVICE +class MTPInvalidSendPathError(PathError): + + def __init__(self, folder): + PathError.__init__(self, 'Trying to send to ignored folder: %s'%folder) + self.folder = folder + class MTP_DEVICE(BASE): METADATA_CACHE = 'metadata.calibre' @@ -46,6 +53,7 @@ class MTP_DEVICE(BASE): self._prefs = None self.device_defaults = DeviceDefaults() self.current_device_defaults = {} + self.highlight_ignored_folders = False @property def prefs(self): @@ -387,6 +395,8 @@ class MTP_DEVICE(BASE): for infile, fname, mi in izip(files, names, metadata): path = self.create_upload_path(prefix, mi, fname, routing) + if path and self.is_folder_ignored(storage, path[0]): + raise MTPInvalidSendPathError(path[0]) parent = self.ensure_parent(storage, path) if hasattr(infile, 'read'): pos = infile.tell() @@ -488,7 +498,7 @@ class MTP_DEVICE(BASE): def config_widget(self): from calibre.gui2.device_drivers.mtp_config import MTPConfig - return MTPConfig(self) + return MTPConfig(self, highlight_ignored_folders=self.highlight_ignored_folders) def save_settings(self, cw): cw.commit() diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 1047fef1b6..85e992e264 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -985,6 +985,12 @@ class DeviceMixin(object): # {{{ return except: pass + if getattr(job, 'exception', None).__class__.__name__ == 'MTPInvalidSendPathError': + try: + from calibre.gui2.device_drivers.mtp_config import SendError + return SendError(self, job.exception).exec_() + except: + traceback.print_exc() try: prints(job.details, file=sys.stderr) except: diff --git a/src/calibre/gui2/device_drivers/mtp_config.py b/src/calibre/gui2/device_drivers/mtp_config.py index 63002e90eb..b71766b7da 100644 --- a/src/calibre/gui2/device_drivers/mtp_config.py +++ b/src/calibre/gui2/device_drivers/mtp_config.py @@ -13,7 +13,7 @@ from PyQt4.Qt import (QWidget, QListWidgetItem, Qt, QToolButton, QLabel, QTabWidget, QGridLayout, QListWidget, QIcon, QLineEdit, QVBoxLayout, QPushButton, QGroupBox, QScrollArea, QHBoxLayout, QComboBox, pyqtSignal, QSizePolicy, QDialog, QDialogButtonBox, QPlainTextEdit, - QApplication) + QApplication, QSize) from calibre.ebooks import BOOK_EXTENSIONS from calibre.gui2 import error_dialog @@ -328,7 +328,7 @@ class FormatRules(QGroupBox): class MTPConfig(QTabWidget): - def __init__(self, device, parent=None): + def __init__(self, device, parent=None, highlight_ignored_folders=False): QTabWidget.__init__(self, parent) self._device = weakref.ref(device) @@ -375,6 +375,10 @@ class MTPConfig(QTabWidget): b.clicked.connect(self.ignore_device) self.config_ign_folders_button = cif = QPushButton( QIcon(I('tb_folder.png')), _('Change scanned &folders')) + cif.setStyleSheet( + 'QPushButton { font-weight: bold; }') + if highlight_ignored_folders: + cif.setIconSize(QSize(64, 64)) self.show_debug_button = bd = QPushButton(QIcon(I('debug.png')), _('Show device information')) bd.clicked.connect(self.show_debug_info) @@ -383,9 +387,9 @@ class MTPConfig(QTabWidget): l.addWidget(b, 0, 0, 1, 2) l.addWidget(la, 1, 0, 1, 1) l.addWidget(self.formats, 2, 0, 5, 1) - l.addWidget(self.send_to, 2, 1, 1, 1) + l.addWidget(cif, 2, 1, 1, 1) l.addWidget(self.template, 3, 1, 1, 1) - l.addWidget(cif, 4, 1, 1, 1) + l.addWidget(self.send_to, 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) @@ -481,6 +485,37 @@ class MTPConfig(QTabWidget): self.device.prefs[self.current_device_key] = p +class SendError(QDialog): + + def __init__(self, gui, error): + QDialog.__init__(self, gui) + self.l = l = QVBoxLayout() + self.setLayout(l) + self.la = la = QLabel('

'+ + _('You are trying to send books into the %s folder. This ' + 'folder is currently ignored by calibre when scanning the ' + 'device. You have tell calibre you want this folder scanned ' + 'in order to be able to send books to it. Click the ' + 'configure button below to send books to it.')%error.folder) + la.setWordWrap(True) + la.setMinimumWidth(500) + l.addWidget(la) + self.bb = bb = QDialogButtonBox(QDialogButtonBox.Close) + self.b = bb.addButton(_('Configure'), bb.AcceptRole) + bb.accepted.connect(self.accept) + bb.rejected.connect(self.reject) + l.addWidget(bb) + self.setWindowTitle(_('Cannot send to %s')%error.folder) + self.setWindowIcon(QIcon(I('dialog_error.png'))) + + self.resize(self.sizeHint()) + + def accept(self): + QDialog.accept(self) + dev = self.parent().device_manager.connected_device + dev.highlight_ignored_folders = True + self.parent().configure_connected_device() + dev.highlight_ignored_folders = False if __name__ == '__main__': from calibre.gui2 import Application