From 30f29c61174bdef6d10b6375a9430004b6f7a3ed Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 25 Sep 2011 09:40:35 -0600 Subject: [PATCH 1/3] Fix regression that broke customization of Kobo device plugin --- src/calibre/devices/kobo/driver.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index fa4796a5a9..393b96442b 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -51,11 +51,11 @@ class KOBO(USBMS): EXTRA_CUSTOMIZATION_MESSAGE = [ _('The Kobo supports several collections including ')+\ - 'Read, Closed, Im_Reading ' +\ + 'Read, Closed, Im_Reading. ' +\ _('Create tags for automatic management'), ] - EXTRA_CUSTOMIZATION_DEFAULT = ', '.join(['tags']) + EXTRA_CUSTOMIZATION_DEFAULT = [', '.join(['tags'])] OPT_COLLECTIONS = 0 @@ -659,7 +659,7 @@ class KOBO(USBMS): "Read":2, "Closed":3, "Shortlist":4, - # "Preview":99, # Unsupported as we don't want to change it + # "Preview":99, # Unsupported as we don't want to change it } # Define lists for the ReadStatus From 8cb2e172540cb981416efbf8cb16a230c9d4f162 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 25 Sep 2011 11:57:31 -0600 Subject: [PATCH 2/3] Fix #856158 (Truncating files when adding from withing library directory) --- src/calibre/db/backend.py | 6 +++--- src/calibre/gui2/metadata/basic_widgets.py | 15 +++++++++------ src/calibre/ptempfile.py | 13 +++++++++++++ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index c29e0d5c12..7dd6e052ea 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -8,7 +8,7 @@ __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' # Imports {{{ -import os, shutil, uuid, json, glob, time, tempfile +import os, shutil, uuid, json, glob, time from functools import partial import apsw @@ -16,7 +16,7 @@ import apsw from calibre import isbytestring, force_unicode, prints from calibre.constants import (iswindows, filesystem_encoding, preferred_encoding) -from calibre.ptempfile import PersistentTemporaryFile +from calibre.ptempfile import PersistentTemporaryFile, SpooledTemporaryFile from calibre.db.schema_upgrades import SchemaUpgrade from calibre.library.field_metadata import FieldMetadata from calibre.ebooks.metadata import title_sort, author_to_author_sort @@ -805,7 +805,7 @@ class DB(object): shutil.copyfileobj(f, pt) return pt.name if as_file: - ret = tempfile.SpooledTemporaryFile(SPOOL_SIZE) + ret = SpooledTemporaryFile(SPOOL_SIZE) shutil.copyfileobj(f, ret) ret.seek(0) else: diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py index fe20be765f..fbde89b7b7 100644 --- a/src/calibre/gui2/metadata/basic_widgets.py +++ b/src/calibre/gui2/metadata/basic_widgets.py @@ -7,7 +7,7 @@ __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import textwrap, re, os, errno +import textwrap, re, os, errno, shutil from PyQt4.Qt import (Qt, QDateEdit, QDate, pyqtSignal, QMessageBox, QIcon, QToolButton, QWidget, QLabel, QGridLayout, QApplication, @@ -33,8 +33,9 @@ from calibre.gui2.comments_editor import Editor from calibre.library.comments import comments_to_html from calibre.gui2.dialogs.tag_editor import TagEditor from calibre.utils.icu import strcmp -from calibre.ptempfile import PersistentTemporaryFile +from calibre.ptempfile import PersistentTemporaryFile, SpooledTemporaryFile from calibre.gui2.languages import LanguagesEdit as LE +from calibre.db.backend import SPOOL_SIZE def save_dialog(parent, title, msg, det_msg=''): d = QMessageBox(parent) @@ -43,8 +44,6 @@ def save_dialog(parent, title, msg, det_msg=''): d.setStandardButtons(QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) return d.exec_() - - ''' The interface common to all widgets used to set basic metadata class BasicMetadataWidget(object): @@ -731,8 +730,12 @@ class FormatsManager(QWidget): else: old_extensions.add(ext) for ext in new_extensions: - db.add_format(id_, ext, open(paths[ext], 'rb'), notify=False, - index_is_id=True) + with SpooledTemporaryFile(SPOOL_SIZE) as spool: + with open(paths[ext], 'rb') as f: + shutil.copyfileobj(f, spool) + spool.seek(0) + db.add_format(id_, ext, spool, notify=False, + index_is_id=True) dbfmts = db.formats(id_, index_is_id=True) db_extensions = set([f.lower() for f in (dbfmts.split(',') if dbfmts else [])]) diff --git a/src/calibre/ptempfile.py b/src/calibre/ptempfile.py index 34df148f15..aca8397f53 100644 --- a/src/calibre/ptempfile.py +++ b/src/calibre/ptempfile.py @@ -181,4 +181,17 @@ class TemporaryFile(object): +class SpooledTemporaryFile(tempfile.SpooledTemporaryFile): + + def __init__(self, max_size=0, suffix="", prefix="", dir=None, mode='w+b', + bufsize=-1): + if prefix == None: + prefix = '' + if suffix is None: + suffix = '' + if dir is None: + dir = base_dir() + tempfile.SpooledTemporaryFile.__init__(self, max_size=max_size, suffix=suffix, + prefix=prefix, dir=dir, mode=mode, bufsize=bufsize) + From 31ad166e9928a7fe809079f154eb54554527fa32 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 25 Sep 2011 12:00:25 -0600 Subject: [PATCH 3/3] Ensure use of SpooledTempFile does not temporarily create files outside the calibre temp dir --- src/calibre/library/database2.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index d6c2ddd659..f491b16291 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en' The database used to store ebook metadata ''' import os, sys, shutil, cStringIO, glob, time, functools, traceback, re, \ - json, uuid, tempfile, hashlib, copy + json, uuid, hashlib, copy from collections import defaultdict import threading, random from itertools import repeat @@ -26,7 +26,8 @@ from calibre.library.sqlite import connect, IntegrityError from calibre.library.prefs import DBPrefs from calibre.ebooks.metadata.book.base import Metadata from calibre.constants import preferred_encoding, iswindows, filesystem_encoding -from calibre.ptempfile import PersistentTemporaryFile, base_dir +from calibre.ptempfile import (PersistentTemporaryFile, + base_dir, SpooledTemporaryFile) from calibre.customize.ui import run_plugins_on_import from calibre import isbytestring from calibre.utils.filenames import ascii_filename @@ -610,7 +611,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): with lopen(os.path.join(tpath, 'cover.jpg'), 'wb') as f: f.write(cdata) for format in formats: - with tempfile.SpooledTemporaryFile(max_size=SPOOL_SIZE) as stream: + with SpooledTemporaryFile(SPOOL_SIZE) as stream: try: self.copy_format_to(id, format, stream, index_is_id=True) stream.seek(0) @@ -694,7 +695,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): shutil.copyfileobj(f, pt) return pt.name if as_file: - ret = tempfile.SpooledTemporaryFile(SPOOL_SIZE) + ret = SpooledTemporaryFile(SPOOL_SIZE) shutil.copyfileobj(f, ret) ret.seek(0) else: @@ -1282,7 +1283,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): shutil.copyfileobj(f, pt) ret = pt.name elif as_file: - ret = tempfile.SpooledTemporaryFile(max_size=SPOOL_SIZE) + ret = SpooledTemporaryFile(SPOOL_SIZE) shutil.copyfileobj(f, ret) ret.seek(0) # Various bits of code try to use the name as the default