Skip to content

Commit

Permalink
[OPT-1018] DrawioToDict improvements - refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
smaneroiriusrisk committed Oct 17, 2023
1 parent 00433b8 commit 57f31c5
Show file tree
Hide file tree
Showing 22 changed files with 5,251 additions and 444 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def add_children(children, tag_name, separated_attributes):
return {tag_name: {k: v[0] if len(v) == 1 else v for k, v in dd.items()}}


def xml2dict(t, separated_attributes=False):
def xml2dict(t, separated_attributes=False) -> dict:
tag_name = get_tag(t)
d = {tag_name: {} if t.attrib else None}
children = list(t)
Expand All @@ -61,11 +61,11 @@ def xml2dict(t, separated_attributes=False):
return d


class XmlToJson:
class XmlToDict:

def __init__(self, xml: str):
self.xml = xml

def to_json(self):
def to_dict(self) -> dict:
xml_data = ElementTree.XML(self.xml)
return xml2dict(xml_data)
File renamed without changes.
7 changes: 7 additions & 0 deletions sl_util/tests/resources/test_resource_paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import os

path = os.path.dirname(__file__)

# xml testing files
random_data_xml = f'{path}/xml/random_data.xml'
random_data_xml_json = f'{path}/xml/random_data_xml.json'
33 changes: 33 additions & 0 deletions sl_util/tests/resources/xml/random_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<root>
<flower>sunlight</flower>
<with waste="hurried">men</with>
<reason ship="nuts">-862244492</reason>
<exclaimed>
<widely>composition</widely>
<!--excited-->
<regular>spirit</regular>
<record>
<another experience="twice">
<!--sentence rays person-->
<teacher food="hay">1184223729.943545</teacher>
<count>magic</count>
<title>648067907.3277977</title>
<strange immediately="bread">change</strange>
<!--mainly row-->
<instrument>particular</instrument>
<finest>-1459099875.7289388</finest>
</another>
<hay smell="plates">loose</hay>
<tobacco>552630041.6824405</tobacco>
<peace suppose="motor">-45766333</peace>
<!--badly know nobody distance mighty-->
<birthday>stretch</birthday>
<food native="good">within</food>
</record>
<cookies tobacco="conversation">-1213510200.834167</cookies>
<dinner>-557912696.1980629</dinner>
<yard alone="willing">birds</yard>
</exclaimed>
<identity>459467385.41047287</identity>
<clean recognize="dried">1248105488</clean>
</root>
62 changes: 62 additions & 0 deletions sl_util/tests/resources/xml/random_data_xml.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"root": {
"clean": {
"recognize": "dried",
"text": "1248105488"
},
"exclaimed": {
"cookies": {
"text": "-1213510200.834167",
"tobacco": "conversation"
},
"dinner": "-557912696.1980629",
"record": {
"another": {
"count": "magic",
"experience": "twice",
"finest": "-1459099875.7289388",
"instrument": "particular",
"strange": {
"immediately": "bread",
"text": "change"
},
"teacher": {
"food": "hay",
"text": "1184223729.943545"
},
"title": "648067907.3277977"
},
"birthday": "stretch",
"food": {
"native": "good",
"text": "within"
},
"hay": {
"smell": "plates",
"text": "loose"
},
"peace": {
"suppose": "motor",
"text": "-45766333"
},
"tobacco": "552630041.6824405"
},
"regular": "spirit",
"widely": "composition",
"yard": {
"alone": "willing",
"text": "birds"
}
},
"flower": "sunlight",
"identity": "459467385.41047287",
"reason": {
"ship": "nuts",
"text": "-862244492"
},
"with": {
"text": "men",
"waste": "hurried"
}
}
}
41 changes: 41 additions & 0 deletions sl_util/tests/unit/test_xml_to_dict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import json
from unittest import TestCase

import pytest

from sl_util.sl_util.dict_utils import compare_dict
from sl_util.sl_util.file_utils import get_byte_data
from sl_util.sl_util.xml_to_dict import XmlToDict
from sl_util.tests.resources.test_resource_paths import random_data_xml, random_data_xml_json


class TestXmlToDict(TestCase):

