Files
Grinch-AP/WebHost.py

132 lines
4.9 KiB
Python
Raw Permalink Normal View History

2024-09-03 01:26:46 +02:00
import argparse
2020-06-20 20:03:06 +02:00
import os
import multiprocessing
import logging
import typing
2020-06-20 20:03:06 +02:00
import ModuleUpdate
2022-03-14 21:30:18 +01:00
ModuleUpdate.requirements_files.add(os.path.join("WebHostLib", "requirements.txt"))
ModuleUpdate.update()
# in case app gets imported by something like gunicorn
import Utils
import settings
from Utils import get_file_safe_name
2022-03-14 21:30:18 +01:00
if typing.TYPE_CHECKING:
from flask import Flask
Utils.local_path.cached_path = os.path.dirname(__file__)
settings.no_gui = True
configpath = os.path.abspath("config.yaml")
2022-03-31 05:08:15 +02:00
if not os.path.exists(configpath): # fall back to config.yaml in home
configpath = os.path.abspath(Utils.user_path('config.yaml'))
2020-06-20 20:03:06 +02:00
2020-06-27 18:17:36 +02:00
def get_app() -> "Flask":
from WebHostLib import register, cache, app as raw_app
from WebHostLib.models import db
2020-07-10 17:42:22 +02:00
app = raw_app
if os.path.exists(configpath) and not app.config["TESTING"]:
2020-06-20 20:03:06 +02:00
import yaml
app.config.from_file(configpath, yaml.safe_load)
2020-06-20 20:03:06 +02:00
logging.info(f"Updated config from {configpath}")
2024-09-03 01:26:46 +02:00
# inside get_app() so it's usable in systems like gunicorn, which do not run WebHost.py, but import it.
parser = argparse.ArgumentParser(allow_abbrev=False)
2024-09-03 01:26:46 +02:00
parser.add_argument('--config_override', default=None,
help="Path to yaml config file that overrules config.yaml.")
args = parser.parse_known_args()[0]
if args.config_override:
import yaml
app.config.from_file(os.path.abspath(args.config_override), yaml.safe_load)
logging.info(f"Updated config from {args.config_override}")
if not app.config["HOST_ADDRESS"]:
logging.info("Getting public IP, as HOST_ADDRESS is empty.")
app.config["HOST_ADDRESS"] = Utils.get_public_ipv4()
logging.info(f"HOST_ADDRESS was set to {app.config['HOST_ADDRESS']}")
register()
cache.init_app(app)
2020-06-20 20:03:06 +02:00
db.bind(**app.config["PONY"])
db.generate_mapping(create_tables=True)
2020-07-10 17:42:22 +02:00
return app
def copy_tutorials_files_to_static() -> None:
import shutil
import zipfile
from werkzeug.utils import secure_filename
zfile: zipfile.ZipInfo
2022-08-18 00:27:37 +02:00
from worlds.AutoWorld import AutoWorldRegister
worlds = {}
for game, world in AutoWorldRegister.world_types.items():
if hasattr(world.web, 'tutorials') and (not world.hidden or game == 'Archipelago'):
worlds[game] = world
base_target_path = Utils.local_path("WebHostLib", "static", "generated", "docs")
2024-06-12 15:34:46 +02:00
shutil.rmtree(base_target_path, ignore_errors=True)
for game, world in worlds.items():
# copy files from world's docs folder to the generated folder
target_path = os.path.join(base_target_path, secure_filename(game))
os.makedirs(target_path, exist_ok=True)
2022-08-18 00:27:37 +02:00
if world.zip_path:
zipfile_path = world.zip_path
assert os.path.isfile(zipfile_path), f"{zipfile_path} is not a valid file(path)."
assert zipfile.is_zipfile(zipfile_path), f"{zipfile_path} is not a valid zipfile."
with zipfile.ZipFile(zipfile_path) as zf:
for zfile in zf.infolist():
if not zfile.is_dir() and "/docs/" in zfile.filename:
zfile.filename = os.path.basename(zfile.filename)
with open(os.path.join(target_path, secure_filename(zfile.filename)), "wb") as f:
f.write(zf.read(zfile))
else:
source_path = Utils.local_path(os.path.dirname(world.__file__), "docs")
files = os.listdir(source_path)
for file in files:
shutil.copyfile(Utils.local_path(source_path, file),
Utils.local_path(target_path, secure_filename(file)))
2022-03-14 21:30:18 +01:00
2020-07-10 17:42:22 +02:00
if __name__ == "__main__":
multiprocessing.freeze_support()
multiprocessing.set_start_method('spawn')
logging.basicConfig(format='[%(asctime)s] %(message)s', level=logging.INFO)
from WebHostLib.lttpsprites import update_sprites_lttp
from WebHostLib.autolauncher import autohost, autogen, stop
from WebHostLib.options import create as create_options_files
2021-09-07 00:42:02 +02:00
try:
update_sprites_lttp()
except Exception as e:
logging.exception(e)
logging.warning("Could not update LttP sprites.")
2020-07-10 17:42:22 +02:00
app = get_app()
create_options_files()
copy_tutorials_files_to_static()
2020-07-10 17:42:22 +02:00
if app.config["SELFLAUNCH"]:
autohost(app.config)
if app.config["SELFGEN"]:
autogen(app.config)
2020-07-10 17:42:22 +02:00
if app.config["SELFHOST"]: # using WSGI, you just want to run get_app()
if app.config["DEBUG"]:
app.run(debug=True, port=app.config["PORT"])
else:
from waitress import serve
2020-07-10 17:42:22 +02:00
serve(app, port=app.config["PORT"], threads=app.config["WAITRESS_THREADS"])
else:
from time import sleep
try:
while True:
sleep(1) # wait for process to be killed
except (SystemExit, KeyboardInterrupt):
pass
stop() # stop worker threads