src.cmd_types.commands

Commands abstract classes defined here. You may register your own(see plugins.plugin_archives)

  1"""Commands abstract classes defined here. You may register your own(see plugins.plugin_archives)"""
  2
  3import inspect
  4import logging
  5from abc import ABC, abstractmethod
  6
  7from src.cmd_types.output import CommandOutput
  8from src.decorators import handlers
  9from src.extra import utils
 10import src.decorators.commands_register as cmd_register
 11
 12
 13class ExecutableCommand(ABC):
 14    """
 15    Abstract class for executable commands(has no undo method)
 16    :param args: list of arguments passed to the command
 17    :type args: list[str]
 18    """
 19
 20    logger: logging.Logger
 21
 22    name: str
 23    """Name of the command"""
 24
 25    flags: list | None
 26    """Flags names to parse(with '-' in front)"""
 27
 28    def __init__(self, args: list[str]):
 29        self.args = args
 30        """List of arguments passed to the command"""
 31
 32
 33    def _log_error(self, msg):
 34        """
 35        Logs an error in format {name}: {msg}
 36        :param msg: error message
 37        :type msg: str
 38        """
 39        utils.log_error(self.name+": "+msg, logger=self.logger)
 40
 41    def parse_flags(self) -> dict[str, bool]:
 42        """
 43        Parse the flags passed in the args
 44        :return: dict of {flag: True/False}
 45        :rtype: dict[str, bool]
 46        """
 47        parsed_flags = {}
 48        if self.flags:
 49            for flag in self.flags:
 50                no_flag = utils.remove_arg(flag, self.args)
 51                parsed_flags[flag] = (len(self.args) != len(no_flag))
 52                self.args = no_flag
 53
 54        return parsed_flags
 55
 56    def exec(self, line: str):
 57        """
 58        Executes a line in terminal. Be cautious
 59        :param line: line to execute
 60        :type line: str
 61        """
 62        cur_frame = inspect.currentframe()
 63        f_back = cur_frame.f_back #type: ignore
 64        while not getattr(f_back.f_locals["self"], 'execute_command', None): #type: ignore
 65
 66            f_back = f_back.f_back #type: ignore
 67            if not f_back:
 68                break
 69        if f_back:
 70            return f_back.f_locals["self"].execute_command(line) #type: ignore
 71        return None
 72
 73    @abstractmethod
 74    def _parse_args(self):
 75        """Parses command line arguments"""
 76
 77    @abstractmethod
 78    def execute(self) -> CommandOutput:
 79        """Executes command"""
 80
 81    @cmd_register.display_in_help("--help")
 82    def help(self, *args, **kwargs):
 83
 84        """Display this message"""
 85
 86        outs: list[tuple[str, str]] = []
 87        for name, obj in inspect.getmembers(self):
 88            if inspect.ismethod(obj) and not name.startswith("__"):
 89                if getattr(obj, "__display_help__", False):
 90                    name_to_append = getattr(obj, "__help_name__", None) or name
 91                    doc = getattr(obj, "__doc__", "")
 92                    outs.append((name_to_append, doc))
 93        output = ""
 94        max_len_tup = max(outs, key=lambda x: len(x[0]))
 95        max_len = len(max_len_tup[0])
 96        for out in outs:
 97            output += out[0] + " " * (max_len - len(out[0])) + 2 * "\t" + out[1] + "\n"
 98
 99        return CommandOutput(stdout = output)
100
101    @handlers.handle_all_default
102    def handled_run(self) -> CommandOutput:
103        """
104        Runs a command with exception handlers, registered by default.
105        You may create your own abstract class with this method overriden
106
107        :return: command execution result
108        :rtype: CommandOutput
109        """
110        return self.execute()
111
112    def history(self):
113        """
114        Writes command to history file
115        """
116        line = ' '.join([self.name]+self.args)
117        utils.write_history(line)
118
119
120class UndoableCommand(ExecutableCommand, ABC):
121
122    """
123    Abstract class for undoable commands(fields of ExecutableCommand are included)
124    """
125
126    @abstractmethod
127    def undo(self):
128        """Undoes command"""
class ExecutableCommand(abc.ABC):
 14class ExecutableCommand(ABC):
 15    """
 16    Abstract class for executable commands(has no undo method)
 17    :param args: list of arguments passed to the command
 18    :type args: list[str]
 19    """
 20
 21    logger: logging.Logger
 22
 23    name: str
 24    """Name of the command"""
 25
 26    flags: list | None
 27    """Flags names to parse(with '-' in front)"""
 28
 29    def __init__(self, args: list[str]):
 30        self.args = args
 31        """List of arguments passed to the command"""
 32
 33
 34    def _log_error(self, msg):
 35        """
 36        Logs an error in format {name}: {msg}
 37        :param msg: error message
 38        :type msg: str
 39        """
 40        utils.log_error(self.name+": "+msg, logger=self.logger)
 41
 42    def parse_flags(self) -> dict[str, bool]:
 43        """
 44        Parse the flags passed in the args
 45        :return: dict of {flag: True/False}
 46        :rtype: dict[str, bool]
 47        """
 48        parsed_flags = {}
 49        if self.flags:
 50            for flag in self.flags:
 51                no_flag = utils.remove_arg(flag, self.args)
 52                parsed_flags[flag] = (len(self.args) != len(no_flag))
 53                self.args = no_flag
 54
 55        return parsed_flags
 56
 57    def exec(self, line: str):
 58        """
 59        Executes a line in terminal. Be cautious
 60        :param line: line to execute
 61        :type line: str
 62        """
 63        cur_frame = inspect.currentframe()
 64        f_back = cur_frame.f_back #type: ignore
 65        while not getattr(f_back.f_locals["self"], 'execute_command', None): #type: ignore
 66
 67            f_back = f_back.f_back #type: ignore
 68            if not f_back:
 69                break
 70        if f_back:
 71            return f_back.f_locals["self"].execute_command(line) #type: ignore
 72        return None
 73
 74    @abstractmethod
 75    def _parse_args(self):
 76        """Parses command line arguments"""
 77
 78    @abstractmethod
 79    def execute(self) -> CommandOutput:
 80        """Executes command"""
 81
 82    @cmd_register.display_in_help("--help")
 83    def help(self, *args, **kwargs):
 84
 85        """Display this message"""
 86
 87        outs: list[tuple[str, str]] = []
 88        for name, obj in inspect.getmembers(self):
 89            if inspect.ismethod(obj) and not name.startswith("__"):
 90                if getattr(obj, "__display_help__", False):
 91                    name_to_append = getattr(obj, "__help_name__", None) or name
 92                    doc = getattr(obj, "__doc__", "")
 93                    outs.append((name_to_append, doc))
 94        output = ""
 95        max_len_tup = max(outs, key=lambda x: len(x[0]))
 96        max_len = len(max_len_tup[0])
 97        for out in outs:
 98            output += out[0] + " " * (max_len - len(out[0])) + 2 * "\t" + out[1] + "\n"
 99
