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