diff --git a/src/calibre/customize/conversion.py b/src/calibre/customize/conversion.py index c358986d18..7573dddeac 100644 --- a/src/calibre/customize/conversion.py +++ b/src/calibre/customize/conversion.py @@ -133,6 +133,14 @@ class InputFormatPlugin(Plugin): #: (option_name, recommended_value, recommendation_level) recommendations = set([]) + def get_images(self): + ''' + Return a list of absolute paths to the images, if this input plugin + represents an image collection. The list of images is in the same order + as the spine and the TOC. + ''' + raise NotImplementedError() + def convert(self, stream, options, file_ext, log, accelerators): ''' This method must be implemented in sub-classes. It must return diff --git a/src/calibre/ebooks/comic/input.py b/src/calibre/ebooks/comic/input.py index f6d6557ee4..82070bbc72 100755 --- a/src/calibre/ebooks/comic/input.py +++ b/src/calibre/ebooks/comic/input.py @@ -357,6 +357,9 @@ class ComicInput(InputFormatPlugin): thumbnail = None return new_pages + def get_images(self): + return self._images + def convert(self, stream, opts, file_ext, log, accelerators, progress=lambda p, m : m): from calibre.ebooks.metadata import MetaInformation @@ -401,6 +404,9 @@ class ComicInput(InputFormatPlugin): spine = [] for comic in comics: spine.extend(map(href, comic[2])) + self._images = [] + for comic in comics: + self._images.extend(comic[1]) opf.create_spine(spine) toc = TOC() if len(comics) == 1: diff --git a/src/calibre/ebooks/pdf/output.py b/src/calibre/ebooks/pdf/output.py index 20ba5028b0..7b8b0323ab 100644 --- a/src/calibre/ebooks/pdf/output.py +++ b/src/calibre/ebooks/pdf/output.py @@ -40,7 +40,7 @@ class PDFOutput(OutputFormatPlugin): OptionRecommendation(name='margin_right', recommended_value='1', level=OptionRecommendation.LOW, help=_('The right margin around the document.')), - + OptionRecommendation(name='unit', recommended_value='inch', level=OptionRecommendation.LOW, short_switch='u', choices=UNITS.keys(), help=_('The unit of measure. Default is inch. Choices ' @@ -58,15 +58,18 @@ class PDFOutput(OutputFormatPlugin): help=_('The orientation of the page. Default is portrait. Choices ' 'are %s' % ORIENTATIONS.keys())), ]) - + def convert(self, oeb_book, output_path, input_plugin, opts, log): + self.opts, self.log = opts, log + if input_plugin.is_image_collection: + self.convert_images(input_plugin.get_images()) with TemporaryDirectory('_pdf_out') as oebdir: OEBOutput(None).convert(oeb_book, oebdir, input_plugin, opts, log) opf = glob.glob(os.path.join(oebdir, '*.opf'))[0] writer = PDFWriter(log, opts) - + close = False if not hasattr(output_path, 'write'): close = True @@ -75,10 +78,10 @@ class PDFOutput(OutputFormatPlugin): out_stream = open(output_path, 'wb') else: out_stream = output_path - + out_stream.seek(0) out_stream.truncate() writer.dump(opf, out_stream, PDFMetadata(oeb_book.metadata)) - + if close: out_stream.close() diff --git a/src/calibre/ebooks/pdf/writer.py b/src/calibre/ebooks/pdf/writer.py index f91dae44fd..7a9973c6d7 100644 --- a/src/calibre/ebooks/pdf/writer.py +++ b/src/calibre/ebooks/pdf/writer.py @@ -9,12 +9,11 @@ __docformat__ = 'restructuredtext en' Write content to PDF. ''' -import os, shutil, sys +import os, shutil from calibre.ptempfile import PersistentTemporaryDirectory -from calibre.customize.profiles import OutputProfile from calibre.ebooks.pdf.pageoptions import unit, paper_size, \ - orientation, size + orientation, size from calibre.ebooks.metadata import authors_to_string from calibre.ebooks.metadata.opf2 import OPF @@ -24,12 +23,12 @@ from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, \ from PyQt4.QtWebKit import QWebView from pyPdf import PdfFileWriter, PdfFileReader - + class PDFMetadata(object): def __init__(self, oeb_metadata=None): self.title = _('Unknown') self.author = _('Unknown') - + if oeb_metadata != None: if len(oeb_metadata.title) >= 1: self.title = oeb_metadata.title[0].value @@ -42,16 +41,16 @@ class PDFWriter(QObject): if QApplication.instance() is None: QApplication([]) QObject.__init__(self) - + self.logger = log - + self.loop = QEventLoop() self.view = QWebView() self.connect(self.view, SIGNAL('loadFinished(bool)'), self._render_html) self.render_queue = [] self.combine_queue = [] self.tmp_path = PersistentTemporaryDirectory('_pdf_output_parts') - + self.custom_size = None if opts.custom_size != None: width, sep, height = opts.custom_size.partition('x') @@ -62,44 +61,44 @@ class PDFWriter(QObject): self.custom_size = (width, height) except: self.custom_size = None - + self.opts = opts - + def dump(self, opfpath, out_stream, pdf_metadata): self.metadata = pdf_metadata self._delete_tmpdir() - + opf = OPF(opfpath, os.path.dirname(opfpath)) self.render_queue = [i.path for i in opf.spine] self.combine_queue = [] self.out_stream = out_stream - + QMetaObject.invokeMethod(self, "_render_book", Qt.QueuedConnection) self.loop.exec_() - + @QtCore.pyqtSignature('_render_book()') def _render_book(self): if len(self.render_queue) == 0: self._write() else: self._render_next() - + def _render_next(self): item = str(self.render_queue.pop(0)) self.combine_queue.append(os.path.join(self.tmp_path, '%i.pdf' % (len(self.combine_queue) + 1))) - + self.logger.info('Processing %s...' % item) - + self.view.load(QUrl(item)) def _render_html(self, ok): if ok: item_path = os.path.join(self.tmp_path, '%i.pdf' % len(self.combine_queue)) - + self.logger.debug('\tRendering item %s as %i' % (os.path.basename(str(self.view.url().toLocalFile())), len(self.combine_queue))) - + printer = QPrinter(QPrinter.HighResolution) - + if self.opts.output_profile.short_name == 'default': if self.custom_size == None: printer.setPaperSize(paper_size(self.opts.paper_size)) @@ -107,7 +106,7 @@ class PDFWriter(QObject): printer.setPaperSize(QSizeF(self.custom_size[0], self.custom_size[1]), unit(self.opts.unit)) else: printer.setPaperSize(QSizeF(self.opts.output_profile.width / self.opts.output_profile.dpi, self.opts.output_profile.height / self.opts.output_profile.dpi), QPrinter.Inch) - + printer.setPageMargins(size(self.opts.margin_left), size(self.opts.margin_top), size(self.opts.margin_right), size(self.opts.margin_bottom), unit(self.opts.unit)) printer.setOrientation(orientation(self.opts.orientation)) printer.setOutputFormat(QPrinter.PdfFormat) @@ -122,7 +121,7 @@ class PDFWriter(QObject): def _write(self): self.logger.info('Combining individual PDF parts...') - + try: outPDF = PdfFileWriter(title=self.metadata.title, author=self.metadata.author) for item in self.combine_queue: