Implement setting metadata in textual PDFs

This commit is contained in:
Kovid Goyal 2019-07-08 17:19:46 +05:30
parent b25766f6aa
commit 87b86d86a8
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 59 additions and 43 deletions

View File

@ -23,29 +23,6 @@ PAPER_SIZES = ('a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'b0', 'b1',
'b2', 'b3', 'b4', 'b5', 'b6', 'legal', 'letter')
class PDFMetadata(object): # {{{
def __init__(self, mi=None):
from calibre import force_unicode
from calibre.ebooks.metadata import authors_to_string
self.title = _('Unknown')
self.author = _('Unknown')
self.tags = ''
self.mi = mi
if mi is not None:
if mi.title:
self.title = mi.title
if mi.authors:
self.author = authors_to_string(mi.authors)
if mi.tags:
self.tags = ', '.join(mi.tags)
self.title = force_unicode(self.title)
self.author = force_unicode(self.author)
# }}}
class PDFOutput(OutputFormatPlugin):
name = 'PDF Output'
@ -201,7 +178,7 @@ class PDFOutput(OutputFormatPlugin):
def convert_images(self, images):
from calibre.ebooks.pdf.image_writer import convert
convert(images, self.output_path, self.opts, PDFMetadata(self.metadata))
convert(images, self.output_path, self.opts, self.metadata)
def get_cover_data(self):
oeb = self.oeb
@ -261,4 +238,4 @@ class PDFOutput(OutputFormatPlugin):
oeb_output = plugin_for_output_format('oeb')
oeb_output.convert(oeb_book, oeb_dir, self.input_plugin, self.opts, self.log)
opfpath = glob.glob(os.path.join(oeb_dir, '*.opf'))[0]
convert(opfpath, self.opts, self.output_path, self.log)
convert(opfpath, self.opts, metadata=self.metadata, output_path=self.output_path, log=self.log)

View File

@ -6,17 +6,19 @@ from __future__ import absolute_import, division, print_function, unicode_litera
import os
from PyQt5.Qt import QApplication, QUrl, QTimer
from PyQt5.Qt import QApplication, QTimer, QUrl
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from calibre.constants import iswindows
from calibre.ebooks.oeb.polish.container import Container as ContainerBase
from calibre.ebooks.oeb.polish.split import merge_html
from calibre.ebooks.pdf.image_writer import (
PDFMetadata, get_page_layout, update_metadata
)
from calibre.gui2 import setup_unix_signals
from calibre.gui2.webengine import secure_webengine
from calibre.ebooks.pdf.image_writer import get_page_layout
from calibre.utils.logging import default_log
from calibre.utils.podofo import get_podofo
from polyglot.builtins import range
OK, LOAD_FAILED, KILL_SIGNAL = range(0, 3)
@ -96,7 +98,7 @@ class Renderer(QWebEnginePage):
return self.pdf_data
def convert(opf_path, opts, output_path=None, log=default_log):
def convert(opf_path, opts, metadata=None, output_path=None, log=default_log):
container = Container(opf_path, log)
spine_names = [name for name, is_linear in container.spine_names]
master = spine_names[0]
@ -109,7 +111,14 @@ def convert(opf_path, opts, output_path=None, log=default_log):
renderer = Renderer(opts)
page_layout = get_page_layout(opts)
pdf_data = renderer.convert_html_file(index_file, page_layout, settle_time=1)
podofo = get_podofo()
pdf_doc = podofo.PDFDoc()
pdf_doc.load(pdf_data)
if metadata is not None:
update_metadata(pdf_doc, PDFMetadata(metadata))
pdf_data = pdf_doc.write()
if output_path is None:
return pdf_data
with open(output_path, 'wb') as f:

View File

@ -12,6 +12,30 @@ from calibre.ebooks.metadata.xmp import metadata_to_xmp_packet
from calibre.utils.img import image_from_path
from calibre.utils.podofo import get_podofo, set_metadata_implementation
class PDFMetadata(object): # {{{
def __init__(self, mi=None):
from calibre import force_unicode
from calibre.ebooks.metadata import authors_to_string
self.title = _('Unknown')
self.author = _('Unknown')
self.tags = ''
self.mi = mi
if mi is not None:
if mi.title:
self.title = mi.title
if mi.authors:
self.author = authors_to_string(mi.authors)
if mi.tags:
self.tags = ', '.join(mi.tags)
self.title = force_unicode(self.title)
self.author = force_unicode(self.author)
# }}}
# Page layout {{{
@ -82,8 +106,17 @@ def draw_image_page(painter, img, preserve_aspect_ratio=True):
painter.drawImage(page_rect, img)
def convert(images, output_path, opts, pdf_metadata):
def update_metadata(pdf_doc, pdf_metadata):
if pdf_metadata.mi:
xmp_packet = metadata_to_xmp_packet(pdf_metadata.mi)
set_metadata_implementation(
pdf_doc, pdf_metadata.title, pdf_metadata.mi.authors,
pdf_metadata.mi.book_producer, pdf_metadata.mi.tags, xmp_packet)
def convert(images, output_path, opts, metadata):
writer = QPdfWriter(output_path)
pdf_metadata = PDFMetadata(metadata)
writer.setCreator(pdf_metadata.author)
writer.setTitle(pdf_metadata.title)
writer.setPageLayout(get_page_layout(opts, for_comic=True))
@ -97,16 +130,13 @@ def convert(images, output_path, opts, pdf_metadata):
draw_image_page(painter, img)
finally:
painter.end()
if pdf_metadata.mi:
podofo = get_podofo()
pdf_doc = podofo.PDFDoc()
with open(output_path, 'r+b') as f:
raw = f.read()
pdf_doc.load(raw)
xmp_packet = metadata_to_xmp_packet(pdf_metadata.mi)
set_metadata_implementation(
pdf_doc, pdf_metadata.title, pdf_metadata.mi.authors,
pdf_metadata.mi.book_producer, pdf_metadata.tags, xmp_packet)
raw = pdf_doc.write()
f.seek(0), f.truncate()
f.write(raw)
podofo = get_podofo()
pdf_doc = podofo.PDFDoc()
with open(output_path, 'r+b') as f:
raw = f.read()
pdf_doc.load(raw)
update_metadata(pdf_doc, pdf_metadata)
raw = pdf_doc.write()
f.seek(0), f.truncate()
f.write(raw)