mirror of
https://github.com/OpenVGLab/OmniLottie.git
synced 2026-09-17 07:36:27 +00:00
Initial Commit
This commit is contained in:
@@ -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))
|
||||
Reference in New Issue
Block a user