diff --git a/resources/jacket/template.xhtml b/resources/jacket/template.xhtml index 9492965940..4751be2c67 100644 --- a/resources/jacket/template.xhtml +++ b/resources/jacket/template.xhtml @@ -20,6 +20,10 @@ {author} + {publisher} ({pubdate}) diff --git a/src/calibre/ebooks/oeb/transforms/jacket.py b/src/calibre/ebooks/oeb/transforms/jacket.py index f20953f3c6..49957b443b 100644 --- a/src/calibre/ebooks/oeb/transforms/jacket.py +++ b/src/calibre/ebooks/oeb/transforms/jacket.py @@ -9,10 +9,11 @@ __docformat__ = 'restructuredtext en' import os import re import sys +from contextlib import suppress from string import Formatter from xml.sax.saxutils import escape -from calibre import guess_type, prepare_string_for_xml, strftime +from calibre import guess_type, prepare_string_for_xml from calibre.constants import iswindows from calibre.ebooks.chardet import strip_encoding_declarations from calibre.ebooks.metadata import fmt_sidx, rating_to_stars @@ -21,7 +22,8 @@ from calibre.ebooks.oeb.base import ( XHTML, XHTML_NS, XPath, urldefrag, urlnormalize, xml2text ) from calibre.library.comments import comments_to_html, markdown -from calibre.utils.date import as_local_time, is_date_undefined +from calibre.utils.config import tweaks +from calibre.utils.date import as_local_time, format_date, is_date_undefined from calibre.utils.icu import sort_key from polyglot.builtins import map, unicode_type @@ -196,6 +198,27 @@ class Series(unicode_type): return s +class Timestamp: + + def __init__(self, dt, render_template): + self.dt = as_local_time(dt) + self.is_date_undefined = dt is None or is_date_undefined(dt) + self.default_render = '' if self.is_date_undefined else escape(format_date(self.dt, render_template)) + + def __repr__(self): + return self.default_render + __str__ = __repr__ + + def __bool__(self): + return bool(self.default_render) + + def __getattr__(self, template): + with suppress(Exception): + if not self.is_date_undefined: + return escape(format_date(self.dt, template)) + return '' + + class Tags(unicode_type): def __new__(self, tags, output_profile): @@ -281,14 +304,13 @@ def render_jacket(mi, output_profile, publisher = '' publisher = escape(publisher) - try: - if is_date_undefined(mi.pubdate): - pubdate = '' - else: - dt = as_local_time(mi.pubdate) - pubdate = strftime('%Y', dt.timetuple()) - except: - pubdate = '' + pubdate = timestamp = None + with suppress(Exception): + if not is_date_undefined(mi.pubdate): + pubdate = mi.pubdate + with suppress(Exception): + if not is_date_undefined(mi.timestamp): + timestamp = mi.timestamp rating = get_rating(mi.rating, output_profile.ratings_char, output_profile.empty_ratings_char) @@ -318,11 +340,12 @@ def render_jacket(mi, output_profile, css=css, title=title, author=author, - publisher=publisher, - pubdate_label=_('Published'), pubdate=pubdate, + publisher=publisher, publisher_label=_('Publisher'), + pubdate_label=_('Published'), pubdate=Timestamp(pubdate, tweaks['gui_pubdate_display_format']), series_label=ngettext('Series', 'Series', 1), series=series, rating_label=_('Rating'), rating=rating, tags_label=_('Tags'), tags=tags, + timestamp=Timestamp(timestamp, tweaks['gui_timestamp_display_format']), timestamp_label=_('Date'), comments=comments, footer='', display=display, @@ -338,6 +361,8 @@ def render_jacket(mi, output_profile, args[dkey] = Series(mi.get(key), mi.get(key + '_index')) elif dt == 'rating': args[dkey] = rating_to_stars(mi.get(key), m.get('display', {}).get('allow_half_stars', False)) + elif dt == 'datetime': + args[dkey] = Timestamp(mi.get(key), m.get('display', {}).get('date_format','dd MMM yyyy')) elif dt == 'comments': val = val or '' ctype = m.get('display', {}).get('interpret_as') or 'html' @@ -372,6 +397,8 @@ def render_jacket(mi, output_profile, has_data['tags'] = bool(tags) has_data['rating'] = bool(rating) has_data['pubdate'] = bool(pubdate) + has_data['timestamp'] = bool(timestamp) + has_data['publisher'] = bool(publisher) for k, v in has_data.items(): setattr(display, k, 'initial' if v else 'none') display.title = 'initial'