| 
									
										
										
										
											2021-05-13 21:57:11 +02:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  | from uuid import UUID | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-20 01:01:42 +02:00
										 |  |  | from flask import request, session, url_for | 
					
						
							|  |  |  | from markupsafe import Markup | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  | from pony.orm import commit | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-26 15:01:40 -06:00
										 |  |  | from Utils import restricted_dumps | 
					
						
							| 
									
										
										
										
											2022-09-30 00:36:30 +02:00
										 |  |  | from WebHostLib import app | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  | from WebHostLib.check import get_yaml_data, roll_options | 
					
						
							| 
									
										
										
										
											2021-11-17 16:58:43 +01:00
										 |  |  | from WebHostLib.generate import get_meta | 
					
						
							| 
									
										
										
										
											2022-10-17 01:08:31 +02:00
										 |  |  | from WebHostLib.models import Generation, STATE_QUEUED, Seed, STATE_ERROR | 
					
						
							|  |  |  | from . import api_endpoints | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @api_endpoints.route('/generate', methods=['POST']) | 
					
						
							|  |  |  | def generate_api(): | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         options = {} | 
					
						
							|  |  |  |         race = False | 
					
						
							| 
									
										
										
										
											2021-11-03 22:38:29 +01:00
										 |  |  |         meta_options_source = {} | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  |         if 'file' in request.files: | 
					
						
							| 
									
										
										
										
											2024-01-11 14:44:12 -08:00
										 |  |  |             files = request.files.getlist('file') | 
					
						
							|  |  |  |             options = get_yaml_data(files) | 
					
						
							| 
									
										
										
										
											2022-12-06 00:40:51 +01:00
										 |  |  |             if isinstance(options, Markup): | 
					
						
							|  |  |  |                 return {"text": options.striptags()}, 400 | 
					
						
							|  |  |  |             if isinstance(options, str): | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  |                 return {"text": options}, 400 | 
					
						
							|  |  |  |             if "race" in request.form: | 
					
						
							|  |  |  |                 race = bool(0 if request.form["race"] in {"false"} else int(request.form["race"])) | 
					
						
							| 
									
										
										
										
											2021-11-03 22:38:29 +01:00
										 |  |  |             meta_options_source = request.form | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-05 22:27:15 +01:00
										 |  |  |         # json_data is optional, we can have it silently fall to None as it used to do. | 
					
						
							|  |  |  |         # See https://flask.palletsprojects.com/en/2.2.x/api/#flask.Request.get_json -> Changelog -> 2.1 | 
					
						
							|  |  |  |         json_data = request.get_json(silent=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  |         if json_data: | 
					
						
							| 
									
										
										
										
											2021-11-03 22:38:29 +01:00
										 |  |  |             meta_options_source = json_data | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  |             if 'weights' in json_data: | 
					
						
							|  |  |  |                 # example: options = {"player1weights" : {<weightsdata>}} | 
					
						
							|  |  |  |                 options = json_data["weights"] | 
					
						
							|  |  |  |             if "race" in json_data: | 
					
						
							|  |  |  |                 race = bool(0 if json_data["race"] in {"false"} else int(json_data["race"])) | 
					
						
							| 
									
										
										
										
											2021-11-03 22:38:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  |         if not options: | 
					
						
							|  |  |  |             return {"text": "No options found. Expected file attachment or json weights." | 
					
						
							|  |  |  |                     }, 400 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if len(options) > app.config["MAX_ROLL"]: | 
					
						
							|  |  |  |             return {"text": "Max size of multiworld exceeded", | 
					
						
							|  |  |  |                     "detail": app.config["MAX_ROLL"]}, 409 | 
					
						
							| 
									
										
										
										
											2023-04-17 13:19:27 +02:00
										 |  |  |         meta = get_meta(meta_options_source, race) | 
					
						
							|  |  |  |         results, gen_options = roll_options(options, set(meta["plando_options"])) | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  |         if any(type(result) == str for result in results.values()): | 
					
						
							|  |  |  |             return {"text": str(results), | 
					
						
							|  |  |  |                     "detail": results}, 400 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             gen = Generation( | 
					
						
							| 
									
										
										
										
											2025-07-26 15:01:40 -06:00
										 |  |  |                 options=restricted_dumps({name: vars(options) for name, options in gen_options.items()}), | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  |                 # convert to json compatible | 
					
						
							| 
									
										
										
										
											2021-11-17 16:58:43 +01:00
										 |  |  |                 meta=json.dumps(meta), state=STATE_QUEUED, | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  |                 owner=session["_id"]) | 
					
						
							|  |  |  |             commit() | 
					
						
							|  |  |  |             return {"text": f"Generation of seed {gen.id} started successfully.", | 
					
						
							|  |  |  |                     "detail": gen.id, | 
					
						
							|  |  |  |                     "encoded": app.url_map.converters["suuid"].to_url(None, gen.id), | 
					
						
							| 
									
										
										
										
											2020-12-04 02:59:23 -05:00
										 |  |  |                     "wait_api_url": url_for("api.wait_seed_api", seed=gen.id, _external=True), | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  |                     "url": url_for("wait_seed", seed=gen.id, _external=True)}, 201 | 
					
						
							|  |  |  |     except Exception as e: | 
					
						
							| 
									
										
										
										
											2021-05-14 14:12:21 +02:00
										 |  |  |         return {"text": "Uncaught Exception:" + str(e)}, 500 | 
					
						
							| 
									
										
										
										
											2021-05-13 21:57:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 01:33:57 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | @api_endpoints.route('/status/<suuid:seed>') | 
					
						
							|  |  |  | def wait_seed_api(seed: UUID): | 
					
						
							|  |  |  |     seed_id = seed | 
					
						
							|  |  |  |     seed = Seed.get(id=seed_id) | 
					
						
							|  |  |  |     if seed: | 
					
						
							|  |  |  |         return {"text": "Generation done"}, 201 | 
					
						
							|  |  |  |     generation = Generation.get(id=seed_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not generation: | 
					
						
							|  |  |  |         return {"text": "Generation not found"}, 404 | 
					
						
							|  |  |  |     elif generation.state == STATE_ERROR: | 
					
						
							|  |  |  |         return {"text": "Generation failed"}, 500 | 
					
						
							|  |  |  |     return {"text": "Generation running"}, 202 |