##// END OF EJS Templates
Fix CLI
jespinoza -
r1253:1a0d43dcc943
parent child
Show More
@@ -1,208 +1,236
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('/dev/null', '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.cli import templates
16 from schainpy.cli import templates
17 import inspect
18 try:
19 from queue import Queue
20 except:
21 from Queue import Queue
17 sys.stdout = save_stdout
22 sys.stdout = save_stdout
18
23
19
24
20 def getProcs():
25 def getProcs():
21 modules = dir(schainpy.model)
26 modules = dir(schainpy.model)
22 procs = check_module(modules, ProcessingUnit)
27 procs = check_module(modules, 'processing')
23 try:
28 try:
24 procs.remove('ProcessingUnit')
29 procs.remove('ProcessingUnit')
25 except Exception as e:
30 except Exception as e:
26 pass
31 pass
27 return procs
32 return procs
28
33
29 def getOperations():
34 def getOperations():
30 module = dir(schainpy.model)
35 module = dir(schainpy.model)
31 noProcs = [x for x in module if not x.endswith('Proc')]
36 noProcs = [x for x in module if not x.endswith('Proc')]
32 operations = check_module(noProcs, Operation)
37 operations = check_module(noProcs, 'operation')
33 try:
38 try:
34 operations.remove('Operation')
39 operations.remove('Operation')
40 operations.remove('Figure')
41 operations.remove('Plot')
35 except Exception as e:
42 except Exception as e:
36 pass
43 pass
37 return operations
44 return operations
38
45
39 def getArgs(op):
46 def getArgs(op):
40 module = locate('schainpy.model.{}'.format(op))
47 module = locate('schainpy.model.{}'.format(op))
41 args = module().getAllowedArgs()
48
49 if hasattr(module, '__attrs'):
50 args = module.__attrs__
51 else:
52 args = inspect.getargspec(module.run).args
42 try:
53 try:
43 args.remove('self')
54 args.remove('self')
44 except Exception as e:
55 except Exception as e:
45 pass
56 pass
46 try:
57 try:
47 args.remove('dataOut')
58 args.remove('dataOut')
48 except Exception as e:
59 except Exception as e:
49 pass
60 pass
50 return args
61 return args
51
62
63 def getDoc(obj):
64 module = locate('schainpy.model.{}'.format(obj))
65 try:
66 obj = module(1,2,3,Queue(),5)
67 except:
68 obj = module()
69 return obj.__doc__
70
52 def getAll():
71 def getAll():
53 allModules = dir(schainpy.model)
72 modules = getOperations()
54 modules = check_module(allModules, Operation)
73 modules.extend(getProcs())
55 modules.extend(check_module(allModules, ProcessingUnit))
56 return modules
74 return modules
57
75
58
76
59 def print_version(ctx, param, value):
77 def print_version(ctx, param, value):
60 if not value or ctx.resilient_parsing:
78 if not value or ctx.resilient_parsing:
61 return
79 return
62 click.echo(schainpy.__version__)
80 click.echo(schainpy.__version__)
63 ctx.exit()
81 ctx.exit()
64
82
65
83
66 PREFIX = 'experiment'
84 PREFIX = 'experiment'
67
85
68 @click.command()
86 @click.command()
69 @click.option('--version', '-v', is_flag=True, callback=print_version, help='SChain version', type=str)
87 @click.option('--version', '-v', is_flag=True, callback=print_version, help='SChain version', type=str)
70 @click.argument('command', default='run', required=True)
88 @click.argument('command', default='run', required=True)
71 @click.argument('nextcommand', default=None, required=False, type=str)
89 @click.argument('nextcommand', default=None, required=False, type=str)
72 def main(command, nextcommand, version):
90 def main(command, nextcommand, version):
73 """COMMAND LINE INTERFACE FOR SIGNAL CHAIN - JICAMARCA RADIO OBSERVATORY V3.0\n
91 """COMMAND LINE INTERFACE FOR SIGNAL CHAIN - JICAMARCA RADIO OBSERVATORY V3.0\n
74 Available commands.\n
92 Available commands.\n
75 xml: runs a schain XML generated file\n
93 xml: runs a schain XML generated file\n
76 run: runs any python script starting 'experiment_'\n
94 run: runs any python script starting 'experiment_'\n
77 generate: generates a template schain script\n
95 generate: generates a template schain script\n
78 search: return avilable operations, procs or arguments of the give operation/proc\n"""
96 list: return a list of available procs and operations\n
97 search: return avilable operations, procs or arguments of the given
98 operation/proc\n"""
79 if command == 'xml':
99 if command == 'xml':
80 runFromXML(nextcommand)
100 runFromXML(nextcommand)
81 elif command == 'generate':
101 elif command == 'generate':
82 generate()
102 generate()
83 elif command == 'test':
103 elif command == 'test':
84 test()
104 test()
85 elif command == 'run':
105 elif command == 'run':
86 runschain(nextcommand)
106 runschain(nextcommand)
87 elif command == 'search':
107 elif command == 'search':
88 search(nextcommand)
108 search(nextcommand)
109 elif command == 'list':
110 cmdlist(nextcommand)
89 else:
111 else:
90 log.error('Command {} is not defined'.format(command))
112 log.error('Command {} is not defined'.format(command))
91
113
92
114
93 def check_module(possible, instance):
115 def check_module(possible, instance):
94 def check(x):
116 def check(x):
95 try:
117 try:
96 instancia = locate('schainpy.model.{}'.format(x))
118 instancia = locate('schainpy.model.{}'.format(x))
97 return isinstance(instancia(), instance)
119 ret = instancia.proc_type == instance
120 return ret
98 except Exception as e:
121 except Exception as e:
99 return False
122 return False
100 clean = clean_modules(possible)
123 clean = clean_modules(possible)
101 return [x for x in clean if check(x)]
124 return [x for x in clean if check(x)]
102
125
103
126
104 def clean_modules(module):
127 def clean_modules(module):
105 noEndsUnder = [x for x in module if not x.endswith('__')]
128 noEndsUnder = [x for x in module if not x.endswith('__')]
106 noStartUnder = [x for x in noEndsUnder if not x.startswith('__')]
129 noStartUnder = [x for x in noEndsUnder if not x.startswith('__')]
107 noFullUpper = [x for x in noStartUnder if not x.isupper()]
130 noFullUpper = [x for x in noStartUnder if not x.isupper()]
108 return noFullUpper
131 return noFullUpper
109
132
110
133 def cmdlist(nextcommand):
111 def search(nextcommand):
112 if nextcommand is None:
134 if nextcommand is None:
113 log.error('There is no Operation/ProcessingUnit to search', '')
135 log.error('Missing argument, available arguments: procs, operations', '')
114 elif nextcommand == 'procs':
136 elif nextcommand == 'procs':
115 procs = getProcs()
137 procs = getProcs()
116 log.success(
138 log.success(
117 'Current ProcessingUnits are:\n{}'.format('\n'.join(procs)), '')
139 'Current ProcessingUnits are:\n {}'.format('\n '.join(procs)), '')
118
119 elif nextcommand == 'operations':
140 elif nextcommand == 'operations':
120 operations = getOperations()
141 operations = getOperations()
121 log.success('Current Operations are:\n{}'.format(
142 log.success('Current Operations are:\n {}'.format(
122 '\n'.join(operations)), '')
143 '\n '.join(operations)), '')
144 else:
145 log.error('Wrong argument', '')
146
147 def search(nextcommand):
148 if nextcommand is None:
149 log.error('There is no Operation/ProcessingUnit to search', '')
123 else:
150 else:
124 try:
151 try:
125 args = getArgs(nextcommand)
152 args = getArgs(nextcommand)
153 doc = getDoc(nextcommand)
126 if len(args) == 0:
154 if len(args) == 0:
127 log.success('`{}` has no arguments'.format(nextcommand), '')
155 log.success('\n{} has no arguments'.format(nextcommand), '')
128 else:
156 else:
129 log.success('`{}` arguments: {}'.format(
157 log.success('{}\n{}\n\narguments:\n {}'.format(
130 nextcommand, ', '.join(args)), '')
158 nextcommand, doc, ', '.join(args)), '')
131 except Exception as e:
159 except Exception as e:
132 log.error('Module `{}` does not exists'.format(nextcommand), '')
160 log.error('Module `{}` does not exists'.format(nextcommand), '')
133 allModules = getAll()
161 allModules = getAll()
134 similar = [t[0] for t in process.extract(nextcommand, allModules, limit=12) if t[1]>80]
162 similar = [t[0] for t in process.extract(nextcommand, allModules, limit=12) if t[1]>80]
135 log.success('Possible modules are: {}'.format(', '.join(similar)), '')
163 log.success('Possible modules are: {}'.format(', '.join(similar)), '')
136
164
137 def runschain(nextcommand):
165 def runschain(nextcommand):
138 if nextcommand is None:
166 if nextcommand is None:
139 currentfiles = glob.glob('./{}_*.py'.format(PREFIX))
167 currentfiles = glob.glob('./{}_*.py'.format(PREFIX))
140 numberfiles = len(currentfiles)
168 numberfiles = len(currentfiles)
141 if numberfiles > 1:
169 if numberfiles > 1:
142 log.error('There is more than one file to run')
170 log.error('There is more than one file to run')
143 elif numberfiles == 1:
171 elif numberfiles == 1:
144 subprocess.call(['python ' + currentfiles[0]], shell=True)
172 subprocess.call(['python ' + currentfiles[0]], shell=True)
145 else:
173 else:
146 log.error('There is no file to run')
174 log.error('There is no file to run')
147 else:
175 else:
148 try:
176 try:
149 subprocess.call(['python ' + nextcommand], shell=True)
177 subprocess.call(['python ' + nextcommand], shell=True)
150 except Exception as e:
178 except Exception as e:
151 log.error("I cannot run the file. Does it exists?")
179 log.error("I cannot run the file. Does it exists?")
152
180
153
181
154 def basicInputs():
182 def basicInputs():
155 inputs = {}
183 inputs = {}
156 inputs['name'] = click.prompt(
184 inputs['name'] = click.prompt(
157 'Name of the project', default="project", type=str)
185 'Name of the project', default="project", type=str)
158 inputs['desc'] = click.prompt(
186 inputs['desc'] = click.prompt(
159 'Enter a description', default="A schain project", type=str)
187 'Enter a description', default="A schain project", type=str)
160 inputs['multiprocess'] = click.prompt(
188 inputs['multiprocess'] = click.prompt(
161 '''Select data type:
189 '''Select data type:
162
190
163 - Voltage (*.r): [1]
191 - Voltage (*.r): [1]
164 - Spectra (*.pdata): [2]
192 - Spectra (*.pdata): [2]
165 - Voltage and Spectra (*.r): [3]
193 - Voltage and Spectra (*.r): [3]
166
194
167 -->''', type=int)
195 -->''', type=int)
168 inputs['path'] = click.prompt('Data path', default=os.getcwd(
196 inputs['path'] = click.prompt('Data path', default=os.getcwd(
169 ), type=click.Path(exists=True, resolve_path=True))
197 ), type=click.Path(exists=True, resolve_path=True))
170 inputs['startDate'] = click.prompt(
198 inputs['startDate'] = click.prompt(
171 'Start date', default='1970/01/01', type=str)
199 'Start date', default='1970/01/01', type=str)
172 inputs['endDate'] = click.prompt(
200 inputs['endDate'] = click.prompt(
173 'End date', default='2018/12/31', type=str)
201 'End date', default='2018/12/31', type=str)
174 inputs['startHour'] = click.prompt(
202 inputs['startHour'] = click.prompt(
175 'Start hour', default='00:00:00', type=str)
203 'Start hour', default='00:00:00', type=str)
176 inputs['endHour'] = click.prompt('End hour', default='23:59:59', type=str)
204 inputs['endHour'] = click.prompt('End hour', default='23:59:59', type=str)
177 inputs['figpath'] = inputs['path'] + '/figs'
205 inputs['figpath'] = inputs['path'] + '/figs'
178 return inputs
206 return inputs
179
207
180
208
181 def generate():
209 def generate():
182 inputs = basicInputs()
210 inputs = basicInputs()
183
211
184 if inputs['multiprocess'] == 1:
212 if inputs['multiprocess'] == 1:
185 current = templates.voltage.format(**inputs)
213 current = templates.voltage.format(**inputs)
186 elif inputs['multiprocess'] == 2:
214 elif inputs['multiprocess'] == 2:
187 current = templates.spectra.format(**inputs)
215 current = templates.spectra.format(**inputs)
188 elif inputs['multiprocess'] == 3:
216 elif inputs['multiprocess'] == 3:
189 current = templates.voltagespectra.format(**inputs)
217 current = templates.voltagespectra.format(**inputs)
190 scriptname = '{}_{}.py'.format(PREFIX, inputs['name'])
218 scriptname = '{}_{}.py'.format(PREFIX, inputs['name'])
191 script = open(scriptname, 'w')
219 script = open(scriptname, 'w')
192 try:
220 try:
193 script.write(current)
221 script.write(current)
194 log.success('Script {} generated'.format(scriptname))
222 log.success('Script {} generated'.format(scriptname))
195 except Exception as e:
223 except Exception as e:
196 log.error('I cannot create the file. Do you have writing permissions?')
224 log.error('I cannot create the file. Do you have writing permissions?')
197
225
198
226
199 def test():
227 def test():
200 log.warning('testing')
228 log.warning('testing')
201
229
202
230
203 def runFromXML(filename):
231 def runFromXML(filename):
204 controller = Project()
232 controller = Project()
205 if not controller.readXml(filename):
233 if not controller.readXml(filename):
206 return
234 return
207 controller.start()
235 controller.start()
208 return
236 return
General Comments 0
You need to be logged in to leave comments. Login now