diff --git a/pymvr/__init__.py b/pymvr/__init__.py index ecf28c9..fe622d6 100644 --- a/pymvr/__init__.py +++ b/pymvr/__init__.py @@ -31,7 +31,7 @@ from .value import Matrix, Color # type: ignore from enum import Enum -__version__ = "1.0.2" +__version__ = "1.0.3.dev9" def _find_root(pkg: "zipfile.ZipFile") -> "ElementTree.Element": @@ -91,7 +91,7 @@ def __init__(self): verMajor=self.version_major, verMinor=self.version_minor, provider=self.provider, - provider_version=self.provider_version, + providerVersion=self.provider_version, ) def write_mvr(self, path: Optional[str] = None): @@ -207,7 +207,7 @@ def __init__( *args, **kwargs, ): - self.layers = layers + self.layers = layers if layers else Layers() self.aux_data = aux_data super().__init__(xml_node, *args, **kwargs) @@ -215,6 +215,8 @@ def _read_xml(self, xml_node: "Element"): layers_node = xml_node.find("Layers") if layers_node is not None: self.layers = Layers(xml_node=layers_node) + else: + self.layers = Layers() aux_data_collect = xml_node.find("AUXData") @@ -225,11 +227,10 @@ def _read_xml(self, xml_node: "Element"): def to_xml(self, parent: Element): element = ElementTree.SubElement(parent, "Scene") - if self.layers: + if self.layers is not None: self.layers.to_xml(element) if self.aux_data: self.aux_data.to_xml(element) - return element class Layers(BaseNode): @@ -298,7 +299,6 @@ def to_xml(self, parent: Element): element = ElementTree.SubElement(parent, type(self).__name__) for _data in self.data: element.append(_data.to_xml()) - return element class ScaleHandelingEnum(Enum): @@ -412,13 +412,13 @@ def __len__(self): class BaseChildNode(BaseNode): def __init__( self, - name: Optional[str] = None, + name: Optional[str] = "", uuid: Optional[str] = None, gdtf_spec: Optional[str] = None, gdtf_mode: Optional[str] = None, matrix: Optional[Matrix] = None, classing: Optional[str] = None, - fixture_id: Optional[str] = None, + fixture_id: Optional[str] = "", fixture_id_numeric: int = 0, unit_number: int = 0, custom_id: int = 0, @@ -461,7 +461,7 @@ def __init__( super().__init__(xml_node, *args, **kwargs) def _read_xml(self, xml_node: "Element"): - self.name = xml_node.attrib.get("name") + self.name = xml_node.attrib.get("name") or "" uuid = xml_node.attrib.get("uuid") if uuid is not None: self.uuid = uuid @@ -487,7 +487,7 @@ def _read_xml(self, xml_node: "Element"): _fixture_id_node = xml_node.find("FixtureID") if _fixture_id_node is not None: - self.fixture_id = _fixture_id_node.text + self.fixture_id = _fixture_id_node.text or "" _fixture_id_numeric_node = xml_node.find("FixtureIDNumeric") if ( @@ -572,7 +572,9 @@ def populate_xml(self, element: Element): if self.connections: self.connections.to_xml(element) - ElementTree.SubElement(element, "FixtureID").text = str(self.fixture_id) or "0" + ElementTree.SubElement(element, "FixtureID").text = ( + str(self.fixture_id or "") or "" + ) ElementTree.SubElement(element, "FixtureIDNumeric").text = str( self.fixture_id_numeric ) @@ -692,7 +694,7 @@ def to_xml(self, parent: Element): class MappingDefinition(BaseNode): def __init__( self, - name: Optional[str] = None, + name: Optional[str] = "", uuid: Optional[str] = None, size_x: int = 0, size_y: int = 0, @@ -703,6 +705,8 @@ def __init__( **kwargs, ): self.name = name + if uuid is None: + uuid = str(py_uuid.uuid4()) self.uuid = uuid self.size_x = size_x self.size_y = size_y @@ -713,8 +717,10 @@ def __init__( super().__init__(xml_node, *args, **kwargs) def _read_xml(self, xml_node: "Element"): - self.name = xml_node.attrib.get("name") - self.uuid = xml_node.attrib.get("uuid") + self.name = xml_node.attrib.get("name") or "" + uuid = xml_node.attrib.get("uuid") + if uuid is not None: + self.uuid = uuid size_x_node = xml_node.find("SizeX") if size_x_node is not None and size_x_node.text is not None: @@ -757,7 +763,6 @@ def __init__( protocols: Optional["Protocols"] = None, mappings: Optional["Mappings"] = None, gobo: Optional["Gobo"] = None, - unit_number: int = 0, xml_node: Optional["Element"] = None, *args, **kwargs, @@ -772,7 +777,6 @@ def __init__( self.protocols = protocols if protocols is not None else Protocols() self.mappings = mappings if mappings is not None else Mappings() self.gobo = gobo - self.unit_number = unit_number kwargs["xml_node"] = xml_node super().__init__(*args, **kwargs) @@ -821,10 +825,6 @@ def _read_xml(self, xml_node: "Element"): if gobo_node is not None: self.gobo = Gobo(xml_node=gobo_node) - unit_number_node = xml_node.find("UnitNumber") - if unit_number_node is not None and unit_number_node.text is not None: - self.unit_number = int(unit_number_node.text) - def to_xml(self): attributes = {"name": self.name, "uuid": self.uuid} if self.multipatch: @@ -858,8 +858,6 @@ def to_xml(self): if self.gobo: element.append(self.gobo.to_xml()) - ElementTree.SubElement(element, "UnitNumber").text = str(self.unit_number) - return element def __str__(self): @@ -869,7 +867,7 @@ def __str__(self): class GroupObject(BaseNode): def __init__( self, - name: Optional[str] = None, + name: Optional[str] = "", uuid: Optional[str] = None, classing: Optional[str] = None, child_list: Optional["ChildList"] = None, @@ -879,7 +877,9 @@ def __init__( **kwargs, ): self.name = name - self.uuid = uuid + if uuid is None: + uuid = str(py_uuid.uuid4()) + self.uuid: str = uuid self.classing = classing self.child_list = child_list self.matrix = matrix if matrix is not None else Matrix(0) @@ -887,8 +887,10 @@ def __init__( super().__init__(xml_node, *args, **kwargs) def _read_xml(self, xml_node: "Element"): - self.name = xml_node.attrib.get("name") - self.uuid = xml_node.attrib.get("uuid") + self.name = xml_node.attrib.get("name") or "" + uuid = xml_node.attrib.get("uuid") + if uuid is not None: + self.uuid = uuid classing_node = xml_node.find("Classing") if classing_node is not None: self.classing = classing_node.text @@ -1008,7 +1010,7 @@ def __init__( super().__init__(xml_node, *args, **kwargs) def _read_xml(self, xml_node: "Element"): - self.name = xml_node.attrib.get("name", "") + self.name = xml_node.attrib.get("name") or "" uuid = xml_node.attrib.get("uuid") if uuid is not None: self.uuid = uuid @@ -1086,18 +1088,22 @@ class Class(BaseNode): def __init__( self, uuid: Optional[str] = None, - name: Optional[str] = None, + name: Optional[str] = "", xml_node: Optional["Element"] = None, *args, **kwargs, ): + if uuid is None: + uuid = str(py_uuid.uuid4()) self.uuid = uuid self.name = name super().__init__(xml_node, *args, **kwargs) def _read_xml(self, xml_node: "Element"): - self.name = xml_node.attrib.get("name") - self.uuid = xml_node.attrib.get("uuid") + self.name = xml_node.attrib.get("name") or "" + uuid = xml_node.attrib.get("uuid") + if uuid is not None: + self.uuid = uuid def __str__(self): return f"{self.name}" @@ -1113,18 +1119,22 @@ class Position(BaseNode): def __init__( self, uuid: Optional[str] = None, - name: Optional[str] = None, + name: Optional[str] = "", xml_node: Optional["Element"] = None, *args, **kwargs, ): + if uuid is None: + uuid = str(py_uuid.uuid4()) self.uuid = uuid self.name = name super().__init__(xml_node, *args, **kwargs) def _read_xml(self, xml_node: "Element"): - self.name = xml_node.attrib.get("name") - self.uuid = xml_node.attrib.get("uuid") + self.name = xml_node.attrib.get("name") or "" + uuid = xml_node.attrib.get("uuid") + if uuid is not None: + self.uuid = uuid def __str__(self): return f"{self.name}" @@ -1136,51 +1146,6 @@ def to_xml(self): return element -class Symdef(BaseNode): - def __init__( - self, - uuid: Optional[str] = None, - name: Optional[str] = None, - geometry3d: Optional[List["Geometry3D"]] = None, - symbol: Optional[List["Symbol"]] = None, - xml_node: Optional["Element"] = None, - *args, - **kwargs, - ): - self.uuid = uuid - self.name = name - self.geometry3d = geometry3d if geometry3d is not None else [] - self.symbol = symbol if symbol is not None else [] - super().__init__(xml_node, *args, **kwargs) - - def _read_xml(self, xml_node: "Element"): - self.name = xml_node.attrib.get("name") - self.uuid = xml_node.attrib.get("uuid") - - child_list = xml_node.find("ChildList") - if child_list is not None: - self.symbol = [Symbol(xml_node=i) for i in child_list.findall("Symbol")] - _geometry3d = [ - Geometry3D(xml_node=i) for i in child_list.findall("Geometry3D") - ] - else: - self.symbol = [] - _geometry3d = [] - - # sometimes the list of geometry3d is full of duplicates, eliminate them here - self.geometry3d = list(set(_geometry3d)) - - def to_xml(self): - element = ElementTree.Element( - type(self).__name__, name=self.name, uuid=self.uuid - ) - for geo in self.geometry3d: - element.append(geo.to_xml()) - for sym in self.symbol: - element.append(sym.to_xml()) - return element - - class Geometry3D(BaseNode): def __init__( self, @@ -1233,13 +1198,17 @@ def __init__( *args, **kwargs, ): - self.uuid = uuid + if uuid is None: + uuid = str(py_uuid.uuid4()) + self.uuid: str = uuid self.symdef = symdef self.matrix = matrix if matrix is not None else Matrix(0) super().__init__(xml_node, *args, **kwargs) def _read_xml(self, xml_node: "Element"): - self.uuid = xml_node.attrib.get("uuid") + uuid = xml_node.attrib.get("uuid") + if uuid is not None: + self.uuid = uuid self.symdef = xml_node.attrib.get("symdef") matrix_node = xml_node.find("Matrix") if matrix_node is not None and matrix_node.text is not None: @@ -1284,11 +1253,58 @@ def to_xml(self, parent: Element): return element +class SymdefChildList(Geometries): + # this is like the Geometries class, but called ChildList + def to_xml(self, parent: Element): + element = ElementTree.SubElement(parent, "ChildList") + for geo in self.geometry3d: + element.append(geo.to_xml()) + for sym in self.symbol: + element.append(sym.to_xml()) + return element + + +class Symdef(BaseNode): + def __init__( + self, + uuid: Optional[str] = None, + name: Optional[str] = "", + child_list: Optional["SymdefChildList"] = None, + xml_node: Optional["Element"] = None, + *args, + **kwargs, + ): + self.name = name + if uuid is None: + uuid = str(py_uuid.uuid4()) + self.uuid: str = uuid + self.child_list = child_list + super().__init__(xml_node, *args, **kwargs) + + def _read_xml(self, xml_node: "Element"): + self.name = xml_node.attrib.get("name") or "" + uuid = xml_node.attrib.get("uuid") + if uuid is not None: + self.uuid = uuid + + child_list_node = xml_node.find("ChildList") + if child_list_node is not None: + self.child_list = SymdefChildList(xml_node=child_list_node) + + def to_xml(self): + element = ElementTree.Element( + type(self).__name__, name=self.name, uuid=self.uuid + ) + if self.child_list: + self.child_list.to_xml(parent=element) + return element + + class FocusPoint(BaseNode): def __init__( self, uuid: Optional[str] = None, - name: Optional[str] = None, + name: Optional[str] = "", matrix: Optional[Matrix] = None, classing: Optional[str] = None, geometries: Optional["Geometries"] = None, @@ -1297,7 +1313,9 @@ def __init__( **kwargs, ): self.name = name - self.uuid = uuid + if uuid is None: + uuid = str(py_uuid.uuid4()) + self.uuid: str = uuid self.matrix = matrix if matrix is not None else Matrix(0) self.classing = classing if geometries is None: @@ -1307,8 +1325,10 @@ def __init__( super().__init__(xml_node, *args, **kwargs) def _read_xml(self, xml_node: "Element"): - self.uuid = xml_node.attrib.get("uuid") - self.name = xml_node.attrib.get("name") + uuid = xml_node.attrib.get("uuid") + if uuid is not None: + self.uuid = uuid + self.name = xml_node.attrib.get("name") or "" matrix_node = xml_node.find("Matrix") if matrix_node is not None and matrix_node.text is not None: self.matrix = Matrix(str_repr=matrix_node.text) @@ -1504,7 +1524,7 @@ class Protocol(BaseNode): def __init__( self, geometry: Optional[str] = "NetworkInOut_1", - name: Optional[str] = None, + name: Optional[str] = "", type_: Optional[str] = None, version: Optional[str] = None, transmission: Optional[str] = None, @@ -1521,7 +1541,7 @@ def __init__( def _read_xml(self, xml_node: "Element"): self.geometry = xml_node.attrib.get("geometry") - self.name = xml_node.attrib.get("name") + self.name = xml_node.attrib.get("name") or "" self.type = xml_node.attrib.get("type") self.version = xml_node.attrib.get("version") self.transmission = xml_node.attrib.get("transmission") @@ -1546,6 +1566,10 @@ def to_xml(self): class Alignment(BaseNode): + geometry: Optional[str] + up: Optional[str] + direction: Optional[str] + def __init__( self, geometry: Optional[str] = "Beam", @@ -1589,12 +1613,12 @@ def __init__( *args, **kwargs, ): - self.universal = universal + self.universal = universal if universal is not None else "" self.target = target super().__init__(xml_node, *args, **kwargs) def _read_xml(self, xml_node: "Element"): - self.universal = xml_node.attrib.get("universal") + self.universal = xml_node.attrib.get("universal") or "" self.target = xml_node.attrib.get("target") def __str__(self):