mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.3 KiB
239 lines
7.3 KiB
#!/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 + "'] = {}")
|
|
|