diff --git a/src/calibre/ebooks/metadata/opf3.py b/src/calibre/ebooks/metadata/opf3.py index 963f30db0a..cc4d2e9eec 100644 --- a/src/calibre/ebooks/metadata/opf3.py +++ b/src/calibre/ebooks/metadata/opf3.py @@ -701,6 +701,14 @@ def read_rating(root, prefixes, refines): continue +def create_rating(root, prefixes, val): + ensure_prefix(root, prefixes, 'calibre', CALIBRE_PREFIX) + m = XPath('./opf:metadata')(root)[0] + d = m.makeelement(OPF('meta'), attrib={'property':'calibre:rating'}) + d.text = val + m.append(d) + + def set_rating(root, prefixes, refines, val): pq = '%s:rating' % CALIBRE_PREFIX for meta in XPath('./opf:metadata/opf:meta[@name="calibre:rating"]')(root): @@ -710,11 +718,7 @@ def set_rating(root, prefixes, refines, val): if prop.lower() == pq: remove_element(meta, refines) if val: - ensure_prefix(root, prefixes, 'calibre', CALIBRE_PREFIX) - m = XPath('./opf:metadata')(root)[0] - d = m.makeelement(OPF('meta'), attrib={'property':'calibre:rating'}) - d.text = '%.2g' % val - m.append(d) + create_rating(root, prefixes, '%.2g' % val) # }}} # Series {{{ @@ -745,17 +749,21 @@ def read_series(root, prefixes, refines): return None, series_index +def create_series(root, refines, series, series_index): + m = XPath('./opf:metadata')(root)[0] + d = m.makeelement(OPF('meta'), attrib={'property':'belongs-to-collection'}) + d.text = series + m.append(d) + set_refines(d, refines, refdef('collection-type', 'series'), refdef('group-position', series_index)) + + def set_series(root, prefixes, refines, series, series_index): for meta in XPath('./opf:metadata/opf:meta[@name="calibre:series" or @name="calibre:series_index"]')(root): remove_element(meta, refines) for meta in XPath('./opf:metadata/opf:meta[@property="belongs-to-collection"]')(root): remove_element(meta, refines) - m = XPath('./opf:metadata')(root)[0] if series: - d = m.makeelement(OPF('meta'), attrib={'property':'belongs-to-collection'}) - d.text = series - m.append(d) - set_refines(d, refines, refdef('collection-type', 'series'), refdef('group-position', '%.2g' % series_index)) + create_series(root, refines, series, '%.2g' % series_index) # }}} # User metadata {{{ diff --git a/src/calibre/ebooks/metadata/opf_2_to_3.py b/src/calibre/ebooks/metadata/opf_2_to_3.py index 3a48021199..17aa762c36 100644 --- a/src/calibre/ebooks/metadata/opf_2_to_3.py +++ b/src/calibre/ebooks/metadata/opf_2_to_3.py @@ -7,8 +7,8 @@ from __future__ import absolute_import, division, print_function, unicode_litera from lxml import etree from calibre.ebooks.metadata.opf3 import ( - DC, OPF, XPath, create_timestamp, ensure_id, parse_date, read_prefixes, - read_refines, refdef, remove_element, set_refines + DC, OPF, XPath, create_rating, create_series, create_timestamp, ensure_id, + parse_date, read_prefixes, read_refines, refdef, remove_element, set_refines ) from calibre.ebooks.metadata.utils import parse_opf, pretty_print_opf @@ -110,6 +110,35 @@ def upgrade_date(root, data): remove_element(date, data.refines) +def upgrade_rating(root, data): + rating = None + for meta in XPath('./opf:metadata/opf:meta[@name="calibre:rating"]')(root): + remove_element(meta, data.refines) + rating = meta.get('content') + if rating is not None: + create_rating(root, data.prefixes, rating) + + +def upgrade_series(root, data): + series, series_index = None, '1.0' + for meta in XPath('./opf:metadata/opf:meta[@name="calibre:series"]')(root): + remove_element(meta, data.refines) + series = meta.get('content') + for meta in XPath('./opf:metadata/opf:meta[@name="calibre:series_index"]')(root): + remove_element(meta, data.refines) + series_index = meta.get('content') + + if series: + create_series(root, data.refines, series, series_index) + + +def remove_invalid_attrs_in_dc_metadata(root, data): + for tag in XPath('//*[namespace-uri() = "{}"]'.format(DC('')[1:-1]))(root): + for k in tuple(tag.attrib): + if k != 'id': + del tag.attrib[k] + + def upgrade_metadata(root): data = Data() data.prefixes = read_prefixes(root) @@ -121,7 +150,10 @@ def upgrade_metadata(root): upgrade_authors(root, data) upgrade_timestamp(root, data) upgrade_date(root, data) + upgrade_rating(root, data) + upgrade_series(root, data) + remove_invalid_attrs_in_dc_metadata(root, data) pretty_print_opf(root)