mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
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:
parent
a34ea87a94
commit
07da7b239c
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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:
|
||||||
|
@ -36,7 +36,7 @@ def meta_info_to_oeb_metadata(mi, m, log, override_input_metadata=False):
|
|||||||
m.clear('description')
|
m.clear('description')
|
||||||
m.add('description', mi.comments)
|
m.add('description', mi.comments)
|
||||||
elif override_input_metadata:
|
elif override_input_metadata:
|
||||||
m.clear('description')
|
m.clear('description')
|
||||||
if not mi.is_null('publisher'):
|
if not mi.is_null('publisher'):
|
||||||
m.clear('publisher')
|
m.clear('publisher')
|
||||||
m.add('publisher', mi.publisher)
|
m.add('publisher', mi.publisher)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user