Beispiel #1
0
 def configure_path(self, path: Configured_Path, manually: bool) -> None:
     if manually:
         logger.trace(f"Configuring path {path.internal_name} manually")
         while True:
             try:
                 # Special treatment of ...
                 if False:
                     pass
                 # Normal paths
                 else:
                     logger.trace(f"Normal treatment")
                     input_path = utils.input_path(
                         f"Input path to the {path.comment}: ")
                     created_path = utils.provide_dir(input_path)
                 break
             except OSError as err:
                 # Happens if, for example, a folder or a file cannot be created because it already exists.
                 logger.error(err)
                 continue
     else:
         logger.trace(f"Configuring paths automatically")
         # Special case
         if False:
             pass
         # Normal case
         else:
             created_path = utils.provide_dir(path.conf_path)
     logger.debug(f"created_path {str(created_path)}")
     # update the path in the list of configured paths
     path.conf_path = created_path
     logger.trace(f"_{path.internal_name}.conf_path = {created_path}")
Beispiel #2
0
 def __init__(self, cfg_path: pathlib.Path, autoconfig: bool) -> None:
     self.path_to_config_file = cfg_path
     self.path_to_home = utils.provide_dir(self.path_to_config_file.parent)
     self.path_to_starter_home = pathlib.Path.home() / utils.home_dir_name
     self._local_sub_dir = Configured_Path(
         internal_name="local_sub_dir",
         comment="Just an example of a subdirectory",
         preconf_path=self.path_to_starter_home / "subdir",
     )
     self.configured_paths = (self._local_sub_dir, )
     self.read_config_and_check_syntax()
     self.parse_config_and_check_values()
     self.set_logging_colors()
     # Let's create convenient highlighting shortcut functions
     # so that we can write e.g. `config.noteworthy(word)` instead of
     # config.highlight(word, config.highlight_noteworthy)
     logger.debug(
         f"Creating convenient shortcut functions for keyword highlighting:"
     )
     for highlight_definition in self.highlight_definitions:
         setattr(
             self, highlight_definition.type,
             partial(self.highlight,
                     color_tag=getattr(
                         self, "_".join(
                             ("highlight", highlight_definition.type)))))
         logger.debug(
             f"Config.{highlight_definition.type} = lambda word: Config.highlight(word, Config.highlight_{highlight_definition.type}"
         )
     while (wrong_paths := self.filter_wrong_paths(self.configured_paths)):
         self.wizard(wrong_paths, autoconfig)
         self.create_config_file()
         self.read_config_and_check_syntax()
         self.parse_config_and_check_values()
Beispiel #3
0
def cli_start(version) -> None:
    """
    Entry point for the starter start from command line
    """
    parser = argument_parser()
    argcomplete.autocomplete(parser)
    cli_args = parser.parse_args(namespace=OrderedNamespace())
    logger.trace(f"Parsed arguments: {cli_args}")
    logger.debug(f"Ordered command line arguments: {tuple(cli_args.ordered())}")
    path_to_config = path_to_dir / utils.configuration_file_name
    try:
        if cli_args.version:
            logger.info(f"{version}")
        with config_loader.Config(path_to_config, cli_args.autoconfig) as config:
            config.cli_args = cli_args
            run(config)
    except errors.WrongConfiguration as err:
        logger.trace(f"Handling WrongConfiguration error (will just type it out for the user)")
        if err.payload is not None:
            logger.error(f"{err.message}: {err.payload.__class__.__name__} {err.payload}")
        logger.error(f"Correct `{str(path_to_config)}` manually or delete it to create a default one.")
    except KeyboardInterrupt as e:
        logger.error(f"Keyboard Interrupt")
    except Exception as err:
        logger.exception(f"Uncaught exception {repr(err)} occurred.")
    finally:
        pass
Beispiel #4
0
 def set_default_log_level_colors(self) -> None:
     section = "Log level colors"
     for log_level in self.log_levels:
         variable = "_".join(("log_level", log_level.level.lower()))
         self.config_parser.set(section, variable, log_level.default_color)
         logger.debug(
             f"self.config_parser.set({repr(section)}, {repr(variable)}, {repr(log_level.default_color)})"
         )
Beispiel #5
0
 def read_config_file(self) -> None:
     """
     Reads current configuration file
     """
     self.reset_parser()
     logger.trace(f"config_parser might raise FileNotFoundError")
     self.config_parser.read_file(open(self.path_to_config_file))
     logger.trace(f"config_parser did not raise FileNotFoundError")
     logger.debug(f"{self.path_to_config_file.name} read successfully")
