##// END OF EJS Templates
Fix CLI
Juan C. Espinoza -
r1180:2858555d5123
parent child
Show More
@@ -1,168 +1,200
1 import click
1 import click
2 import schainpy
2 import schainpy
3 import subprocess
3 import subprocess
4 import os
4 import os
5 import sys
5 import sys
6 import glob
6 import glob
7 save_stdout = sys.stdout
7 save_stdout = sys.stdout
8 sys.stdout = open('trash', 'w')
8 sys.stdout = open('/dev/null', 'w')
9 from multiprocessing import cpu_count
9 from multiprocessing import cpu_count
10 from schainpy.controller import Project
10 from schainpy.controller import Project
11 from schainpy.model import Operation, ProcessingUnit
11 from schainpy.model import Operation, ProcessingUnit
12 from schainpy.utils import log
12 from schainpy.utils import log
13 from importlib import import_module
13 from importlib import import_module
14 from pydoc import locate
14 from pydoc import locate
15 from fuzzywuzzy import process
15 from fuzzywuzzy import process
16 from schainpy.utils import paramsFinder
16 from schainpy.cli import templates
17 import templates
18 sys.stdout = save_stdout
17 sys.stdout = save_stdout
19
18
20
19
20 def getProcs():
21 modules = dir(schainpy.model)
22 procs = check_module(modules, ProcessingUnit)
23 try:
24 procs.remove('ProcessingUnit')
25 except Exception as e:
26 pass
27 return procs
28
29 def getOperations():
30 module = dir(schainpy.model)
31 noProcs = [x for x in module if not x.endswith('Proc')]
32 operations = check_module(noProcs, Operation)
33 try:
34 operations.remove('Operation')
35 except Exception as e:
36 pass
37 return operations
38
39 def getArgs(op):
40 module = locate('schainpy.model.{}'.format(op))
41 args = module().getAllowedArgs()
42 try:
43 args.remove('self')
44 except Exception as e:
45 pass
46 try:
47 args.remove('dataOut')
48 except Exception as e:
49 pass
50 return args
51
52 def getAll():
53 allModules = dir(schainpy.model)
54 modules = check_module(allModules, Operation)
55 modules.extend(check_module(allModules, ProcessingUnit))
56 return modules
57
58
21 def print_version(ctx, param, value):
59 def print_version(ctx, param, value):
22 if not value or ctx.resilient_parsing:
60 if not value or ctx.resilient_parsing:
23 return
61 return
24 click.echo(schainpy.__version__)
62 click.echo(schainpy.__version__)
25 ctx.exit()
63 ctx.exit()
26
64
27
65
28 cliLogger = log.makelogger('schain cli')
29 PREFIX = 'experiment'
66 PREFIX = 'experiment'
30
67
31
32 @click.command()
68 @click.command()
33 @click.option('--version', '-v', is_flag=True, callback=print_version, help='SChain version', type=str)
69 @click.option('--version', '-v', is_flag=True, callback=print_version, help='SChain version', type=str)
34 @click.argument('command', default='run', required=True)
70 @click.argument('command', default='run', required=True)
35 @click.argument('nextcommand', default=None, required=False, type=str)
71 @click.argument('nextcommand', default=None, required=False, type=str)
36 def main(command, nextcommand, version):
72 def main(command, nextcommand, version):
37 """COMMAND LINE INTERFACE FOR SIGNAL CHAIN - JICAMARCA RADIO OBSERVATORY \n
73 """COMMAND LINE INTERFACE FOR SIGNAL CHAIN - JICAMARCA RADIO OBSERVATORY \n
38 Available commands.\n
74 Available commands.\n
39 --xml: runs a schain XML generated file\n
75 --xml: runs a schain XML generated file\n
40 run: runs any python script starting 'experiment_'\n
76 run: runs any python script starting 'experiment_'\n
41 generate: generates a template schain script\n
77 generate: generates a template schain script\n
42 search: return avilable operations, procs or arguments of the give operation/proc\n"""
78 search: return avilable operations, procs or arguments of the give operation/proc\n"""
43 if command == 'xml':
79 if command == 'xml':
44 runFromXML(nextcommand)
80 runFromXML(nextcommand)
45 elif command == 'generate':
81 elif command == 'generate':
46 generate()
82 generate()
47 elif command == 'test':
83 elif command == 'test':
48 test()
84 test()
49 elif command == 'run':
85 elif command == 'run':
50 runschain(nextcommand)
86 runschain(nextcommand)
51 elif command == 'search':
87 elif command == 'search':
52 search(nextcommand)
88 search(nextcommand)
53 else:
89 else:
54 log.error('Command {} is not defined'.format(command))
90 log.error('Command {} is not defined'.format(command))
55
91
56
92
57 def check_module(possible, instance):
93 def check_module(possible, instance):
58 def check(x):
94 def check(x):
59 try:
95 try:
60 instancia = locate('schainpy.model.{}'.format(x))
96 instancia = locate('schainpy.model.{}'.format(x))
61 return isinstance(instancia(), instance)
97 return isinstance(instancia(), instance)
62 except Exception as e:
98 except Exception as e:
63 return False
99 return False
64 clean = clean_modules(possible)
100 clean = clean_modules(possible)
65 return [x for x in clean if check(x)]
101 return [x for x in clean if check(x)]
66
102
67
103
68 def clean_modules(module):
104 def clean_modules(module):
69 noEndsUnder = [x for x in module if not x.endswith('__')]
105 noEndsUnder = [x for x in module if not x.endswith('__')]
70 noStartUnder = [x for x in noEndsUnder if not x.startswith('__')]
106 noStartUnder = [x for x in noEndsUnder if not x.startswith('__')]
71 noFullUpper = [x for x in noStartUnder if not x.isupper()]
107 noFullUpper = [x for x in noStartUnder if not x.isupper()]
72 return noFullUpper
108 return noFullUpper
73
109
74
110
75 def search(nextcommand):
111 def search(nextcommand):
76 if nextcommand is None:
112 if nextcommand is None:
77 log.error('There is no Operation/ProcessingUnit to search')
113 log.error('There is no Operation/ProcessingUnit to search', '')
78 elif nextcommand == 'procs':
114 elif nextcommand == 'procs':
79 procs = paramsFinder.getProcs()
115 procs = getProcs()
80 log.success(
116 log.success(
81 'Current ProcessingUnits are:\n\033[1m{}\033[0m'.format('\n'.join(procs)))
117 'Current ProcessingUnits are:\n{}'.format('\n'.join(procs)), '')
82
118
83 elif nextcommand == 'operations':
119 elif nextcommand == 'operations':
84 operations = paramsFinder.getOperations()
120 operations = getOperations()
85 log.success('Current Operations are:\n\033[1m{}\033[0m'.format(
121 log.success('Current Operations are:\n{}'.format(
86 '\n'.join(operations)))
122 '\n'.join(operations)), '')
87 else:
123 else:
88 try:
124 try:
89 args = paramsFinder.getArgs(nextcommand)
125 args = getArgs(nextcommand)
90 log.warning(
91 'Use this feature with caution. It may not return all the allowed arguments')
92 if len(args) == 0:
126 if len(args) == 0:
93 log.success('{} has no arguments'.format(nextcommand))
127 log.success('`{}` has no arguments'.format(nextcommand), '')
94 else:
128 else:
95 log.success('Showing {} arguments:\n\033[1m{}\033[0m'.format(
129 log.success('`{}` arguments: {}'.format(
96 nextcommand, '\n'.join(args)))
130 nextcommand, ', '.join(args)), '')
97 except Exception as e:
131 except Exception as e:
98 log.error('Module {} does not exists'.format(nextcommand))
132 log.error('Module `{}` does not exists'.format(nextcommand), '')
99 allModules = paramsFinder.getAll()
133 allModules = getAll()
100 similar = process.extractOne(nextcommand, allModules)[0]
134 similar = [t[0] for t in process.extract(nextcommand, allModules, limit=12) if t[1]>80]
101 log.success('Showing {} instead'.format(similar))
135 log.success('Possible modules are: {}'.format(', '.join(similar)), '')
102 search(similar)
103
104
136
105 def runschain(nextcommand):
137 def runschain(nextcommand):
106 if nextcommand is None:
138 if nextcommand is None:
107 currentfiles = glob.glob('./{}_*.py'.format(PREFIX))
139 currentfiles = glob.glob('./{}_*.py'.format(PREFIX))
108 numberfiles = len(currentfiles)
140 numberfiles = len(currentfiles)
109 if numberfiles > 1:
141 if numberfiles > 1:
110 log.error('There is more than one file to run')
142 log.error('There is more than one file to run')
111 elif numberfiles == 1:
143 elif numberfiles == 1:
112 subprocess.call(['python ' + currentfiles[0]], shell=True)
144 subprocess.call(['python ' + currentfiles[0]], shell=True)
113 else:
145 else:
114 log.error('There is no file to run')
146 log.error('There is no file to run')
115 else:
147 else:
116 try:
148 try:
117 subprocess.call(['python ' + nextcommand], shell=True)
149 subprocess.call(['python ' + nextcommand], shell=True)
118 except Exception as e:
150 except Exception as e:
119 log.error("I cannot run the file. Does it exists?")
151 log.error("I cannot run the file. Does it exists?")
120
152
121
153
122 def basicInputs():
154 def basicInputs():
123 inputs = {}
155 inputs = {}
124 inputs['desc'] = click.prompt(
156 inputs['desc'] = click.prompt(
125 'Enter a description', default="A schain project", type=str)
157 'Enter a description', default="A schain project", type=str)
126 inputs['name'] = click.prompt(
158 inputs['name'] = click.prompt(
127 'Name of the project', default="project", type=str)
159 'Name of the project', default="project", type=str)
128 inputs['path'] = click.prompt('Data path', default=os.getcwd(
160 inputs['path'] = click.prompt('Data path', default=os.getcwd(
129 ), type=click.Path(exists=True, resolve_path=True))
161 ), type=click.Path(exists=True, resolve_path=True))
130 inputs['startDate'] = click.prompt(
162 inputs['startDate'] = click.prompt(
131 'Start date', default='1970/01/01', type=str)
163 'Start date', default='1970/01/01', type=str)
132 inputs['endDate'] = click.prompt(
164 inputs['endDate'] = click.prompt(
133 'End date', default='2017/12/31', type=str)
165 'End date', default='2017/12/31', type=str)
134 inputs['startHour'] = click.prompt(
166 inputs['startHour'] = click.prompt(
135 'Start hour', default='00:00:00', type=str)
167 'Start hour', default='00:00:00', type=str)
136 inputs['endHour'] = click.prompt('End hour', default='23:59:59', type=str)
168 inputs['endHour'] = click.prompt('End hour', default='23:59:59', type=str)
137 inputs['figpath'] = inputs['path'] + '/figs'
169 inputs['figpath'] = inputs['path'] + '/figs'
138 return inputs
170 return inputs
139
171
140
172
141 def generate():
173 def generate():
142 inputs = basicInputs()
174 inputs = basicInputs()
143 inputs['multiprocess'] = click.confirm('Is this a multiprocess script?')
175 inputs['multiprocess'] = click.confirm('Is this a multiprocess script?')
144 if inputs['multiprocess']:
176 if inputs['multiprocess']:
145 inputs['nProcess'] = click.prompt(
177 inputs['nProcess'] = click.prompt(
146 'How many process?', default=cpu_count(), type=int)
178 'How many process?', default=cpu_count(), type=int)
147 current = templates.multiprocess.format(**inputs)
179 current = templates.multiprocess.format(**inputs)
148 else:
180 else:
149 current = templates.basic.format(**inputs)
181 current = templates.basic.format(**inputs)
150 scriptname = '{}_{}.py'.format(PREFIX, inputs['name'])
182 scriptname = '{}_{}.py'.format(PREFIX, inputs['name'])
151 script = open(scriptname, 'w')
183 script = open(scriptname, 'w')
152 try:
184 try:
153 script.write(current)
185 script.write(current)
154 log.success('Script {} generated'.format(scriptname))
186 log.success('Script {} generated'.format(scriptname))
155 except Exception as e:
187 except Exception as e:
156 log.error('I cannot create the file. Do you have writing permissions?')
188 log.error('I cannot create the file. Do you have writing permissions?')
157
189
158
190
159 def test():
191 def test():
160 log.warning('testing')
192 log.warning('testing')
161
193
162
194
163 def runFromXML(filename):
195 def runFromXML(filename):
164 controller = Project()
196 controller = Project()
165 if not controller.readXml(filename):
197 if not controller.readXml(filename):
166 return
198 return
167 controller.start()
199 controller.start()
168 return
200 return
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now