1
# -*- coding: utf-8 -*-
4
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
5
__docformat__ = 'restructuredtext en'
14
from calibre.ptempfile import PersistentTemporaryDirectory
15
from calibre.ebooks.pdf.pageoptions import unit, paper_size, \
17
from calibre.ebooks.metadata import authors_to_string
19
from PyQt4 import QtCore
20
from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, \
21
QApplication, QPrinter, QMetaObject, QSizeF, Qt
22
from PyQt4.QtWebKit import QWebView
24
from pyPdf import PdfFileWriter, PdfFileReader
26
class PDFMetadata(object):
27
def __init__(self, oeb_metadata=None):
28
self.title = _('Unknown')
29
self.author = _('Unknown')
31
if oeb_metadata != None:
32
if len(oeb_metadata.title) >= 1:
33
self.title = oeb_metadata.title[0].value
34
if len(oeb_metadata.creator) >= 1:
35
self.author = authors_to_string([x.value for x in oeb_metadata.creator])
38
class PDFWriter(QObject):
39
def __init__(self, opts, log):
40
if QApplication.instance() is None:
42
QObject.__init__(self)
46
self.loop = QEventLoop()
47
self.view = QWebView()
48
self.connect(self.view, SIGNAL('loadFinished(bool)'), self._render_html)
49
self.render_queue = []
50
self.combine_queue = []
51
self.tmp_path = PersistentTemporaryDirectory('_pdf_output_parts')
53
self.custom_size = None
54
if opts.custom_size != None:
55
width, sep, height = opts.custom_size.partition('x')
60
self.custom_size = (width, height)
62
self.custom_size = None
66
self.size = self._size()
68
def dump(self, items, out_stream, pdf_metadata):
69
self.metadata = pdf_metadata
72
self.render_queue = items
73
self.combine_queue = []
74
self.out_stream = out_stream
76
QMetaObject.invokeMethod(self, "_render_book", Qt.QueuedConnection)
81
The size of a pdf page in cm.
83
printer = QPrinter(QPrinter.HighResolution)
85
if self.opts.output_profile.short_name == 'default':
86
if self.custom_size == None:
87
printer.setPaperSize(paper_size(self.opts.paper_size))
89
printer.setPaperSize(QSizeF(self.custom_size[0], self.custom_size[1]), unit(self.opts.unit))
91
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)
93
printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
94
printer.setOrientation(orientation(self.opts.orientation))
95
printer.setOutputFormat(QPrinter.PdfFormat)
97
size = printer.paperSize(QPrinter.Millimeter)
99
return size.width() / 10, size.height() / 10
101
@QtCore.pyqtSignature('_render_book()')
102
def _render_book(self):
103
if len(self.render_queue) == 0:
108
def _render_next(self):
109
item = str(self.render_queue.pop(0))
110
self.combine_queue.append(os.path.join(self.tmp_path, '%i.pdf' % (len(self.combine_queue) + 1)))
112
self.logger.debug('Processing %s...' % item)
114
self.view.load(QUrl(item))
116
def _render_html(self, ok):
118
item_path = os.path.join(self.tmp_path, '%i.pdf' % len(self.combine_queue))
120
self.logger.debug('\tRendering item %s as %i' % (os.path.basename(str(self.view.url().toLocalFile())), len(self.combine_queue)))
122
printer = QPrinter(QPrinter.HighResolution)
123
printer.setPaperSize(QSizeF(self.size[0] * 10, self.size[1] * 10), QPrinter.Millimeter)
124
printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
125
printer.setOrientation(orientation(self.opts.orientation))
126
printer.setOutputFormat(QPrinter.PdfFormat)
127
printer.setOutputFileName(item_path)
128
self.view.print_(printer)
131
def _delete_tmpdir(self):
132
if os.path.exists(self.tmp_path):
133
shutil.rmtree(self.tmp_path, True)
134
self.tmp_path = PersistentTemporaryDirectory('_pdf_output_parts')
137
self.logger.debug('Combining individual PDF parts...')
140
outPDF = PdfFileWriter(title=self.metadata.title, author=self.metadata.author)
141
for item in self.combine_queue:
142
inputPDF = PdfFileReader(open(item, 'rb'))
143
for page in inputPDF.pages:
145
outPDF.write(self.out_stream)
147
self._delete_tmpdir()
151
class ImagePDFWriter(PDFWriter):
153
def _render_next(self):
154
item = str(self.render_queue.pop(0))
155
self.combine_queue.append(os.path.join(self.tmp_path, '%i.pdf' % (len(self.combine_queue) + 1)))
157
self.logger.debug('Processing %s...' % item)
159
height = 'height: %fcm;' % (self.size[1] * 1.3)
161
html = '<html><body style="margin: 0;"><img src="%s" style="%s display: block; margin-left: auto; margin-right: auto; padding: 0px;" /></body></html>' % (item, height)
163
self.view.setHtml(html)
166
printer = QPrinter(QPrinter.HighResolution)
168
if self.opts.output_profile.short_name == 'default':
169
if self.custom_size == None:
170
printer.setPaperSize(paper_size(self.opts.paper_size))
172
printer.setPaperSize(QSizeF(self.custom_size[0], self.custom_size[1]), unit(self.opts.unit))
174
printer.setPaperSize(QSizeF(self.opts.output_profile.comic_screen_size[0] / self.opts.output_profile.dpi, self.opts.output_profile.comic_screen_size[1] / self.opts.output_profile.dpi), QPrinter.Inch)
176
printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
177
printer.setOrientation(orientation(self.opts.orientation))
178
printer.setOutputFormat(QPrinter.PdfFormat)
180
size = printer.paperSize(QPrinter.Millimeter)
182
return size.width() / 10, size.height() / 10