Make application_id/uuid behave the same as in opf2.py

This commit is contained in:
Kovid Goyal 2016-06-24 00:00:47 +05:30
parent 7734059ff8
commit 3c6bfed2c4
2 changed files with 41 additions and 29 deletions

View File

@ -256,25 +256,29 @@ def set_identifiers(root, prefixes, refines, new_identifiers, force_identifiers=
p = package_identifier.getparent() p = package_identifier.getparent()
p.insert(p.index(package_identifier), ident) p.insert(p.index(package_identifier), ident)
def set_application_id(root, refines, new_application_id=None): def identifier_writer(name):
uid = root.get('unique-identifier') def writer(root, prefixes, refines, ival=None):
package_identifier = None uid = root.get('unique-identifier')
for ident in XPath('./opf:metadata/dc:identifier')(root): package_identifier = None
is_package_id = uid is not None and uid == ident.get('id') for ident in XPath('./opf:metadata/dc:identifier')(root):
if is_package_id: is_package_id = uid is not None and uid == ident.get('id')
package_identifier = ident if is_package_id:
val = (ident.text or '').strip() package_identifier = ident
if val.startswith('calibre:') and not is_package_id: val = (ident.text or '').strip()
remove_element(ident, refines) if (val.startswith(name + ':') or ident.get(OPF('scheme')) == name) and not is_package_id:
metadata = XPath('./opf:metadata')(root)[0] remove_element(ident, refines)
if new_application_id: metadata = XPath('./opf:metadata')(root)[0]
ident = metadata.makeelement(DC('identifier')) if ival:
ident.text = 'calibre:%s' % new_application_id ident = metadata.makeelement(DC('identifier'))
if package_identifier is None: ident.text = '%s:%s' % (name, ival)
metadata.append(ident) if package_identifier is None:
else: metadata.append(ident)
p = package_identifier.getparent() else:
p.insert(p.index(package_identifier), ident) p = package_identifier.getparent()
p.insert(p.index(package_identifier), ident)
return writer
set_application_id = identifier_writer('calibre')
set_uuid = identifier_writer('uuid')
# }}} # }}}
@ -786,7 +790,9 @@ def read_metadata(root):
for key, vals in identifiers.iteritems(): for key, vals in identifiers.iteritems():
if key == 'calibre': if key == 'calibre':
ans.application_id = vals[0] ans.application_id = vals[0]
elif key != 'uuid': elif key == 'uuid':
ans.uuid = vals[0]
else:
ids[key] = vals[0] ids[key] = vals[0]
ans.set_identifiers(ids) ans.set_identifiers(ids)
ans.title = read_title(root, prefixes, refines) or ans.title ans.title = read_title(root, prefixes, refines) or ans.title
@ -867,6 +873,11 @@ def apply_metadata(root, mi, cover_prefix='', cover_data=None, apply_null=False,
set_author_link_map(root, prefixes, refines, getattr(mi, 'author_link_map', None)) set_author_link_map(root, prefixes, refines, getattr(mi, 'author_link_map', None))
if ok('user_categories'): if ok('user_categories'):
set_user_categories(root, prefixes, refines, getattr(mi, 'user_categories', None)) set_user_categories(root, prefixes, refines, getattr(mi, 'user_categories', None))
# We ignore apply_null for the next two to match the behavior with opf2.py
if mi.application_id:
set_application_id(root, prefixes, refines, mi.application_id)
if mi.uuid:
set_uuid(root, prefixes, refines, mi.uuid)
new_user_metadata, current_user_metadata = mi.get_all_user_metadata(True), current_mi.get_all_user_metadata(True) new_user_metadata, current_user_metadata = mi.get_all_user_metadata(True), current_mi.get_all_user_metadata(True)
missing = object() missing = object()
for key in tuple(new_user_metadata): for key in tuple(new_user_metadata):

View File

@ -74,7 +74,7 @@ class TestOPF3(unittest.TestCase):
root = self.get_opf(metadata=idt('a:1')+idt('a:2')+idt('calibre:x')+idt('uuid:y')) root = self.get_opf(metadata=idt('a:1')+idt('a:2')+idt('calibre:x')+idt('uuid:y'))
mi = read_metadata(root) mi = read_metadata(root)
self.ae(mi.application_id, 'x') self.ae(mi.application_id, 'x')
set_application_id(root, default_refines, 'y') set_application_id(root, {}, default_refines, 'y')
mi = read_metadata(root) mi = read_metadata(root)
self.ae(mi.application_id, 'y') self.ae(mi.application_id, 'y')
@ -86,7 +86,7 @@ class TestOPF3(unittest.TestCase):
set_identifiers(root, read_prefixes(root), default_refines, {'i':'2', 'o':'2'}, force_identifiers=True) set_identifiers(root, read_prefixes(root), default_refines, {'i':'2', 'o':'2'}, force_identifiers=True)
self.ae({'i':['2', '1'], 'o':['2']}, ri(root)) self.ae({'i':['2', '1'], 'o':['2']}, ri(root))
root = self.get_opf(metadata=idt('i:1', iid='uid') + idt('r:1') + idt('o:1')) root = self.get_opf(metadata=idt('i:1', iid='uid') + idt('r:1') + idt('o:1'))
set_application_id(root, default_refines, 'y') set_application_id(root, {}, default_refines, 'y')
mi = read_metadata(root) mi = read_metadata(root)
self.ae(mi.application_id, 'y') self.ae(mi.application_id, 'y')
# }}} # }}}
@ -478,23 +478,24 @@ class TestOPF3(unittest.TestCase):
def compare_metadata(mi2, mi3): def compare_metadata(mi2, mi3):
self.ae(mi2.get_all_user_metadata(False), mi3.get_all_user_metadata(False)) self.ae(mi2.get_all_user_metadata(False), mi3.get_all_user_metadata(False))
for field in ALL_METADATA_FIELDS: for field in ALL_METADATA_FIELDS:
if field in 'manifest uuid'.split(): if field != 'manifest':
continue v2, v3 = getattr(mi2, field, None), getattr(mi3, field, None)
v2, v3 = getattr(mi2, field, None), getattr(mi3, field, None) self.ae(v2, v3, '%s: %r != %r' % (field, v2, v3))
self.ae(v2, v3, '%s: %r != %r' % (field, v2, v3))
mi2 = OPF(BytesIO(raw.encode('utf-8'))).to_book_metadata() mi2 = OPF(BytesIO(raw.encode('utf-8'))).to_book_metadata()
root = etree.fromstring(raw) root = etree.fromstring(raw)
root.set('version', '3.0') root.set('version', '3.0')
mi3 = read_metadata(root) mi3 = read_metadata(root)
compare_metadata(mi2, mi3) compare_metadata(mi2, mi3)
apply_metadata(root, mi3) apply_metadata(root, mi3, force_identifiers=True)
compare_metadata(mi3, read_metadata(root)) nmi = read_metadata(root)
compare_metadata(mi3, nmi)
mi3.tags = [] mi3.tags = []
mi3.set('#tags', []) mi3.set('#tags', [])
mi3.set('#number', 0) mi3.set('#number', 0)
mi3.set('#commetns', '') mi3.set('#commetns', '')
apply_metadata(root, mi3) apply_metadata(root, mi3, update_timestamp=True)
self.assertFalse(root.xpath('//*/@name'))
nmi = read_metadata(root) nmi = read_metadata(root)
self.assertEqual(mi2.tags, nmi.tags) self.assertEqual(mi2.tags, nmi.tags)
self.assertEqual(mi2.get('#tags'), nmi.get('#tags')) self.assertEqual(mi2.get('#tags'), nmi.get('#tags'))