Fix Bug #775669: HTMLZ OPF sets cover, adds cover properly when updating metadata, reads cover form guide section of opf in archive.

This commit is contained in:
John Schember 2011-05-04 21:48:44 -04:00
parent a34ea87a94
commit 07da7b239c
4 changed files with 61 additions and 15 deletions

View File

@ -7,10 +7,12 @@ __copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
import posixpath
from calibre import walk from calibre import guess_type, walk
from calibre.customize.conversion import InputFormatPlugin from calibre.customize.conversion import InputFormatPlugin
from calibre.ebooks.chardet import xml_to_unicode from calibre.ebooks.chardet import xml_to_unicode
from calibre.ebooks.metadata.opf2 import OPF
from calibre.utils.zipfile import ZipFile from calibre.utils.zipfile import ZipFile
class HTMLZInput(InputFormatPlugin): class HTMLZInput(InputFormatPlugin):
@ -27,7 +29,7 @@ class HTMLZInput(InputFormatPlugin):
# Extract content from zip archive. # Extract content from zip archive.
zf = ZipFile(stream) zf = ZipFile(stream)
zf.extractall('.') zf.extractall()
for x in walk('.'): for x in walk('.'):
if os.path.splitext(x)[1].lower() in ('.html', '.xhtml', '.htm'): if os.path.splitext(x)[1].lower() in ('.html', '.xhtml', '.htm'):
@ -71,4 +73,23 @@ class HTMLZInput(InputFormatPlugin):
mi = get_file_type_metadata(stream, file_ext) mi = get_file_type_metadata(stream, file_ext)
meta_info_to_oeb_metadata(mi, oeb.metadata, log) meta_info_to_oeb_metadata(mi, oeb.metadata, log)
# Get the cover path from the OPF.
cover_href = None
opf = None
for x in walk('.'):
if os.path.splitext(x)[1].lower() in ('.opf'):
opf = x
break
if opf:
opf = OPF(opf)
cover_href = posixpath.relpath(opf.cover, os.path.dirname(stream.name))
# Set the cover.
if cover_href:
cdata = None
with open(cover_href, 'rb') as cf:
cdata = cf.read()
id, href = oeb.manifest.generate('cover', cover_href)
oeb.manifest.add(id, href, guess_type(cover_href)[0], data=cdata)
oeb.guide.add('cover', 'Cover', href)
return oeb return oeb

View File

@ -7,11 +7,13 @@ __copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
from cStringIO import StringIO
from lxml import etree from lxml import etree
from calibre.customize.conversion import OutputFormatPlugin, \ from calibre.customize.conversion import OutputFormatPlugin, \
OptionRecommendation OptionRecommendation
from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre.utils.zipfile import ZipFile from calibre.utils.zipfile import ZipFile
@ -80,9 +82,30 @@ class HTMLZOutput(OutputFormatPlugin):
with open(fname, 'wb') as img: with open(fname, 'wb') as img:
img.write(data) img.write(data)
# Cover
cover_path = None
try:
cover_data = None
if oeb_book.metadata.cover:
term = oeb_book.metadata.cover[0].term
cover_data = oeb_book.guide[term].item.data
if cover_data:
from calibre.utils.magick.draw import save_cover_data_to
cover_path = os.path.join(tdir, 'cover.jpg')
with open(cover_path, 'w') as cf:
cf.write('')
save_cover_data_to(cover_data, cover_path)
except:
import traceback
traceback.print_exc()
# Metadata # Metadata
with open(os.path.join(tdir, 'metadata.opf'), 'wb') as mdataf: with open(os.path.join(tdir, 'metadata.opf'), 'wb') as mdataf:
mdataf.write(etree.tostring(oeb_book.metadata.to_opf1())) opf = OPF(StringIO(etree.tostring(oeb_book.metadata.to_opf1())))
mi = opf.to_book_metadata()
if cover_path:
mi.cover = 'cover.jpg'
mdataf.write(metadata_to_opf(mi))
htmlz = ZipFile(output_path, 'w') htmlz = ZipFile(output_path, 'w')
htmlz.add_dir(tdir) htmlz.add_dir(tdir)

View File

@ -13,7 +13,7 @@ import posixpath
from cStringIO import StringIO from cStringIO import StringIO
from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.metadata import MetaInformation
from calibre.ebooks.metadata.opf2 import OPF from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils.zipfile import ZipFile, safe_replace from calibre.utils.zipfile import ZipFile, safe_replace
@ -31,9 +31,9 @@ def get_metadata(stream, extract_cover=True):
opf = OPF(opf_stream) opf = OPF(opf_stream)
mi = opf.to_book_metadata() mi = opf.to_book_metadata()
if extract_cover: if extract_cover:
cover_name = opf.raster_cover cover_href = posixpath.relpath(opf.cover, os.path.dirname(stream.name))
if cover_name: if cover_href:
mi.cover_data = ('jpg', zf.read(cover_name)) mi.cover_data = ('jpg', zf.read(cover_href))
except: except:
return mi return mi
return mi return mi
@ -59,17 +59,19 @@ def set_metadata(stream, mi):
except: except:
pass pass
if new_cdata: if new_cdata:
raster_cover = opf.raster_cover cover = opf.cover
if not raster_cover: if not cover:
raster_cover = 'cover.jpg' cover = 'cover.jpg'
cpath = posixpath.join(posixpath.dirname(opf_path), raster_cover) cpath = posixpath.join(posixpath.dirname(opf_path), cover)
new_cover = _write_new_cover(new_cdata, cpath) new_cover = _write_new_cover(new_cdata, cpath)
replacements[cpath] = open(new_cover.name, 'rb') replacements[cpath] = open(new_cover.name, 'rb')
mi.cover = cover
# Update the metadata. # Update the metadata.
opf.smart_update(mi, replace_metadata=True) old_mi = opf.to_book_metadata()
newopf = StringIO(opf.render()) old_mi.smart_update(mi)
safe_replace(stream, opf_path, newopf, extra_replacements=replacements) newopf = StringIO(metadata_to_opf(old_mi))
safe_replace(stream, opf_path, newopf, extra_replacements=replacements, add_missing=True)
# Cleanup temporary files. # Cleanup temporary files.
try: try: