Coverage for lib/lottie/parsers/sif/xml/core_nodes.py: 85%
103 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
1from xml.dom import minidom
2import copy
3from uuid import uuid4
5from .utils import *
6from lottie.parsers.sif.sif.core import ObjectRegistry
9class XmlDescriptor:
10 def __init__(self, name):
11 self.name = name
12 self.att_name = name.replace("-", "_").replace("[", "_").replace("]", "").replace(".", "_")
14 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
15 raise NotImplementedError
17 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
18 raise NotImplementedError
20 def from_python(self, value):
21 raise NotImplementedError
23 def initialize_object(self, dict, obj):
24 if self.att_name in dict:
25 setattr(obj, self.att_name, self.from_python(dict[self.att_name]))
26 else:
27 setattr(obj, self.att_name, self.default())
29 def clean(self, value):
30 return self.from_python(value)
32 def default(self):
33 return None
35 def __repr__(self):
36 return "%s(%r)" % (self.__class__.__name__, self.name)
39class TypedXmlDescriptor(XmlDescriptor):
40 def __init__(self, name, type=str, default_value=None, att_name=None):
41 super().__init__(name)
42 self.type = type
43 self.default_value = default_value
44 if att_name is not None:
45 self.att_name = att_name
47 def from_python(self, value):
48 if value is None and self.default_value is None:
49 return None
50 if not value_isinstance(value, self.type):
51 return self.type(value)
52 return value
54 def default(self):
55 return copy.deepcopy(self.default_value)
58class ValueReference:
59 def __init__(self, id, value=None):
60 self.value = value
61 self.id = id
63 @classmethod
64 def from_registry(cls, id, registry: ObjectRegistry):
65 return cls(id, registry.get_object(id))
68class XmlAttribute(TypedXmlDescriptor):
69 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
70 xml_str = parent.getAttribute(self.name)
71 if xml_str:
72 if xml_str.startswith(":") and xml_str[1:] in registry.registry: 72 ↛ 73line 72 didn't jump to line 73, because the condition on line 72 was never true
73 value = ValueReference.from_registry(xml_str[1:], registry)
74 else:
75 value = value_from_xml_string(xml_str, self.type, registry)
76 setattr(obj, self.att_name, value)
78 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
79 value = getattr(obj, self.att_name)
80 if value is not None: 80 ↛ exitline 80 didn't return from function 'to_xml', because the condition on line 80 was never false
81 if isinstance(value, ValueReference): 81 ↛ 82line 81 didn't jump to line 82, because the condition on line 81 was never true
82 xml_str = ":" + value.id
83 else:
84 xml_str = value_to_xml_string(value, self.type)
85 parent.setAttribute(self.name, xml_str)
88class XmlFixedAttribute(XmlDescriptor):
89 def __init__(self, name, value, type=str):
90 super().__init__(name)
91 self.value = value
92 self.type = type
94 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
95 parent.setAttribute(self.name, value_to_xml_string(self.value, self.type))
97 def from_python(self, value):
98 if value != self.value: 98 ↛ 99line 98 didn't jump to line 99, because the condition on line 98 was never true
99 raise ValueError("Value of %s should be %s, got %s" % (self.name, self.value, value))
100 return value
102 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
103 xml_str = parent.getAttribute(self.name)
104 setattr(obj, self.att_name, value_from_xml_string(xml_str, self.type, registry))
106 def default(self):
107 return self.value
110class XmlSimpleElement(TypedXmlDescriptor):
111 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
112 cn = xml_first_element_child(parent, self.name, allow_none=True)
113 if cn: 113 ↛ 116line 113 didn't jump to line 116, because the condition on line 113 was never false
114 value = value_from_xml_string(xml_text(cn), self.type, registry)
115 else:
116 value = self.default_value
118 setattr(obj, self.att_name, value)
120 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
121 value = getattr(obj, self.att_name)
122 if value is not None: 122 ↛ exitline 122 didn't return from function 'to_xml', because the condition on line 122 was never false
123 parent.appendChild(xml_make_text(dom, self.name, value_to_xml_string(value, self.type)))
126class XmlMeta(TypedXmlDescriptor):
127 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
128 for cn in xml_child_elements(parent, "meta"): 128 ↛ 133line 128 didn't jump to line 133, because the loop on line 128 didn't complete
129 if cn.getAttribute("name") == self.name:
130 value = value_from_xml_string(cn.getAttribute("content"), self.type, registry)
131 break
132 else:
133 value = self.default_value
135 setattr(obj, self.att_name, value)
137 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
138 value = getattr(obj, self.att_name)
139 if value is not None: 139 ↛ exitline 139 didn't return from function 'to_xml', because the condition on line 139 was never false
140 meta = parent.appendChild(dom.createElement("meta"))
141 meta.setAttribute("name", self.name)
142 meta.setAttribute("content", value_to_xml_string(value, self.type))