35
35
logger = logging.getLogger('cmdprint') # for stdout
36
36
logger_stderr = logging.getLogger('fatalerror') # for stderr
37
logger_tuto = logging.getLogger('tutorial') # for stdout
38
logger_plugin = logging.getLogger('tutorial_plugin') # for stdout
39
41
import madgraph.various.misc as misc
768
770
def help_quit(self):
769
771
logger.info("-- terminates the application",'$MG:color:BLUE')
770
logger.info("syntax: quit",'$MG:color:BLACK')
772
logger.info("syntax: quit",'$MG:BOLD')
772
774
help_EOF = help_quit
774
776
def help_history(self):
775
777
logger.info("-- interact with the command history.",'$MG:color:BLUE')
776
logger.info("syntax: history [FILEPATH|clean|.] ",'$MG:color:BLACK')
778
logger.info("syntax: history [FILEPATH|clean|.] ",'$MG:BOLD')
777
779
logger.info(" > If FILEPATH is \'.\' and \'output\' is done,")
778
780
logger.info(" Cards/proc_card_mg5.dat will be used.")
779
781
logger.info(" > If FILEPATH is omitted, the history will be output to stdout.")
782
784
def help_help(self):
783
785
logger.info("-- access to the in-line help",'$MG:color:BLUE')
784
logger.info("syntax: help",'$MG:color:BLACK')
786
logger.info("syntax: help",'$MG:BOLD')
786
788
def help_save(self):
787
789
"""help text for save"""
788
790
logger.info("-- save options configuration to filepath.",'$MG:color:BLUE')
789
logger.info("syntax: save [options] [FILEPATH]",'$MG:color:BLACK')
791
logger.info("syntax: save [options] [FILEPATH]",'$MG:BOLD')
791
793
def help_display(self):
792
794
"""help for display command"""
793
795
logger.info("-- display a the status of various internal state variables",'$MG:color:BLUE')
794
logger.info("syntax: display " + "|".join(self._display_opts),'$MG:color:BLACK')
796
logger.info("syntax: display " + "|".join(self._display_opts),'$MG:BOLD')
796
798
class CompleteCmd(object):
797
799
"""Extension of the cmd object for only the complete command"""
1185
1188
self.store_line(line)
1186
1189
return None # print the question and use the pipe
1187
1190
logger.info(question_instance.question)
1188
logger.info('The answer to the previous question is not set in your input file', '$MG:color:BLACK')
1189
logger.info('Use %s value' % default, '$MG:color:BLACK')
1191
logger.info('The answer to the previous question is not set in your input file', '$MG:BOLD')
1192
logger.info('Use %s value' % default, '$MG:BOLD')
1190
1193
return str(default)
1192
1195
line = line.replace('\n','').strip()
1211
1214
line = os.path.expanduser(os.path.expandvars(line))
1212
1215
if os.path.isfile(line):
1217
if line.startswith(('http', 'www')):
1214
1219
elif hasattr(question_instance, 'casesensitive') and not question_instance.casesensitive:
1215
1220
for entry in question_instance.allow_arg:
1216
1221
if line.lower() == entry.lower():
1321
1326
self.options['crash_on_error']:
1322
1327
logger.info('stop computation due to crash_on_error=True')
1323
1328
sys.exit(str(error))
1324
1330
#stop the execution if on a non interactive mode
1325
if self.use_rawinput == False:
1331
if self.use_rawinput == False or self.inputfile:
1334
if self.mother.use_rawinput is False:
1337
elif self.mother.mother:
1338
if self.mother.mother.use_rawinput is False:
1346
1360
self.options['crash_on_error']:
1347
1361
logger.info('stop computation due to crash_on_error=True')
1348
1362
sys.exit(str(error))
1349
1364
#stop the execution if on a non interactive mode
1350
if self.use_rawinput == False:
1365
if self.use_rawinput == False or self.inputfile:
1368
if self.mother.use_rawinput is False:
1370
elif self.mother.mother:
1371
if self.mother.mother.use_rawinput is False:
1352
1374
# Remove failed command from history
1353
1375
self.history.pop()
1382
1404
logger.info('stop computation due to crash_on_error=True')
1383
1405
sys.exit(str(error))
1385
#stop the execution if on a non interactive mode
1386
if self.use_rawinput == False:
1407
#stop the execution if on a non interactive mode
1408
if self.use_rawinput == False or self.inputfile:
1411
if self.mother.use_rawinput is False:
1413
elif self.mother.mother:
1414
if self.mother.mother.use_rawinput is False:
1388
1417
# Remove failed command from history
1389
1418
if self.history:
1390
1419
self.history.pop()
1427
1456
me_dir = os.path.basename(me_dir) + ' '
1429
1458
misc.EasterEgg('error')
1433
except self.InvalidCmd as error:
1462
except self.InvalidCmd as error:
1435
self.nice_error_handling(error, line)
1464
stop = self.nice_error_handling(error, line)
1436
1465
self.history.pop()
1438
self.nice_user_error(error, line)
1467
stop = self.nice_user_error(error, line)
1439
1469
if self.allow_notification_center:
1440
1470
misc.apple_notify('Run %sfailed' % me_dir,
1441
1471
'Invalid Command: %s' % error.__class__.__name__)
1443
1473
except self.ConfigurationError as error:
1444
self.nice_config_error(error, line)
1474
stop = self.nice_config_error(error, line)
1445
1475
if self.allow_notification_center:
1446
1476
misc.apple_notify('Run %sfailed' % me_dir,
1447
1477
'Configuration error')
1448
1478
except Exception as error:
1449
self.nice_error_handling(error, line)
1479
stop = self.nice_error_handling(error, line)
1450
1480
if self.mother:
1451
1481
self.do_quit('')
1452
1482
if self.allow_notification_center:
1982
2020
def help_shell(self):
1983
2021
"""help for the shell"""
1984
2022
logger.info("-- run the shell command CMD and catch output",'$MG:color:BLUE')
1985
logger.info("syntax: shell CMD (or ! CMD)",'$MG:color:BLACK')
2023
logger.info("syntax: shell CMD (or ! CMD)",'$MG:BOLD')
2027
class NotValidInput(Exception): pass
1990
2028
#===============================================================================
1991
2029
# Question with auto-completion
1992
2030
#===============================================================================
2007
2045
def __init__(self, question, allow_arg=[], default=None,
2008
2046
mother_interface=None, *arg, **opt):
2009
2048
self.question = question
2010
2049
self.wrong_answer = 0 # forbids infinite loop
2011
2050
self.allow_arg = [str(a) for a in allow_arg]
2100
2141
if reprint_opt:
2101
2142
if not prev_timer:
2102
2143
self.question = pat.sub('',self.question)
2144
print self.question.encode('utf8')
2105
2146
if self.mother_interface:
2106
2147
answer = self.mother_interface.check_answer_in_input_file(self, 'EOF',
2107
2148
path=self.allowpath)
2123
2164
if out['Options']:
2124
logger.info( "Here is the list of all valid options:", '$MG:color:BLACK')
2165
logger.info( "Here is the list of all valid options:", '$MG:BOLD')
2125
2166
logger.info( " "+ "\n ".join(out['Options']))
2126
2167
if out['command']:
2127
logger.info( "Here is the list of command available:", '$MG:color:BLACK')
2168
logger.info( "Here is the list of command available:", '$MG:BOLD')
2128
2169
logger.info( " "+ "\n ".join(out['command']))
2130
2171
if out['Options']:
2131
logger.info( "Here is the list of all valid options starting with \'%s\'" % text, '$MG:color:BLACK')
2172
logger.info( "Here is the list of all valid options starting with \'%s\'" % text, '$MG:BOLD')
2132
2173
logger.info( " "+ "\n ".join(out['Options']))
2133
2174
if out['command']:
2134
logger.info( "Here is the list of command available starting with \'%s\':" % text, '$MG:color:BLACK')
2175
logger.info( "Here is the list of command available starting with \'%s\':" % text, '$MG:BOLD')
2135
2176
logger.info( " "+ "\n ".join(out['command']))
2136
2177
elif not out['Options']:
2137
logger.info( "No possibility starting with \'%s\'" % text, '$MG:color:BLACK')
2138
logger.info( "You can type help XXX, to see all command starting with XXX", '$MG:color:BLACK')
2178
logger.info( "No possibility starting with \'%s\'" % text, '$MG:BOLD')
2179
logger.info( "You can type help XXX, to see all command starting with XXX", '$MG:BOLD')
2139
2180
def complete_help(self, text, line, begidx, endidx):
2141
2182
return self.completenames(text, line)
2303
2344
Behavior for each switch can be customize via:
2304
2345
set_default_XXXX() -> set default value
2346
This is super-seeded by self.default_switch if that attribute is defined (and has a key for XXXX)
2305
2347
get_allowed_XXXX() -> return list of possible value
2306
2348
check_value_XXXX(value) -> return True/False if the user can set such value
2307
2349
switch_off_XXXXX() -> set it off (called for special mode)
2364
2406
allowed_args += opts['allow_arg']
2365
2407
del opts['allow_arg']
2367
super(ControlSwitch, self).__init__(question, allowed_args, *args, **opts)
2409
allowed_args +=["0", "done"]
2410
SmartQuestion.__init__(self, question, allowed_args, *args, **opts)
2368
2411
self.options = self.mother_interface.options
2370
2413
def special_check_answer_in_input_file(self, line, default):
2403
2446
for key,_ in self.to_control:
2404
2447
key = key.lower()
2448
if hasattr(self, 'default_switch') and key in self.default_switch:
2449
self.switch[key] = self.default_switch[key]
2405
2451
if hasattr(self, 'set_default_%s' % key):
2406
2452
getattr(self, 'set_default_%s' % key)()
2408
2454
self.default_switch_for(key)
2410
2456
def default_switch_for(self, key):
2411
2457
"""use this if they are no dedicated function for such key"""
2461
2507
return getattr(self, 'get_allowed_%s' % key)()
2463
2509
return ['ON', 'OFF']
2465
def default(self, line):
2511
def default(self, line, raise_error=False):
2466
2512
"""Default action if line is not recognized"""
2468
2514
line=line.strip().replace('@', '__at__')
2484
2532
base, value = line.split(' ', 1)
2485
2533
elif hasattr(self, 'ans_%s' % line.lower()):
2486
2534
base, value = line.lower(), None
2487
elif line.isdigit() and line in [`i` for i in range(1, len(self.switch)+1)]:
2535
elif line.isdigit() and line in [`i` for i in range(1, len(self.to_control)+1)]:
2488
2536
# go from one valid option to the next in the get_allowed for that option
2489
2537
base = self.to_control[int(line)-1][0].lower()
2490
2538
return self.default(base) # just recall this function with the associate name
2523
2573
value = value.lower()
2524
2574
getattr(self, 'ans_%s' % base)(value)
2525
2575
elif base in self.switch:
2526
self.set_switch(base, value)
2576
self.set_switch(base, value)
2578
raise NotValidInput('Not valid command: %s' % line)
2528
2580
logger.warning('Not valid command: %s' % line)
2791
2841
info = 'Please install module'
2844
def do_help(self, line, list_command=False):
2845
"""dedicated help for the control switch"""
2848
return self.print_help_for_switch(line)
2850
# here for simple "help"
2852
logger.info(" In order to change a switch you can:")
2853
logger.info(" - type 'NAME = VALUE' to set the switch NAME to a given value.")
2854
logger.info(" - type 'ID = VALUE' to set the switch correspond to the line ID to a given value.")
2855
logger.info(" - type 'ID' where ID is the value of the line to pass from one value to the next.")
2856
logger.info(" - type 'NAME' to set the switch NAME to the next value.")
2858
logger.info(" You can type 'help NAME' for more help on a given switch")
2860
logger.info(" Special keyword:", '$MG:BOLD')
2861
logger.info(" %s" % '\t'.join([p[4:] for p in dir(self) if p.startswith('ans_')]) )
2862
logger.info(" type 'help XXX' for more information")
2864
super(ControlSwitch, self).do_help(line)
2867
def print_help_for_switch(self, line):
2870
arg = line.split()[0]
2872
if hasattr(self, 'help_%s' % arg):
2873
return getattr(self, 'help_%s' % arg)('')
2875
if hasattr(self, 'ans_%s' % arg):
2876
return getattr(self, 'help_%s' % arg).__doc__
2878
if arg in self.switch:
2879
logger.info(" information for switch %s: ", arg, '$MG:BOLD')
2880
logger.info(" allowed value:")
2881
logger.info(" %s", '\t'.join(self.get_allowed(arg)))
2882
if hasattr(self, 'help_text_%s' % arg):
2884
for line in getattr(self, 'help_text_%s' % arg):
2794
2890
def question_formatting(self, nb_col = 80,
2795
2891
ldescription=0,
2964
3060
return upper, lower, f1, f2
2966
def create_question(self):
3062
def create_question(self, help_text=True):
2967
3063
""" create the question with correct formatting"""
2969
3065
# geth the number of line and column of the shell to adapt the printing
3054
3150
if not example:
3055
3151
example = ('KEY', 'VALUE')
3058
["Either type the switch number (1 to %s) to change its setting," % len(self.to_control),
3059
"Set any switch explicitly (e.g. type '%s=%s' at the prompt)" % example,
3060
"Type 'help' for the list of all valid option",
3061
"Type '0', 'auto', 'done' or just press enter when you are done."]
3063
# check on the number of row:
3064
if len(text) > nb_rows:
3065
# too many lines. Remove some
3066
to_remove = [ -2, #Type 'help' for the list of all valid option
3068
-4, #Either type the switch number (1 to %s) to change its setting,
3069
-3, # Set any switch explicitly
3070
-1, # Type '0', 'auto', 'done' or just press enter when you are done.
3072
to_remove = to_remove[:min(len(to_remove), len(text)-nb_rows)]
3073
text = [t for i,t in enumerate(text) if i-len(text) not in to_remove]
3155
["Either type the switch number (1 to %s) to change its setting," % len(self.to_control),
3156
"Set any switch explicitly (e.g. type '%s=%s' at the prompt)" % example,
3157
"Type 'help' for the list of all valid option",
3158
"Type '0', 'auto', 'done' or just press enter when you are done."]
3160
# check on the number of row:
3161
if len(text) > nb_rows:
3162
# too many lines. Remove some
3163
to_remove = [ -2, #Type 'help' for the list of all valid option
3165
-4, #Either type the switch number (1 to %s) to change its setting,
3166
-3, # Set any switch explicitly
3167
-1, # Type '0', 'auto', 'done' or just press enter when you are done.
3169
to_remove = to_remove[:min(len(to_remove), len(text)-nb_rows)]
3170
text = [t for i,t in enumerate(text) if i-len(text) not in to_remove]
3075
3172
self.question = "\n".join(text)
3076
3173
return self.question
3081
3176
#===============================================================================
3083
3178
#===============================================================================