Add support for setting metadata in KEPUB files

This commit is contained in:
Kovid Goyal 2025-02-21 10:51:15 +05:30
parent 30bcd86634
commit 08524e760b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 20 additions and 13 deletions

View File

@ -440,13 +440,14 @@ plugins += [x for x in list(locals().values()) if isinstance(x, type) and
class EPUBMetadataWriter(MetadataWriterPlugin):
name = 'Set EPUB metadata'
file_types = {'epub'}
description = _('Set metadata in %s files')%'EPUB'
file_types = {'epub', 'kepub'}
description = _('Set metadata in EPUB and KEPUB files')
def set_metadata(self, stream, mi, type):
def set_metadata(self, stream, mi, ftype):
from calibre.ebooks.metadata.epub import set_metadata
q = self.site_customization or ''
set_metadata(stream, mi, apply_null=self.apply_null, force_identifiers=self.force_identifiers, add_missing_cover='disable-add-missing-cover' != q)
set_metadata(stream, mi, apply_null=self.apply_null, force_identifiers=self.force_identifiers, ftype=ftype,
add_missing_cover='disable-add-missing-cover' != q or ftype == 'kepub')
def customization_help(self, gui=False):
h = 'disable-add-missing-cover'

View File

@ -290,7 +290,7 @@ def serialize_cover_data(new_cdata, cpath):
return save_cover_data_to(new_cdata, data_fmt=os.path.splitext(cpath)[1][1:])
def set_metadata(stream, mi, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True):
def set_metadata(stream, mi, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True, ftype='epub'):
stream.seek(0)
reader = get_zip_reader(stream, root=os.getcwd())
new_cdata = None
@ -308,7 +308,7 @@ def set_metadata(stream, mi, apply_null=False, update_timestamp=False, force_ide
opfbytes, ver, raster_cover = set_metadata_opf(
reader.read_bytes(reader.opf_path), mi, cover_prefix=posixpath.dirname(reader.opf_path),
cover_data=new_cdata, apply_null=apply_null, update_timestamp=update_timestamp,
force_identifiers=force_identifiers, add_missing_cover=add_missing_cover)
force_identifiers=force_identifiers, add_missing_cover=add_missing_cover, ftype=ftype)
cpath = None
replacements = {}
if new_cdata and raster_cover:

View File

@ -46,8 +46,10 @@ def get_metadata(stream, ftype='epub'):
return get_metadata_from_parsed(root, ftype)
def set_metadata_opf2(root, cover_prefix, mi, opf_version,
cover_data=None, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True):
def set_metadata_opf2(
root, cover_prefix, mi, opf_version,
cover_data=None, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True, ftype='epub',
):
mi = MetaInformation(mi)
for x in ('guide', 'toc', 'manifest', 'spine'):
setattr(mi, x, None)
@ -85,7 +87,7 @@ def set_metadata_opf2(root, cover_prefix, mi, opf_version,
[x.getparent().remove(x) for x in opf.root.xpath('//*[local-name()="meta" and @name="cover"]')]
m = opf.create_metadata_element('meta', is_dc=False)
m.set('name', 'cover'), m.set('content', i.get('id'))
else:
if opf_version.major > 2 or ftype == 'kepub':
for x in opf.root.xpath('//*[local-name()="item" and contains(@properties, "cover-image")]'):
x.set('properties', x.get('properties').replace('cover-image', '').strip())
i.set('properties', 'cover-image')
@ -94,8 +96,10 @@ def set_metadata_opf2(root, cover_prefix, mi, opf_version,
return opf.render(), raster_cover
def set_metadata_opf3(root, cover_prefix, mi, opf_version,
cover_data=None, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True):
def set_metadata_opf3(
root, cover_prefix, mi, opf_version,
cover_data=None, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True, ftype='epub',
):
raster_cover = apply_metadata(
root, mi, cover_prefix=cover_prefix, cover_data=cover_data,
apply_null=apply_null, update_timestamp=update_timestamp,
@ -103,14 +107,16 @@ def set_metadata_opf3(root, cover_prefix, mi, opf_version,
return etree.tostring(root, encoding='utf-8'), raster_cover
def set_metadata(stream, mi, cover_prefix='', cover_data=None, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True):
def set_metadata(
stream, mi, cover_prefix='', cover_data=None, apply_null=False, update_timestamp=False, force_identifiers=False, add_missing_cover=True, ftype='epub'
):
if isinstance(stream, bytes):
stream = DummyFile(stream)
root = parse_opf(stream)
ver = parse_opf_version(root.get('version'))
f = set_metadata_opf2 if ver.major < 3 else set_metadata_opf3
opfbytes, raster_cover = f(
root, cover_prefix, mi, ver, cover_data=cover_data,
root, cover_prefix, mi, ver, cover_data=cover_data, ftype=ftype,
apply_null=apply_null, update_timestamp=update_timestamp,
force_identifiers=force_identifiers, add_missing_cover=add_missing_cover)
return opfbytes, ver, raster_cover