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)