From aceb4655f22bf916da388afdaacb25598492072c Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Tue, 28 Jun 2011 19:43:14 +0100 Subject: [PATCH] Commit to merge from trunk --- resources/metadata_sqlite.sql | 3 ++- src/calibre/ebooks/metadata/opf2.py | 11 +++++++-- src/calibre/gui2/__init__.py | 8 +++++++ src/calibre/gui2/book_details.py | 16 +++++++++++-- src/calibre/gui2/dialogs/restore_library.py | 2 +- src/calibre/gui2/preferences/look_feel.py | 1 + src/calibre/gui2/preferences/look_feel.ui | 26 +++++++++++++++++++-- src/calibre/gui2/tag_browser/view.py | 2 +- src/calibre/library/restore.py | 12 ++++++++++ src/calibre/library/schema_upgrades.py | 2 +- 10 files changed, 73 insertions(+), 10 deletions(-) diff --git a/resources/metadata_sqlite.sql b/resources/metadata_sqlite.sql index aa29d4b8de..83f55c2762 100644 --- a/resources/metadata_sqlite.sql +++ b/resources/metadata_sqlite.sql @@ -1,6 +1,7 @@ CREATE TABLE authors ( id INTEGER PRIMARY KEY, name TEXT NOT NULL COLLATE NOCASE, sort TEXT COLLATE NOCASE, + link TEXT NOT NULL DEFAULT "", UNIQUE(name) ); CREATE TABLE books ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -545,4 +546,4 @@ CREATE TRIGGER series_update_trg BEGIN UPDATE series SET sort=NEW.name WHERE id=NEW.id; END; -pragma user_version=20; +pragma user_version=21; diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index c1cd2a739f..2ec4ed83ea 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -481,6 +481,13 @@ def dump_user_categories(cats): return json.dumps(object_to_unicode(cats), ensure_ascii=False, skipkeys=True) +def dump_author_links(links): + if not links: + links = {} + from calibre.ebooks.metadata.book.json_codec import object_to_unicode + return json.dumps(object_to_unicode(links), ensure_ascii=False, + skipkeys=True) + class OPF(object): # {{{ MIMETYPE = 'application/oebps-package+xml' @@ -539,7 +546,7 @@ class OPF(object): # {{{ formatter=json.loads, renderer=dump_user_categories) author_link_map = MetadataField('author_link_map', is_dc=False, - formatter=json.loads) + formatter=json.loads, renderer=dump_author_links) def __init__(self, stream, basedir=os.getcwdu(), unquote_urls=True, populate_spine=True): @@ -1338,7 +1345,7 @@ def metadata_to_opf(mi, as_string=True): factory(DC('subject'), tag) meta = lambda n, c: factory('meta', name='calibre:'+n, content=c) if getattr(mi, 'author_link_map', None) is not None: - meta('author_link_map', json.dumps(mi.author_link_map)) + meta('author_link_map', dump_author_links(mi.author_link_map)) if mi.series: meta('series', mi.series) if mi.series_index is not None: diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 8dbc72ab98..88c5653ee7 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -181,6 +181,14 @@ def _config(): # {{{ help=_('Show the average rating per item indication in the tag browser')) c.add_opt('disable_animations', default=False, help=_('Disable UI animations')) + c.add_opt('default_author_link', + default='http://en.wikipedia.org/w/index.php?search={author}', + help='

' + + _('Enter a template to be used to create a link for' + 'an author in the books information dialog. This template will ' + 'be used when no link has been provided for the author using ' + 'Manage Authors. You can use the values {author} and ' + '{author_sort}, and any template function.') + '

