From ae2e0b87196d49848d5f2a591c06909d77613ef0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 7 Jun 2011 20:27:45 -0600 Subject: [PATCH] Prevent the user from choosing a library path longer than 75 chars on windows --- src/calibre/gui2/actions/choose_library.py | 13 ++++++++++--- src/calibre/gui2/dialogs/choose_library.py | 17 +++++++++++++---- src/calibre/gui2/wizard/__init__.py | 9 ++++++++- src/calibre/library/database2.py | 16 ++++++++++++++-- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/calibre/gui2/actions/choose_library.py b/src/calibre/gui2/actions/choose_library.py index 9fd156b802..ac13f2c94a 100644 --- a/src/calibre/gui2/actions/choose_library.py +++ b/src/calibre/gui2/actions/choose_library.py @@ -11,10 +11,11 @@ from functools import partial from PyQt4.Qt import QMenu, Qt, QInputDialog, QToolButton from calibre import isbytestring -from calibre.constants import filesystem_encoding +from calibre.constants import filesystem_encoding, iswindows from calibre.utils.config import prefs -from calibre.gui2 import gprefs, warning_dialog, Dispatcher, error_dialog, \ - question_dialog, info_dialog +from calibre.gui2 import (gprefs, warning_dialog, Dispatcher, error_dialog, + question_dialog, info_dialog) +from calibre.library.database2 import LibraryDatabase2 from calibre.gui2.actions import InterfaceAction class LibraryUsageStats(object): # {{{ @@ -229,6 +230,12 @@ class ChooseLibraryAction(InterfaceAction): return error_dialog(self.gui, _('Already exists'), _('The folder %s already exists. Delete it first.') % newloc, show=True) + if (iswindows and len(newloc) > + LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT): + return error_dialog(self.gui, _('Too long'), + _('Path to library too long. Must be less than' + ' %d characters.')%LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT, + show=True) try: os.rename(loc, newloc) except: diff --git a/src/calibre/gui2/dialogs/choose_library.py b/src/calibre/gui2/dialogs/choose_library.py index 24bd6591c6..4e1424f0fc 100644 --- a/src/calibre/gui2/dialogs/choose_library.py +++ b/src/calibre/gui2/dialogs/choose_library.py @@ -11,10 +11,11 @@ from PyQt4.Qt import QDialog from calibre.gui2.dialogs.choose_library_ui import Ui_Dialog from calibre.gui2 import error_dialog, choose_dir -from calibre.constants import filesystem_encoding +from calibre.constants import filesystem_encoding, iswindows from calibre import isbytestring, patheq from calibre.utils.config import prefs from calibre.gui2.wizard import move_library +from calibre.library.database2 import LibraryDatabase2 class ChooseLibrary(QDialog, Ui_Dialog): @@ -57,12 +58,20 @@ class ChooseLibrary(QDialog, Ui_Dialog): _('There is no existing calibre library at %s')%loc, show=True) return False - if ac in ('new', 'move') and not empty: - error_dialog(self, _('Not empty'), + if ac in ('new', 'move'): + if not empty: + error_dialog(self, _('Not empty'), _('The folder %s is not empty. Please choose an empty' ' folder')%loc, show=True) - return False + return False + if (iswindows and len(loc) > + LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT): + error_dialog(self, _('Too long'), + _('Path to library too long. Must be less than' + ' %d characters.')%LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT, + show=True) + return False return True diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py index 5875373dfe..a98c4aaa16 100644 --- a/src/calibre/gui2/wizard/__init__.py +++ b/src/calibre/gui2/wizard/__init__.py @@ -16,7 +16,7 @@ from PyQt4.Qt import QWizard, QWizardPage, QPixmap, Qt, QAbstractListModel, \ from calibre import __appname__, patheq from calibre.library.database2 import LibraryDatabase2 from calibre.library.move import MoveLibrary -from calibre.constants import filesystem_encoding +from calibre.constants import filesystem_encoding, iswindows from calibre.gui2.wizard.send_email import smtp_prefs from calibre.gui2.wizard.device_ui import Ui_WizardPage as DeviceUI from calibre.gui2.wizard.library_ui import Ui_WizardPage as LibraryUI @@ -656,6 +656,13 @@ class LibraryPage(QWizardPage, LibraryUI): x = choose_dir(self, 'database location dialog', _('Select location for books')) if x: + if (iswindows and len(x) > + LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT): + return error_dialog(self, _('Too long'), + _('Path to library too long. Must be less than' + ' %d characters.')%LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT, + show=True) + if self.is_library_dir_suitable(x): self.location.setText(x) else: diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 9c4c3eb004..03c0712daa 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -82,6 +82,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): An ebook metadata database that stores references to ebook files on disk. ''' PATH_LIMIT = 40 if 'win32' in sys.platform else 100 + WINDOWS_LIBRARY_PATH_LIMIT = 75 @dynamic_property def user_version(self): @@ -122,9 +123,20 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): return property(doc=doc, fget=fget, fset=fset) def connect(self): - if 'win32' in sys.platform and len(self.library_path) + 4*self.PATH_LIMIT + 10 > 259: - raise ValueError('Path to library too long. Must be less than %d characters.'%(259-4*self.PATH_LIMIT-10)) + if iswindows and len(self.library_path) + 4*self.PATH_LIMIT + 10 > 259: + raise ValueError(_( + 'Path to library too long. Must be less than' + ' %d characters.')%(259-4*self.PATH_LIMIT-10)) exists = os.path.exists(self.dbpath) + if not exists: + # Be more strict when creating new libraries as the old calculation + # allowed for max path lengths of 265 chars. + if (iswindows and len(self.library_path) > + self.WINDOWS_LIBRARY_PATH_LIMIT): + raise ValueError(_( + 'Path to library too long. Must be less than' + ' %d characters.')%self.WINDOWS_LIBRARY_PATH_LIMIT) + self.conn = connect(self.dbpath, self.row_factory) if exists and self.user_version == 0: self.conn.close()