Commit to merge from trunk

This commit is contained in:
Charles Haley 2011-06-28 19:43:14 +01:00
parent 4c3473d82c
commit aceb4655f2
10 changed files with 73 additions and 10 deletions

View File

@ -1,6 +1,7 @@
CREATE TABLE authors ( id INTEGER PRIMARY KEY, CREATE TABLE authors ( id INTEGER PRIMARY KEY,
name TEXT NOT NULL COLLATE NOCASE, name TEXT NOT NULL COLLATE NOCASE,
sort TEXT COLLATE NOCASE, sort TEXT COLLATE NOCASE,
link TEXT NOT NULL DEFAULT "",
UNIQUE(name) UNIQUE(name)
); );
CREATE TABLE books ( id INTEGER PRIMARY KEY AUTOINCREMENT, CREATE TABLE books ( id INTEGER PRIMARY KEY AUTOINCREMENT,
@ -545,4 +546,4 @@ CREATE TRIGGER series_update_trg
BEGIN BEGIN
UPDATE series SET sort=NEW.name WHERE id=NEW.id; UPDATE series SET sort=NEW.name WHERE id=NEW.id;
END; END;
pragma user_version=20; pragma user_version=21;

View File

@ -481,6 +481,13 @@ def dump_user_categories(cats):
return json.dumps(object_to_unicode(cats), ensure_ascii=False, return json.dumps(object_to_unicode(cats), ensure_ascii=False,
skipkeys=True) 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): # {{{ class OPF(object): # {{{
MIMETYPE = 'application/oebps-package+xml' MIMETYPE = 'application/oebps-package+xml'
@ -539,7 +546,7 @@ class OPF(object): # {{{
formatter=json.loads, formatter=json.loads,
renderer=dump_user_categories) renderer=dump_user_categories)
author_link_map = MetadataField('author_link_map', is_dc=False, 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, def __init__(self, stream, basedir=os.getcwdu(), unquote_urls=True,
populate_spine=True): populate_spine=True):
@ -1338,7 +1345,7 @@ def metadata_to_opf(mi, as_string=True):
factory(DC('subject'), tag) factory(DC('subject'), tag)
meta = lambda n, c: factory('meta', name='calibre:'+n, content=c) meta = lambda n, c: factory('meta', name='calibre:'+n, content=c)
if getattr(mi, 'author_link_map', None) is not None: 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: if mi.series:
meta('series', mi.series) meta('series', mi.series)
if mi.series_index is not None: if mi.series_index is not None:

View File

@ -181,6 +181,14 @@ def _config(): # {{{
help=_('Show the average rating per item indication in the tag browser')) help=_('Show the average rating per item indication in the tag browser'))
c.add_opt('disable_animations', default=False, c.add_opt('disable_animations', default=False,
help=_('Disable UI animations')) help=_('Disable UI animations'))
c.add_opt('default_author_link',
default='http://en.wikipedia.org/w/index.php?search={author}',
help='<p>' +
_('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.') + '</p>')
# This option is no longer used. It remains for compatibility with upgrades # This option is no longer used. It remains for compatibility with upgrades
# so the value can be migrated # so the value can be migrated

View File