Beispiel #6
0
 def set_default_highlight(
     self,
     section: Literal["Highlight colors", "Highlight keywords"],
     attr_prefix: Literal["highlight", "keyword"],
     nt_attr: Literal["default_color", "default_keywords"],
 ) -> None:
     for highlight_definition in self.highlight_definitions:
         variable = "_".join((attr_prefix, highlight_definition.type))
         value = getattr(highlight_definition, nt_attr)
         self.config_parser.set(section, variable, value)
         logger.debug(
             f"self.config_parser.set({repr(section)}, {repr(variable)}, {repr(value)}"
         )
Beispiel #7
0
 def check_and_set_keyword_highlight_groups(
         self, keyword_highlight_group: str) -> None:
     wl = tuple(
         filter(
             bool,
             re.split(
                 self.color_delimiter,
                 self.config_parser.get("Highlight keywords",
                                        keyword_highlight_group))))
     setattr(self, keyword_highlight_group, wl)
     for word in wl:
         self.highlight_keywords[word] = keyword_highlight_group.replace(
             "keywords", "highlight")
         logger.debug(
             f"Config.highlight_keywords[{repr(word)}] = {repr(self.highlight_keywords[word])}"
         )
Beispiel #8
0
def provide_dir(directory: pathlib.Path) -> pathlib.Path:
    """
    Checks if there is a directory of name `dir_name` in the user home path.
    If not, it will try to create one. 
    """
    if directory.exists() and directory.is_dir():
        logger.trace(f"Found directory {str(directory)}")
    else:
        while True:
            try:
                directory.mkdir()
                logger.success(f"Created directory {str(directory)}")
                break
            except FileNotFoundError:
                provide_dir(directory.parent)
                continue
            except FileExistsError:
                logger.debug(f"{directory} already exists")
                break
    return directory
Beispiel #9
0
    def wizard(self, wrong_paths: Tuple[Configured_Path],
               autoconfig: bool) -> None:
        """
        Configuration wizard helps the user to correct the paths which don't exist
        """
        wiz_menu = menu.Text_Menu(menu_name="Configuration Wizard",
                                  heading=r"""
 ____ ____ __ _ ____ _ ____ _  _ ____ ____ ___ _ ____ __ _
 |___ [__] | \| |--- | |__, |__| |--< |--|  |  | [__] | \|
 _  _ _ ___  ____ ____ ___
 |/\| |  /__ |--| |--< |__>
 """)
        heading_was_shown = False
        number_to_word = dict((
            (1, "one"),
            (2, "two"),
            (3, "three"),
            (4, "four"),
            (5, "five"),
            (6, "six"),
            (7, "seven"),
            (8, "eight"),
            (9, "nine"),
            (10, "ten"),
            (11, "eleven"),
            (12, "twelve"),
        ))
        for path in wrong_paths:
            if not heading_was_shown:
                wiz_menu.show_heading("INFO")
                heading_was_shown = True
            reason = (
                f"{path.internal_name} ({path.conf_path}) does not exist!")
            comment = path.comment
            options = OrderedDict((
                ("A", f""),
                ("C", "Create this path automatically"),
                ("M", "Manually input correct path to use or to create"),
                ("Q",
                 f"Quit to edit {self.highlight(path.internal_name, self.highlight_noteworthy)} in {self.highlight(self.path_to_config_file.name, self.highlight_noteworthy)} manually"
                 ),
            ))
            number_of_remaining_paths = len(
                wrong_paths) - 1 - wrong_paths.index(path)
            if number_of_remaining_paths >= 2:
                options[
                    "A"] = f"Automatically configure this and {self.noteworthy(number_to_word[number_of_remaining_paths])} remaining path settings"
            elif number_of_remaining_paths == 1:
                options[
                    "A"] = f"Automatically configure this and {self.noteworthy(number_to_word[number_of_remaining_paths])} remaining path setting"
            else:  # number_of_remaining_paths == 0
                del options["A"]
            if autoconfig:
                choice = "C"
            else:
                choice = None
            if not choice:
                wiz_menu.show_reason(reason, "IMPORTANT")
                wiz_menu.show_comment(
                    "".join((" " * len(utils.warn("")),
                             comment[0].capitalize() + comment[1:])), "INFO")
                choice = wiz_menu.choose_from(options, "PROCEDURE")
            if choice == "A":
                autoconfig = True
                choice = "C"
            logger.debug(f"Your choice: {choice}")
            if choice == "C":
                self.configure_path(path, manually=False)
            elif choice == "M":
                self.configure_path(path, manually=True)
            elif choice == "Q":
                # create config file to save the progress until now
                self.create_config_file()
                logger.trace(f"Raising WrongConfiguration error")
                raise errors.WrongConfiguration(
                    f"Who needs a wizard, when you can edit `{self.path_to_config_file.name}` yourself, right?",
                    None)
        self.create_config_file()