100        return CommandOutput(stdout = output)
101
102    @handlers.handle_all_default
103    def handled_run(self) -> CommandOutput:
104        """
105        Runs a command with exception handlers, registered by default.
106        You may create your own abstract class with this method overriden
107
108        :return: command execution result
109        :rtype: CommandOutput
110        """
111        return self.execute()
112
113    def history(self):
114        """
115        Writes command to history file
116        """
117        line = ' '.join([self.name]+self.args)
118        utils.write_history(line)

Abstract class for executable commands(has no undo method)

Parameters
  • args: list of arguments passed to the command
logger: logging.Logger
name: str

Name of the command

flags: list | None

Flags names to parse(with '-' in front)

args

List of arguments passed to the command

def parse_flags(self) -> dict[str, bool]:
42    def parse_flags(self) -> dict[str, bool]:
43        """
44        Parse the flags passed in the args
45        :return: dict of {flag: True/False}
46        :rtype: dict[str, bool]
47        """
48        parsed_flags = {}
49        if self.flags:
50            for flag in self.flags:
51                no_flag = utils.remove_arg(flag, self.args)
52                parsed_flags[flag] = (len(self.args) != len(no_flag))
53                self.args = no_flag
54
55        return parsed_flags

Parse the flags passed in the args

Returns

dict of {flag: True/False}

def exec(self, line: str):
57    def exec(self, line: str):
58        """
59        Executes a line in terminal. Be cautious
60        :param line: line to execute
61        :type line: str
62        """
63        cur_frame = inspect.currentframe()
64        f_back = cur_frame.f_back #type: ignore
65        while not getattr(f_back.f_locals["self"], 'execute_command', None): #type: ignore
66
67            f_back = f_back.f_back #type: ignore
68            if not f_back:
69                break
70        if f_back:
71            return f_back.f_locals["self"].execute_command(line) #type: ignore
72        return None

Executes a line in terminal. Be cautious

Parameters
  • line: line to execute
@abstractmethod
def execute(self) -> src.cmd_types.output.CommandOutput:
78    @abstractmethod
79    def execute(self) -> CommandOutput:
80        """Executes command"""

Executes command

@cmd_register.display_in_help('--help')
def help(self, *args, **kwargs):
 82    @cmd_register.display_in_help("--help")
 83    def help(self, *args, **kwargs):
 84
 85        """Display this message"""
 86
 87        outs: list[tuple[str, str]] = []
 88        for name, obj in inspect.getmembers(self):
 89            if inspect.ismethod(obj) and not name.startswith("__"):
 90                if getattr(obj, "__display_help__", False):
 91                    name_to_append = getattr(obj, "__help_name__", None) or name
 92                    doc = getattr(obj, "__doc__", "")
 93                    outs.append((name_to_append, doc))
 94        output = ""
 95        max_len_tup = max(outs, key=lambda x: len(x[0]))
 96        max_len = len(max_len_tup[0])
 97        for out in outs:
 98            output += out[0] + " " * (max_len - len(out[0])) + 2 * "\t" + out[1] + "\n"
 99
100        return CommandOutput(stdout = output)

Display this message

@handlers.handle_all_default
def handled_run(self) -> src.cmd_types.output.CommandOutput:
102    @handlers.handle_all_default
103    def handled_run(self) -> CommandOutput:
104        """
105        Runs a command with exception handlers, registered by default.
106        You may create your own abstract class with this method overriden
107
108        :return: command execution result
109        :rtype: CommandOutput
110        """
111        return self.execute()

Runs a command with exception handlers, registered by default. You may create your own abstract class with this method overriden

Returns

command execution result

def history(self):
113    def history(self):
114        """
115        Writes command to history file
116        """
117        line = ' '.join([self.name]+self.args)
118        utils.write_history(line)

Writes command to history file

class UndoableCommand(ExecutableCommand, abc.ABC):
121class UndoableCommand(ExecutableCommand, ABC):
122
123    """
124    Abstract class for undoable commands(fields of ExecutableCommand are included)
125    """
126
127    @abstractmethod
128    def undo(self):
129        """Undoes command"""

Abstract class for undoable commands(fields of ExecutableCommand are included)

@abstractmethod
def undo(self):
127    @abstractmethod
128    def undo(self):
129        """Undoes command"""

Undoes command