Commit 42b55b5f authored by Łukasz Nowak's avatar Łukasz Nowak Committed by Thomas Gambier

Synchronise xml2dict and dict2xml

All tools from the ecosystem shall use the same way to convert between python's
dict and XML.

Additionally stabilise generated XMLs by sorting the dictionary.
parent 1bc9a264
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
# #
############################################################################## ##############################################################################
from lxml import etree
import random import random
import string import string
import time import time
...@@ -37,7 +36,8 @@ from slapos.slap.slap import Computer, ComputerPartition, \ ...@@ -37,7 +36,8 @@ from slapos.slap.slap import Computer, ComputerPartition, \
SoftwareRelease, SoftwareInstance, NotFoundError SoftwareRelease, SoftwareInstance, NotFoundError
from slapos.proxy.db_version import DB_VERSION from slapos.proxy.db_version import DB_VERSION
import slapos.slap import slapos.slap
from slapos.util import bytes2str, str2bytes, unicode2str, sqlite_connect from slapos.util import bytes2str, unicode2str, sqlite_connect, \
xml2dict, dict2xml
from flask import g, Flask, request, abort from flask import g, Flask, request, abort
from slapos.util import loads, dumps from slapos.util import loads, dumps
...@@ -53,39 +53,6 @@ class UnauthorizedError(Exception): ...@@ -53,39 +53,6 @@ class UnauthorizedError(Exception):
pass pass
def xml2dict(xml):
result_dict = {}
if xml:
tree = etree.fromstring(str2bytes(xml))
for element in tree.iter(tag=etree.Element):
if element.tag == 'parameter':
key = element.get('id')
value = result_dict.get(key, None)
if value is not None:
value = value + ' ' + element.text
else:
value = element.text
result_dict[key] = value
return result_dict
def dict2xml(dictionary):
instance = etree.Element('instance')
for k, v in six.iteritems(dictionary):
if isinstance(k, bytes):
k = k.decode('utf-8')
if isinstance(v, bytes):
v = v.decode('utf-8')
elif not isinstance(v, six.text_type):
v = str(v)
etree.SubElement(instance, "parameter",
attrib={'id': k}).text = v
return bytes2str(etree.tostring(instance,
pretty_print=True,
xml_declaration=True,
encoding='utf-8'))
def partitiondict2partition(partition): def partitiondict2partition(partition):
slap_partition = ComputerPartition(partition['computer_reference'], slap_partition = ComputerPartition(partition['computer_reference'],
partition['reference']) partition['reference'])
......
from lxml import etree
from six.moves.urllib import parse from six.moves.urllib import parse
import netaddr import netaddr
def xml2dict(xml):
result_dict = {}
if xml is not None and xml != '':
tree = etree.fromstring(xml.encode('utf-8'))
for element in tree.iter(tag=etree.Element):
if element.tag == 'parameter':
key = element.get('id')
value = result_dict.get(key, None)
if value is not None:
value = value + ' ' + element.text
else:
value = element.text
result_dict[key] = value
return result_dict
def _addIpv6Brackets(url): def _addIpv6Brackets(url):
# if master_url contains an ipv6 without bracket, add it # if master_url contains an ipv6 without bracket, add it
......
...@@ -120,5 +120,56 @@ class TestUtil(unittest.TestCase): ...@@ -120,5 +120,56 @@ class TestUtil(unittest.TestCase):
for value in [True, False, 1, '1', 't', 'tru', 'truelle', 'f', 'fals', 'falsey']: for value in [True, False, 1, '1', 't', 'tru', 'truelle', 'f', 'fals', 'falsey']:
self.assertRaises(ValueError, string_to_boolean, value) self.assertRaises(ValueError, string_to_boolean, value)
xml2dict_xml = slapos.util.bytes2str(b"""<?xml version='1.0' encoding='utf-8'?>
<instance>
<parameter id="badstr">\xc5\x81</parameter>
<parameter id="badu">\xc5\x81</parameter>
<parameter id="emptystr"></parameter>
<parameter id="int">1</parameter>
<parameter id="intstr">1</parameter>
<parameter id="key">str</parameter>
<parameter id="list">['one', 2]</parameter>
<parameter id="none">None</parameter>
<parameter id="ukey">ustr</parameter>
</instance>
""")
xml2dict_indict = {
u'ukey': u'ustr',
'key': 'str',
'int': 1,
'intstr': '1',
'emptystr': '',
'none': None,
'list': ['one', 2],
'badstr': u'\u0141'.encode('utf-8'),
'badu': u'\u0141'
}
xml2dict_outdict = {
'badstr': u'\u0141',
'badu': u'\u0141',
'emptystr': None,
'int': '1',
'intstr': '1',
'key': 'str',
'list': "['one', 2]",
'none': 'None',
'ukey': 'ustr'}
def test_xml2dict(self):
self.assertEqual(
self.xml2dict_outdict,
slapos.util.xml2dict(self.xml2dict_xml)
)
def test_dict2xml(self):
self.maxDiff = None
self.assertEqual(
self.xml2dict_xml,
slapos.util.dict2xml(self.xml2dict_indict)
)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -34,6 +34,8 @@ import struct ...@@ -34,6 +34,8 @@ import struct
import subprocess import subprocess
import sqlite3 import sqlite3
from xml_marshaller.xml_marshaller import dumps, loads from xml_marshaller.xml_marshaller import dumps, loads
from lxml import etree
import six
def mkdir_p(path, mode=0o700): def mkdir_p(path, mode=0o700):
...@@ -144,3 +146,35 @@ else: ...@@ -144,3 +146,35 @@ else:
return s.encode() return s.encode()
def unicode2str(s): def unicode2str(s):
return s return s
def dict2xml(dictionary):
instance = etree.Element('instance')
for k, v in sorted(six.iteritems(dictionary)):
if isinstance(k, bytes):
k = k.decode('utf-8')
if isinstance(v, bytes):
v = v.decode('utf-8')
elif not isinstance(v, six.text_type):
v = str(v)
etree.SubElement(instance, "parameter",
attrib={'id': k}).text = v
return bytes2str(etree.tostring(instance,
pretty_print=True,
xml_declaration=True,
encoding='utf-8'))
def xml2dict(xml):
result_dict = {}
if xml:
tree = etree.fromstring(str2bytes(xml))
for element in tree.iterfind('parameter'):
key = element.get('id')
value = result_dict.get(key, None)
if value is not None:
value = value + ' ' + element.text
else:
value = element.text
result_dict[key] = value
return result_dict
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment