From 938fe0fa667254ff64bb6e20b2f6226a1b107570 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 4 Aug 2013 12:35:19 +0530 Subject: [PATCH] EPUB Input: Use raster cover metadata EPUB Input: If the EPUB file identifies an actual cover image in addition to the titlepage html file, use the cover image instead of rendering the titlepage. This is faster and has the advantage that an EPUB to EPUB conversion preserves internal cover structure. --- .../ebooks/conversion/plugins/epub_input.py | 41 ++++++++++++++----- src/calibre/ebooks/metadata/opf2.py | 4 +- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/calibre/ebooks/conversion/plugins/epub_input.py b/src/calibre/ebooks/conversion/plugins/epub_input.py index 5ccf00c643..b40f76a78e 100644 --- a/src/calibre/ebooks/conversion/plugins/epub_input.py +++ b/src/calibre/ebooks/conversion/plugins/epub_input.py @@ -75,6 +75,10 @@ class EPUBInput(InputFormatPlugin): return False def rationalize_cover(self, opf, log): + ''' Ensure that the cover information in the guide is correct. That + means, at most one entry with type="cover" that points to a raster + cover and at most one entry with type="titlepage" that points to an + HTML titlepage. ''' removed = None from lxml import etree guide_cover, guide_elem = None, None @@ -109,24 +113,41 @@ class EPUBInput(InputFormatPlugin): # display in the end spine[0].attrib.pop('linear', None) opf.spine[0].is_linear = True - guide_elem.set('href', 'calibre_raster_cover.jpg') + # Ensure that the guide has a cover entry pointing to a raster cover + # and a titlepage entry pointing to the html titlepage. The titlepage + # entry will be used by the epub output plugin, the raster cover entry + # by other output plugins. + from calibre.ebooks.oeb.base import OPF - t = etree.SubElement(elem[0].getparent(), OPF('item'), - href=guide_elem.get('href'), id='calibre_raster_cover') - t.set('media-type', 'image/jpeg') + + # Search for a raster cover identified in the OPF + raster_cover = opf.raster_cover + + # Set the cover guide entry + if raster_cover is not None: + guide_elem.set('href', raster_cover) + else: + # Render the titlepage to create a raster cover + from calibre.ebooks import render_html_svg_workaround + guide_elem.set('href', 'calibre_raster_cover.jpg') + t = etree.SubElement( + elem[0].getparent(), OPF('item'), href=guide_elem.get('href'), id='calibre_raster_cover') + t.set('media-type', 'image/jpeg') + if os.path.exists(guide_cover): + renderer = render_html_svg_workaround(guide_cover, log) + if renderer is not None: + open('calibre_raster_cover.jpg', 'wb').write( + renderer) + + # Set the titlepage guide entry for elem in list(opf.iterguide()): if elem.get('type', '').lower() == 'titlepage': elem.getparent().remove(elem) + t = etree.SubElement(guide_elem.getparent(), OPF('reference')) t.set('type', 'titlepage') t.set('href', guide_cover) t.set('title', 'Title Page') - from calibre.ebooks import render_html_svg_workaround - if os.path.exists(guide_cover): - renderer = render_html_svg_workaround(guide_cover, log) - if renderer is not None: - open('calibre_raster_cover.jpg', 'wb').write( - renderer) return removed def find_opf(self): diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 77e334dd3e..25d4855980 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -1083,12 +1083,12 @@ class OPF(object): # {{{ for item in self.itermanifest(): if item.get('id', None) == cover_id: mt = item.get('media-type', '') - if 'xml' not in mt: + if mt and 'xml' not in mt and 'html' not in mt: return item.get('href', None) for item in self.itermanifest(): if item.get('href', None) == cover_id: mt = item.get('media-type', '') - if mt.startswith('image/'): + if mt and mt.startswith('image/'): return item.get('href', None) @dynamic_property