diff --git a/src/calibre/ebooks/metadata/epub.py b/src/calibre/ebooks/metadata/epub.py index a8c2105c02..360869cc9c 100644 --- a/src/calibre/ebooks/metadata/epub.py +++ b/src/calibre/ebooks/metadata/epub.py @@ -106,9 +106,11 @@ class CoverRenderer(QObject): WIDTH = 600 HEIGHT = 800 - def __init__(self, url, size, loop): + def __init__(self, path): + if QApplication.instance() is None: + QApplication([]) QObject.__init__(self) - self.loop = loop + self.loop = QEventLoop() self.page = QWebPage() pal = self.page.palette() pal.setBrush(QPalette.Background, Qt.white) @@ -117,33 +119,43 @@ class CoverRenderer(QObject): self.page.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) self.page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) QObject.connect(self.page, SIGNAL('loadFinished(bool)'), self.render_html) - self.image_data = None + self._image_data = None self.rendered = False + url = QUrl.fromLocalFile(os.path.normpath(path)) self.page.mainFrame().load(url) def render_html(self, ok): - self.rendered = True try: if not ok: + self.rendered = True return - #size = self.page.mainFrame().contentsSize() - #width, height = fit_image(size.width(), size.height(), self.WIDTH, self.HEIGHT)[1:] - #self.page.setViewportSize(QSize(width, height)) image = QImage(self.page.viewportSize(), QImage.Format_ARGB32) image.setDotsPerMeterX(96*(100/2.54)) image.setDotsPerMeterY(96*(100/2.54)) painter = QPainter(image) self.page.mainFrame().render(painter) painter.end() - ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) image.save(buf, 'JPEG') - self.image_data = str(ba.data()) + self._image_data = str(ba.data()) finally: self.loop.exit(0) - + self.rendered = True + + def image_data(): + def fget(self): + if not self.rendered: + self.loop.exec_() + count = 0 + while count < 50 and not self.rendered: + time.sleep(0.1) + count += 1 + return self._image_data + return property(fget=fget) + image_data = image_data() + def get_cover(opf, opf_path, stream): spine = list(opf.spine_items()) @@ -155,20 +167,11 @@ def get_cover(opf, opf_path, stream): stream.seek(0) ZipFile(stream).extractall() opf_path = opf_path.replace('/', os.sep) - cpage = os.path.join(tdir, os.path.dirname(opf_path), *cpage.split('/')) + cpage = os.path.join(tdir, os.path.dirname(opf_path), cpage) if not os.path.exists(cpage): return - if QApplication.instance() is None: - QApplication([]) - url = QUrl.fromLocalFile(cpage) - loop = QEventLoop() - cr = CoverRenderer(url, os.stat(cpage).st_size, loop) - loop.exec_() - count = 0 - while count < 50 and not cr.rendered: - time.sleep(0.1) - count += 1 - return cr.image_data + cr = CoverRenderer(cpage) + return cr.image_data def get_metadata(stream, extract_cover=True): """ Return metadata as a :class:`MetaInformation` object """ diff --git a/src/calibre/ebooks/oeb/base.py b/src/calibre/ebooks/oeb/base.py index 927592ac0e..8b505ae4aa 100644 --- a/src/calibre/ebooks/oeb/base.py +++ b/src/calibre/ebooks/oeb/base.py @@ -23,6 +23,8 @@ from calibre import LoggingInterface from calibre.translations.dynamic import translate from calibre.startup import get_lang from calibre.ebooks.oeb.entitydefs import ENTITYDEFS +from calibre.ebooks.metadata.epub import CoverRenderer +from calibre.ptempfile import TemporaryDirectory XML_NS = 'http://www.w3.org/XML/1998/namespace' XHTML_NS = 'http://www.w3.org/1999/xhtml' @@ -798,7 +800,6 @@ class TOC(object): class OEBBook(object): COVER_SVG_XP = XPath('h:body//svg:svg[position() = 1]') COVER_OBJECT_XP = XPath('h:body//h:object[@data][position() = 1]') - COVER_IMG_XP = XPath('h:body//h:img[@src][position() = 1]') def __init__(self, opfpath=None, container=None, encoding=None, logger=FauxLogger()): @@ -1055,6 +1056,17 @@ class OEBBook(object): if self._toc_from_html(opf): return self._toc_from_spine(opf) + def _cover_from_html(self, hcover): + with TemporaryDirectory('_html_cover') as tdir: + writer = DirWriter() + writer.dump(self, tdir) + path = os.path.join(tdir, hcover.href) + renderer = CoverRenderer(path) + data = renderer.image_data + id, href = self.manifest.generate('cover', 'cover.jpeg') + item = self.manifest.add(id, href, JPEG_MIME, data=data) + return item + def _locate_cover_image(self): if self.metadata.cover: id = str(self.metadata.cover[0]) @@ -1088,18 +1100,10 @@ class OEBBook(object): item = self.manifest.hrefs.get(href, None) if item is not None and item.media_type in OEB_IMAGES: return item - if self.COVER_IMG_XP(html): - img = self.COVER_IMG_XP(html)[0] - href = hcover.abshref(img.get('src')) - item = self.manifest.hrefs.get(href, None) - if item is not None and item.media_type in OEB_IMAGES: - return item - return None + return self._cover_from_html(hcover) def _ensure_cover_image(self): cover = self._locate_cover_image() - if not cover: - return if self.metadata.cover: self.metadata.cover[0].value = cover.id return