mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from trunk
This commit is contained in:
commit
4b64056e5b
@ -1,5 +1,6 @@
|
|||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
import re
|
import re
|
||||||
|
from datetime import date, timedelta
|
||||||
|
|
||||||
class HBR(BasicNewsRecipe):
|
class HBR(BasicNewsRecipe):
|
||||||
|
|
||||||
@ -12,13 +13,14 @@ class HBR(BasicNewsRecipe):
|
|||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
|
|
||||||
LOGIN_URL = 'http://hbr.org/login?request_url=/'
|
LOGIN_URL = 'http://hbr.org/login?request_url=/'
|
||||||
INDEX = 'http://hbr.org/current'
|
INDEX = 'http://hbr.org/archive-toc/BR'
|
||||||
|
|
||||||
keep_only_tags = [dict(name='div', id='pageContainer')]
|
keep_only_tags = [dict(name='div', id='pageContainer')]
|
||||||
remove_tags = [dict(id=['mastheadContainer', 'magazineHeadline',
|
remove_tags = [dict(id=['mastheadContainer', 'magazineHeadline',
|
||||||
'articleToolbarTopRD', 'pageRightSubColumn', 'pageRightColumn',
|
'articleToolbarTopRD', 'pageRightSubColumn', 'pageRightColumn',
|
||||||
'todayOnHBRListWidget', 'mostWidget', 'keepUpWithHBR',
|
'todayOnHBRListWidget', 'mostWidget', 'keepUpWithHBR',
|
||||||
'mailingListTout', 'partnerCenter', 'pageFooter',
|
'mailingListTout', 'partnerCenter', 'pageFooter',
|
||||||
|
'superNavHeadContainer', 'hbrDisqus',
|
||||||
'articleToolbarTop', 'articleToolbarBottom', 'articleToolbarRD']),
|
'articleToolbarTop', 'articleToolbarBottom', 'articleToolbarRD']),
|
||||||
dict(name='iframe')]
|
dict(name='iframe')]
|
||||||
extra_css = '''
|
extra_css = '''
|
||||||
@ -55,9 +57,14 @@ class HBR(BasicNewsRecipe):
|
|||||||
|
|
||||||
|
|
||||||
def hbr_get_toc(self):
|
def hbr_get_toc(self):
|
||||||
soup = self.index_to_soup(self.INDEX)
|
today = date.today()
|
||||||
url = soup.find('a', text=lambda t:'Full Table of Contents' in t).parent.get('href')
|
future = today + timedelta(days=30)
|
||||||
return self.index_to_soup('http://hbr.org'+url)
|
for x in [x.strftime('%y%m') for x in (future, today)]:
|
||||||
|
url = self.INDEX + x
|
||||||
|
soup = self.index_to_soup(url)
|
||||||
|
if not soup.find(text='Issue Not Found'):
|
||||||
|
return soup
|
||||||
|
raise Exception('Could not find current issue')
|
||||||
|
|
||||||
def hbr_parse_section(self, container, feeds):
|
def hbr_parse_section(self, container, feeds):
|
||||||
current_section = None
|
current_section = None
|
||||||
|
@ -474,20 +474,13 @@ def serialize_user_metadata(metadata_elem, all_user_metadata, tail='\n'+(' '*8))
|
|||||||
metadata_elem.append(meta)
|
metadata_elem.append(meta)
|
||||||
|
|
||||||
|
|
||||||
def dump_user_categories(cats):
|
def dump_dict(cats):
|
||||||
if not cats:
|
if not cats:
|
||||||
cats = {}
|
cats = {}
|
||||||
from calibre.ebooks.metadata.book.json_codec import object_to_unicode
|
from calibre.ebooks.metadata.book.json_codec import object_to_unicode
|
||||||
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'
|
||||||
@ -544,9 +537,9 @@ class OPF(object): # {{{
|
|||||||
formatter=parse_date, renderer=isoformat)
|
formatter=parse_date, renderer=isoformat)
|
||||||
user_categories = MetadataField('user_categories', is_dc=False,
|
user_categories = MetadataField('user_categories', is_dc=False,
|
||||||
formatter=json.loads,
|
formatter=json.loads,
|
||||||
renderer=dump_user_categories)
|
renderer=dump_dict)
|
||||||
author_link_map = MetadataField('author_link_map', is_dc=False,
|
author_link_map = MetadataField('author_link_map', is_dc=False,
|
||||||
formatter=json.loads, renderer=dump_author_links)
|
formatter=json.loads, renderer=dump_dict)
|
||||||
|
|
||||||
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):
|
||||||
@ -1345,7 +1338,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', dump_author_links(mi.author_link_map))
|
meta('author_link_map', dump_dict(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:
|
||||||
@ -1359,7 +1352,7 @@ def metadata_to_opf(mi, as_string=True):
|
|||||||
if mi.title_sort:
|
if mi.title_sort:
|
||||||
meta('title_sort', mi.title_sort)
|
meta('title_sort', mi.title_sort)
|
||||||
if mi.user_categories:
|
if mi.user_categories:
|
||||||
meta('user_categories', dump_user_categories(mi.user_categories))
|
meta('user_categories', dump_dict(mi.user_categories))
|
||||||
|
|
||||||
serialize_user_metadata(metadata, mi.get_all_user_metadata(False))
|
serialize_user_metadata(metadata, mi.get_all_user_metadata(False))
|
||||||
|
|
||||||
|
@ -83,13 +83,14 @@ gprefs.defaults['tags_browser_partition_method'] = 'first letter'
|
|||||||
gprefs.defaults['tags_browser_collapse_at'] = 100
|
gprefs.defaults['tags_browser_collapse_at'] = 100
|
||||||
gprefs.defaults['edit_metadata_single_layout'] = 'default'
|
gprefs.defaults['edit_metadata_single_layout'] = 'default'
|
||||||
gprefs.defaults['book_display_fields'] = [
|
gprefs.defaults['book_display_fields'] = [
|
||||||
('title', False), ('authors', False), ('formats', True),
|
('title', False), ('authors', True), ('formats', True),
|
||||||
('series', True), ('identifiers', True), ('tags', True),
|
('series', True), ('identifiers', True), ('tags', True),
|
||||||
('path', True), ('publisher', False), ('rating', False),
|
('path', True), ('publisher', False), ('rating', False),
|
||||||
('author_sort', False), ('sort', False), ('timestamp', False),
|
('author_sort', False), ('sort', False), ('timestamp', False),
|
||||||
('uuid', False), ('comments', True), ('id', False), ('pubdate', False),
|
('uuid', False), ('comments', True), ('id', False), ('pubdate', False),
|
||||||
('last_modified', False), ('size', False),
|
('last_modified', False), ('size', False),
|
||||||
]
|
]
|
||||||
|
gprefs.defaults['default_author_link'] = 'http://en.wikipedia.org/w/index.php?search={author}'
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
@ -181,14 +182,6 @@ 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
|
||||||
|
@ -129,14 +129,14 @@ def render_data(mi, use_roman_numbers=True, all_fields=False):
|
|||||||
for aut in mi.authors:
|
for aut in mi.authors:
|
||||||
if mi.author_link_map[aut]:
|
if mi.author_link_map[aut]:
|
||||||
link = mi.author_link_map[aut]
|
link = mi.author_link_map[aut]
|
||||||
elif config.get('default_author_link'):
|
elif gprefs.get('default_author_link'):
|
||||||
vals = {'author': aut}
|
vals = {'author': aut}
|
||||||
try:
|
try:
|
||||||
vals['author_sort'] = mi.author_sort_map[aut]
|
vals['author_sort'] = mi.author_sort_map[aut]
|
||||||
except:
|
except:
|
||||||
vals['author_sort'] = aut
|
vals['author_sort'] = aut
|
||||||
link = formatter.safe_format(
|
link = formatter.safe_format(
|
||||||
config.get('default_author_link'), vals, '', vals)
|
gprefs.get('default_author_link'), vals, '', vals)
|
||||||
if link:
|
if link:
|
||||||
authors.append(u'<a href="%s">%s</a>'%(urllib2.quote(link), aut))
|
authors.append(u'<a href="%s">%s</a>'%(urllib2.quote(link), aut))
|
||||||
else:
|
else:
|
||||||
|
@ -90,7 +90,6 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
self.ids_to_highlight_set = set()
|
self.ids_to_highlight_set = set()
|
||||||
self.current_highlighted_idx = None
|
self.current_highlighted_idx = None
|
||||||
self.highlight_only = False
|
self.highlight_only = False
|
||||||
self.current_row = -1
|
|
||||||
self.colors = frozenset([unicode(c) for c in QColor.colorNames()])
|
self.colors = frozenset([unicode(c) for c in QColor.colorNames()])
|
||||||
self.formatter = SafeFormat()
|
self.formatter = SafeFormat()
|
||||||
self.read_config()
|
self.read_config()
|
||||||
@ -174,7 +173,6 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
self.color_cache = defaultdict(dict)
|
self.color_cache = defaultdict(dict)
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if row == current_row:
|
if row == current_row:
|
||||||
self.current_row = row
|
|
||||||
self.new_bookdisplay_data.emit(
|
self.new_bookdisplay_data.emit(
|
||||||
self.get_book_display_info(row))
|
self.get_book_display_info(row))
|
||||||
self.dataChanged.emit(self.index(row, 0), self.index(row,
|
self.dataChanged.emit(self.index(row, 0), self.index(row,
|
||||||
@ -332,8 +330,6 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
def refresh(self, reset=True):
|
def refresh(self, reset=True):
|
||||||
self.db.refresh(field=None)
|
self.db.refresh(field=None)
|
||||||
self.resort(reset=reset)
|
self.resort(reset=reset)
|
||||||
if self.current_row >= 0:
|
|
||||||
self.new_bookdisplay_data.emit(self.get_book_display_info(self.current_row))
|
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.color_cache = defaultdict(dict)
|
self.color_cache = defaultdict(dict)
|
||||||
@ -373,14 +369,12 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
|
|
||||||
def current_changed(self, current, previous, emit_signal=True):
|
def current_changed(self, current, previous, emit_signal=True):
|
||||||
if current.isValid():
|
if current.isValid():
|
||||||
self.current_row = idx = current.row()
|
idx = current.row()
|
||||||
data = self.get_book_display_info(idx)
|
data = self.get_book_display_info(idx)
|
||||||
if emit_signal:
|
if emit_signal:
|
||||||
self.new_bookdisplay_data.emit(data)
|
self.new_bookdisplay_data.emit(data)
|
||||||
else:
|
else:
|
||||||
return data
|
return data
|
||||||
else:
|
|
||||||
self.current_row = -1
|
|
||||||
|
|
||||||
def get_book_info(self, index):
|
def get_book_info(self, index):
|
||||||
if isinstance(index, int):
|
if isinstance(index, int):
|
||||||
|
@ -138,7 +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)
|
r('default_author_link', gprefs)
|
||||||
|
|
||||||
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
|
||||||
|
@ -246,7 +246,7 @@
|
|||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QHBoxLayout">
|
<layout class="QHBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Default author link template:</string>
|
<string>Default author link template:</string>
|
||||||
</property>
|
</property>
|
||||||
@ -256,7 +256,15 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="opt_default_author_link"/>
|
<widget class="QLineEdit" name="opt_default_author_link">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><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.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user