forked from nsacyber/WALKOFF
-
Notifications
You must be signed in to change notification settings - Fork 1
/
makeApp.py
140 lines (123 loc) · 6.06 KB
/
makeApp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import argparse
from os import walk
import os.path
import re
import yaml
main_dir = os.path.dirname(os.path.realpath(__file__))
apps_dir = main_dir + '/apps'
def _convert_2_camelcase(input_value):
if input_value[0] != input_value[:1].upper():
input_value = input_value[:1].upper() + input_value[1:]
if '-' in input_value or '_' in input_value or ' ' in input_value:
input_splits = re.findall('[A-Za-z0-9]+', input_value)
input_formatted = [input_split[:1].upper() + input_split[1:] for input_split in input_splits]
input_value = ''.join(input_formatted)
return input_value
def _separate_camelcase(input_value):
out = re.findall('[A-Z][a-z0-9]*', input_value)
return ' '.join(out)
def make_template(app_name):
skeleton_app_dir = apps_dir + '/SkeletonApp'
# Create new app directory if it doesn't exists
app_name = _convert_2_camelcase(app_name)
new_app_dir = apps_dir + '/' + app_name
if not os.path.exists(new_app_dir):
os.makedirs(new_app_dir)
for (dirpath, dirnames, filenames) in walk(skeleton_app_dir):
if '__pycache__' not in dirpath:
for fn in filenames:
if dirpath == skeleton_app_dir:
write_fp = new_app_dir + '/' + fn
else:
sub_dir = dirpath.replace(skeleton_app_dir, new_app_dir)
if not os.path.exists(sub_dir):
os.makedirs(sub_dir)
write_fp = sub_dir + '/' + fn
with open(dirpath + '/' + fn) as read_from_file:
with open(write_fp, 'w') as write_to_file:
for line in read_from_file:
if 'SkeletonApp' in line:
line = line.replace('SkeletonApp', app_name)
elif 'Skeleton App' in line:
line = line.replace('Skeleton App', _separate_camelcase(app_name))
write_to_file.write(line)
print('Finished generating the template at', new_app_dir)
else:
print('Template already exist at', new_app_dir)
def generate_methods(input_fp):
actual_fp = ''
if input_fp.count('/') > 0:
if os.path.isfile(input_fp):
actual_fp = input_fp
else:
for (dirpath, dirnames, filenames) in walk(main_dir):
if input_fp in filenames:
actual_fp = dirpath + '/' + input_fp
if actual_fp == '':
print('Unable to find file. Please check that the yaml file exist at', input_fp)
return
with open(actual_fp) as yaml_file:
yaml_dict = yaml.load(yaml_file)
app_name = _convert_2_camelcase(yaml_dict['info']['title'])
new_app_dir = apps_dir + '/' + app_name
if not os.path.exists(new_app_dir):
print('Unable to find directory. Please check that the app exist at', new_app_dir)
return
main_py = new_app_dir + '/main.py'
init_lines = []
with open(main_py) as read_from_file:
for line in read_from_file:
if '@action' in line:
break
else:
init_lines.append(line)
with open(main_py, 'w') as write_to_file:
write_to_file.writelines(init_lines[:max(loc for loc, val in enumerate(init_lines) if val == '\n')+1])
with open(main_py, 'a') as write_to_file:
actions = yaml_dict['actions']
for action in actions:
action_val = actions[action]
lines = []
if 'description' in action_val:
lines.append("'''")
lines.append(action_val['description'])
parameters_args = ''
if 'parameters' in action_val:
parameters0 = action_val['parameters'][0]
lines.append('Inputs:')
parameters_str = '{0} ({1}): {2}'.format(parameters0['name'], parameters0['type'],
parameters0['description'])
parameters_args = ', ' + parameters0['name']
required_val = parameters0['required']
if not required_val:
parameters_str += ' (Optional)'
parameters_args += '=None'
lines.append(parameters_str)
if 'returns' in action_val:
success_val = action_val['returns']['Success']
lines.append('Output:')
lines.append('{0}: {1}'.format(success_val['schema']['type'], success_val['description']))
lines.append("'''")
lines.append('@action')
lines.append('def {0}(self{1}):'.format(action.replace(' ', '_'), parameters_args))
lines.append('\tpass')
lines.append('\n')
write_to_file.writelines('\n'.join(['\t' + line for line in lines]))
cur_fp = new_app_dir + '/api.yaml'
if actual_fp != cur_fp:
with open(actual_fp) as yaml_file:
with open(cur_fp, 'w') as write_to_file:
for line in yaml_file:
write_to_file.write(line)
print('Updated', cur_fp)
print('Successfully generated methods for {0} at {1}'.format(_separate_camelcase(app_name), new_app_dir))
help_msg_app_name = 'make template for app with name provided by app_name. The new app is stored under the "apps" ' \
'directory.'
help_msg_yaml = 'generate methods for app using yaml file at the filepath provided. If YAML_FILE is a filename, ' \
'then it is assumed the file is located inside the WALKOFF directory; otherwise, an absolute ' \
'filepath is required. If there are multiple files with the same filename, then the first file ' \
'found will be used.'
parser = argparse.ArgumentParser(description='Make the template for a new app.')
parser.add_argument("--app_name", type=make_template, help=help_msg_app_name)
parser.add_argument("--yaml", type=generate_methods, help=help_msg_yaml, metavar=('YAML_FILE'))
args = parser.parse_args()