diff options
Diffstat (limited to 'lib/metadata.py')
| -rw-r--r-- | lib/metadata.py | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/lib/metadata.py b/lib/metadata.py new file mode 100644 index 00000000..837fbf00 --- /dev/null +++ b/lib/metadata.py @@ -0,0 +1,85 @@ +import json +import re +from collections.abc import MutableMapping + +import inkex +from lxml import etree + +from .utils.settings import DEFAULT_METADATA, global_settings + + +def strip_namespace(tag): + """Remove xml namespace from a tag name. + + >>> {http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd}namedview + <<< namedview + """ + + match = re.match(r'^\{[^}]+\}(.+)$', tag) + + if match: + return match.group(1) + else: + return tag + + +class InkStitchMetadata(MutableMapping): + """Helper class to get and set inkstitch-specific metadata attributes. + + Operates on a document and acts like a dict. Setting an item adds or + updates a metadata element in the document. Getting an item retrieves + a metadata element's text contents or None if an element by that name + doesn't exist. + """ + + def __init__(self, document): + super().__init__() + self.document = document + self.metadata = document.metadata + + for setting in DEFAULT_METADATA: + if self[setting] is None: + self[setting] = global_settings[f'default_{setting}'] + + # Because this class inherints from MutableMapping, all we have to do is + # implement these five methods and we get a full dict-like interface. + def __setitem__(self, name, value): + item = self._find_item(name) + item.text = json.dumps(value) + + def _find_item(self, name, create=True): + tag = inkex.addNS(name, "inkstitch") + item = self.metadata.find(tag) + if item is None and create: + item = etree.SubElement(self.metadata, tag) + + return item + + def __getitem__(self, name): + item = self._find_item(name) + + try: + return json.loads(item.text) + except (ValueError, TypeError): + return None + + def __delitem__(self, name): + item = self._find_item(name, create=False) + + if item is not None: + self.metadata.remove(item) + + def __iter__(self): + for child in self.metadata: + if child.prefix == "inkstitch": + yield strip_namespace(child.tag) + + def __len__(self): + i = 0 + for i, item in enumerate(self): + pass + + return i + 1 + + def __json__(self): + return dict(self) |