@ -5,6 +5,7 @@ __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import urllib2
from PyQt4.Qt import (QPixmap, QSize, QWidget, Qt, pyqtSignal, QUrl, from PyQt4.Qt import (QPixmap, QSize, QWidget, Qt, pyqtSignal, QUrl,
QPropertyAnimation, QEasingCurve, QApplication, QFontInfo, 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, from calibre.gui2 import (config, open_local_file, open_url, pixmap_to_data,
gprefs) gprefs)
from calibre.utils.icu import sort_key from calibre.utils.icu import sort_key
from calibre.utils.formatter import EvalFormatter
def render_html(mi, css, vertical, widget, all_fields=False): # {{{ def render_html(mi, css, vertical, widget, all_fields=False): # {{{
table = render_data(mi, all_fields=all_fields, 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))) _('Ids')+':', links)))
elif field == 'authors' and not isdevice: elif field == 'authors' and not isdevice:
authors = [] authors = []
formatter = EvalFormatter()
for aut in mi.authors: for aut in mi.authors:
if mi.author_link_map[aut]: if mi.author_link_map[aut]:
authors.append(u'<a href="%s">%s</a>' % link = mi.author_link_map[aut]
(mi.author_link_map[aut], 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'<a href="%s">%s</a>'%(urllib2.quote(link), aut))
else: else:
authors.append(aut) authors.append(aut)
ans.append((field, u'<td class="title">%s</td><td>%s</td>'%(name, ans.append((field, u'<td class="title">%s</td><td>%s</td>'%(name,

View File

@ -54,7 +54,7 @@ class DBRestore(QDialog):
def reject(self): def reject(self):
self.rejected = True self.rejected = True
self.restorer.progress_callback = lambda x, y: x self.restorer.progress_callback = lambda x, y: x
QDialog.rejecet(self) QDialog.reject(self)
def update(self): def update(self):
if self.restorer.is_alive(): if self.restorer.is_alive():

View File

@ -138,6 +138,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
(_('Partitioned'), 'partition')] (_('Partitioned'), 'partition')]
r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_partition_method', gprefs, choices=choices)
r('tags_browser_collapse_at', gprefs) r('tags_browser_collapse_at', gprefs)
r('default_author_link', config)
choices = set([k for k in db.field_metadata.all_field_keys() choices = set([k for k in db.field_metadata.all_field_keys()
if db.field_metadata[k]['is_category'] and if db.field_metadata[k]['is_category'] and

View File

@ -192,7 +192,7 @@
<string>Book Details</string> <string>Book Details</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_12"> <layout class="QGridLayout" name="gridLayout_12">
<item row="0" column="0" rowspan="2"> <item row="1" column="0" rowspan="2">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
<string>Select displayed metadata</string> <string>Select displayed metadata</string>
@ -243,6 +243,28 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Default author link template:</string>
</property>
<property name="toolTip">
<string><p>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.</p></string>
</property>
<property name="buddy">
<cstring>opt_default_author_link</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="opt_default_author_link"/>
</item>
</layout>
</item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QCheckBox" name="opt_use_roman_numerals_for_series_number"> <widget class="QCheckBox" name="opt_use_roman_numerals_for_series_number">
<property name="text"> <property name="text">
@ -253,7 +275,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>Note that &lt;b&gt;comments&lt;/b&gt; will always be displayed at the end, regardless of the position you assign here.</string> <string>Note that &lt;b&gt;comments&lt;/b&gt; will always be displayed at the end, regardless of the position you assign here.</string>

View File

@ -136,7 +136,7 @@ class TagsView(QTreeView): # {{{
return expanded_categories, state_map return expanded_categories, state_map
def reread_collapse_parameters(self): 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): def set_database(self, db, tag_match, sort_by):
self._model.set_database(db) self._model.set_database(db)

View File

@ -53,6 +53,7 @@ class Restore(Thread):
self.mismatched_dirs = [] self.mismatched_dirs = []
self.successes = 0 self.successes = 0
self.tb = None self.tb = None
self.authors_links = {}
@property @property
def errors_occurred(self): def errors_occurred(self):
@ -160,6 +161,12 @@ class Restore(Thread):
else: else:
self.mismatched_dirs.append(dirpath) 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): def create_cc_metadata(self):
self.books.sort(key=itemgetter('timestamp')) self.books.sort(key=itemgetter('timestamp'))
self.custom_columns = {} self.custom_columns = {}
@ -206,6 +213,11 @@ class Restore(Thread):
self.failed_restores.append((book, traceback.format_exc())) self.failed_restores.append((book, traceback.format_exc()))
self.progress_callback(book['mi'].title, i+1) 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() db.conn.close()
def restore_book(self, book, db): def restore_book(self, book, db):

View File

@ -606,7 +606,7 @@ class SchemaUpgrade(object):
''' '''
script = ''' 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) self.conn.executescript(script)