1#!/usr/bin/env python3 2__package__ = 'configurator.pyodide' 3 4import json 5 6import xmltodict 7 8from . import convert_result, nuc11_scenario, IS_WEB 9 10if IS_WEB: 11 # load js function from 12 # misc/config_tools/configurator/packages/configurator/src/pyodide.js 13 # by pyodide js library 14 # noinspection PyUnresolvedReferences 15 from js import __dynamic__load__scenario__from__pyodide__ 16 17 scenario_json_schema = __dynamic__load__scenario__from__pyodide__() 18else: 19 from . import scenario_json_schema 20 21 22def get_array_and_int_keys(): 23 array_keys = [] 24 int_keys = ['@id'] 25 26 def object_mapper(obj): 27 if not isinstance(obj, dict): 28 return obj 29 for key, value in obj.items(): 30 if not isinstance(value, dict): 31 continue 32 if value.get('type', '') == 'array': 33 array_keys.append(key) 34 elif value.get('type', '') == 'integer': 35 int_keys.append(key) 36 return obj 37 38 json.loads(scenario_json_schema, object_hook=object_mapper) 39 array_keys = list(set(array_keys)) 40 int_keys = list(set(int_keys)) 41 return array_keys, int_keys 42 43 44def load_scenario_xml(scenario): 45 """ 46 convert scenario xml to json data followed scenario json schema 47 48 :type scenario: str 49 :param scenario: scenario xml text 50 :return: 51 """ 52 arr_keys, int_keys = get_array_and_int_keys() 53 scenario_xml = xmltodict.parse(scenario) 54 scenario_xml = json.dumps(scenario_xml) 55 56 def correct_struct(obj): 57 if not isinstance(obj, dict): 58 return obj 59 keys_need_remove = [] 60 for key, value in obj.items(): 61 if value is None: 62 keys_need_remove.append(key) 63 continue 64 if key in int_keys: 65 if isinstance(obj[key], list): 66 obj[key] = [int(x) for x in obj[key]] 67 elif not isinstance(value, int): 68 obj[key] = int(value) 69 if key in arr_keys and not isinstance(value, list): 70 obj[key] = [value] 71 for key in keys_need_remove: 72 del obj[key] 73 return obj 74 75 scenario_dict = json.loads(scenario_xml, object_hook=correct_struct) 76 return scenario_dict 77 78 79def main(scenario): 80 result = load_scenario_xml(scenario) 81 return convert_result(result) 82 83 84def test(): 85 main(nuc11_scenario) 86 87 88if __name__ == '__main__': 89 test() 90