From 3c52d1b046c02e0284f50d3035d5e75a0a9f6f4d Mon Sep 17 00:00:00 2001 From: CordlessCoder Date: Tue, 5 Jul 2022 22:39:22 +0300 Subject: [PATCH] chore: removed duplicate handle_input calls --- .config.template.toml | 8 +- config.toml | 19 ----- main.py | 23 +++--- utils/console.py | 38 +++++---- utils/tomlchecker.py | 183 +++++++++++------------------------------- 5 files changed, 88 insertions(+), 183 deletions(-) delete mode 100644 config.toml diff --git a/.config.template.toml b/.config.template.toml index e7de56f..1c5ee43 100644 --- a/.config.template.toml +++ b/.config.template.toml @@ -3,7 +3,7 @@ client_id = { optional = false, nmin = 12, nmax = 30, explanation = "the ID of y client_secret = { optional = false, nmin = 20, nmax = 40, explanation = "the SECRET of your Reddit app of SCRIPT type", example = "fFAGRNJru1FTz70BzhT3Zg", regex = "^[-a-zA-Z0-9._~+/]+=*$", input_error = "The client ID can only contain printable characters.", oob_error = "The secret should be over 20 and under 40 characters, double check your input." } username = { optional = false, nmin = 3, nmax = 20, explanation = "the username of your reddit account", example = "asdfghjkl", regex = "^[-_0-9a-zA-Z]+$", oob_error = "A username HAS to be between 3 and 20 characters" } password = { optional = false, nmin = 8, explanation = "the password of your reddit account", example = "fFAGRNJru1FTz70BzhT3Zg", oob_error = "Password too short" } -2fa = { optional = true, options = [ +2fa = { optional = true, type = "bool", options = [ true, false, ], default = false, explanation = "Whether you have Reddit 2FA enabled, Valid options are True and Talse", example = true } @@ -13,14 +13,14 @@ password = { optional = false, nmin = 8, explanation = "the password of your red random = { optional = true, options = [ true, false, -], default = false, explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it. Default: 'False'", example = "True" } +], default = false, type = "bool", explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it. Default: 'False'", example = "True" } subreddit = { optional = false, regex = "[_0-9a-zA-Z]+$", nmin = 3, nmax = 21, explanation = "what subreddit to pull posts from, the name of the sub, not the URL", example = "AskReddit", oob_error = "A subreddit name HAS to be between 3 and 20 characters" } post_id = { optional = false, regex = "^((?!://|://).)*$", explanation = "Used if you want to use a specific post.", example = "urdtfx" } max_comment_length = { default = 500, optional = false, nmin = 10, nmax = 10000, type = "int", explanation = "max number of characters a comment can have. default is 500", example = 500, oob_error = "the max comment length should be between 10 and 10000" } [settings] -allow_nsfw = { optional = true, default = false, example = false, options = [ +allow_nsfw = { optional = true, type = "bool", default = false, example = false, options = [ true, false, ], explanation = "Whether to allow NSFW content, True or False" } @@ -30,7 +30,7 @@ theme = { optional = true, default = "light", example = "dark", options = [ ], explanation = "sets the Reddit theme, either LIGHT or DARK" } times_to_run = { optional = true, default = 1, example = 2, explanation = "used if you want to run multiple times. set to an int e.g. 4 or 29 or 1", type = "int", nmin = 1, oob_error = "It's very hard to run something less than once." } opacity = { optional = true, default = 0.9, example = 0.8, explanation = "Sets the opacity of the comments when overlayed over the background", type = "float", nmin = 0, nmax = 1, oob_error = "The opacity HAS to be between 0 and 1", input_error = "The opacity HAS to be a decimal number between 0 and 1" } -storymode = { optional = true, default = false, example = false, options = [ +storymode = { optional = true, type = "bool", default = false, example = false, options = [ true, false, ] } diff --git a/config.toml b/config.toml deleted file mode 100644 index baba72c..0000000 --- a/config.toml +++ /dev/null @@ -1,19 +0,0 @@ -[settings] -allow_nsfw = false -theme = "light" -times_to_run = 1 -opacity = 0.9 -storymode = false - -[reddit.creds] -client_id = "adsfadsfasdf" -client_secret = "adsfasdfadsfasdfasdf" -username = "asdfasdfadsf" -password = "asdfasdfadsf" -2fa = false - -[reddit.thread] -random = false -subreddit = "asdfasdfadsfadsfadfs" -post_id = "asdfasdfasdf" -max_comment_length = 500 diff --git a/main.py b/main.py index e362aad..b7fdc5c 100755 --- a/main.py +++ b/main.py @@ -1,12 +1,11 @@ #!/usr/bin/env python import math from subprocess import Popen -from os import getenv, name -from dotenv import load_dotenv +from os import name from reddit.subreddit import get_subreddit_threads from utils.cleanup import cleanup from utils.console import print_markdown, print_step -from utils.checker import check_env +from utils.tomlchecker import check_toml # from utils.checker import envUpdate from video_creation.background import download_background, chop_background_video @@ -31,6 +30,7 @@ print_markdown( ) print_step(f"You are using V{VERSION} of the bot") + def main(POST_ID=None): cleanup() reddit_object = get_subreddit_threads(POST_ID) @@ -45,25 +45,24 @@ def main(POST_ID=None): def run_many(times): for x in range(1, times + 1): print_step( - f'on the {x}{("st" if x == 1 else ("nd" if x == 2 else ("rd" if x == 3 else "th")))} iteration of {times}' + f'on the {x}{("th", "st", "nd", "rd", "th", "th", "th", "th","th", "th")[x%10]} iteration of {times}' ) # correct 1st 2nd 3rd 4th 5th.... main() Popen("cls" if name == "nt" else "clear", shell=True).wait() if __name__ == "__main__": - if check_env() is not True: - exit() - load_dotenv() + config = check_toml(".config.template.toml", "config.toml") + config is False and exit() try: - if getenv("TIMES_TO_RUN") and isinstance(int(getenv("TIMES_TO_RUN")), int): - run_many(int(getenv("TIMES_TO_RUN"))) + if config["settings"]["times_to_run"]: + run_many(config["settings"]["times_to_run"]) - elif len(getenv("POST_ID", "").split("+")) > 1: - for index, post_id in enumerate(getenv("POST_ID", "").split("+")): + elif len(config["reddit"]["thread"]["post_id"].split("+")) > 1: + for index, post_id in enumerate(config["reddit"]["thread"]["post_id"].split("+")): index += 1 print_step( - f'on the {index}{("st" if index == 1 else ("nd" if index == 2 else ("rd" if index == 3 else "th")))} post of {len(getenv("POST_ID", "").split("+"))}' + f'on the {index}{("st" if index%10 == 1 else ("nd" if index%10 == 2 else ("rd" if index%10 == 3 else "th")))} post of {len(config["reddit"]["thread"]["post_id"].split("+"))}' ) main(post_id) Popen("cls" if name == "nt" else "clear", shell=True).wait() diff --git a/utils/console.py b/utils/console.py index fdab5d5..46396f2 100644 --- a/utils/console.py +++ b/utils/console.py @@ -23,14 +23,13 @@ def print_step(text): panel = Panel(Text(text, justify="left")) console.print(panel) - + def print_table(items): """Prints items in a table.""" console.print(Columns([Panel(f"[yellow]{item}", expand=True) for item in items])) - def print_substep(text, style=""): """Prints a rich info message without the panelling.""" console.print(text, style=style) @@ -80,8 +79,7 @@ def handle_input( continue elif match != "" and re.match(match, user_input) is None: console.print( - "[red]" + err_message + - "\nAre you absolutely sure it's correct?(y/n)" + "[red]" + err_message + "\nAre you absolutely sure it's correct?(y/n)" ) if input().casefold().startswith("y"): break @@ -99,13 +97,25 @@ def handle_input( while True: console.print(message, end="") user_input = input("").strip() - if user_input not in options: - console.print( - "[red bold]" - + err_message - + "\nValid options are: " - + ", ".join(map(str, options)) - + "." - ) - continue - return user_input + if check_type is not False: + try: + isinstance(eval(user_input), check_type) + return check_type(user_input) + except: + console.print( + "[red bold]" + + err_message + + "\nValid options are: " + + ", ".join(map(str, options)) + + "." + ) + continue + if user_input in options: + return user_input + console.print( + "[red bold]" + + err_message + + "\nValid options are: " + + ", ".join(map(str, options)) + + "." + ) diff --git a/utils/tomlchecker.py b/utils/tomlchecker.py index 85f6a58..c4e8c5a 100755 --- a/utils/tomlchecker.py +++ b/utils/tomlchecker.py @@ -5,14 +5,12 @@ from rich import pretty from rich.console import Console import re -# from utils.console import handle_input -from console import handle_input +from utils.console import handle_input - -console = Console() +# from console import handle_input -printed = False +console = Console() def crawl(obj: dict, func=lambda x, y: print(x, y, end="\n"), path: list = []): @@ -24,124 +22,50 @@ def crawl(obj: dict, func=lambda x, y: print(x, y, end="\n"), path: list = []): def check(value, checks, name): - global printed - if printed is False: - console.print( - """\ -[blue bold]############################### -# # -# Checking TOML configuration # -# # -############################### -If you see any prompts, that means that you have unset/incorrectly set variables, please input the correct values.\ -""" - ) - printed = True - if "type" in checks: + + incorrect = False + if value == {}: + incorrect = True + if not incorrect and "type" in checks: try: value = eval(checks["type"])(value) except: - value = handle_input( - message=( - ( - ("[blue]Example: " + str(checks["example"]) + "\n") - if "example" in checks - else "" - ) - + "[red]" - + ("Non-optional ", "Optional ")[ - "optional" in checks and checks["optional"] is True - ] - ) - + " [#C0CAF5 bold]" - + str(name) - + "[#F7768E bold]=", - check_type=eval(checks["type"]), - extra_info=checks["explanation"] if "explanation" in checks else "", - default=checks["default"] if "default" in checks else NotImplemented, - match=checks["regex"] if "regex" in checks else "", - err_message=checks["input_error"] if "input_error" in checks else "Incorrect input", - nmin=checks["nmin"] if "nmin" in checks else None, - nmax=checks["nmax"] if "nmax" in checks else None, - oob_error=checks["oob_error"] - if "oob_error" in checks - else "Input out of bounds(Value too high/low/long/short)", - ) + incorrect = True if ( - "options" in checks and value not in checks["options"] + not incorrect and "options" in checks and value not in checks["options"] ): # FAILSTATE Value is not one of the options - value = handle_input( - message=( - (("[blue]Example: " + str(checks["example"]) + "\n") if "example" in checks else "") - + "[red]" - + ("Non-optional ", "Optional ")[ - "optional" in checks and checks["optional"] is True - ] - ) - + "[#C0CAF5 bold]" - + str(name) - + "[#F7768E bold]=", - extra_info=checks["explanation"] if "explanation" in checks else "", - err_message=checks["input_error"] if "input_error" in checks else "Incorrect input", - default=checks["default"] if "default" in checks else NotImplemented, - options=checks["options"], + incorrect = True + if ( + not incorrect + and "regex" in checks + and ( + (isinstance(value, str) and re.match(checks["regex"], value) is None) + or not isinstance(value, str) ) - if "regex" in checks and ( - (isinstance(value, str) and re.match(checks["regex"], value) is None) - or not isinstance(value, str) ): # FAILSTATE Value doesn't match regex, or has regex but is not a string. - value = handle_input( - message=( - (("[blue]Example: " + str(checks["example"]) + "\n") if "example" in checks else "") - + "[red]" - + ("Non-optional ", "Optional ")[ - "optional" in checks and checks["optional"] is True - ] - ) - + "[#C0CAF5 bold]" - + str(name) - + "[#F7768E bold]=", - extra_info=checks["explanation"] if "explanation" in checks else "", - match=checks["regex"], - err_message=checks["input_error"] if "input_error" in checks else "Incorrect input", - default=checks["default"] if "default" in checks else NotImplemented, - nmin=checks["nmin"] if "nmin" in checks else None, - nmax=checks["nmax"] if "nmax" in checks else None, - oob_error=checks["oob_error"] - if "oob_error" in checks - else "Input out of bounds(Value too high/low/long/short)", - ) + incorrect = True - if not hasattr(value, "__iter__") and ( - ("nmin" in checks and checks["nmin"] is not None and value < checks["nmin"]) - or ("nmax" in checks and checks["nmax"] is not None and value > checks["nmax"]) + if ( + not incorrect + and not hasattr(value, "__iter__") + and ( + ("nmin" in checks and checks["nmin"] is not None and value < checks["nmin"]) + or ("nmax" in checks and checks["nmax"] is not None and value > checks["nmax"]) + ) ): - value = handle_input( - message=( - (("[blue]Example: " + str(checks["example"]) + "\n") if "example" in checks else "") - + "[red]" - + ("Non-optional ", "Optional ")[ - "optional" in checks and checks["optional"] is True - ] - ) - + "[#C0CAF5 bold]" - + str(name) - + "[#F7768E bold]=", - extra_info=checks["explanation"] if "explanation" in checks else "", - default=checks["default"] if "default" in checks else NotImplemented, - match=checks["regex"] if "regex" in checks else "", - err_message=checks["input_error"] if "input_error" in checks else "Incorrect input", - nmin=checks["nmin"] if "nmin" in checks else None, - nmax=checks["nmax"] if "nmax" in checks else None, - oob_error=checks["oob_error"] - if "oob_error" in checks - else "Input out of bounds(Value too high/low/long/short)", + incorrect = True + if ( + not incorrect + and hasattr(value, "__iter__") + and ( + ("nmin" in checks and checks["nmin"] is not None and len(value) < checks["nmin"]) + or ("nmax" in checks and checks["nmax"] is not None and len(value) > checks["nmax"]) ) - if hasattr(value, "__iter__") and ( - ("nmin" in checks and checks["nmin"] is not None and len(value) < checks["nmin"]) - or ("nmax" in checks and checks["nmax"] is not None and len(value) > checks["nmax"]) ): + incorrect = True + + if incorrect: value = handle_input( message=( (("[blue]Example: " + str(checks["example"]) + "\n") if "example" in checks else "") @@ -154,6 +78,7 @@ If you see any prompts, that means that you have unset/incorrectly set variables + str(name) + "[#F7768E bold]=", extra_info=checks["explanation"] if "explanation" in checks else "", + check_type=eval(checks["type"]) if "type" in checks else False, default=checks["default"] if "default" in checks else NotImplemented, match=checks["regex"] if "regex" in checks else "", err_message=checks["input_error"] if "input_error" in checks else "Incorrect input", @@ -162,28 +87,7 @@ If you see any prompts, that means that you have unset/incorrectly set variables oob_error=checks["oob_error"] if "oob_error" in checks else "Input out of bounds(Value too high/low/long/short)", - ) - if value == {}: - handle_input( - message=( - (("[blue]Example: " + str(checks["example"]) + "\n") if "example" in checks else "") - + "[red]" - + ("Non-optional ", "Optional ")[ - "optional" in checks and checks["optional"] is True - ] - ) - + "[#C0CAF5 bold]" - + str(name) - + "[#F7768E bold]=", - extra_info=checks["explanation"] if "explanation" in checks else "", - default=checks["default"] if "default" in checks else NotImplemented, - match=checks["regex"] if "regex" in checks else "", - err_message=checks["input_error"] if "input_error" in checks else "Incorrect input", - nmin=checks["nmin"] if "nmin" in checks else None, - nmax=checks["nmax"] if "nmax" in checks else None, - oob_error=checks["oob_error"] - if "oob_error" in checks - else "Input out of bounds(Value too high/low/long/short)", + options=checks["options"] if "options" in checks else None, ) return value @@ -244,11 +148,22 @@ Creating it now.""" f"[red bold]Failed to write to {config_file}. Giving up.\nSuggestion: check the folder's permissions for the user." ) return False + + console.print( + """\ +[blue bold]############################### +# # +# Checking TOML configuration # +# # +############################### +If you see any prompts, that means that you have unset/incorrectly set variables, please input the correct values.\ +""" + ) crawl(template, check_vars) # pretty.pprint(config) with open(config_file, "w") as f: toml.dump(config, f) - return True + return config if __name__ == "__main__":