diff --git a/src/calibre/devices/cybookg3/driver.py b/src/calibre/devices/cybookg3/driver.py index 5dde9ab51d..eebd28ebee 100644 --- a/src/calibre/devices/cybookg3/driver.py +++ b/src/calibre/devices/cybookg3/driver.py @@ -4,9 +4,11 @@ __copyright__ = '2009, John Schember ' Device driver for Bookeen's Cybook Gen 3 ''' -import os, shutil +import os +import shutil from itertools import cycle +from calibre import sanitize_file_name as sanitize from calibre.devices.errors import DeviceError, FreeSpaceError from calibre.devices.usbms.driver import USBMS import calibre.devices.cybookg3.t2b as t2b @@ -57,21 +59,21 @@ class CYBOOKG3(USBMS): for tag in mdata['tags']: if tag.startswith(_('News')): newpath = os.path.join(newpath, 'news') - newpath = os.path.join(newpath, mdata.get('title', '')) - newpath = os.path.join(newpath, mdata.get('timestamp', '')) + newpath = os.path.join(newpath, sanitize(mdata.get('title', ''))) + newpath = os.path.join(newpath, sanitize(mdata.get('timestamp', ''))) elif tag.startswith('/'): newpath += tag newpath = os.path.normpath(newpath) break if newpath == path: - newpath = os.path.join(newpath, mdata.get('authors', _('Unknown'))) - newpath = os.path.join(newpath, mdata.get('title', _('Unknown'))) + newpath = os.path.join(newpath, sanitize(mdata.get('authors', _('Unknown')))) + newpath = os.path.join(newpath, sanitize(mdata.get('title', _('Unknown')))) if not os.path.exists(newpath): os.makedirs(newpath) - filepath = os.path.join(newpath, names.next()) + filepath = os.path.join(newpath, sanitize(names.next())) paths.append(filepath) if hasattr(infile, 'read'): diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 6b1f33818a..6c7049d8e8 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -4,9 +4,11 @@ __copyright__ = '2008, Kovid Goyal ' \ ''' Device driver for the SONY PRS-505 ''' -import os, time +import os +import time from itertools import cycle +from calibre import sanitize_file_name as sanitize from calibre.devices.usbms.cli import CLI from calibre.devices.usbms.device import Device from calibre.devices.errors import DeviceError, FreeSpaceError @@ -150,8 +152,8 @@ class PRS505(CLI, Device): for tag in mdata['tags']: if tag.startswith(_('News')): newpath = os.path.join(newpath, 'news') - newpath = os.path.join(newpath, mdata.get('title', '')) - newpath = os.path.join(newpath, mdata.get('timestamp', '')) + newpath = os.path.join(newpath, sanitize(mdata.get('title', ''))) + newpath = os.path.join(newpath, sanitize(mdata.get('timestamp', ''))) elif tag.startswith('/'): newpath = path newpath += tag @@ -159,13 +161,13 @@ class PRS505(CLI, Device): break if newpath == path: - newpath = os.path.join(newpath, mdata.get('authors', _('Unknown'))) - newpath = os.path.join(newpath, mdata.get('title', _('Unknown'))) + newpath = os.path.join(newpath, sanitize(mdata.get('authors', _('Unknown')))) + newpath = os.path.join(newpath, sanitize(mdata.get('title', _('Unknown')))) if not os.path.exists(newpath): os.makedirs(newpath) - filepath = os.path.join(newpath, names.next()) + filepath = os.path.join(newpath, sanitize(names.next())) paths.append(filepath) self.put_file(infile, paths[-1], replace_file=True) @@ -181,6 +183,9 @@ class PRS505(CLI, Device): return zip(paths, sizes, ctimes, cycle([on_card])) def add_books_to_metadata(self, locations, metadata, booklists): + if not locations or not metadata: + return + metadata = iter(metadata) for location in locations: info = metadata.next() diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index fe39e12077..ae5504fc71 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -7,9 +7,12 @@ driver. It is intended to be subclassed with the relevant parts implemented for a particular device. ''' -import os, fnmatch, shutil +import os +import fnmatch +import shutil from itertools import cycle +from calibre import sanitize_file_name as sanitize from calibre.ebooks.metadata import authors_to_string from calibre.devices.usbms.cli import CLI from calibre.devices.usbms.device import Device @@ -132,8 +135,8 @@ class USBMS(CLI, Device): for tag in mdata['tags']: if tag.startswith(_('News')): newpath = os.path.join(newpath, 'news') - newpath = os.path.join(newpath, mdata.get('title', '')) - newpath = os.path.join(newpath, mdata.get('timestamp', '')) + newpath = os.path.join(newpath, sanitize(mdata.get('title', ''))) + newpath = os.path.join(newpath, sanitize(mdata.get('timestamp', ''))) break elif tag.startswith('/'): newpath += tag @@ -142,13 +145,13 @@ class USBMS(CLI, Device): if newpath == path: newpath = os.path.join(newpath, - mdata.get('authors', _('Unknown')), - mdata.get('title', _('Unknown'))) + sanitize(mdata.get('authors', _('Unknown'))), + sanitize(mdata.get('title', _('Unknown')))) if not os.path.exists(newpath): os.makedirs(newpath) - filepath = os.path.join(newpath, names.next()) + filepath = os.path.join(newpath, sanitize(names.next())) paths.append(filepath) if hasattr(infile, 'read'): diff --git a/src/calibre/ebooks/pdb/header.py b/src/calibre/ebooks/pdb/header.py index c012110a62..75455354c2 100644 --- a/src/calibre/ebooks/pdb/header.py +++ b/src/calibre/ebooks/pdb/header.py @@ -30,7 +30,7 @@ class PdbHeaderReader(object): def name(self): self.stream.seek(0) - return re.sub('[^-A-Za-z0-9]+', '', self.stream.read(32).replace('\x00', '')) + return re.sub('[^-A-Za-z0-9 ]+', '', self.stream.read(32).replace('\x00', '')) def full_section_info(self, number): if number not in range(0, self.num_sections): @@ -66,7 +66,7 @@ class PdbHeaderBuilder(object): def __init__(self, identity, title): self.identity = identity.ljust(3, '\x00')[:8] - self.title = re.sub('[^-A-Za-z0-9]+', '_', title).ljust(32, '\x00')[:32].encode('ascii', 'replace') + self.title = '%s\x00' % re.sub('[^-A-Za-z0-9 ]+', '_', title).ljust(31, '\x00')[:31].encode('ascii', 'replace') def build_header(self, section_lengths, out_stream): ''' diff --git a/src/calibre/gui2/convert/metadata.py b/src/calibre/gui2/convert/metadata.py index d961fef473..01eb5bee1c 100644 --- a/src/calibre/gui2/convert/metadata.py +++ b/src/calibre/gui2/convert/metadata.py @@ -54,7 +54,10 @@ class MetadataWidget(Widget, Ui_Form): if mi.series: self.series.setCurrentIndex(self.series.findText(mi.series)) if mi.series_index is not None: - self.series_index.setValue(mi.series_index) + try: + self.series_index.setValue(mi.series_index) + except: + self.series_index.setValue(1.0) cover = self.db.cover(self.book_id, index_is_id=True) if cover: diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 353f4d9c37..e3aa0e6b8c 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -234,6 +234,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.add_menu.addAction(_('Add books from directories, including ' 'sub directories (Multiple books per directory, assumes every ' 'ebook file is a different book)')) + self.add_menu.addAction(_('Add Empty book. (Book entry with no ' + 'formats)')) self.action_add.setMenu(self.add_menu) QObject.connect(self.action_add, SIGNAL("triggered(bool)"), self.add_books) @@ -243,6 +245,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.add_recursive_single) QObject.connect(self.add_menu.actions()[2], SIGNAL("triggered(bool)"), self.add_recursive_multiple) + QObject.connect(self.add_menu.actions()[3], SIGNAL('triggered(bool)'), + self.add_empty) QObject.connect(self.action_del, SIGNAL("triggered(bool)"), self.delete_books) QObject.connect(self.action_edit, SIGNAL("triggered(bool)"), @@ -779,6 +783,15 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): ''' self.add_recursive(False) + def add_empty(self, checked): + ''' + Add an empty book item to the library. This does not import any formats + from a book file. + ''' + from calibre.ebooks.metadata import MetaInformation + self.library_view.model().db.import_book(MetaInformation(None), []) + self.library_view.model().books_added(1) + def files_dropped(self, paths): to_device = self.stack.currentIndex() != 0 self._add_books(paths, to_device) diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 730ca364d5..3550253ffa 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -198,7 +198,7 @@ class ResultCache(SearchQueryParser): query = query.decode('utf-8') if location in ('tag', 'author', 'format'): location += 's' - all = ('title', 'authors', 'publisher', 'tags', 'comments', 'series', 'formats') + all = ('title', 'authors', 'publisher', 'tags', 'comments', 'series', 'formats', 'isbn') MAP = {} for x in all: MAP[x] = FIELD_MAP[x] diff --git a/src/calibre/utils/search_query_parser.py b/src/calibre/utils/search_query_parser.py index 05e0ed3e8f..35241c89c4 100644 --- a/src/calibre/utils/search_query_parser.py +++ b/src/calibre/utils/search_query_parser.py @@ -52,6 +52,7 @@ class SearchQueryParser(object): 'series', 'comments', 'format', + 'isbn', 'all', ]