From 73d203fa862b0bf2059e631c8922d3488d91e6a9 Mon Sep 17 00:00:00 2001 From: John Schember Date: Wed, 29 Apr 2009 19:04:18 -0400 Subject: [PATCH] pdfmanipulage rotate command. image to pdf output working. --- src/calibre/ebooks/pdf/manipulate/rotate.py | 105 ++++++++++++++++++++ src/calibre/ebooks/pdf/writer.py | 63 +++++++++++- 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/calibre/ebooks/pdf/manipulate/rotate.py diff --git a/src/calibre/ebooks/pdf/manipulate/rotate.py b/src/calibre/ebooks/pdf/manipulate/rotate.py new file mode 100644 index 0000000000..ac46a8e0c8 --- /dev/null +++ b/src/calibre/ebooks/pdf/manipulate/rotate.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- + +__license__ = 'GPL v3' +__copyright__ = '2009, John Schember ' +__docformat__ = 'restructuredtext en' + +''' +Rotate pages of a PDF. +''' + +import os, sys +from optparse import OptionGroup, Option + +from calibre.ebooks.metadata.meta import metadata_from_formats +from calibre.ebooks.metadata import authors_to_string +from calibre.utils.config import OptionParser +from calibre.utils.logging import Log +from calibre.constants import preferred_encoding +from calibre.customize.conversion import OptionRecommendation +from calibre.ebooks.pdf.verify import is_valid_pdf, is_encrypted + +from pyPdf import PdfFileWriter, PdfFileReader + +USAGE = '\n%prog %%name ' + _('''\ +file.pdf degrees + +Rotate pages of a PDF clockwise. +''') + +OPTIONS = set([ + OptionRecommendation(name='output', recommended_value='rotated.pdf', + level=OptionRecommendation.HIGH, long_switch='output', short_switch='o', + help=_('Path to output file. By default a file is created in the current directory.')), +]) + +def print_help(parser, log): + help = parser.format_help().encode(preferred_encoding, 'replace') + log(help) + +def option_parser(name): + usage = USAGE.replace('%%name', name) + return OptionParser(usage=usage) + +def option_recommendation_to_cli_option(add_option, rec): + opt = rec.option + switches = ['-'+opt.short_switch] if opt.short_switch else [] + switches.append('--'+opt.long_switch) + attrs = dict(dest=opt.name, help=opt.help, + choices=opt.choices, default=rec.recommended_value) + add_option(Option(*switches, **attrs)) + +def add_options(parser): + group = OptionGroup(parser, _('Rotate Options:'), _('Options to control the transformation of pdf')) + parser.add_option_group(group) + add_option = group.add_option + + for rec in OPTIONS: + option_recommendation_to_cli_option(add_option, rec) + +def rotate(pdf_path, out_path, degrees, metadata=None): + if metadata == None: + title = _('Unknown') + author = _('Unknown') + else: + title = metadata.title + author = authors_to_string(metadata.authors) + + out_pdf = PdfFileWriter(title=title, author=author) + + pdf = PdfFileReader(open(os.path.abspath(pdf_path), 'rb')) + for page in pdf.pages: + out_pdf.addPage(page.rotateClockwise(int(degrees))) + + with open(out_path, 'wb') as out_file: + out_pdf.write(out_file) + +def main(args=sys.argv, name=''): + log = Log() + parser = option_parser(name) + add_options(parser) + + opts, args = parser.parse_args(args) + args = args[1:] + + if len(args) < 2: + print 'Error: A PDF file and how many degrees to rotate is required.\n' + print_help(parser, log) + return 1 + + if not is_valid_pdf(args[0]): + print 'Error: Could not read file `%s`.' % args[0] + return 1 + + if is_encrypted(args[0]): + print 'Error: file `%s` is encrypted.' % args[0] + return 1 + + mi = metadata_from_formats([args[0]]) + + rotate(args[0], opts.output, args[1], mi) + + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/calibre/ebooks/pdf/writer.py b/src/calibre/ebooks/pdf/writer.py index 80bcacde2c..1700d58025 100644 --- a/src/calibre/ebooks/pdf/writer.py +++ b/src/calibre/ebooks/pdf/writer.py @@ -140,9 +140,70 @@ class ImagePDFWriter(PDFWriter): self.combine_queue.append(os.path.join(self.tmp_path, '%i.pdf' % (len(self.combine_queue) + 1))) self.logger.debug('Processing %s...' % item) + + import Image + + size = self._size() + #height = 'height: %ipx;' % size[1] if Image.open(item).size[1] > size[1] else '' + #height = 'height: %icm;' % size[1] + #height = 'height: %ipx;' % self.opts.output_profile.comic_screen_size[1] +### height = 'height: 594px;' # self.opts.output_profile.comic_screen_size[1] * .78 + + #print + #print size[1] + #print Image.open(item).size[1] + #print Image.open(item).size[1] / self.opts.output_profile.dpi + #print height - html = '' % item + + #height = 'height: %ipx;' % (self.opts.output_profile.comic_screen_size[1] - 160) + #height = 'height: %ipx;' % (self.opts.output_profile.comic_screen_size[1] * .78) + height = 'height: %fcm;' % (size[1] * 1.3) + #print height + + html = '' % (item, height) self.view.setHtml(html) + 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)) + else: + printer.setPaperSize(QSizeF(self.custom_size[0], self.custom_size[1]), unit(self.opts.unit)) + else: + 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) + + printer.setPageMargins(0, 0, 0, 0, QPrinter.Point) + printer.setOrientation(orientation(self.opts.orientation)) + printer.setOutputFormat(QPrinter.PdfFormat) + printer.setOutputFileName(item_path) + self.view.print_(printer) + self._render_book() + + def _size(self): + 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)) + else: + printer.setPaperSize(QSizeF(self.custom_size[0], self.custom_size[1]), unit(self.opts.unit)) + else: + 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) + + printer.setPageMargins(0, 0, 0, 0, QPrinter.Point) + printer.setOrientation(orientation(self.opts.orientation)) + printer.setOutputFormat(QPrinter.PdfFormat) + + size = printer.paperSize(QPrinter.Millimeter) + + return size.width() / 10, size.height() / 10