kopia lustrzana https://github.com/inkstitch/inkstitch
86 wiersze
2.2 KiB
Python
86 wiersze
2.2 KiB
Python
![]() |
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)
|