Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
elebumm
GitHub Repository: elebumm/RedditVideoMakerBot
Path: blob/master/utils/gui_utils.py
493 views
1
import json
2
import re
3
from pathlib import Path
4
5
import toml
6
import tomlkit
7
from flask import flash
8
9
10
# Get validation checks from template
11
def get_checks():
12
template = toml.load("utils/.config.template.toml")
13
checks = {}
14
15
def unpack_checks(obj: dict):
16
for key in obj.keys():
17
if "optional" in obj[key].keys():
18
checks[key] = obj[key]
19
else:
20
unpack_checks(obj[key])
21
22
unpack_checks(template)
23
24
return checks
25
26
27
# Get current config (from config.toml) as dict
28
def get_config(obj: dict, done=None):
29
if done is None:
30
done = {}
31
for key in obj.keys():
32
if not isinstance(obj[key], dict):
33
done[key] = obj[key]
34
else:
35
get_config(obj[key], done)
36
37
return done
38
39
40
# Checks if value is valid
41
def check(value, checks):
42
incorrect = False
43
44
if value == "False":
45
value = ""
46
47
if not incorrect and "type" in checks:
48
try:
49
value = eval(checks["type"])(value) # fixme remove eval
50
except Exception:
51
incorrect = True
52
53
if (
54
not incorrect and "options" in checks and value not in checks["options"]
55
): # FAILSTATE Value isn't one of the options
56
incorrect = True
57
if (
58
not incorrect
59
and "regex" in checks
60
and (
61
(isinstance(value, str) and re.match(checks["regex"], value) is None)
62
or not isinstance(value, str)
63
)
64
): # FAILSTATE Value doesn't match regular expression, or has regular expression but isn't a string.
65
incorrect = True
66
67
if (
68
not incorrect
69
and not hasattr(value, "__iter__")
70
and (
71
("nmin" in checks and checks["nmin"] is not None and value < checks["nmin"])
72
or ("nmax" in checks and checks["nmax"] is not None and value > checks["nmax"])
73
)
74
):
75
incorrect = True
76
77
if (
78
not incorrect
79
and hasattr(value, "__iter__")
80
and (
81
("nmin" in checks and checks["nmin"] is not None and len(value) < checks["nmin"])
82
or ("nmax" in checks and checks["nmax"] is not None and len(value) > checks["nmax"])
83
)
84
):
85
incorrect = True
86
87
if incorrect:
88
return "Error"
89
90
return value
91
92
93
# Modify settings (after the form is submitted)
94
def modify_settings(data: dict, config_load, checks: dict):
95
# Modify config settings
96
def modify_config(obj: dict, config_name: str, value: any):
97
for key in obj.keys():
98
if config_name == key:
99
obj[key] = value
100
elif not isinstance(obj[key], dict):
101
continue
102
else:
103
modify_config(obj[key], config_name, value)
104
105
# Remove empty/incorrect key-value pairs
106
data = {key: value for key, value in data.items() if value and key in checks.keys()}
107
108
# Validate values
109
for name in data.keys():
110
value = check(data[name], checks[name])
111
112
# Value is invalid
113
if value == "Error":
114
flash("Some values were incorrect and didn't save!", "error")
115
else:
116
# Value is valid
117
modify_config(config_load, name, value)
118
119
# Save changes in config.toml
120
with Path("config.toml").open("w") as toml_file:
121
toml_file.write(tomlkit.dumps(config_load))
122
123
flash("Settings saved!")
124
125
return get_config(config_load)
126
127
128
# Delete background video
129
def delete_background(key):
130
# Read backgrounds.json
131
with open("utils/backgrounds.json", "r", encoding="utf-8") as backgrounds:
132
data = json.load(backgrounds)
133
134
# Remove background from backgrounds.json
135
with open("utils/backgrounds.json", "w", encoding="utf-8") as backgrounds:
136
if data.pop(key, None):
137
json.dump(data, backgrounds, ensure_ascii=False, indent=4)
138
else:
139
flash("Couldn't find this background. Try refreshing the page.", "error")
140
return
141
142
# Remove background video from ".config.template.toml"
143
config = tomlkit.loads(Path("utils/.config.template.toml").read_text())
144
config["settings"]["background"]["background_choice"]["options"].remove(key)
145
146
with Path("utils/.config.template.toml").open("w") as toml_file:
147
toml_file.write(tomlkit.dumps(config))
148
149
flash(f'Successfully removed "{key}" background!')
150
151
152
# Add background video
153
def add_background(youtube_uri, filename, citation, position):
154
# Validate YouTube URI
155
regex = re.compile(r"(?:\/|%3D|v=|vi=)([0-9A-z\-_]{11})(?:[%#?&]|$)").search(youtube_uri)
156
157
if not regex:
158
flash("YouTube URI is invalid!", "error")
159
return
160
161
youtube_uri = f"https://www.youtube.com/watch?v={regex.group(1)}"
162
163
# Check if the position is valid
164
if position == "" or position == "center":
165
position = "center"
166
167
elif position.isdecimal():
168
position = int(position)
169
170
else:
171
flash('Position is invalid! It can be "center" or decimal number.', "error")
172
return
173
174
# Sanitize filename
175
regex = re.compile(r"^([a-zA-Z0-9\s_-]{1,100})$").match(filename)
176
177
if not regex:
178
flash("Filename is invalid!", "error")
179
return
180
181
filename = filename.replace(" ", "_")
182
183
# Check if the background doesn't already exist
184
with open("utils/backgrounds.json", "r", encoding="utf-8") as backgrounds:
185
data = json.load(backgrounds)
186
187
# Check if key isn't already taken
188
if filename in list(data.keys()):
189
flash("Background video with this name already exist!", "error")
190
return
191
192
# Check if the YouTube URI isn't already used under different name
193
if youtube_uri in [data[i][0] for i in list(data.keys())]:
194
flash("Background video with this YouTube URI is already added!", "error")
195
return
196
197
# Add background video to json file
198
with open("utils/backgrounds.json", "r+", encoding="utf-8") as backgrounds:
199
data = json.load(backgrounds)
200
201
data[filename] = [youtube_uri, filename + ".mp4", citation, position]
202
backgrounds.seek(0)
203
json.dump(data, backgrounds, ensure_ascii=False, indent=4)
204
205
# Add background video to ".config.template.toml"
206
config = tomlkit.loads(Path("utils/.config.template.toml").read_text())
207
config["settings"]["background"]["background_choice"]["options"].append(filename)
208
209
with Path("utils/.config.template.toml").open("w") as toml_file:
210
toml_file.write(tomlkit.dumps(config))
211
212
flash(f'Added "{citation}-{filename}.mp4" as a new background video!')
213
214
return
215
216