This commit is contained in:
Kovid Goyal 2010-06-30 14:25:16 -06:00
parent 71c8f750e7
commit 8e00c3bc9c

View File

@ -8,7 +8,7 @@ from functools import partial
from calibre import prints from calibre import prints
from calibre.constants import plugins from calibre.constants import plugins
from calibre.ebooks.metadata import MetaInformation, string_to_authors, authors_to_string from calibre.ebooks.metadata import MetaInformation, string_to_authors
pdfreflow, pdfreflow_error = plugins['pdfreflow'] pdfreflow, pdfreflow_error = plugins['pdfreflow']
@ -56,66 +56,10 @@ def get_metadata(stream, cover=True):
get_quick_metadata = partial(get_metadata, cover=False) get_quick_metadata = partial(get_metadata, cover=False)
import cStringIO from calibre.utils.podofo import set_metadata as podofo_set_metadata
from threading import Thread
from calibre.utils.pdftk import set_metadata as pdftk_set_metadata
from calibre.utils.podofo import set_metadata as podofo_set_metadata, Unavailable
def set_metadata(stream, mi): def set_metadata(stream, mi):
stream.seek(0) stream.seek(0)
try:
return podofo_set_metadata(stream, mi) return podofo_set_metadata(stream, mi)
except Unavailable:
pass
try:
return pdftk_set_metadata(stream, mi)
except:
pass
set_metadata_pypdf(stream, mi)
class MetadataWriter(Thread):
def __init__(self, out_pdf, buf):
self.out_pdf = out_pdf
self.buf = buf
Thread.__init__(self)
self.daemon = True
def run(self):
try:
self.out_pdf.write(self.buf)
except RuntimeError:
pass
def set_metadata_pypdf(stream, mi):
# Use a StringIO object for the pdf because we will want to over
# write it later and if we are working on the stream directly it
# could cause some issues.
from pyPdf import PdfFileReader, PdfFileWriter
raw = cStringIO.StringIO(stream.read())
orig_pdf = PdfFileReader(raw)
title = mi.title if mi.title else orig_pdf.documentInfo.title
author = authors_to_string(mi.authors) if mi.authors else orig_pdf.documentInfo.author
out_pdf = PdfFileWriter(title=title, author=author)
out_str = cStringIO.StringIO()
writer = MetadataWriter(out_pdf, out_str)
for page in orig_pdf.pages:
out_pdf.addPage(page)
writer.start()
writer.join(10) # Wait 10 secs for writing to complete
out_pdf.killed = True
writer.join()
if out_pdf.killed:
print 'Failed to set metadata: took too long'
return
stream.seek(0)
stream.truncate()
out_str.seek(0)
stream.write(out_str.read())
stream.seek(0)