Beispiel #1
0
    "StoreExtension",
    # console-related classes
    "Config",
    "ConsoleExit",
    "ConsoleDuplicate",
    "FrameworkConsole",
    "Option",
]

EDITORS = [
    "atom", "emacs", "gedit", "mousepad", "nano", "notepad", "notepad++", "vi",
    "vim"
]
VIEWERS = ["bat", "less"]
try:
    DEFAULT_EDITOR = filter_bin(*EDITORS)[-1]
except IndexError:
    DEFAULT_EDITOR = None
try:
    DEFAULT_VIEWER = filter_bin(*VIEWERS)[0]
except IndexError:
    DEFAULT_VIEWER = None

_output = get_app_session().output
dcount = lambda d, n=0: sum(
    [dcount(v, n) if isinstance(v, dict) else n + 1 for v in d.values()])


def print_formatted_text(*args, **kwargs):
    """ Proxy function that uses the global (capturable) _output. """
    kwargs['output'] = kwargs.get('output', _output)
Beispiel #2
0
class FrameworkConsole(Console):
    """ Framework console subclass for defining specific config options. """
    _entity_class = Console
    aliases = []
    config = Config({
        Option(
            'APP_FOLDER',
            "folder where application assets (i.e. logs) are saved",
            True,
            set_callback=lambda o: o.root._set_app_folder(),
        ):
        "~/.{appname}",
        ROption(
            'DEBUG',
            "debug mode",
            True,
            bool,
            set_callback=lambda o: o.root._set_logging(o.value),
        ):
        "false",
        ROption(
            'TEXT_EDITOR',
            "text file editor to be used",
            False,
            choices=lambda: filter_bin(*EDITORS),
            validate=lambda s, v: which(v) is not None,
        ):
        DEFAULT_EDITOR,
        ROption(
            'TEXT_VIEWER',
            "text file viewer (pager) to be used",
            False,
            choices=lambda: filter_bin(*VIEWERS),
            validate=lambda s, v: which(v) is not None,
        ):
        DEFAULT_VIEWER,
        Option(
            'ENCRYPT_PROJECT',
            "ask for a password to encrypt a project when archiving",
            True,
            bool,
        ):
        "true",
        Option(
            'WORKSPACE',
            "folder where results are saved",
            True,
            set_callback=lambda o: o.root._set_workspace(),
        ):
        "~/Notes",
    })

    def __init__(self, appname=None, *args, **kwargs):
        Console.appname = appname or getattr(self, "appname", Console.appname)
        o, v = self.config.option('APP_FOLDER'), str(self.config['APP_FOLDER'])
        self.config[o] = Path(v.format(appname=self.appname.lower()))
        o.old_value = None
        self._set_app_folder()
        self._set_workspace()
        super(FrameworkConsole, self).__init__(*args, **kwargs)

    def __set_folder(self, option, subpath=""):
        """ Set a new folder, moving an old to the new one if necessary. """
        o = self.config.option(option)
        old, new = o.old_value, o.value
        if old == new:
            return
        try:
            if old is not None:
                os.rename(old, new)
        except Exception as e:
            pass
        Path(new).joinpath(subpath).mkdir(parents=True, exist_ok=True)
        return new

    def _set_app_folder(self):
        """ Set a new APP_FOLDER, moving an old to the new one if necessary. """
        self._files.root_dir = self.__set_folder("APP_FOLDER", "files")
        self._set_logging()

    def _set_logging(self, debug=False, to_file=True):
        """ Set a new logger with the input logging level. """
        l, p = ["INFO", "DEBUG"][debug], None
        if to_file:
            # attach a logger to the console
            lpath = self.app_folder.joinpath("logs")
            lpath.mkdir(parents=True, exist_ok=True)
            p = str(lpath.joinpath("main.log"))
        Console.logger = get_logger(self.__class__.name, p, l)

    def _set_workspace(self):
        """ Set a new APP_FOLDER, moving an old to the new one if necessary. """
        self.__set_folder("WORKSPACE")

    @property
    def app_folder(self):
        """ Shortcut to the current application folder. """
        return Path(self.config.option('APP_FOLDER').value)

    @property
    def workspace(self):
        """ Shortcut to the current workspace. """
        return Path(self.config.option("WORKSPACE").value)
