mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Move PDF output to use new conversion framework
This commit is contained in:
parent
90362ab56a
commit
79e509eeb4
@ -267,9 +267,10 @@ from calibre.ebooks.epub.input import EPUBInput
|
||||
from calibre.ebooks.mobi.input import MOBIInput
|
||||
from calibre.ebooks.oeb.output import OEBOutput
|
||||
from calibre.ebooks.txt.output import TXTOutput
|
||||
from calibre.ebooks.pdf.output import PDFOutput
|
||||
from calibre.customize.profiles import input_profiles, output_profiles
|
||||
|
||||
plugins = [HTML2ZIP, EPUBInput, MOBIInput, OEBOutput, TXTOutput]
|
||||
plugins = [HTML2ZIP, EPUBInput, MOBIInput, OEBOutput, TXTOutput, PDFOutput]
|
||||
plugins += [x for x in list(locals().values()) if isinstance(x, type) and \
|
||||
x.__name__.endswith('MetadataReader')]
|
||||
plugins += [x for x in list(locals().values()) if isinstance(x, type) and \
|
||||
|
@ -1,69 +0,0 @@
|
||||
'''
|
||||
Convert any ebook format to PDF.
|
||||
'''
|
||||
|
||||
from __future__ import with_statement
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net ' \
|
||||
'and Marshall T. Vandegrift <llasram@gmail.com>' \
|
||||
'and John Schember <john@nachtimwald.com>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import sys, os, glob, logging
|
||||
|
||||
from calibre.ebooks.epub.from_any import any2epub, formats, USAGE
|
||||
from calibre.ebooks.epub import config as common_config
|
||||
from calibre.ptempfile import TemporaryDirectory
|
||||
from calibre.ebooks.pdf.writer import oeb2pdf, config as pdf_config
|
||||
|
||||
def config(defaults=None):
|
||||
c = common_config(defaults=defaults, name='pdf')
|
||||
c.remove_opt('profile')
|
||||
pdfc = pdf_config(defaults=defaults)
|
||||
c.update(pdfc)
|
||||
return c
|
||||
|
||||
def option_parser(usage=USAGE):
|
||||
usage = usage % ('PDF', formats())
|
||||
parser = config().option_parser(usage=usage)
|
||||
return parser
|
||||
|
||||
def any2pdf(opts, path, notification=None):
|
||||
ext = os.path.splitext(path)[1]
|
||||
if not ext:
|
||||
raise ValueError('Unknown file type: '+path)
|
||||
ext = ext.lower()[1:]
|
||||
|
||||
if opts.output is None:
|
||||
opts.output = os.path.splitext(os.path.basename(path))[0]+'.pdf'
|
||||
|
||||
opts.output = os.path.abspath(opts.output)
|
||||
orig_output = opts.output
|
||||
|
||||
with TemporaryDirectory('_any2pdf') as tdir:
|
||||
oebdir = os.path.join(tdir, 'oeb')
|
||||
os.mkdir(oebdir)
|
||||
opts.output = os.path.join(tdir, 'dummy.epub')
|
||||
opts.profile = 'None'
|
||||
opts.dont_split_on_page_breaks = True
|
||||
orig_bfs = opts.base_font_size2
|
||||
opts.base_font_size2 = 0
|
||||
any2epub(opts, path, create_epub=False, oeb_cover=True, extract_to=oebdir)
|
||||
opts.base_font_size2 = orig_bfs
|
||||
opf = glob.glob(os.path.join(oebdir, '*.opf'))[0]
|
||||
opts.output = orig_output
|
||||
logging.getLogger('html2epub').info(_('Creating PDF file from EPUB...'))
|
||||
oeb2pdf(opts, opf)
|
||||
|
||||
def main(args=sys.argv):
|
||||
parser = option_parser()
|
||||
opts, args = parser.parse_args(args)
|
||||
if len(args) < 2:
|
||||
parser.print_help()
|
||||
print 'No input file specified.'
|
||||
return 1
|
||||
any2pdf(opts, args[1])
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
62
src/calibre/ebooks/pdf/output.py
Normal file
62
src/calibre/ebooks/pdf/output.py
Normal file
@ -0,0 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
'''
|
||||
Convert OEB ebook format to PDF.
|
||||
'''
|
||||
|
||||
#unit, papersize, orientation, custom_size, profile
|
||||
|
||||
import os
|
||||
|
||||
from calibre.customize.conversion import OutputFormatPlugin, \
|
||||
OptionRecommendation
|
||||
from calibre.ebooks.pdf.writer import PDFWriter, PDFMargins
|
||||
|
||||
class PDFOutput(OutputFormatPlugin):
|
||||
|
||||
name = 'PDF Output'
|
||||
author = 'John Schember'
|
||||
file_type = 'pdf'
|
||||
|
||||
options = set([
|
||||
OptionRecommendation(name='margin_top', recommended_value='1',
|
||||
level=OptionRecommendation.LOW, long_switch='margin_top',
|
||||
help=_('The top margin around the document.')),
|
||||
OptionRecommendation(name='margin_bottom', recommended_value='1',
|
||||
level=OptionRecommendation.LOW, long_switch='margin_bottom',
|
||||
help=_('The bottom margin around the document.')),
|
||||
OptionRecommendation(name='margin_left', recommended_value='1',
|
||||
level=OptionRecommendation.LOW, long_switch='margin_left',
|
||||
help=_('The left margin around the document.')),
|
||||
OptionRecommendation(name='margin_right', recommended_value='1',
|
||||
level=OptionRecommendation.LOW, long_switch='margin_right',
|
||||
help=_('The right margin around the document.')),
|
||||
])
|
||||
|
||||
def convert(self, oeb_book, output_path, input_plugin, opts, log):
|
||||
margins = PDFMargins()
|
||||
margins.top = opts.margin_top
|
||||
margins.bottom = opts.margin_bottom
|
||||
margins.left = opts.margin_left
|
||||
margins.right = opts.margin_right
|
||||
|
||||
writer = PDFWriter(log, margins)
|
||||
|
||||
close = False
|
||||
if not hasattr(output_path, 'write'):
|
||||
close = True
|
||||
if not os.path.exists(os.path.dirname(output_path)) and os.path.dirname(output_path) != '':
|
||||
os.makedirs(os.path.dirname(output_path))
|
||||
out_stream = open(output_path, 'wb')
|
||||
else:
|
||||
out_stream = output_path
|
||||
|
||||
out_stream.seek(0)
|
||||
out_stream.truncate()
|
||||
writer.dump(oeb_book.spine, out_stream)
|
||||
|
||||
if close:
|
||||
out_stream.close()
|
@ -1,20 +1,17 @@
|
||||
'''
|
||||
Write content to PDF.
|
||||
'''
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import with_statement
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os, logging, shutil, sys
|
||||
'''
|
||||
Write content to PDF.
|
||||
'''
|
||||
|
||||
import os, shutil, sys
|
||||
|
||||
from calibre import LoggingInterface
|
||||
from calibre.ebooks.epub.iterator import SpineItem
|
||||
from calibre.ebooks.metadata.opf2 import OPF
|
||||
from calibre.ptempfile import PersistentTemporaryDirectory
|
||||
from calibre.customize.ui import run_plugins_on_postprocess
|
||||
from calibre.utils.config import Config, StringConfig
|
||||
|
||||
from PyQt4 import QtCore
|
||||
from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, QApplication, QPrinter, \
|
||||
QMetaObject, Qt
|
||||
@ -29,13 +26,14 @@ class PDFMargins:
|
||||
self.left = margin
|
||||
self.right = margin
|
||||
|
||||
|
||||
class PDFWriter(QObject):
|
||||
def __init__(self, margins=PDFMargins()):
|
||||
def __init__(self, log, margins=PDFMargins()):
|
||||
if QApplication.instance() is None:
|
||||
QApplication([])
|
||||
QObject.__init__(self)
|
||||
|
||||
self.logger = logging.getLogger('oeb2pdf')
|
||||
self.logger = log
|
||||
|
||||
self.loop = QEventLoop()
|
||||
self.view = QWebView()
|
||||
@ -45,13 +43,12 @@ class PDFWriter(QObject):
|
||||
self.tmp_path = PersistentTemporaryDirectory('_any2pdf_parts')
|
||||
self.margins = margins
|
||||
|
||||
def dump(self, oebpath, path):
|
||||
def dump(self, spine, out_stream):
|
||||
self._delete_tmpdir()
|
||||
|
||||
opf = OPF(oebpath, os.path.dirname(oebpath))
|
||||
self.render_queue = [SpineItem(i.path) for i in opf.spine]
|
||||
self.render_queue = spine[:]
|
||||
self.combine_queue = []
|
||||
self.path = path
|
||||
self.out_stream = out_stream
|
||||
|
||||
QMetaObject.invokeMethod(self, "_render_book", Qt.QueuedConnection)
|
||||
self.loop.exec_()
|
||||
@ -98,75 +95,7 @@ class PDFWriter(QObject):
|
||||
inputPDF = PdfFileReader(file(item, 'rb'))
|
||||
for page in inputPDF.pages:
|
||||
outPDF.addPage(page)
|
||||
outputStream = file(self.path, 'wb')
|
||||
outPDF.write(outputStream)
|
||||
outputStream.close()
|
||||
outPDF.write(self.out_stream)
|
||||
finally:
|
||||
self._delete_tmpdir()
|
||||
self.loop.exit(0)
|
||||
|
||||
|
||||
def config(defaults=None):
|
||||
desc = _('Options to control the conversion to PDF')
|
||||
if defaults is None:
|
||||
c = Config('pdf', desc)
|
||||
else:
|
||||
c = StringConfig(defaults, desc)
|
||||
|
||||
pdf = c.add_group('PDF', _('PDF options.'))
|
||||
|
||||
pdf('margin_top', ['--margin_top'], default=1,
|
||||
help=_('The top margin around the document in inches.'))
|
||||
pdf('margin_bottom', ['--margin_bottom'], default=1,
|
||||
help=_('The bottom margin around the document in inches.'))
|
||||
pdf('margin_left', ['--margin_left'], default=1,
|
||||
help=_('The left margin around the document in inches.'))
|
||||
pdf('margin_right', ['--margin_right'], default=1,
|
||||
help=_('The right margin around the document in inches.'))
|
||||
|
||||
return c
|
||||
|
||||
def option_parser():
|
||||
c = config()
|
||||
parser = c.option_parser(usage='%prog '+_('[options]')+' file.opf')
|
||||
parser.add_option(
|
||||
'-o', '--output', default=None,
|
||||
help=_('Output file. Default is derived from input filename.'))
|
||||
parser.add_option(
|
||||
'-v', '--verbose', default=0, action='count',
|
||||
help=_('Useful for debugging.'))
|
||||
return parser
|
||||
|
||||
def oeb2pdf(opts, inpath):
|
||||
logger = LoggingInterface(logging.getLogger('oeb2pdf'))
|
||||
logger.setup_cli_handler(opts.verbose)
|
||||
|
||||
outpath = opts.output
|
||||
if outpath is None:
|
||||
outpath = os.path.basename(inpath)
|
||||
outpath = os.path.splitext(outpath)[0] + '.pdf'
|
||||
|
||||
margins = PDFMargins()
|
||||
margins.top = opts.margin_top
|
||||
margins.bottom = opts.margin_bottom
|
||||
margins.left = opts.margin_left
|
||||
margins.right = opts.margin_right
|
||||
|
||||
writer = PDFWriter(margins)
|
||||
writer.dump(inpath, outpath)
|
||||
run_plugins_on_postprocess(outpath, 'pdf')
|
||||
logger.log_info(_('Output written to ') + outpath)
|
||||
|
||||
def main(argv=sys.argv):
|
||||
parser = option_parser()
|
||||
opts, args = parser.parse_args(argv[1:])
|
||||
if len(args) != 1:
|
||||
parser.print_help()
|
||||
return 1
|
||||
inpath = args[0]
|
||||
retval = oeb2pdf(opts, inpath)
|
||||
return retval
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
||||
|
@ -56,6 +56,7 @@ class TXTOutput(OutputFormatPlugin):
|
||||
out_stream = output_path
|
||||
|
||||
out_stream.seek(0)
|
||||
out_stream.truncate()
|
||||
out_stream.write(txt)
|
||||
|
||||
if close:
|
||||
|
Loading…
x
Reference in New Issue
Block a user