134 lines
4.9 KiB
Python
134 lines
4.9 KiB
Python
import os
|
|
import sys
|
|
import multiprocessing
|
|
import logging
|
|
import typing
|
|
|
|
import ModuleUpdate
|
|
|
|
ModuleUpdate.requirements_files.add(os.path.join("WebHostLib", "requirements.txt"))
|
|
ModuleUpdate.update()
|
|
|
|
# in case app gets imported by something like gunicorn
|
|
import Utils
|
|
|
|
Utils.local_path.cached_path = os.path.dirname(__file__)
|
|
|
|
from WebHostLib import register, app as raw_app
|
|
from waitress import serve
|
|
|
|
from WebHostLib.models import db
|
|
from WebHostLib.autolauncher import autohost, autogen
|
|
from WebHostLib.lttpsprites import update_sprites_lttp
|
|
from WebHostLib.options import create as create_options_files
|
|
|
|
configpath = os.path.abspath("config.yaml")
|
|
if not os.path.exists(configpath): # fall back to config.yaml in home
|
|
configpath = os.path.abspath(Utils.user_path('config.yaml'))
|
|
|
|
|
|
def get_app():
|
|
register()
|
|
app = raw_app
|
|
if os.path.exists(configpath):
|
|
import yaml
|
|
app.config.from_file(configpath, yaml.safe_load)
|
|
logging.info(f"Updated config from {configpath}")
|
|
db.bind(**app.config["PONY"])
|
|
db.generate_mapping(create_tables=True)
|
|
return app
|
|
|
|
|
|
def create_ordered_tutorials_file() -> typing.List[typing.Dict[str, typing.Any]]:
|
|
import json
|
|
import shutil
|
|
import pathlib
|
|
import zipfile
|
|
|
|
zfile: zipfile.ZipInfo
|
|
|
|
from worlds.AutoWorld import AutoWorldRegister, __file__
|
|
worlds = {}
|
|
data = []
|
|
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")
|
|
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, game)
|
|
os.makedirs(target_path, exist_ok=True)
|
|
|
|
if world.is_zip:
|
|
zipfile_path = pathlib.Path(world.__file__).parents[1]
|
|
|
|
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:
|
|
zf.extract(zfile, target_path)
|
|
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, file))
|
|
|
|
# build a json tutorial dict per game
|
|
game_data = {'gameTitle': game, 'tutorials': []}
|
|
for tutorial in world.web.tutorials:
|
|
# build dict for the json file
|
|
current_tutorial = {
|
|
'name': tutorial.tutorial_name,
|
|
'description': tutorial.description,
|
|
'files': [{
|
|
'language': tutorial.language,
|
|
'filename': game + '/' + tutorial.file_name,
|
|
'link': f'{game}/{tutorial.link}',
|
|
'authors': tutorial.authors
|
|
}]
|
|
}
|
|
|
|
# check if the name of the current guide exists already
|
|
for guide in game_data['tutorials']:
|
|
if guide and tutorial.tutorial_name == guide['name']:
|
|
guide['files'].append(current_tutorial['files'][0])
|
|
break
|
|
else:
|
|
game_data['tutorials'].append(current_tutorial)
|
|
|
|
data.append(game_data)
|
|
with open(Utils.local_path("WebHostLib", "static", "generated", "tutorials.json"), 'w', encoding='utf-8-sig') as json_target:
|
|
generic_data = {}
|
|
for games in data:
|
|
if 'Archipelago' in games['gameTitle']:
|
|
generic_data = data.pop(data.index(games))
|
|
sorted_data = [generic_data] + Utils.title_sorted(data, key=lambda entry: entry["gameTitle"].lower())
|
|
json.dump(sorted_data, json_target, indent=2, ensure_ascii=False)
|
|
return sorted_data
|
|
|
|
|
|
if __name__ == "__main__":
|
|
multiprocessing.freeze_support()
|
|
multiprocessing.set_start_method('spawn')
|
|
logging.basicConfig(format='[%(asctime)s] %(message)s', level=logging.INFO)
|
|
try:
|
|
update_sprites_lttp()
|
|
except Exception as e:
|
|
logging.exception(e)
|
|
logging.warning("Could not update LttP sprites.")
|
|
app = get_app()
|
|
create_options_files()
|
|
create_ordered_tutorials_file()
|
|
if app.config["SELFLAUNCH"]:
|
|
autohost(app.config)
|
|
if app.config["SELFGEN"]:
|
|
autogen(app.config)
|
|
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:
|
|
serve(app, port=app.config["PORT"], threads=app.config["WAITRESS_THREADS"])
|