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