home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1061 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  10.4 KB  |  275 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2009, John Schember <john@nachtimwald.com>'
  6. __docformat__ = 'restructuredtext en'
  7. import os
  8. import shutil
  9. from calibre.ptempfile import PersistentTemporaryDirectory
  10. from calibre.ebooks.pdf.pageoptions import unit, paper_size, orientation
  11. from calibre.ebooks.metadata import authors_to_string
  12. from calibre.ptempfile import PersistentTemporaryFile
  13. from calibre import __appname__, __version__, fit_image
  14. from PyQt4 import QtCore
  15. from PyQt4.Qt import QUrl, QEventLoop, QObject, QPrinter, QMetaObject, QSizeF, Qt, QPainter, QPixmap
  16. from PyQt4.QtWebKit import QWebView
  17. from pyPdf import PdfFileWriter, PdfFileReader
  18.  
  19. def get_pdf_printer():
  20.     return QPrinter(QPrinter.HighResolution)
  21.  
  22.  
  23. def get_custom_size(opts):
  24.     custom_size = None
  25.     if opts.custom_size != None:
  26.         (width, sep, height) = opts.custom_size.partition('x')
  27.         if height != '':
  28.             
  29.             try:
  30.                 width = int(width)
  31.                 height = int(height)
  32.                 custom_size = (width, height)
  33.             custom_size = None
  34.  
  35.         
  36.     
  37.     return custom_size
  38.  
  39.  
  40. def setup_printer(opts, for_comic = False):
  41.     is_ok_to_use_qt = is_ok_to_use_qt
  42.     import calibre.gui2
  43.     if not is_ok_to_use_qt():
  44.         raise Exception('Not OK to use Qt')
  45.     is_ok_to_use_qt()
  46.     printer = get_pdf_printer()
  47.     custom_size = get_custom_size(opts)
  48.     if opts.output_profile.short_name == 'default':
  49.         if custom_size is None:
  50.             printer.setPaperSize(paper_size(opts.paper_size))
  51.         else:
  52.             printer.setPaperSize(QSizeF(custom_size[0], custom_size[1]), unit(opts.unit))
  53.     elif for_comic:
  54.         pass
  55.     
  56.     w = opts.output_profile.width
  57.     h = None if for_comic else opts.output_profile.height
  58.     dpi = opts.output_profile.dpi
  59.     printer.setPaperSize(QSizeF(float(w) / dpi, float(h) / dpi), QPrinter.Inch)
  60.     printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
  61.     printer.setOrientation(orientation(opts.orientation))
  62.     printer.setOutputFormat(QPrinter.PdfFormat)
  63.     return printer
  64.  
  65.  
  66. def get_printer_page_size(opts, for_comic = False):
  67.     printer = setup_printer(opts, for_comic = for_comic)
  68.     size = printer.paperSize(QPrinter.Millimeter)
  69.     return (size.width() / 10, size.height() / 10)
  70.  
  71.  
  72. def draw_image_page(printer, painter, p, preserve_aspect_ratio = True):
  73.     page_rect = printer.pageRect()
  74.     if preserve_aspect_ratio:
  75.         aspect_ratio = float(p.width()) / p.height()
  76.         nw = page_rect.width()
  77.         nh = page_rect.height()
  78.         if aspect_ratio > 1:
  79.             nh = int(page_rect.width() / aspect_ratio)
  80.         else:
  81.             nw = page_rect.height() * aspect_ratio
  82.         (__, nnw, nnh) = fit_image(nw, nh, page_rect.width(), page_rect.height())
  83.         dx = int((page_rect.width() - nnw) / 2)
  84.         dy = int((page_rect.height() - nnh) / 2)
  85.         page_rect.moveTo(dx, dy)
  86.         page_rect.setHeight(nnh)
  87.         page_rect.setWidth(nnw)
  88.     
  89.     painter.drawPixmap(page_rect, p, p.rect())
  90.  
  91.  
  92. class PDFMetadata(object):
  93.     
  94.     def __init__(self, oeb_metadata = None):
  95.         self.title = _('Unknown')
  96.         self.author = _('Unknown')
  97.         if oeb_metadata != None:
  98.             if len(oeb_metadata.title) >= 1:
  99.                 self.title = oeb_metadata.title[0].value
  100.             
  101.             if len(oeb_metadata.creator) >= 1:
  102.                 self.author = []([ x.value for x in oeb_metadata.creator ])
  103.             
  104.         
  105.  
  106.  
  107.  
  108. class PDFWriter(QObject):
  109.     
  110.     def __init__(self, opts, log, cover_data = None):
  111.         is_ok_to_use_qt = is_ok_to_use_qt
  112.         import calibre.gui2
  113.         if not is_ok_to_use_qt():
  114.             raise Exception('Not OK to use Qt')
  115.         is_ok_to_use_qt()
  116.         QObject.__init__(self)
  117.         self.logger = log
  118.         self.loop = QEventLoop()
  119.         self.view = QWebView()
  120.         self.view.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform)
  121.         self.view.loadFinished.connect(self._render_html, type = Qt.QueuedConnection)
  122.         self.render_queue = []
  123.         self.combine_queue = []
  124.         self.tmp_path = PersistentTemporaryDirectory('_pdf_output_parts')
  125.         self.opts = opts
  126.         self.size = get_printer_page_size(opts)
  127.         self.cover_data = cover_data
  128.  
  129.     
  130.     def dump(self, items, out_stream, pdf_metadata):
  131.         self.metadata = pdf_metadata
  132.         self._delete_tmpdir()
  133.         self.render_queue = items
  134.         self.combine_queue = []
  135.         self.out_stream = out_stream
  136.         QMetaObject.invokeMethod(self, '_render_book', Qt.QueuedConnection)
  137.         self.loop.exec_()
  138.  
  139.     
  140.     def _render_book(self):
  141.         if len(self.render_queue) == 0:
  142.             self._write()
  143.         else:
  144.             self._render_next()
  145.  
  146.     _render_book = QtCore.pyqtSignature('_render_book()')(_render_book)
  147.     
  148.     def _render_next(self):
  149.         item = str(self.render_queue.pop(0))
  150.         self.combine_queue.append(os.path.join(self.tmp_path, '%i.pdf' % (len(self.combine_queue) + 1)))
  151.         self.logger.debug('Processing %s...' % item)
  152.         self.view.load(QUrl.fromLocalFile(item))
  153.  
  154.     
  155.     def get_printer(self, set_horz_margins = False):
  156.         printer = get_pdf_printer()
  157.         printer.setPaperSize(QSizeF(self.size[0] * 10, self.size[1] * 10), QPrinter.Millimeter)
  158.         if set_horz_margins:
  159.             printer.setPageMargins(0, self.opts.margin_top, 0, self.opts.margin_bottom, QPrinter.Point)
  160.         else:
  161.             printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
  162.         printer.setOrientation(orientation(self.opts.orientation))
  163.         printer.setOutputFormat(QPrinter.PdfFormat)
  164.         printer.setFullPage(not set_horz_margins)
  165.         return printer
  166.  
  167.     
  168.     def _render_html(self, ok):
  169.         if ok:
  170.             item_path = os.path.join(self.tmp_path, '%i.pdf' % len(self.combine_queue))
  171.             self.logger.debug('\tRendering item %s as %i' % (os.path.basename(str(self.view.url().toLocalFile())), len(self.combine_queue)))
  172.             printer = self.get_printer(set_horz_margins = True)
  173.             printer.setOutputFileName(item_path)
  174.             self.view.print_(printer)
  175.         
  176.         self._render_book()
  177.  
  178.     
  179.     def _delete_tmpdir(self):
  180.         if os.path.exists(self.tmp_path):
  181.             shutil.rmtree(self.tmp_path, True)
  182.             self.tmp_path = PersistentTemporaryDirectory('_pdf_output_parts')
  183.         
  184.  
  185.     
  186.     def insert_cover(self):
  187.         if self.cover_data is None:
  188.             return None
  189.         item_path = os.path.join(self.tmp_path, 'cover.pdf')
  190.         printer = self.get_printer()
  191.         printer.setOutputFileName(item_path)
  192.         self.combine_queue.insert(0, item_path)
  193.         p = QPixmap()
  194.         p.loadFromData(self.cover_data)
  195.         if not p.isNull():
  196.             painter = QPainter(printer)
  197.             draw_image_page(printer, painter, p, preserve_aspect_ratio = self.opts.preserve_cover_aspect_ratio)
  198.             painter.end()
  199.         
  200.  
  201.     
  202.     def _write(self):
  203.         self.logger.debug('Combining individual PDF parts...')
  204.         self.insert_cover()
  205.         
  206.         try:
  207.             outPDF = PdfFileWriter(title = self.metadata.title, author = self.metadata.author)
  208.             for item in self.combine_queue:
  209.                 inputPDF = PdfFileReader(open(item, 'rb'))
  210.                 for page in inputPDF.pages:
  211.                     outPDF.addPage(page)
  212.                 
  213.             
  214.             outPDF.write(self.out_stream)
  215.         finally:
  216.             self._delete_tmpdir()
  217.             self.loop.exit(0)
  218.  
  219.  
  220.  
  221.  
  222. class ImagePDFWriter(object):
  223.     
  224.     def __init__(self, opts, log, cover_data = None):
  225.         self.opts = opts
  226.         self.log = log
  227.         self.size = get_printer_page_size(opts, for_comic = True)
  228.  
  229.     
  230.     def dump(self, items, out_stream, pdf_metadata):
  231.         f = PersistentTemporaryFile('_comic2pdf.pdf')
  232.         f.close()
  233.         
  234.         try:
  235.             self.render_images(f.name, pdf_metadata, items)
  236.             
  237.             try:
  238.                 x = _[1]
  239.                 shutil.copyfileobj(x, out_stream)
  240.             finally:
  241.                 pass
  242.  
  243.         finally:
  244.             os.remove(f.name)
  245.  
  246.  
  247.     
  248.     def render_images(self, outpath, mi, items):
  249.         printer = get_pdf_printer()
  250.         printer.setPaperSize(QSizeF(self.size[0] * 10, self.size[1] * 10), QPrinter.Millimeter)
  251.         printer.setPageMargins(0, 0, 0, 0, QPrinter.Point)
  252.         printer.setOrientation(orientation(self.opts.orientation))
  253.         printer.setOutputFormat(QPrinter.PdfFormat)
  254.         printer.setOutputFileName(outpath)
  255.         printer.setDocName(mi.title)
  256.         printer.setCreator(u'%s [%s]' % (__appname__, __version__))
  257.         printer.setFullPage(True)
  258.         painter = QPainter(printer)
  259.         painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
  260.         for i, imgpath in enumerate(items):
  261.             self.log('Rendering image:', i)
  262.             p = QPixmap()
  263.             p.load(imgpath)
  264.             if not p.isNull():
  265.                 if i > 0:
  266.                     printer.newPage()
  267.                 
  268.                 draw_image_page(printer, painter, p)
  269.                 continue
  270.             self.log.warn('Failed to load image', i)
  271.         
  272.         painter.end()
  273.  
  274.  
  275.