From 9e6ee404b96e824e00a7b56535821814172d89d0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 17 Jun 2016 21:04:08 +0530 Subject: [PATCH] Setting of application_id Also when deleting elements, remove all refines that refer to them --- src/calibre/ebooks/metadata/opf3.py | 28 +++++++++++++++++++++++- src/calibre/ebooks/metadata/opf3_test.py | 13 ++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/calibre/ebooks/metadata/opf3.py b/src/calibre/ebooks/metadata/opf3.py index 1b6570a8d7..eae6a2502c 100644 --- a/src/calibre/ebooks/metadata/opf3.py +++ b/src/calibre/ebooks/metadata/opf3.py @@ -43,6 +43,12 @@ def regex(r, flags=0): except KeyError: _re_cache[(r, flags)] = ans = re.compile(r, flags) return ans + +def remove_element(e, refines): + e.getparent().remove(e) + for x in refines[e.get('id')]: + x.getparent().remove(x) + refines.pop(e.get('id'), None) # }}} # Prefixes {{{ @@ -133,7 +139,7 @@ def set_identifiers(root, prefixes, refines, new_identifiers, force_identifiers= continue scheme, val = parse_identifier(ident, val, refines) if not scheme or not val or force_identifiers or scheme in new_identifiers: - ident.getparent().remove(ident) + remove_element(ident, refines) continue metadata = XPath('./opf:metadata')(root)[0] for scheme, val in new_identifiers.iteritems(): @@ -145,6 +151,26 @@ def set_identifiers(root, prefixes, refines, new_identifiers, force_identifiers= p = package_identifier.getparent() p.insert(p.index(package_identifier), ident) +def set_application_id(root, refines, new_application_id=None): + uid = root.get('unique-identifier') + package_identifier = None + for ident in XPath('./opf:metadata/dc:identifier')(root): + is_package_id = uid is not None and uid == ident.get('id') + if is_package_id: + package_identifier = ident + val = (ident.text or '').strip() + if val.startswith('calibre:') and not is_package_id: + remove_element(ident, refines) + metadata = XPath('./opf:metadata')(root)[0] + if new_application_id: + ident = metadata.makeelement(DC('identifier')) + ident.text = 'calibre:%s' % new_application_id + if package_identifier is None: + metadata.append(ident) + else: + p = package_identifier.getparent() + p.insert(p.index(package_identifier), ident) + # }}} def read_metadata(root): diff --git a/src/calibre/ebooks/metadata/opf3_test.py b/src/calibre/ebooks/metadata/opf3_test.py index e2a4be01ff..f9e92a337c 100644 --- a/src/calibre/ebooks/metadata/opf3_test.py +++ b/src/calibre/ebooks/metadata/opf3_test.py @@ -11,7 +11,7 @@ from lxml import etree from calibre.ebooks.metadata.opf3 import ( parse_prefixes, reserved_prefixes, expand_prefix, read_identifiers, - read_metadata, set_identifiers, XPath + read_metadata, set_identifiers, XPath, set_application_id ) TEMPLATE = '''{metadata}''' # noqa @@ -51,9 +51,12 @@ class TestOPF3(unittest.TestCase): (idt('a:1')+idt('a:2'), {'a':['1', '2']}), ): self.ae(result, ri(self.get_opf(m))) - mi = read_metadata(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) self.ae(mi.application_id, 'x') + set_application_id(root, default_refines, 'y') + mi = read_metadata(root) + self.ae(mi.application_id, 'y') root = self.get_opf(metadata=idt('i:1', iid='uid') + idt('r:1') + idt('o:1')) set_identifiers(root, reserved_prefixes, default_refines, {'i':'2', 'o':'2'}) @@ -62,6 +65,10 @@ class TestOPF3(unittest.TestCase): root = self.get_opf(metadata=idt('i:1', iid='uid') + idt('r:1') + idt('o:1')) set_identifiers(root, reserved_prefixes, default_refines, {'i':'2', 'o':'2'}, force_identifiers=True) 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')) + set_application_id(root, default_refines, 'y') + mi = read_metadata(root) + self.ae(mi.application_id, 'y') class TestRunner(unittest.main):