diff --git a/src/calibre/devices/interface.py b/src/calibre/devices/interface.py index 6bbb658f2c..ed51962236 100644 --- a/src/calibre/devices/interface.py +++ b/src/calibre/devices/interface.py @@ -150,10 +150,13 @@ class Device(object): the device. @param locations: Result of a call to L{upload_books} @param metadata: List of dictionaries. Each dictionary must have the - keys C{title}, C{authors}, C{cover}, C{tags}. The value of the C{cover} + keys C{title}, C{authors}, C{author_sort}, C{cover}, C{tags}. + The value of the C{cover} element can be None or a three element tuple (width, height, data) where data is the image data in JPEG format as a string. C{tags} must be a possibly empty list of strings. C{authors} must be a string. + C{author_sort} may be None. It is upto the driver to decide whether to + use C{author_sort} or not. The dictionary can also have an optional key "tag order" which should be another dictionary that maps tag names to lists of book ids. The ids are ids from the book database. diff --git a/src/calibre/devices/prs505/books.py b/src/calibre/devices/prs505/books.py index 06d205fb02..38b708a312 100644 --- a/src/calibre/devices/prs505/books.py +++ b/src/calibre/devices/prs505/books.py @@ -55,7 +55,7 @@ class Book(object): title = book_metadata_field("title") authors = book_metadata_field("author", \ - formatter=lambda x: x if x and x.strip() else "Unknown") + formatter=lambda x: x if x and x.strip() else _('Unknown')) mime = book_metadata_field("mime") rpath = book_metadata_field("path") id = book_metadata_field("id", formatter=int) @@ -193,7 +193,7 @@ class BookList(_BookList): attrs = { "title" : info["title"], 'titleSorter' : sortable_title(info['title']), - "author" : info["authors"] if info['authors'] else 'Unknown', \ + "author" : info["authors"] if info['authors'] else _('Unknown'), "page":"0", "part":"0", "scale":"0", \ "sourceid":sourceid, "id":str(cid), "date":"", \ "mime":mime, "path":name, "size":str(size) diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 2e3b5ff047..c172d26e1a 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -18,7 +18,7 @@ from calibre.ebooks.chardet import xml_to_unicode from calibre import relpath from calibre.constants import __appname__, __version__ from calibre.ebooks.metadata.toc import TOC -from calibre.ebooks.metadata import MetaInformation +from calibre.ebooks.metadata import MetaInformation, string_to_authors class Resource(object): @@ -614,7 +614,7 @@ class OPF(object): def fget(self): ans = [] for elem in self.authors_path(self.metadata): - ans.extend([x.strip() for x in self.get_text(elem).split(',')]) + ans.extend(string_to_authors(self.get_text(elem))) return ans def fset(self, val): @@ -624,8 +624,8 @@ class OPF(object): for author in val: attrib = {'{%s}role'%self.NAMESPACES['opf']: 'aut'} elem = self.create_metadata_element('creator', attrib=attrib) - self.set_text(elem, author) - + self.set_text(elem, author.strip()) + return property(fget=fget, fset=fset) @apply diff --git a/src/calibre/gui2/dialogs/config.py b/src/calibre/gui2/dialogs/config.py index bbd5475e2b..2b093a45b5 100644 --- a/src/calibre/gui2/dialogs/config.py +++ b/src/calibre/gui2/dialogs/config.py @@ -180,11 +180,12 @@ class ConfigDialog(QDialog, Ui_Dialog): self.toolbar_button_size.setCurrentIndex(0 if icons == self.ICON_SIZES[0] else 1 if icons == self.ICON_SIZES[1] else 2) self.show_toolbar_text.setChecked(config['show_text_in_toolbar']) - for ext in BOOK_EXTENSIONS: + book_exts = sorted(BOOK_EXTENSIONS) + for ext in book_exts: self.single_format.addItem(ext.upper(), QVariant(ext)) single_format = config['save_to_disk_single_format'] - self.single_format.setCurrentIndex(BOOK_EXTENSIONS.index(single_format)) + self.single_format.setCurrentIndex(book_exts.index(single_format)) self.cover_browse.setValue(config['cover_flow_queue_length']) self.systray_notifications.setChecked(not config['disable_tray_notification']) from calibre.translations.compiled import translations @@ -203,7 +204,7 @@ class ConfigDialog(QDialog, Ui_Dialog): self.pdf_metadata.setChecked(prefs['read_file_metadata']) added_html = False - for ext in BOOK_EXTENSIONS: + for ext in book_exts: ext = ext.lower() ext = re.sub(r'(x{0,1})htm(l{0,1})', 'html', ext) if ext == 'lrf' or is_supported('book.'+ext): diff --git a/src/calibre/gui2/library.py b/src/calibre/gui2/library.py index 1868623787..38652ad971 100644 --- a/src/calibre/gui2/library.py +++ b/src/calibre/gui2/library.py @@ -20,6 +20,7 @@ from calibre.gui2 import NONE, TableView, qstring_to_unicode, config, \ error_dialog from calibre.utils.search_query_parser import SearchQueryParser from calibre.ebooks.metadata.meta import set_metadata as _set_metadata +from calibre.ebooks.metadata import string_to_authors class LibraryDelegate(QItemDelegate): COLOR = QColor("blue") @@ -364,12 +365,13 @@ class BooksModel(QAbstractTableModel): return data - def get_metadata(self, rows, rows_are_ids=False): - metadata = [] + def get_metadata(self, rows, rows_are_ids=False, full_metadata=False): + metadata, _full_metadata = [], [] if not rows_are_ids: rows = [self.db.id(row.row()) for row in rows] for id in rows: mi = self.db.get_metadata(id, index_is_id=True) + _full_metadata.append(mi) au = authors_to_string(mi.authors if mi.authors else [_('Unknown')]) tags = mi.tags if mi.tags else [] if mi.series is not None: @@ -377,6 +379,7 @@ class BooksModel(QAbstractTableModel): info = { 'title' : mi.title, 'authors' : au, + 'author_sort' : mi.author_sort, 'cover' : self.db.cover(id, index_is_id=True), 'tags' : tags, 'comments': mi.comments, @@ -387,7 +390,10 @@ class BooksModel(QAbstractTableModel): } metadata.append(info) - return metadata + if full_metadata: + return metadata, _full_metadata + else: + return metadata def get_preferred_formats_from_ids(self, ids, all_formats, mode='r+b'): ans = [] @@ -928,12 +934,8 @@ class DeviceBooksModel(BooksModel): au = self.unknown if role == Qt.EditRole: return QVariant(au) - au = au.split(',') - authors = [] - for i in au: - authors += i.strip().split('&') - jau = [ a.strip() for a in authors ] - return QVariant("\n".join(jau)) + authors = string_to_authors(au) + return QVariant("\n".join(authors)) elif col == 2: size = self.db[self.map[row]].size return QVariant(BooksView.human_readable(size)) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index b4049fc739..3972e00bdd 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -1,3 +1,4 @@ +from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' import os, sys, textwrap, collections, traceback, time @@ -910,12 +911,13 @@ class Main(MainWindow, Ui_MainWindow): if not self.device_manager or not rows or len(rows) == 0: return ids = iter(self.library_view.model().id(r) for r in rows) - metadata = self.library_view.model().get_metadata(rows) + metadata, full_metadata = self.library_view.model().get_metadata( + rows, full_metadata=True) for mi in metadata: cdata = mi['cover'] if cdata: mi['cover'] = self.cover_to_thumbnail(cdata) - metadata = iter(metadata) + metadata, full_metadata = iter(metadata), iter(full_metadata) _files = self.library_view.model().get_preferred_formats(rows, self.device_manager.device_class.FORMATS, paths=True, set_metadata=True, @@ -923,22 +925,15 @@ class Main(MainWindow, Ui_MainWindow): files = [getattr(f, 'name', None) for f in _files] bad, good, gf, names, remove_ids = [], [], [], [], [] for f in files: - mi = metadata.next() + mi, smi = metadata.next(), full_metadata.next() id = ids.next() if f is None: bad.append(mi['title']) else: remove_ids.append(id) - aus = mi['authors'].split(',') - aus2 = [] - for a in aus: - aus2.extend(a.split('&')) try: - smi = MetaInformation(mi['title'], aus2) - smi.comments = mi.get('comments', None) - _f = open(f, 'r+b') - set_metadata(_f, smi, f.rpartition('.')[2]) - _f.close() + with open(f, 'r+b') as _f: + set_metadata(_f, smi, f.rpartition('.')[2]) except: print 'Error setting metadata in book:', mi['title'] traceback.print_exc()