Conversion: Insert metadata as jacket: Allow adding timestamp and publisher fields. Also allow controlling the formatting of date/time fields.

This commit is contained in:
Kovid Goyal 2021-07-11 08:49:53 +05:30
parent 728dd1f9f0
commit 2f4f786688
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 43 additions and 12 deletions

View File

@ -20,6 +20,10 @@
<td class="cbj_author" colspan="2">{author}</td> <td class="cbj_author" colspan="2">{author}</td>
</tr> </tr>
<tr> <tr>
<!-- When formatting dates you can specify the type of formatting, for example
{pubdate.yyyy} while show only the publication year, and, {pubdate.dd MMM yyyy}
will show the day, month and year. For the full list of supported formatting codes
see the documentation of "Control how dates are displayed" in Preferences->Tweaks -->
<td class="cbj_pubdata" colspan="2">{publisher} ({pubdate})</td> <td class="cbj_pubdata" colspan="2">{publisher} ({pubdate})</td>
</tr> </tr>

View File

@ -9,10 +9,11 @@ __docformat__ = 'restructuredtext en'
import os import os
import re import re
import sys import sys
from contextlib import suppress
from string import Formatter from string import Formatter
from xml.sax.saxutils import escape 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.constants import iswindows
from calibre.ebooks.chardet import strip_encoding_declarations from calibre.ebooks.chardet import strip_encoding_declarations
from calibre.ebooks.metadata import fmt_sidx, rating_to_stars 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 XHTML, XHTML_NS, XPath, urldefrag, urlnormalize, xml2text
) )
from calibre.library.comments import comments_to_html, markdown 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 calibre.utils.icu import sort_key
from polyglot.builtins import map, unicode_type from polyglot.builtins import map, unicode_type
@ -196,6 +198,27 @@ class Series(unicode_type):
return s 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): class Tags(unicode_type):
def __new__(self, tags, output_profile): def __new__(self, tags, output_profile):
@ -281,14 +304,13 @@ def render_jacket(mi, output_profile,
publisher = '' publisher = ''
publisher = escape(publisher) publisher = escape(publisher)
try: pubdate = timestamp = None
if is_date_undefined(mi.pubdate): with suppress(Exception):
pubdate = '' if not is_date_undefined(mi.pubdate):
else: pubdate = mi.pubdate
dt = as_local_time(mi.pubdate) with suppress(Exception):
pubdate = strftime('%Y', dt.timetuple()) if not is_date_undefined(mi.timestamp):
except: timestamp = mi.timestamp
pubdate = ''
rating = get_rating(mi.rating, output_profile.ratings_char, output_profile.empty_ratings_char) 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, css=css,
title=title, title=title,
author=author, author=author,
publisher=publisher, publisher=publisher, publisher_label=_('Publisher'),
pubdate_label=_('Published'), pubdate=pubdate, pubdate_label=_('Published'), pubdate=Timestamp(pubdate, tweaks['gui_pubdate_display_format']),
series_label=ngettext('Series', 'Series', 1), series=series, series_label=ngettext('Series', 'Series', 1), series=series,
rating_label=_('Rating'), rating=rating, rating_label=_('Rating'), rating=rating,
tags_label=_('Tags'), tags=tags, tags_label=_('Tags'), tags=tags,
timestamp=Timestamp(timestamp, tweaks['gui_timestamp_display_format']), timestamp_label=_('Date'),
comments=comments, comments=comments,
footer='', footer='',
display=display, display=display,
@ -338,6 +361,8 @@ def render_jacket(mi, output_profile,
args[dkey] = Series(mi.get(key), mi.get(key + '_index')) args[dkey] = Series(mi.get(key), mi.get(key + '_index'))
elif dt == 'rating': elif dt == 'rating':
args[dkey] = rating_to_stars(mi.get(key), m.get('display', {}).get('allow_half_stars', False)) 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': elif dt == 'comments':
val = val or '' val = val or ''
ctype = m.get('display', {}).get('interpret_as') or 'html' 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['tags'] = bool(tags)
has_data['rating'] = bool(rating) has_data['rating'] = bool(rating)
has_data['pubdate'] = bool(pubdate) has_data['pubdate'] = bool(pubdate)
has_data['timestamp'] = bool(timestamp)
has_data['publisher'] = bool(publisher)
for k, v in has_data.items(): for k, v in has_data.items():
setattr(display, k, 'initial' if v else 'none') setattr(display, k, 'initial' if v else 'none')
display.title = 'initial' display.title = 'initial'