class Command:
  def __init__(self, f_name, f_obj, help, module = "Builtin"):
    self.log = Log()
    self.log.newline()
    self.log.info("Creating command {}".format(f_name))
    self.log.line("-")
    self.name = f_name
    self.func = f_obj
    self.help = self.func.__doc__ or ""
    self.module = module
    self.admin_required = "admin" in self.func.__code__.co_varnames
    self.nargs = self.func.__code__.co_argcount
    self.defaults = self.func.__defaults__
    self.argdefault = {}
    if (self.defaults):
      self.noptargs = len(self.defaults) 
    else:
      self.noptargs = 0
    self.args = self.func.__code__.co_varnames[:self.nargs - self.noptargs]
    self.optargs = self.func.__code__.co_varnames[self.nargs-self.noptargs:
                                                  self.noptargs+1]
    self.hints = typing.get_type_hints(self.func) 
    if "self" in self.args:
      self.nargs -= 1
    self.args = tuple([x for x in self.args if x != "self"])
    for i in range(self.noptargs):
      self.argdefault[self.optargs[i]] = self.defaults[i]

    if self.nargs > 0:
      self.log.info("ARGS: " + ", ".join(self.args))
      self.log.info("OPTARGS: " + ", ".join(self.optargs))
      self.log.info("DEFAULTS: " + ", ".join(
                            ["{}={}".format(
                      i, self.argdefault[i]) for i in self.argdefault]))      
    else:
      self.log.info("No arguments")
    self.delim = ","
    self.NOSPLIT = "NOSPLIT" in self.func.__code__.co_varnames

    self.success = True
    self.log.line("-")
    self.log.info(self)

  def getHelp(self):
    h =  self.name + ":\n" + self.help 
    if self.nargs > 0:
      h += "\nARGS: " + ", ".join(self.args) + "\n" 
    if self.noptargs > 0:
      h +=  "\nOPTARGS: " + " , ".join(self.optargs)
    if "\n" not in h:
      h += " (No Arguments)"
    return h 

  def run(self, args, user_is_admin=False):
    if self.admin_required and not user_is_admin:
      self.log.warning("{} requires administrative permissions".format(self.name))
    self.log.newline()
    self.log.newline()
    self.log.line("+")
    if not self.NOSPLIT:
      args = self._formatArgs(args.split(self.delim))
    else:
      args = self._formatArgs([args])
    self.log.info("Running {} with args {}".format(self.name, args))
    output = self.func(**args)
    self.log.line("+")
    self.log.newline()
    self.log.newline()
    return output
  
  def _formatArgs(self, args):
    args = [x.strip() for x in args if x != '']
    processedArgs = {}
    allargs = self.args + self.optargs
    for i in range(self.nargs):
      arg = ""
      argn = allargs[i]
      if i >= len(args):
        arg = self.argdefault[argn]
      else:
        arg = args[i]
      if allargs[i] in self.hints:
        try:
          arg = self.hints[argn](arg)
        except ValueError as ex:
          raise ArgumentFormatError(ex)
      processedArgs[argn] = arg
    
    return processedArgs

  def __repr__(self):
    x = "\n\nCOMMAND DEFINITION ::- \n"
    return x+"\nCommand (\n Name: {}.{},\n Args: {},\n OptArgs: {}\n Admin: {}\n)\n".format(
            self.module, self.name, self.args, self.optargs, self.admin_required)
