WebHost: fixup WebHostLib/options.py ()

* WebHost: fixup WebHostLib/options.py

* Update WebHostLib/options.py

* Update WebHostLib/options.py

* fix visibility flag handling
This commit is contained in:
Fabian Dill 2024-05-19 20:21:46 +02:00 committed by GitHub
parent e97eddcdaf
commit 2801e21296
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 67 deletions

View File

@ -70,37 +70,41 @@ def generate(race=False):
flash(options) flash(options)
else: else:
meta = get_meta(request.form, race) meta = get_meta(request.form, race)
results, gen_options = roll_options(options, set(meta["plando_options"])) return start_generation(options, meta)
if any(type(result) == str for result in results.values()):
return render_template("checkResult.html", results=results)
elif len(gen_options) > app.config["MAX_ROLL"]:
flash(f"Sorry, generating of multiworlds is limited to {app.config['MAX_ROLL']} players. "
f"If you have a larger group, please generate it yourself and upload it.")
elif len(gen_options) >= app.config["JOB_THRESHOLD"]:
gen = Generation(
options=pickle.dumps({name: vars(options) for name, options in gen_options.items()}),
# convert to json compatible
meta=json.dumps(meta),
state=STATE_QUEUED,
owner=session["_id"])
commit()
return redirect(url_for("wait_seed", seed=gen.id))
else:
try:
seed_id = gen_game({name: vars(options) for name, options in gen_options.items()},
meta=meta, owner=session["_id"].int)
except BaseException as e:
from .autolauncher import handle_generation_failure
handle_generation_failure(e)
return render_template("seedError.html", seed_error=(e.__class__.__name__ + ": " + str(e)))
return redirect(url_for("view_seed", seed=seed_id))
return render_template("generate.html", race=race, version=__version__) return render_template("generate.html", race=race, version=__version__)
def start_generation(options: Dict[str, Union[dict, str]], meta: Dict[str, Any]):
results, gen_options = roll_options(options, set(meta["plando_options"]))
if any(type(result) == str for result in results.values()):
return render_template("checkResult.html", results=results)
elif len(gen_options) > app.config["MAX_ROLL"]:
flash(f"Sorry, generating of multiworlds is limited to {app.config['MAX_ROLL']} players. "
f"If you have a larger group, please generate it yourself and upload it.")
elif len(gen_options) >= app.config["JOB_THRESHOLD"]:
gen = Generation(
options=pickle.dumps({name: vars(options) for name, options in gen_options.items()}),
# convert to json compatible
meta=json.dumps(meta),
state=STATE_QUEUED,
owner=session["_id"])
commit()
return redirect(url_for("wait_seed", seed=gen.id))
else:
try:
seed_id = gen_game({name: vars(options) for name, options in gen_options.items()},
meta=meta, owner=session["_id"].int)
except BaseException as e:
from .autolauncher import handle_generation_failure
handle_generation_failure(e)
return render_template("seedError.html", seed_error=(e.__class__.__name__ + ": " + str(e)))
return redirect(url_for("view_seed", seed=seed_id))
def gen_game(gen_options: dict, meta: Optional[Dict[str, Any]] = None, owner=None, sid=None): def gen_game(gen_options: dict, meta: Optional[Dict[str, Any]] = None, owner=None, sid=None):
if not meta: if not meta:
meta: Dict[str, Any] = {} meta: Dict[str, Any] = {}

View File

