diff --git a/src/calibre/ebooks/metadata/opf3.py b/src/calibre/ebooks/metadata/opf3.py
index fa805a8de4..bc0721eaa0 100644
--- a/src/calibre/ebooks/metadata/opf3.py
+++ b/src/calibre/ebooks/metadata/opf3.py
@@ -115,6 +115,9 @@ def simple_text(f):
def wrapper(*args, **kw):
return normalize_whitespace(f(*args, **kw))
return wrapper
+
+def items_with_property(root, q):
+ return XPath("./opf:manifest/opf:item[@properties and contains(concat(' ', normalize-space(@properties), ' '), ' %s ')]" % q)(root)
# }}}
# Prefixes {{{
@@ -782,6 +785,8 @@ def set_user_metadata(root, prefixes, refines, val):
# }}}
+# Reading/setting Metadata objects {{{
+
def read_metadata(root):
ans = Metadata(_('Unknown'), [_('Unknown')])
prefixes, refines = read_prefixes(root), read_refines(root)
@@ -911,6 +916,46 @@ def set_metadata(stream, mi, cover_prefix='', cover_data=None, apply_null=False,
root, mi, cover_prefix=cover_prefix, cover_data=cover_data,
apply_null=apply_null, update_timestamp=update_timestamp,
force_identifiers=force_identifiers)
+# }}}
+
+# Covers {{{
+
+def raster_cover(root):
+
+ def get_href(item):
+ mt = item.get('media-type')
+ if mt and 'xml' not in mt and 'html' not in mt:
+ href = item.get('href')
+ if href:
+ return href
+
+ for item in items_with_property(root, 'cover-image'):
+ href = get_href(item)
+ if href:
+ return href
+
+ for item_id in XPath('./opf:metadata/opf:meta[@name="cover"]/@content')(root):
+ for item in XPath('./opf:manifest/opf:item[@id and @href and @media-type]')(root):
+ if item.get('id') == item_id:
+ href = get_href(item)
+ if href:
+ return href
+
+def ensure_is_only_raster_cover(root, raster_cover_item_href):
+ refines = read_refines(root)
+ for item in XPath('./opf:metadata/opf:meta[@name="cover"]')(root):
+ remove_element(item, refines)
+ for item in items_with_property(root, 'cover-image'):
+ prop = normalize_whitespace(item.get('properties').replace('cover-image', ''))
+ if prop:
+ item.set('properties', prop)
+ else:
+ del item.attrib['properties']
+ for item in XPath('./opf:manifest/opf:item')(root):
+ if item.get('href') == raster_cover_item_href:
+ item.set('properties', normalize_whitespace((item.get('properties') or '') + ' cover-image'))
+
+# }}}
if __name__ == '__main__':
import sys
diff --git a/src/calibre/ebooks/metadata/opf3_test.py b/src/calibre/ebooks/metadata/opf3_test.py
index 5cd6cd8116..b6bc3d9688 100644
--- a/src/calibre/ebooks/metadata/opf3_test.py
+++ b/src/calibre/ebooks/metadata/opf3_test.py
@@ -22,22 +22,22 @@ from calibre.ebooks.metadata.opf3 import (
set_comments, read_publisher, set_publisher, read_tags, set_tags, read_rating,
set_rating, read_series, set_series, read_user_metadata, set_user_metadata,
read_author_link_map, read_user_categories, set_author_link_map, set_user_categories,
- apply_metadata
+ apply_metadata, raster_cover, ensure_is_only_raster_cover
)
# This import is needed to prevent a test from running slowly
from calibre.ebooks.oeb.polish.pretty import pretty_opf, pretty_xml_tree # noqa
read_author_link_map, read_user_categories, set_author_link_map, set_user_categories
-TEMPLATE = '''{metadata}''' % CALIBRE_PREFIX # noqa
+TEMPLATE = '''{metadata}{manifest}''' % CALIBRE_PREFIX # noqa
default_refines = defaultdict(list)
class TestOPF3(unittest.TestCase):
ae = unittest.TestCase.assertEqual
- def get_opf(self, metadata=''):
- return etree.fromstring(TEMPLATE.format(metadata=metadata))
+ def get_opf(self, metadata='', manifest=''):
+ return etree.fromstring(TEMPLATE.format(metadata=metadata, manifest=manifest))
def test_prefix_parsing(self): # {{{
self.ae(parse_prefixes('foaf: http://xmlns.com/foaf/spec/\n dbp: http://dbpedia.org/ontology/'),
@@ -205,6 +205,20 @@ class TestOPF3(unittest.TestCase):
self.ae('p', st(root, 'p '))
# }}}
+ def test_raster_cover(self): # {{{
+ def rt(root):
+ return raster_cover(root)
+ root = self.get_opf('', ' ')
+ self.ae('x.jpg', rt(root))
+ root = self.get_opf('',
+ ' ')
+ self.ae('y.jpg', rt(root))
+ ensure_is_only_raster_cover(root, 'x.jpg')
+ self.ae('x.jpg', rt(root))
+ self.ae(['x.jpg'], root.xpath('//*[@properties="cover-image"]/@href'))
+ self.assertFalse(root.xpath('//*[@name]'))
+ # }}}
+
def test_tags(self): # {{{
def rt(root):
return read_tags(root, read_prefixes(root), read_refines(root))