mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement setting metadata in textual PDFs
This commit is contained in:
parent
b25766f6aa
commit
87b86d86a8
@ -23,29 +23,6 @@ PAPER_SIZES = ('a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'b0', 'b1',
|
|||||||
'b2', 'b3', 'b4', 'b5', 'b6', 'legal', 'letter')
|
'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):
|
class PDFOutput(OutputFormatPlugin):
|
||||||
|
|
||||||
name = 'PDF Output'
|
name = 'PDF Output'
|
||||||
@ -201,7 +178,7 @@ class PDFOutput(OutputFormatPlugin):
|
|||||||
|
|
||||||
def convert_images(self, images):
|
def convert_images(self, images):
|
||||||
from calibre.ebooks.pdf.image_writer import convert
|
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):
|
def get_cover_data(self):
|
||||||
oeb = self.oeb
|
oeb = self.oeb
|
||||||
@ -261,4 +238,4 @@ class PDFOutput(OutputFormatPlugin):
|
|||||||
oeb_output = plugin_for_output_format('oeb')
|
oeb_output = plugin_for_output_format('oeb')
|
||||||
oeb_output.convert(oeb_book, oeb_dir, self.input_plugin, self.opts, self.log)
|
oeb_output.convert(oeb_book, oeb_dir, self.input_plugin, self.opts, self.log)
|
||||||
opfpath = glob.glob(os.path.join(oeb_dir, '*.opf'))[0]
|
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)
|
||||||
|
@ -6,17 +6,19 @@ from __future__ import absolute_import, division, print_function, unicode_litera
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from PyQt5.Qt import QApplication, QUrl, QTimer
|
from PyQt5.Qt import QApplication, QTimer, QUrl
|
||||||
from PyQt5.QtWebEngineWidgets import QWebEnginePage
|
from PyQt5.QtWebEngineWidgets import QWebEnginePage
|
||||||
|
|
||||||
from calibre.constants import iswindows
|
from calibre.constants import iswindows
|
||||||
from calibre.ebooks.oeb.polish.container import Container as ContainerBase
|
from calibre.ebooks.oeb.polish.container import Container as ContainerBase
|
||||||
from calibre.ebooks.oeb.polish.split import merge_html
|
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 import setup_unix_signals
|
||||||
from calibre.gui2.webengine import secure_webengine
|
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.logging import default_log
|
||||||
|
from calibre.utils.podofo import get_podofo
|
||||||
from polyglot.builtins import range
|
from polyglot.builtins import range
|
||||||
|
|
||||||
OK, LOAD_FAILED, KILL_SIGNAL = range(0, 3)
|
OK, LOAD_FAILED, KILL_SIGNAL = range(0, 3)
|
||||||
@ -96,7 +98,7 @@ class Renderer(QWebEnginePage):
|
|||||||
return self.pdf_data
|
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)
|
container = Container(opf_path, log)
|
||||||
spine_names = [name for name, is_linear in container.spine_names]
|
spine_names = [name for name, is_linear in container.spine_names]
|
||||||
master = spine_names[0]
|
master = spine_names[0]
|
||||||
@ -109,7 +111,14 @@ def convert(opf_path, opts, output_path=None, log=default_log):
|
|||||||
renderer = Renderer(opts)
|
renderer = Renderer(opts)
|
||||||
page_layout = get_page_layout(opts)
|
page_layout = get_page_layout(opts)
|
||||||
pdf_data = renderer.convert_html_file(index_file, page_layout, settle_time=1)
|
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:
|
if output_path is None:
|
||||||
return pdf_data
|
return pdf_data
|
||||||
with open(output_path, 'wb') as f:
|
with open(output_path, 'wb') as f:
|
||||||
|
@ -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.img import image_from_path
|
||||||
from calibre.utils.podofo import get_podofo, set_metadata_implementation
|
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 {{{
|
# Page layout {{{
|
||||||
|
|
||||||
|
|
||||||
@ -82,8 +106,17 @@ def draw_image_page(painter, img, preserve_aspect_ratio=True):
|
|||||||
painter.drawImage(page_rect, img)
|
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)
|
writer = QPdfWriter(output_path)
|
||||||
|
pdf_metadata = PDFMetadata(metadata)
|
||||||
writer.setCreator(pdf_metadata.author)
|
writer.setCreator(pdf_metadata.author)
|
||||||
writer.setTitle(pdf_metadata.title)
|
writer.setTitle(pdf_metadata.title)
|
||||||
writer.setPageLayout(get_page_layout(opts, for_comic=True))
|
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)
|
draw_image_page(painter, img)
|
||||||
finally:
|
finally:
|
||||||
painter.end()
|
painter.end()
|
||||||
if pdf_metadata.mi:
|
|
||||||
podofo = get_podofo()
|
podofo = get_podofo()
|
||||||
pdf_doc = podofo.PDFDoc()
|
pdf_doc = podofo.PDFDoc()
|
||||||
with open(output_path, 'r+b') as f:
|
with open(output_path, 'r+b') as f:
|
||||||
raw = f.read()
|
raw = f.read()
|
||||||
pdf_doc.load(raw)
|
pdf_doc.load(raw)
|
||||||
xmp_packet = metadata_to_xmp_packet(pdf_metadata.mi)
|
update_metadata(pdf_doc, pdf_metadata)
|
||||||
set_metadata_implementation(
|
raw = pdf_doc.write()
|
||||||
pdf_doc, pdf_metadata.title, pdf_metadata.mi.authors,
|
f.seek(0), f.truncate()
|
||||||
pdf_metadata.mi.book_producer, pdf_metadata.tags, xmp_packet)
|
f.write(raw)
|
||||||
raw = pdf_doc.write()
|
|
||||||
f.seek(0), f.truncate()
|
|
||||||
f.write(raw)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user