From 2801e212969dbc69afa71f96e5ff6e3e3efa4d7d Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 19 May 2024 20:21:46 +0200 Subject: [PATCH] WebHost: fixup WebHostLib/options.py (#3332) * WebHost: fixup WebHostLib/options.py * Update WebHostLib/options.py * Update WebHostLib/options.py * fix visibility flag handling --- WebHostLib/generate.py | 58 ++++++++++++++++++++------------------- WebHostLib/options.py | 61 +++++++++++++++--------------------------- 2 files changed, 52 insertions(+), 67 deletions(-) diff --git a/WebHostLib/generate.py b/WebHostLib/generate.py index ee1ce591..a78560cb 100644 --- a/WebHostLib/generate.py +++ b/WebHostLib/generate.py @@ -70,37 +70,41 @@ def generate(race=False): flash(options) else: meta = get_meta(request.form, race) - 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)) + return start_generation(options, meta) 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): if not meta: meta: Dict[str, Any] = {} diff --git a/WebHostLib/options.py b/WebHostLib/options.py index e631d31b..f52f0f3d 100644 --- a/WebHostLib/options.py +++ b/WebHostLib/options.py @@ -1,33 +1,33 @@ import collections.abc -import os -import yaml -import requests 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 -from Options import Visibility -from flask import redirect, render_template, request, Response -from worlds.AutoWorld import AutoWorldRegister from Utils import local_path -from textwrap import dedent +from worlds.AutoWorld import AutoWorldRegister from . import app, cache -def create(): +def create() -> None: target_folder = local_path("WebHostLib", "static", "generated") yaml_folder = os.path.join(target_folder, "configs") 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: return AutoWorldRegister.world_types[game_name].web.theme 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] if world.hidden or world.web.options_page is False: 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} for option_name, option in world.options_dataclass.type_hints.items(): # Exclude settings from options pages if their visibility is disabled - if not is_complex and option.visibility < Visibility.simple_ui: - continue - - if is_complex and option.visibility < Visibility.complex_ui: - continue - - grouped_options[option_groups.get(option, "Game Options")][option_name] = option + if visibility_flag in option.visibility: + grouped_options[option_groups.get(option, "Game Options")][option_name] = option return render_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): - payload = { - "race": 0, - "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 generate_game(options: Dict[str, Union[dict, str]]) -> Union[Response, str]: + from .generate import start_generation + return start_generation(options, {"plando_options": ["items", "connections", "texts", "bosses"]}) -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.headers["Content-Type"] = "text/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") -def filter_dedent(text: str): +def filter_dedent(text: str) -> str: return dedent(text).strip("\n ") @@ -111,7 +92,7 @@ def option_presets(game: str) -> Response: return json.JSONEncoder.default(self, obj) json_data = json.dumps(presets, cls=SetEncoder) - response = flask.Response(json_data) + response = Response(json_data) response.headers["Content-Type"] = "application/json" return response @@ -169,7 +150,7 @@ def generate_weighted_yaml(game: str): } if intent_generate: - return generate_game(player_name, formatted_options) + return generate_game({player_name: formatted_options}) else: return send_yaml(player_name, formatted_options) @@ -243,7 +224,7 @@ def generate_yaml(game: str): } if intent_generate: - return generate_game(player_name, formatted_options) + return generate_game({player_name: formatted_options}) else: return send_yaml(player_name, formatted_options)