Esempio n. 2
0
class Conf:
    """Class for parsing simple (key sep value) format files"""
    def __init__(self, filename, sep=":"):
        self.log = Log()
        self.filename = filename
        self.log.info("Reading {}".format(filename))
        self.config = {}
        self.sep = sep
        self._readFile()
        self._extractConfig()
        self.log.info("Succesfully parsed {}".format(filename))

    def _readFile(self):
        """Read in the configuration file"""

        self.log.debug("Opening file {}".format(self.filename))
        ##Open the config file
        try:
            f = open(self.filename, "r")
        except FileNotFoundError:
            self.log.error("File '{}' not found!".format(self.filename))

        ##Read in each line, ignoring empty lines
        self.text = [x[:-1] for x in f.readlines() if x[:-1] != ""]
        self.log.debug("File read succesfully")
        ##Close the file
        f.close()
        self.log.debug("{} closed".format(self.filename))

    def writeFile(self, alternateFile=None):
        """Write the changed configuration back to a file"""

        self.log.info("Writing config back to file")
        filename = self.filename
        ##Just in case the user wants to change location
        if alternateFile:
            filename = alternateFile
        self.log.info("Writing to {}".format(filename))

        try:
            with open(filename, "w") as f:
                for i in sorted(self.config):
                    f.write("{}:{}\n".format(i, self.config[i]))
        except Exception as e:
            self.log.warning("An error occurred -- {}".format(e))
            return 1
        self.log.debug("{} Written succesfully".format(filename))
        return 0

    def _extractConfig(self):
        """Get all the key value pairs from the config file"""

        ##Keep track of line of debug purposes
        lineno = 1
        for i in self.text:
            ##Split the line by the seperator
            setting, sep, value = i.partition(self.sep)
            if setting in self.config:
                ##If we've already seen that key before
                self.log.warning("Duplicate setting '{}' (Line {})".format(
                    setting, lineno))
            else:
                ##Check for empty setting name
                if setting == "":
                    self.log.warning(
                        "Empty setting name (Line {})".format(lineno))
                else:
                    ##Check for empty value
                    if value == "":
                        self.log.warning(
                            "Empty setting value '{}'(Line {})".format(
                                setting, lineno))
                    else:
                        ##It all looks good
                        self.config[setting] = value
            lineno += 1

    def getValue(self, key):
        """Get the value associated with a key"""

        if key in self.config:
            return self.config[key]
        else:
            ##If we can't find the key
            self.log.error("Setting '{}' not found!".format(key))
            return 0

    def getData(self, key):
        """Get the parsed value of a key - for lists and dicts"""
        x = self.getValue(key)
        return eval(x)

    def setValue(self, key, value):
        """Change the value of a setting"""

        if key == "":
            self.log.warning(
                "Non-empty keys only please! (value thrown: {})".format(value))
            return False
        else:
            self.config[key] = value
            return True
class Command:
    def __init__(self, f_name, f_obj, help, module="Builtin"):
        self.log = Log()
        self.log.newline()
        self.log.info("Creating command {}".format(f_name))
        self.log.line("-")
        self.name = f_name
        self.func = f_obj
        self.help = self.func.__doc__ or ""
        self.module = module
        self.admin_required = "admin" in self.func.__code__.co_varnames
        self.nargs = self.func.__code__.co_argcount
        self.defaults = self.func.__defaults__
        self.argdefault = {}
        if (self.defaults):
            self.noptargs = len(self.defaults)
        else:
            self.noptargs = 0
        self.args = self.func.__code__.co_varnames[:self.nargs - self.noptargs]
        self.optargs = self.func.__code__.co_varnames[self.nargs - self.
                                                      noptargs:self.noptargs +
                                                      1]
        self.hints = typing.get_type_hints(self.func)
        if "self" in self.args:
            self.nargs -= 1
        self.args = tuple([x for x in self.args if x != "self"])
        for i in range(self.noptargs):
            self.argdefault[self.optargs[i]] = self.defaults[i]

        if self.nargs > 0:
            self.log.info("ARGS: " + ", ".join(self.args))
            self.log.info("OPTARGS: " + ", ".join(self.optargs))
            self.log.info("DEFAULTS: " + ", ".join([
                "{}={}".format(i, self.argdefault[i]) for i in self.argdefault
            ]))
        else:
            self.log.info("No arguments")
        self.delim = ","
        self.NOSPLIT = "NOSPLIT" in self.func.__code__.co_varnames

        self.success = True
        self.log.line("-")
        self.log.info(self)

    def getHelp(self):
        h = self.name + ":\n" + self.help
        if self.nargs > 0:
            h += "\nARGS: " + ", ".join(self.args) + "\n"
        if self.noptargs > 0:
            h += "\nOPTARGS: " + " , ".join(self.optargs)
        if "\n" not in h:
            h += " (No Arguments)"
        return h

    def run(self, args, user_is_admin=False):
        if self.admin_required and not user_is_admin:
            self.log.warning("{} requires administrative permissions".format(
                self.name))
        self.log.newline()
        self.log.newline()
        self.log.line("+")
        if not self.NOSPLIT:
            args = self._formatArgs(args.split(self.delim))
        else:
            args = self._formatArgs([args])
        self.log.info("Running {} with args {}".format(self.name, args))
        output = self.func(**args)
        self.log.line("+")
        self.log.newline()
        self.log.newline()
        return output

    def _formatArgs(self, args):
        args = [x.strip() for x in args if x != '']
        processedArgs = {}
        allargs = self.args + self.optargs
        for i in range(self.nargs):
            arg = ""
            argn = allargs[i]
            if i >= len(args):
                arg = self.argdefault[argn]
            else:
                arg = args[i]
            if allargs[i] in self.hints:
                try:
                    arg = self.hints[argn](arg)
                except ValueError as ex:
                    raise ArgumentFormatError(ex)
            processedArgs[argn] = arg

        return processedArgs

    def __repr__(self):
        x = "\n\nCOMMAND DEFINITION ::- \n"
        return x + "\nCommand (\n Name: {}.{},\n Args: {},\n OptArgs: {}\n Admin: {}\n)\n".format(
            self.module, self.name, self.args, self.optargs,
            self.admin_required)