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