') # This option is no longer used. It remains for compatibility with upgrades # so the value can be migrated diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py index ef21773ae4..1927b1448e 100644 --- a/src/calibre/gui2/book_details.py +++ b/src/calibre/gui2/book_details.py @@ -5,6 +5,7 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' +import urllib2 from PyQt4.Qt import (QPixmap, QSize, QWidget, Qt, pyqtSignal, QUrl, QPropertyAnimation, QEasingCurve, QApplication, QFontInfo, @@ -23,6 +24,7 @@ from calibre.library.comments import comments_to_html from calibre.gui2 import (config, open_local_file, open_url, pixmap_to_data, gprefs) from calibre.utils.icu import sort_key +from calibre.utils.formatter import EvalFormatter def render_html(mi, css, vertical, widget, all_fields=False): # {{{ table = render_data(mi, all_fields=all_fields, @@ -123,10 +125,20 @@ def render_data(mi, use_roman_numbers=True, all_fields=False): _('Ids')+':', links))) elif field == 'authors' and not isdevice: authors = [] + formatter = EvalFormatter() for aut in mi.authors: if mi.author_link_map[aut]: - authors.append(u'%s' % - (mi.author_link_map[aut], aut)) + link = mi.author_link_map[aut] + elif config.get('default_author_link'): + vals = {'author': aut} + try: + vals['author_sort'] = mi.author_sort_map[aut] + except: + vals['author_sort'] = aut + link = formatter.safe_format( + config.get('default_author_link'), vals, '', vals) + if link: + authors.append(u'%s'%(urllib2.quote(link), aut)) else: authors.append(aut) ans.append((field, u'%s%s'%(name, diff --git a/src/calibre/gui2/dialogs/restore_library.py b/src/calibre/gui2/dialogs/restore_library.py index a57d6c86c1..60b224d1cd 100644 --- a/src/calibre/gui2/dialogs/restore_library.py +++ b/src/calibre/gui2/dialogs/restore_library.py @@ -54,7 +54,7 @@ class DBRestore(QDialog): def reject(self): self.rejected = True self.restorer.progress_callback = lambda x, y: x - QDialog.rejecet(self) + QDialog.reject(self) def update(self): if self.restorer.is_alive(): diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index a2850679f1..841193373b 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -138,6 +138,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) + r('default_author_link', config) choices = set([k for k in db.field_metadata.all_field_keys() if db.field_metadata[k]['is_category'] and diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui index cc9133a36f..8dadfe3424 100644 --- a/src/calibre/gui2/preferences/look_feel.ui +++ b/src/calibre/gui2/preferences/look_feel.ui @@ -192,7 +192,7 @@ Book Details - + Select displayed metadata @@ -243,6 +243,28 @@ + + + + + + Default author link template: + + +

Enter a template that will be used to create a link for +an author in the books information dialog. Used when no link has been +provided for the author in Manage Authors.

+
+ + opt_default_author_link + +
+
+ + + +
+
@@ -253,7 +275,7 @@ - + Note that <b>comments</b> will always be displayed at the end, regardless of the position you assign here. diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index 1fad4eb9a3..c878630234 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -136,7 +136,7 @@ class TagsView(QTreeView): # {{{ return expanded_categories, state_map def reread_collapse_parameters(self): - self._model.reread_collapse_parameters(self.get_state()[1]) + self._model.reread_collapse_model(self.get_state()) def set_database(self, db, tag_match, sort_by): self._model.set_database(db) diff --git a/src/calibre/library/restore.py b/src/calibre/library/restore.py index 8bd7174849..4fab2edbd6 100644 --- a/src/calibre/library/restore.py +++ b/src/calibre/library/restore.py @@ -53,6 +53,7 @@ class Restore(Thread): self.mismatched_dirs = [] self.successes = 0 self.tb = None + self.authors_links = {} @property def errors_occurred(self): @@ -160,6 +161,12 @@ class Restore(Thread): else: self.mismatched_dirs.append(dirpath) + alm = mi.get('author_link_map', {}) + for author, link in alm.iteritems(): + existing_link, timestamp = self.authors_links.get(author, (None, None)) + if existing_link is None or existing_link != link and timestamp < mi.timestamp: + self.authors_links[author] = (link, mi.timestamp) + def create_cc_metadata(self): self.books.sort(key=itemgetter('timestamp')) self.custom_columns = {} @@ -206,6 +213,11 @@ class Restore(Thread): self.failed_restores.append((book, traceback.format_exc())) self.progress_callback(book['mi'].title, i+1) + for author in self.authors_links.iterkeys(): + link, ign = self.authors_links[author] + db.conn.execute('UPDATE authors SET link=? WHERE name=?', + (link, author.replace(',', '|'))) + db.conn.commit() db.conn.close() def restore_book(self, book, db): diff --git a/src/calibre/library/schema_upgrades.py b/src/calibre/library/schema_upgrades.py index 3c64785178..2907e43098 100644 --- a/src/calibre/library/schema_upgrades.py +++ b/src/calibre/library/schema_upgrades.py @@ -606,7 +606,7 @@ class SchemaUpgrade(object): ''' script = ''' - ALTER TABLE authors ADD COLUMN link TEXT NON NULL DEFAULT ""; + ALTER TABLE authors ADD COLUMN link TEXT NOT NULL DEFAULT ""; ''' self.conn.executescript(script)