Add files via upload

pull/861/head
CordlessCoder 3 years ago committed by GitHub
parent 3de18b6719
commit eefd56e16f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,7 +4,6 @@ from rich.markdown import Markdown
from rich.padding import Padding from rich.padding import Padding
from rich.panel import Panel from rich.panel import Panel
from rich.text import Text from rich.text import Text
from rich.columns import Columns
import re import re
console = Console() console = Console()
@ -29,12 +28,6 @@ def print_substep(text, style=""):
console.print(text, style=style) console.print(text, style=style)
def print_table(items):
"""Prints items in a table."""
console.print(Columns([Panel(f"[yellow]{item}", expand=True) for item in items]))
def handle_input( def handle_input(
message: str = "", message: str = "",
check_type=False, check_type=False,
@ -44,33 +37,67 @@ def handle_input(
nmax=None, nmax=None,
oob_error="", oob_error="",
extra_info="", extra_info="",
options: list = None,
default=NotImplemented,
): ):
match = re.compile(match + "$") if default is not NotImplemented:
console.print(extra_info, no_wrap=True) console.print(
"[green]"
+ message
+ '\n[blue bold]The default value is "'
+ str(default)
+ '"\nDo you want to use it?(y/n)'
)
if input().casefold().startswith("y"):
return default
if options is None:
match = re.compile(match)
console.print("[green bold]" + extra_info, no_wrap=True)
while True: while True:
console.print(message, end="") console.print(message, end="")
user_input = input("").strip() user_input = input("").strip()
if re.match(match, user_input) is not None:
if check_type is not False: if check_type is not False:
try: try:
user_input = check_type(user_input) # this line is fine user_input = check_type(user_input)
if nmin is not None and user_input < nmin: if (nmin is not None and user_input < nmin) or (
console.print("[red]" + oob_error) # Input too low failstate nmax is not None and user_input > nmax
continue ):
if nmax is not None and user_input > nmax: # FAILSTATE Input out of bounds
console.print("[red]" + oob_error) # Input too high console.print("[red]" + oob_error)
continue continue
break # Successful type conversion and number in bounds break # Successful type conversion and number in bounds
except ValueError: except ValueError:
console.print("[red]" + err_message) # Type conversion failed # Type conversion failed
console.print("[red]" + err_message)
continue continue
if nmin is not None and len(user_input) < nmin: # Check if string is long enough elif match != "" and re.match(match, user_input) is None:
console.print("[red]" + oob_error) console.print(
"[red]" + err_message +
"\nAre you absolutely sure it's correct?(y/n)"
)
if input().casefold().startswith("y"):
break
continue continue
if nmax is not None and len(user_input) > nmax: # Check if string is not too long else:
console.print("[red]" + oob_error) # FAILSTATE Input STRING out of bounds
if (nmin is not None and len(user_input) < nmin) or (
nmax is not None and len(user_input) > nmax
):
console.print("[red bold]" + oob_error)
continue
break # SUCCESS Input STRING in bounds
return user_input
console.print(extra_info, no_wrap=True)
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 continue
break
console.print("[red]" + err_message)
return user_input return user_input

@ -0,0 +1,262 @@
#!/usr/bin/env python
# import os
import toml
from rich import pretty
from rich.console import Console
import re
# from utils.console import handle_input
from console import handle_input
console = Console()
printed = False
def crawl(obj: dict, func=lambda x, y: print(x, y, end="\n"), path: list = []):
for key in obj.keys():
if type(obj[key]) is dict:
crawl(obj[key], func, path + [key])
continue
func(path + [key], obj[key])
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:
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)",
)
if (
"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"],
)
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)",
)
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"])
):
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)",
)
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"])
):
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)",
)
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)",
)
return value
def crawl_and_check(obj: dict, path: list, checks: dict = {}, name=""):
if len(path) == 0:
return check(obj, checks, name)
if path[0] not in obj.keys():
obj[path[0]] = {}
obj[path[0]] = crawl_and_check(obj[path[0]], path[1:], checks, path[0])
return obj
def check_vars(path, checks):
global config
crawl_and_check(config, path, checks)
def check_toml(template_file, config_file) -> bool:
try:
template = toml.load(template_file)
except Exception as error:
console.print(
f"[red bold]Encountered error when trying to to load {template_file}: {error}"
)
return False
try:
global config
config = toml.load(config_file)
except (toml.TomlDecodeError):
console.print(
f"""[blue]Couldn't read {config_file}.
Overwrite it?(y/n)"""
)
if not input().startswith("y"):
print("Unable to read config, and not allowed to overwrite it. Giving up.")
return False
else:
try:
with open(config_file, "w") as f:
f.write("")
except:
console.print(
f"[red bold]Failed to overwrite {config_file}. Giving up.\nSuggestion: check {config_file} permissions for the user."
)
return False
except (FileNotFoundError):
console.print(
f"""[blue]Couldn't find {config_file}
Creating it now."""
)
try:
with open(config_file, "x") as f:
f.write("")
config = {}
except:
console.print(
f"[red bold]Failed to write to {config_file}. Giving up.\nSuggestion: check the folder's permissions for the user."
)
return False
crawl(template, check_vars)
pretty.pprint(config)
with open(config_file, "w") as f:
toml.dump(config, f)
return True
if __name__ == "__main__":
check_toml(".config.template.toml", "config.toml")
Loading…
Cancel
Save