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