Add files via upload

pull/861/head
CordlessCoder 2 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.panel import Panel
from rich.text import Text
from rich.columns import Columns
import re
console = Console()
@ -29,12 +28,6 @@ def print_substep(text, 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(
message: str = "",
check_type=False,
@ -44,33 +37,67 @@ def handle_input(
nmax=None,
oob_error="",
extra_info="",
options: list = None,
default=NotImplemented,
):
match = re.compile(match + "$")
console.print(extra_info, no_wrap=True)
while True:
console.print(message, end="")
user_input = input("").strip()
if re.match(match, user_input) is not None:
if default is not NotImplemented:
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:
console.print(message, end="")
user_input = input("").strip()
if check_type is not False:
try:
user_input = check_type(user_input) # this line is fine
if nmin is not None and user_input < nmin:
console.print("[red]" + oob_error) # Input too low failstate
continue
if nmax is not None and user_input > nmax:
console.print("[red]" + oob_error) # Input too high
user_input = check_type(user_input)
if (nmin is not None and user_input < nmin) or (
nmax is not None and user_input > nmax
):
# FAILSTATE Input out of bounds
console.print("[red]" + oob_error)
continue
break # Successful type conversion and number in bounds
except ValueError:
console.print("[red]" + err_message) # Type conversion failed
# Type conversion failed
console.print("[red]" + err_message)
continue
if nmin is not None and len(user_input) < nmin: # Check if string is long enough
console.print("[red]" + oob_error)
elif match != "" and re.match(match, user_input) is None:
console.print(
"[red]" + err_message +
"\nAre you absolutely sure it's correct?(y/n)"
)
if input().casefold().startswith("y"):
break
continue
if nmax is not None and len(user_input) > nmax: # Check if string is not too long
console.print("[red]" + oob_error)
continue
break
console.print("[red]" + err_message)
return user_input
else:
# 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
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