Initial Commit

This commit is contained in:
OmniLottie
2026-03-01 21:36:54 +08:00
commit a386c803e1
199 changed files with 42253 additions and 0 deletions
+142
View File
@@ -0,0 +1,142 @@
from xml.dom import minidom
import copy
from uuid import uuid4
from .utils import *
from lottie.parsers.sif.sif.core import ObjectRegistry
class XmlDescriptor:
def __init__(self, name):
self.name = name
self.att_name = name.replace("-", "_").replace("[", "_").replace("]", "").replace(".", "_")
def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
raise NotImplementedError
def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
raise NotImplementedError
def from_python(self, value):
raise NotImplementedError
def initialize_object(self, dict, obj):
if self.att_name in dict:
setattr(obj, self.att_name, self.from_python(dict[self.att_name]))
else:
setattr(obj, self.att_name, self.default())
def clean(self, value):
return self.from_python(value)
def default(self):
return None
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self.name)
class TypedXmlDescriptor(XmlDescriptor):
def __init__(self, name, type=str, default_value=None, att_name=None):
super().__init__(name)
self.type = type
self.default_value = default_value
if att_name is not None:
self.att_name = att_name
def from_python(self, value):
if value is None and self.default_value is None:
return None
if not value_isinstance(value, self.type):
return self.type(value)
return value
def default(self):
return copy.deepcopy(self.default_value)
class ValueReference:
def __init__(self, id, value=None):
self.value = value
self.id = id
@classmethod
def from_registry(cls, id, registry: ObjectRegistry):
return cls(id, registry.get_object(id))
class XmlAttribute(TypedXmlDescriptor):
def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
xml_str = parent.getAttribute(self.name)
if xml_str:
if xml_str.startswith(":") and xml_str[1:] in registry.registry:
value = ValueReference.from_registry(xml_str[1:], registry)
else:
value = value_from_xml_string(xml_str, self.type, registry)
setattr(obj, self.att_name, value)
def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
value = getattr(obj, self.att_name)
if value is not None:
if isinstance(value, ValueReference):
xml_str = ":" + value.id
else:
xml_str = value_to_xml_string(value, self.type)
parent.setAttribute(self.name, xml_str)
class XmlFixedAttribute(XmlDescriptor):
def __init__(self, name, value, type=str):
super().__init__(name)
self.value = value
self.type = type
def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
parent.setAttribute(self.name, value_to_xml_string(self.value, self.type))
def from_python(self, value):
if value != self.value:
raise ValueError("Value of %s should be %s, got %s" % (self.name, self.value, value))
return value
def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
xml_str = parent.getAttribute(self.name)
setattr(obj, self.att_name, value_from_xml_string(xml_str, self.type, registry))
def default(self):
return self.value
class XmlSimpleElement(TypedXmlDescriptor):
def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
cn = xml_first_element_child(parent, self.name, allow_none=True)
if cn:
value = value_from_xml_string(xml_text(cn), self.type, registry)
else:
value = self.default_value
setattr(obj, self.att_name, value)
def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
value = getattr(obj, self.att_name)
if value is not None:
parent.appendChild(xml_make_text(dom, self.name, value_to_xml_string(value, self.type)))
class XmlMeta(TypedXmlDescriptor):
def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry):
for cn in xml_child_elements(parent, "meta"):
if cn.getAttribute("name") == self.name:
value = value_from_xml_string(cn.getAttribute("content"), self.type, registry)
break
else:
value = self.default_value
setattr(obj, self.att_name, value)
def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document):
value = getattr(obj, self.att_name)
if value is not None:
meta = parent.appendChild(dom.createElement("meta"))
meta.setAttribute("name", self.name)
meta.setAttribute("content", value_to_xml_string(value, self.type))