Beispiel #10
0
 def create_config_file(self) -> None:
     """
     Creates the default config file
     """
     self.reset_parser()
     self.config_parser.add_section("Local Paths")
     self.config_parser.set(
         "Local Paths",
         "# You can write paths in Windows format or Linux/POSIX format.")
     self.config_parser.set(
         "Local Paths",
         "# A trailing '/' at the end of the final directory in a POSIX path"
     )
     self.config_parser.set(
         "Local Paths",
         "# or a '\\' at the end of the final directory of a Windows path")
     self.config_parser.set("Local Paths",
                            "# does not interfere with the path parser.")
     self.config_parser.set("Local Paths", "")
     for path in self.configured_paths:
         logger.trace(
             f"Setting {path.internal_name} to path.conf_path = {str(path.conf_path)} in the config file"
         )
         self.config_parser.set(
             "Local Paths",
             f"# {path.comment[0].capitalize()}{path.comment[1:]}")
         self.config_parser.set("Local Paths", f"{path.internal_name}",
                                f"{path.conf_path}")
     self.config_parser.add_section("Values")
     self.config_parser.set("Values", "# Some config values")
     self.config_parser.set("Values", "")
     self.config_parser.set("Values", "preset_value", "42")
     self.config_parser.add_section("Log level colors")
     self.config_parser.set(
         "Log level colors",
         "# Default colors of log levels which are output to the user.")
     self.config_parser.set(
         "Log level colors",
         "# Acceptable values are the keywords from the AnsiParser class")
     self.config_parser.set(
         "Log level colors",
         "# in https://github.com/Delgan/loguru/blob/master/loguru/_colorizer.py"
     )
     self.config_parser.set(
         "Log level colors",
         "# e.g. 'black', 'red', 'green', 'cyan', 'white' ...")
     self.config_parser.set(
         "Log level colors",
         "# optionally prefixed with 'light-', e.g. 'light-blue', 'light-yellow' etc."
     )
     self.config_parser.set(
         "Log level colors",
         "# You can also add style and background, e.g. 'light-green, underline, LIGHT-BLACK'"
     )
     self.config_parser.set(
         "Log level colors",
         "# Separate the words with a comma and a space.")
     self.config_parser.set(
         "Log level colors",
         "# Value 'normal' can be used to disable color highlighting.")
     self.config_parser.set("Log level colors", "")
     self.set_default_log_level_colors()
     self.config_parser.add_section("Highlight colors")
     self.config_parser.set(
         "Highlight colors",
         "# Certain words or substrings in log lines will be highlighted")
     self.config_parser.set(
         "Highlight colors",
         "# and temporarily override the log line's default color.")
     self.config_parser.set(
         "Highlight colors",
         "# Use the same color-defining rules as in the section Log level colors"
     )
     self.config_parser.set(
         "Highlight colors",
         "# to define the colors of each highlight type.")
     self.config_parser.set(
         "Log level colors",
         "# Value 'normal' can be used to disable color highlighting.")
     self.config_parser.set("Highlight colors", "")
     self.set_default_highlight(section="Highlight colors",
                                attr_prefix="highlight",
                                nt_attr="default_color")
     self.config_parser.add_section("Highlight keywords")
     self.config_parser.set(
         "Highlight keywords",
         "# Define which words or substrings will be highlighted with which highlight type."
     )
     self.config_parser.set("Highlight keywords",
                            "# Separate words with a comma and a space.")
     self.config_parser.set(
         "Highlight keywords",
         "# These keywords are highlighted only in certain predefined output lines"
     )
     self.config_parser.set(
         "Highlight keywords",
         "# where they are expected, e.g. when retrieved as values from RSI properties."
     )
     self.config_parser.set(
         "Highlight keywords",
         "# Defining a keyword here guarantees by no means")
     self.config_parser.set(
         "Highlight keywords",
         "# that it would also be highlighted in any other output line.")
     self.config_parser.set(
         "Highlight keywords",
         "# Experts: You can use regular expressions here, but they must not contain ', '"
     )
     self.config_parser.set(
         "Highlight keywords",
         "# because this is used as a keyword separator. If needed, use '\\ \\,' in the regex."
     )
     self.config_parser.set("Highlight keywords", "")
     self.set_default_highlight(section="Highlight keywords",
                                attr_prefix="keywords",
                                nt_attr="default_keywords")
     with open(self.path_to_config_file, mode="w",
               encoding="utf-8") as configfh:
         self.config_parser.write(configfh)
     logger.debug(f"Config file written")
Beispiel #11
0
 def wrapped(*args, **kwargs):
     start = time.time()
     result = func(*args, **kwargs)
     end = time.time()
     logger.debug("Function '{}' executed in {:f} s", name, end - start)
     return result