def test_to_dict(self):
# GIVEN the source MTMT data
xml = get_byte_data(random_data_xml).decode()
# AND the parser
parser = XmlToDict(xml)
# AND the expected result
expected_data = json.loads(get_byte_data(random_data_xml_json).decode())

# WHEN we convert to json
result_data = parser.to_dict()

# THEN the result is as expected
result, expected = compare_dict(result_data, expected_data)
assert result == expected

def test_to_dict_invalid_data(self):
# GIVEN the source MTMT data
xml = "INVALID XML CONTENT"
# AND the parser
parser = XmlToDict(xml)

# WHEN we convert to json
# THEN a ParseError is raised
with pytest.raises(Exception) as error:
parser.to_dict()
# AND the error is as expected
assert error.typename == 'ParseError'
assert str(error.value.msg) == 'syntax error: line 1, column 0'
18 changes: 9 additions & 9 deletions slp_drawio/slp_drawio/load/drawio_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ class DrawioLoader(ProviderLoader):
Builder for a drawio class from the xml data
"""

def __init__(self, project_id: str, source):
self.project_id = project_id
self.source = source
self.diagram = None

def load(self):
try:
source = DrawIOToDict(self.source).to_dict()
source_dict = DrawIOToDict(self.source).to_dict()

representation: DiagramRepresentation = DiagramRepresentationLoader(self.project_id, source).load()
components: [DiagramComponent] = DiagramComponentLoader(source).load()
dataflows: [DiagramDataflow] = DiagramDataflowLoader(source).load()
representation: DiagramRepresentation = DiagramRepresentationLoader(self.project_id, source_dict).load()
components: [DiagramComponent] = DiagramComponentLoader(source_dict).load()
dataflows: [DiagramDataflow] = DiagramDataflowLoader(source_dict).load()

self.diagram: Diagram = Diagram(representation, components, dataflows)
except Exception as e:
Expand All @@ -32,10 +37,5 @@ def load(self):
message = e.__str__()
raise LoadingSourceFileError('Source file cannot be loaded', detail, message)

def __init__(self, project_id: str, source):
self.project_id = project_id
self.source = source
self.diagram = None

def get_diagram(self) -> Diagram:
return self.diagram
31 changes: 28 additions & 3 deletions slp_drawio/slp_drawio/load/drawio_to_dict.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,41 @@
import base64
import logging
import zlib
from tempfile import SpooledTemporaryFile
from urllib.parse import unquote

from slp_drawio.slp_drawio.load.objects.drawio_wrapper import DrawioWrapper
from defusedxml import ElementTree

from sl_util.sl_util.xml_to_dict import XmlToDict

logger = logging.getLogger(__name__)

DEFAULT_ENCODING = 'utf8'
DIAGRAM_TAG = 'diagram'


class DrawIOToDict:

def __init__(self, source):
file: SpooledTemporaryFile = source.file
self.wrapper = DrawioWrapper(file.read())
self.encoding = 'utf8'
self.content: str = file.read().decode()
self.decode_b64_tag('diagram')

def to_dict(self) -> dict:
return self.wrapper.json()
return XmlToDict(self.content).to_dict()

def decode_b64_tag(self, tag):
tree = ElementTree.XML(self.content)
tree_tag = tree.find(tag)
children = list(tree_tag.iter())
if len(children) <= 1:
logger.debug(f'{tag} tag is encoded')
data = base64.b64decode(tree_tag.text, validate=True)
xml = zlib.decompress(data, wbits=-15).decode()
xml = unquote(xml)
diagram_tree = ElementTree.fromstring(xml)
tree_tag.append(diagram_tree)
tree_tag.text = None
self.content = ElementTree.tostring(tree, encoding=self.encoding)
logger.debug(f'{tag} tag decoded successfully')
32 changes: 0 additions & 32 deletions slp_drawio/slp_drawio/load/objects/drawio_wrapper.py

This file was deleted.

32 changes: 0 additions & 32 deletions slp_drawio/tests/load/objects/test_drawio_wrapper.py

This file was deleted.

35 changes: 0 additions & 35 deletions slp_drawio/tests/load/test_drawio_to_dict.py

This file was deleted.

File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 57f31c5

Please sign in to comment.