@ -1,33 +1,33 @@
import collections.abc import collections.abc
import os
import yaml
import requests
import json import json
import flask import os
from textwrap import dedent
from typing import Dict, Union
import yaml
from flask import redirect, render_template, request, Response
import Options import Options
from Options import Visibility
from flask import redirect, render_template, request, Response
from worlds.AutoWorld import AutoWorldRegister
from Utils import local_path from Utils import local_path
from textwrap import dedent from worlds.AutoWorld import AutoWorldRegister
from . import app, cache from . import app, cache
def create(): def create() -> None:
target_folder = local_path("WebHostLib", "static", "generated") target_folder = local_path("WebHostLib", "static", "generated")
yaml_folder = os.path.join(target_folder, "configs") yaml_folder = os.path.join(target_folder, "configs")
Options.generate_yaml_templates(yaml_folder) Options.generate_yaml_templates(yaml_folder)
def get_world_theme(game_name: str): def get_world_theme(game_name: str) -> str:
if game_name in AutoWorldRegister.world_types: if game_name in AutoWorldRegister.world_types:
return AutoWorldRegister.world_types[game_name].web.theme return AutoWorldRegister.world_types[game_name].web.theme
return 'grass' return 'grass'
def render_options_page(template: str, world_name: str, is_complex: bool = False): def render_options_page(template: str, world_name: str, is_complex: bool = False) -> Union[Response, str]:
visibility_flag = Options.Visibility.complex_ui if is_complex else Options.Visibility.simple_ui
world = AutoWorldRegister.world_types[world_name] world = AutoWorldRegister.world_types[world_name]
if world.hidden or world.web.options_page is False: if world.hidden or world.web.options_page is False:
return redirect("games") return redirect("games")
@ -39,13 +39,8 @@ def render_options_page(template: str, world_name: str, is_complex: bool = False
grouped_options = {group: {} for group in ordered_groups} grouped_options = {group: {} for group in ordered_groups}
for option_name, option in world.options_dataclass.type_hints.items(): for option_name, option in world.options_dataclass.type_hints.items():
# Exclude settings from options pages if their visibility is disabled # Exclude settings from options pages if their visibility is disabled
if not is_complex and option.visibility < Visibility.simple_ui: if visibility_flag in option.visibility:
continue grouped_options[option_groups.get(option, "Game Options")][option_name] = option
if is_complex and option.visibility < Visibility.complex_ui:
continue
grouped_options[option_groups.get(option, "Game Options")][option_name] = option
return render_template( return render_template(
template, template,
@ -58,26 +53,12 @@ def render_options_page(template: str, world_name: str, is_complex: bool = False
) )
def generate_game(player_name: str, formatted_options: dict): def generate_game(options: Dict[str, Union[dict, str]]) -> Union[Response, str]:
payload = { from .generate import start_generation
"race": 0, return start_generation(options, {"plando_options": ["items", "connections", "texts", "bosses"]})
"hint_cost": 10,
"forfeit_mode": "auto",
"remaining_mode": "disabled",
"collect_mode": "goal",
"weights": {
player_name: formatted_options,
},
}
r = requests.post("https://archipelago.gg/api/generate", json=payload)
if 200 <= r.status_code <= 299:
response_data = r.json()
return redirect(response_data["url"])
else:
return r.text
def send_yaml(player_name: str, formatted_options: dict): def send_yaml(player_name: str, formatted_options: dict) -> Response:
response = Response(yaml.dump(formatted_options, sort_keys=False)) response = Response(yaml.dump(formatted_options, sort_keys=False))
response.headers["Content-Type"] = "text/yaml" response.headers["Content-Type"] = "text/yaml"
response.headers["Content-Disposition"] = f"attachment; filename={player_name}.yaml" response.headers["Content-Disposition"] = f"attachment; filename={player_name}.yaml"
@ -85,7 +66,7 @@ def send_yaml(player_name: str, formatted_options: dict):
@app.template_filter("dedent") @app.template_filter("dedent")
def filter_dedent(text: str): def filter_dedent(text: str) -> str:
return dedent(text).strip("\n ") return dedent(text).strip("\n ")
@ -111,7 +92,7 @@ def option_presets(game: str) -> Response:
return json.JSONEncoder.default(self, obj) return json.JSONEncoder.default(self, obj)
json_data = json.dumps(presets, cls=SetEncoder) json_data = json.dumps(presets, cls=SetEncoder)
response = flask.Response(json_data) response = Response(json_data)
response.headers["Content-Type"] = "application/json" response.headers["Content-Type"] = "application/json"
return response return response
@ -169,7 +150,7 @@ def generate_weighted_yaml(game: str):
} }
if intent_generate: if intent_generate:
return generate_game(player_name, formatted_options) return generate_game({player_name: formatted_options})
else: else:
return send_yaml(player_name, formatted_options) return send_yaml(player_name, formatted_options)
@ -243,7 +224,7 @@ def generate_yaml(game: str):
} }
if intent_generate: if intent_generate:
return generate_game(player_name, formatted_options) return generate_game({player_name: formatted_options})
else: else:
return send_yaml(player_name, formatted_options) return send_yaml(player_name, formatted_options)