From ce11b099126fc845067f4da1266e204ebb977a1f Mon Sep 17 00:00:00 2001 From: "didierlopes.eth" Date: Tue, 15 Mar 2022 08:49:33 +0000 Subject: [PATCH] Add execute routines command to main menu (#1485) --- .../alternative/covid/covid_view.py | 2 +- gamestonk_terminal/helper_funcs.py | 20 ++++ terminal.py | 99 ++++++++++++++++++- 3 files changed, 118 insertions(+), 3 deletions(-) diff --git a/gamestonk_terminal/alternative/covid/covid_view.py b/gamestonk_terminal/alternative/covid/covid_view.py index fea164edfa4..7a609c0f566 100644 --- a/gamestonk_terminal/alternative/covid/covid_view.py +++ b/gamestonk_terminal/alternative/covid/covid_view.py @@ -143,7 +143,7 @@ def display_covid_stat( else: if len(external_axes) != 1: logger.error("Expected list of one axis item.") - console.print("[red]Expected list of 1 axis item./n[/red]") + console.print("[red]Expected list of 1 axis item.\n[/red]") return (ax,) = external_axes diff --git a/gamestonk_terminal/helper_funcs.py b/gamestonk_terminal/helper_funcs.py index ebceb52ff82..23a1e64abe9 100644 --- a/gamestonk_terminal/helper_funcs.py +++ b/gamestonk_terminal/helper_funcs.py @@ -60,6 +60,26 @@ def set_command_location(cmd_loc: str): command_location = cmd_loc +def check_path(path: str) -> str: + """Check that path file exists + + Parameters + ---------- + path: str + path of file + + Returns + ------- + str: + Ratio of similarity between two strings + """ + if os.path.isfile(path): + return path + logger.error("Expected list of one axis item.") + console.print("The path file provided does not exist.\n[/red]") + return "" + + def log_and_raise(error: Union[argparse.ArgumentTypeError, ValueError]) -> None: logger.error(str(error)) raise error diff --git a/terminal.py b/terminal.py index 2b089235caa..44548ff0809 100644 --- a/terminal.py +++ b/terminal.py @@ -20,6 +20,8 @@ from gamestonk_terminal.helper_funcs import ( get_flair, get_user_timezone_or_invalid, replace_user_timezone, + check_path, + parse_known_args_and_warn, ) from gamestonk_terminal.loggers import setup_logging @@ -50,6 +52,7 @@ class TerminalController(BaseController): "keys", "settings", "tz", + "exe", ] CHOICES_MENUS = [ "stocks", @@ -113,7 +116,8 @@ class TerminalController(BaseController): about about us update update terminal automatically - tz set different timezone[/cmds][menu] + tz set different timezone + exe execute automated routine script[/cmds][menu] > settings set feature flags and style charts > keys set API keys and check their validity[/menu] @@ -227,6 +231,96 @@ class TerminalController(BaseController): self.queue = self.queue[1:] replace_user_timezone("/".join(other_args)) + def call_exe(self, other_args: List[str]): + """Process exe command""" + # Merge rest of string path to other_args and remove queue since it is a dir + other_args += self.queue + full_input = " ".join(other_args) + if " " in full_input: + other_args_processed = full_input.split(" ") + else: + other_args_processed = [full_input] + self.queue = [] + + path_routine = "" + args = list() + for idx, path_dir in enumerate(other_args_processed): + if path_dir in ("-i", "--input"): + args = [path_routine[1:]] + other_args_processed[idx:] + break + path_routine += f"/{path_dir}" + + if not args: + args = [path_routine[1:]] + + parser_exe = argparse.ArgumentParser( + add_help=False, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + prog="exe", + description="Execute automated routine script.", + ) + parser_exe.add_argument( + "-p", + "--path", + help="The path or .gst file to run.", + dest="path", + default="", + type=check_path, + ) + parser_exe.add_argument( + "-i", + "--input", + help="Select multiple inputs to be replaced in the routine and separated by commas. E.g. GME,AMC,BTC-USD", + dest="routine_args", + type=lambda s: [str(item) for item in s.split(",")], + default=None, + ) + if args and "-" not in args[0][0]: + args.insert(0, "-p") + ns_parser_exe = parse_known_args_and_warn(parser_exe, args) + if ns_parser_exe: + if ns_parser_exe.path: + with open(ns_parser_exe.path) as fp: + raw_lines = [x for x in fp if not is_reset(x)] + + if ns_parser_exe.routine_args: + lines = list() + idx = 0 + for rawline in raw_lines: + arg_to_replace = f"$ARGV[{idx}]" + templine = rawline + while arg_to_replace in rawline: + if idx > (len(ns_parser_exe.routine_args) - 1): + console.print( + "[red]There are more arguments on the routine " + ".gst file than input args provided[/red]" + ) + return + templine = templine.replace( + arg_to_replace, ns_parser_exe.routine_args[idx] + ) + idx += 1 + arg_to_replace = f"$ARGV[{idx}]" + + lines.append(templine) + + if idx < len(ns_parser_exe.routine_args): + console.print( + "[red]There are more inputs provided than the number " + "of arguments on routine .gst file\n[/red]" + ) + + else: + lines = raw_lines + + simulate_argv = f"/{'/'.join([line.rstrip() for line in lines])}" + file_cmds = simulate_argv.replace("//", "/home/").split() + file_cmds = ( + insert_start_slash(file_cmds) if file_cmds else file_cmds + ) + cmds_with_params = " ".join(file_cmds) + self.queue = cmds_with_params.split("/") + def terminal(jobs_cmds: List[str] = None): """Terminal Menu""" @@ -429,8 +523,9 @@ def run_scripts( simulate_argv = f"/{'/'.join([line.rstrip() for line in lines])}" file_cmds = simulate_argv.replace("//", "/home/").split() - file_cmds = insert_start_slash(file_cmds) if file_cmds else file_cmds + file_cmds = [" ".join(file_cmds)] + if not test_mode: terminal(file_cmds) # TODO: Add way to track how many commands are tested