mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-21 22:40:44 -04:00
Commit to merge from trunk
This commit is contained in:
parent
4c3473d82c
commit
aceb4655f2
@ -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;
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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():
|
||||||
|
@ -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
|
||||||
|
@ -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 <b>comments</b> will always be displayed at the end, regardless of the position you assign here.</string>
|
<string>Note that <b>comments</b> will always be displayed at the end, regardless of the position you assign here.</string>
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user