######################################################################## # File : CLI.py # Author : Andrei Tsaregorodtsev ######################################################################## """ CLI is the base class for all the DIRAC consoles ( CLIs ). It contains several utilities and signal handlers of general purpose. """ from __future__ import print_function from __future__ import absolute_import from __future__ import division __RCSID__ = "45ddde113 (2021-10-01 11:19:55 +0200) Chris Burr <christopher.burr@cern.ch>" import six import cmd import sys import os import signal from DIRAC import gLogger gColors = {"red": 1, "green": 2, "yellow": 3, "blue": 4} def colorEnabled(): return os.environ.get("TERM") in ("xterm", "xterm-color") def colorize(text, color): """Return colorized text""" if not colorEnabled(): return text startCode = "\033[;3" endCode = "\033[0m" if isinstance(color, six.integer_types): return "%s%sm%s%s" % (startCode, color, text, endCode) try: return "%s%sm%s%s" % (startCode, gColors[color], text, endCode) except Exception: return text class CLI(cmd.Cmd): def __init__(self): cmd.Cmd.__init__(self) self.indentSpace = 20 self._initSignals() def _handleSignal(self, sig, frame): print("\nReceived signal", sig, ", exiting ...") self.do_quit(self) def _initSignals(self): """ Registers signal handlers """ for sigNum in (signal.SIGINT, signal.SIGQUIT, signal.SIGKILL, signal.SIGTERM): try: signal.signal(sigNum, self._handleSignal) except Exception: pass def _errMsg(self, errMsg): """ Print out a colorized error log message :param str errMsg: error message string :return: nothing """ gLogger.error("%s %s" % (colorize("[ERROR]", "red"), errMsg)) def emptyline(self): pass def do_exit(self, args): """Exit the shell. usage: exit """ self.do_quit(self) def do_quit(self, args): """Exit the shell. usage: quit """ gLogger.notice("") sys.exit(0) def do_EOF(self, args): """Handler for EOF ( Ctrl D ) signal - perform quit""" self.do_quit(args) def do_execfile(self, args): """Execute a series of CLI commands from a given file usage: execfile <filename> """ argss = args.split() fname = argss[0] if not os.path.exists(fname): print("Error: File not found %s" % fname) return with open(fname, "r") as input_cmd: contents = input_cmd.readlines() for line in contents: try: gLogger.notice("\n--> Executing %s\n" % line) self.onecmd(line) except Exception as error: self._errMsg(str(error)) break return def printPair(self, key, value, separator=":"): valueList = value.split("\n") print("%s%s%s %s" % (key, " " * (self.indentSpace - len(key)), separator, valueList[0].strip())) for valueLine in valueList[1:-1]: print("%s %s" % (" " * self.indentSpace, valueLine.strip())) def do_help(self, args): """ Shows help information Usage: help <command> If no command is specified all commands are shown """ if len(args) == 0: print("\nAvailable commands:\n") attrList = sorted(dir(self)) for attribute in attrList: if attribute.startswith("do_"): self.printPair(attribute[3:], getattr(self, attribute).__doc__[1:]) print("") else: command = args.split()[0].strip() try: obj = getattr(self, "do_%s" % command) except Exception: print("There's no such %s command" % command) return self.printPair(command, obj.__doc__[1:])