123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- #!/usr/bin/python3
- #parses the output of /usr/sbin/kamctl rpc app_python.api_list
- #
- #usage ./kemi_mock.py api.json > KSR.py
- #or for python 3.2
- #./kemi_mock.py api.json --no-union > KSR.py
- import json
- import sys
- from collections import defaultdict
- #python 3.2 doesnt support types.Union
- noUnion = False
- reserved_keywords = {"async"}
- def printMocReturn(module_name, func, indent):
- param_names = []
- param_list = []
- param_signature = ""
- if func['params'] is not None and func['params'] != 'none':
- param_list = func['params'].split(", ")
- i = 0
- for _ in param_list:
- param_names.append("param"+str(i))
- i = i + 1
- param_signature = ", ".join(param_names)
- prefix = ""
- for i in range(indent):
- prefix = prefix+"\t"
- print(prefix + "if \""+func['name']+"\" not in _mock_data['"+module_name+"']:")
- printDefaultReturn(func, indent+1)
- print(prefix + "node = _mock_data['"+module_name+"']['"+func['name']+"']")
- print(prefix + "if isinstance(node, types.FunctionType):")
- print(prefix + "\treturn node("+param_signature+")")
- for param in param_names:
- print(prefix + "if not isinstance(node, dict):")
- print(prefix + "\treturn node")
- print(prefix + "if str(" + param + ") in node:")
- print(prefix + "\tnode = node[str("+param+")]")
- print(prefix + "else:")
- printDefaultReturn(func, indent+1)
- print(prefix + "return node")
- def printDefaultReturn(func, indent):
- prefix = ""
- for i in range(indent):
- prefix = prefix+"\t"
- if func['ret'] == "bool":
- print(prefix + "return True")
- elif func['ret'] == "int":
- print(prefix + "return 1")
- elif func['ret'] == "str":
- print(prefix + "return \"\"")
- elif func['ret'] == "xval":
- print(prefix + "return None")
- else:
- print(prefix + "return")
- def printFunction(module_name, func, indent):
- params = ""
- log_params = ""
- if module_name == "":
- log_params = "\"" + func['name'] + "\""
- else:
- log_params = "\"" + module_name + "." + func['name'] + "\""
- log_format_params = "%s"
- param_list = []
- if func['params'] is not None and func['params'] != "none":
- param_list = func['params'].split(", ")
- i = 0
- for _ in param_list:
- if params != "":
- params = params + ", "
- params = params + "param" + str(i) + ": " + param_list[i]
- log_params = log_params + ", param" + str(i)
- log_format_params = log_format_params + ", %s"
- i = i+1
- if len(param_list) > 0:
- log_params = "(" + log_params + ")"
- prefix = ""
- for i in range(indent):
- prefix = prefix+"\t"
- if indent > 0:
- print(prefix + "@staticmethod")
- if func['ret'] == "bool":
- print(prefix + "def " + func['name'] +"("+params+") -> bool:")
- elif func['ret'] == "int":
- print(prefix + "def " + func['name'] +"("+params+") -> int:")
- elif func['ret'] == "str":
- print(prefix + "def " + func['name'] + "(" + params + ") -> int:")
- elif func['ret'] == "xval":
- if noUnion:
- print(prefix + "def " + func['name'] + "(" + params + "):")
- else:
- print(prefix + "def " + func['name'] +"("+params+") -> Union[int, str, None]:")
- else:
- print(prefix + "def " + func['name'] +"("+params+"):")
- generate_function_doc(module_name, func, prefix)
- print(prefix + "\tprint(\"Calling " + log_format_params + "\" % "+log_params+")")
- printMocReturn(module_name, func, indent+1)
- print("")
- def generate_function_doc(module_name, func, prefix):
- if documentation is not None and module_name in documentation:
- function_parts = func['name'].split("_")
- for i in range(len(function_parts), 0, -1):
- function_prefix = "_".join(function_parts[:i])
- if function_prefix in documentation[module_name]["functions"]:
- print(prefix + "\t\"\"\"")
- documentation_lines = documentation[module_name]["functions"][function_prefix].split("\n")
- for line in documentation_lines:
- print(prefix + "\t" + line.replace("\\", "\\\\\\\\"))
- print(prefix + "\t\"\"\"")
- break
- classes = defaultdict(list)
- if len(sys.argv) < 2:
- print("Please specify the json file to parse")
- sys.exit(-1)
- documentation = None
- if len(sys.argv) > 2:
- for i in range(2,len(sys.argv)):
- if sys.argv[i] == "--no-union":
- noUnion = True
- else:
- with open(sys.argv[i]) as f:
- documentation = json.load(f)
- if not noUnion:
- print("from typing import Union")
- print("import sys")
- print("import types")
- print("_mock_data = {}")
- print("")
- with open(sys.argv[1]) as f:
- data = json.load(f)
- for method in data['result']['methods']:
- classes[method['func']['module']].append(method['func'])
- if "pv" not in classes:
- classes['pv'].append({'params': 'str',
- 'ret': 'xval',
- 'name': 'get'}
- )
- classes['pv'].append({'params': 'str',
- 'ret': 'xval',
- 'name': 'gete'}
- )
- classes['pv'].append({'params': 'str, int',
- 'ret': 'xval',
- 'name': 'getvn'}
- )
- classes['pv'].append({'params': 'str, str',
- 'ret': 'xval',
- 'name': 'getvs'}
- )
- classes['pv'].append({'params': 'str',
- 'ret': 'xval',
- 'name': 'getw'}
- )
- classes['pv'].append({'params': 'str, int',
- 'ret': 'none',
- 'name': 'seti'}
- )
- classes['pv'].append({'params': 'str, str',
- 'ret': 'none',
- 'name': 'sets'}
- )
- classes['pv'].append({'params': 'str',
- 'ret': 'none',
- 'name': 'unset'}
- )
- classes['pv'].append({'params': 'str',
- 'ret': 'none',
- 'name': 'is_null'}
- )
- for module_name, module in classes.items():
- if module_name != "":
- print("")
- print("class " + module_name.capitalize() + ":")
- for func in module:
- printFunction(module_name, func, 1)
- for func in classes['']:
- print("")
- printFunction('', func, 0)
- def document_module(module_name):
- if documentation is not None and module_name in documentation:
- print("\"\"\"")
- documentation_lines = documentation[module_name]["overview"].split("\n")
- for line in documentation_lines:
- print("" + line)
- print("\"\"\"")
- for module_name in classes.keys():
- if module_name != "":
- if module_name in reserved_keywords:
- print("setattr(sys.modules[__name__], '" + module_name + "', " + module_name.capitalize() + "())")
- else:
- print(module_name + " = "+module_name.capitalize()+"()")
- document_module(module_name)
- print("")
- for module_name in classes.keys():
- print("_mock_data['" + module_name + "'] = {}")
|