Beispiel #3
0
class FrameworkConsole(Console):
    """ Framework console subclass for defining specific config options. """
    _entity_class = Console
    aliases = []
    config = Config({
        Option(
            'APP_FOLDER',
            "folder where application assets (i.e. logs) are saved",
            True,
            #set_callback=lambda o: o.root._set_app_folder(debug=o.config.option('DEBUG').value),
            glob=False,
        ):
        "~/.{appname}",
        ROption(
            'DEBUG',
            "debug mode",
            True,
            bool,
            set_callback=lambda o: o.root._set_logging(o.value),
            glob=False,
        ):
        "false",
        ROption(
            'TEXT_EDITOR',
            "text file editor to be used",
            False,
            choices=lambda: filter_bin(*EDITORS),
            validate=lambda s, v: which(v) is not None,
            glob=False,
        ):
        DEFAULT_EDITOR,
        ROption(
            'TEXT_VIEWER',
            "text file viewer (pager) to be used",
            False,
            choices=lambda: filter_bin(*VIEWERS),
            validate=lambda s, v: which(v) is not None,
            glob=False,
        ):
        DEFAULT_VIEWER,
        Option(
            'ENCRYPT_PROJECT',
            "ask for a password to encrypt a project when archiving",
            True,
            bool,
            glob=False,
        ):
        "true",
        Option(
            'WORKSPACE',
            "folder where results are saved",
            True,
            set_callback=lambda o: o.root._set_workspace(),
            glob=False,
        ):
        "~/Notes",
    })

    def __init__(self, appname=None, *args, **kwargs):
        Console._dev_mode = kwargs.pop("dev", False)
        Console.appname = appname or getattr(self, "appname", Console.appname)
        o, v = self.config.option('APP_FOLDER'), str(self.config['APP_FOLDER'])
        self.config[o] = Path(v.format(appname=self.appname.lower()))
        o.old_value = None
        self.config['DEBUG'] = kwargs.get('debug', False)
        self._set_app_folder(silent=True, **kwargs)
        self._set_workspace()
        super(FrameworkConsole, self).__init__(*args, **kwargs)

    def __set_folder(self, option, subpath=""):
        """ Set a new folder, moving an old to the new one if necessary. """
        o = self.config.option(option)
        old, new = o.old_value, o.value
        if old == new:
            return
        try:
            if old is not None:
                os.rename(old, new)
        except Exception as e:
            pass
        Path(new).joinpath(subpath).mkdir(parents=True, exist_ok=True)
        return new

    def _set_app_folder(self, **kwargs):
        """ Set a new APP_FOLDER, moving an old to the new one if necessary. """
        self._files.root_dir = self.__set_folder("APP_FOLDER", "files")
        self._set_logging(
            **kwargs
        )  # this is necessary as the log file is located in APP_FOLDER

    def _set_logging(self, debug=False, to_file=True, **kwargs):
        """ Set a new logger with the input logging level. """
        l, p1, p2, dev = "INFO", None, None, Console._dev_mode
        if debug:
            l = "DETAIL" if Console._dev_mode else "DEBUG"
        if to_file:
            # attach a logger to the console
            lpath = self.app_folder.joinpath("logs")
            lpath.mkdir(parents=True, exist_ok=True)
            p1 = str(lpath.joinpath("main.log"))
            if dev:
                p2 = str(lpath.joinpath("debug.log"))
        if l == "INFO" and not kwargs.get('silent', False):
            self.logger.debug("Set logging to INFO")
        Console._logger = get_logger(self.appname.lower(), p1, l)
        # setup framework's logger with its own get_logger function (configuring other handlers than the default one)
        set_logging_level(
            l,
            self.appname.lower(),
            config_func=lambda lgr, lvl: get_logger(lgr.name, p1, lvl))
        # setup internal (dev) loggers with the default logging.configLogger (enhancement to logging from Tinyscript)
        set_logging_level(l,
                          "core",
                          config_func=lambda lgr, lvl: get_logger(
                              lgr.name, p2, lvl, True, dev))
        if l != "INFO" and not kwargs.get('silent', False):
            self.logger.debug("Set logging to {}".format(l))

    def _set_workspace(self):
        """ Set a new APP_FOLDER, moving an old to the new one if necessary. """
        self.__set_folder("WORKSPACE")

    @property
    def app_folder(self):
        """ Shortcut to the current application folder. """
        return Path(self.config.option('APP_FOLDER').value)

    @property
    def workspace(self):
        """ Shortcut to the current workspace. """
        return Path(self.config.option("WORKSPACE").value)