98 lines
3.6 KiB
Python
98 lines
3.6 KiB
Python
import zipfile
|
|
from typing import *
|
|
|
|
from flask import request, flash, redirect, url_for, render_template, Markup
|
|
|
|
from WebHostLib import app
|
|
|
|
banned_zip_contents = (".sfc",)
|
|
|
|
|
|
def allowed_file(filename):
|
|
return filename.endswith(('.txt', ".yaml", ".zip"))
|
|
|
|
|
|
from Generate import roll_settings, PlandoOptions
|
|
from Utils import parse_yamls
|
|
|
|
|
|
@app.route('/check', methods=['GET', 'POST'])
|
|
def check():
|
|
if request.method == 'POST':
|
|
# check if the post request has the file part
|
|
if 'file' not in request.files:
|
|
flash('No file part')
|
|
else:
|
|
file = request.files['file']
|
|
options = get_yaml_data(file)
|
|
if isinstance(options, str):
|
|
flash(options)
|
|
else:
|
|
results, _ = roll_options(options)
|
|
return render_template("checkResult.html", results=results)
|
|
return render_template("check.html")
|
|
|
|
|
|
@app.route('/mysterycheck')
|
|
def mysterycheck():
|
|
return redirect(url_for("check"), 301)
|
|
|
|
|
|
def get_yaml_data(file) -> Union[Dict[str, str], str, Markup]:
|
|
options = {}
|
|
# if user does not select file, browser also
|
|
# submit an empty part without filename
|
|
if file.filename == '':
|
|
return 'No selected file'
|
|
elif file and allowed_file(file.filename):
|
|
if file.filename.endswith(".zip"):
|
|
|
|
with zipfile.ZipFile(file, 'r') as zfile:
|
|
infolist = zfile.infolist()
|
|
|
|
if any(file.filename.endswith(".archipelago") for file in infolist):
|
|
return Markup("Error: Your .zip file contains an .archipelago file. "
|
|
'Did you mean to <a href="/uploads">host a game</a>?')
|
|
|
|
for file in infolist:
|
|
if file.filename.endswith(banned_zip_contents):
|
|
return "Uploaded data contained a rom file, which is likely to contain copyrighted material. " \
|
|
"Your file was deleted."
|
|
elif file.filename.endswith((".yaml", ".json", ".yml", ".txt")):
|
|
options[file.filename] = zfile.open(file, "r").read()
|
|
else:
|
|
options = {file.filename: file.read()}
|
|
if not options:
|
|
return "Did not find a .yaml file to process."
|
|
return options
|
|
|
|
|
|
def roll_options(options: Dict[str, Union[dict, str]],
|
|
plando_options: Set[str] = frozenset({"bosses", "items", "connections", "texts"})) -> \
|
|
Tuple[Dict[str, Union[str, bool]], Dict[str, dict]]:
|
|
plando_options = PlandoOptions.from_set(set(plando_options))
|
|
results = {}
|
|
rolled_results = {}
|
|
for filename, text in options.items():
|
|
try:
|
|
if type(text) is dict:
|
|
yaml_datas = (text, )
|
|
else:
|
|
yaml_datas = tuple(parse_yamls(text))
|
|
except Exception as e:
|
|
results[filename] = f"Failed to parse YAML data in {filename}: {e}"
|
|
else:
|
|
try:
|
|
if len(yaml_datas) == 1:
|
|
rolled_results[filename] = roll_settings(yaml_datas[0],
|
|
plando_options=plando_options)
|
|
else:
|
|
for i, yaml_data in enumerate(yaml_datas):
|
|
rolled_results[f"{filename}/{i + 1}"] = roll_settings(yaml_data,
|
|
plando_options=plando_options)
|
|
except Exception as e:
|
|
results[filename] = f"Failed to generate mystery in {filename}: {e}"
|
|
else:
|
|
results[filename] = True
|
|
return results, rolled_results
|