2024-01-28 00:46:19 -08:00
|
|
|
import io
|
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
from pathlib import Path
|
|
|
|
from textwrap import dedent
|
2024-03-26 00:53:21 -07:00
|
|
|
from typing import Optional
|
2024-01-28 00:46:19 -08:00
|
|
|
|
|
|
|
import typer
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
from rich import print
|
|
|
|
from rich.logging import RichHandler
|
|
|
|
|
|
|
|
from ttfrog.path import assets
|
|
|
|
|
|
|
|
default_data_path = Path("~/.dnd/ttfrog")
|
2024-03-26 00:53:21 -07:00
|
|
|
default_host = "127.0.0.1"
|
2024-01-28 00:46:19 -08:00
|
|
|
default_port = 2323
|
|
|
|
|
|
|
|
SETUP_HELP = f"""
|
|
|
|
# Please make sure you set the SECRET_KEY in your environment. By default,
|
|
|
|
# TableTop Frog will attempt to load these variables from:
|
|
|
|
# {default_data_path}/defaults
|
|
|
|
#
|
|
|
|
# which may contain the following variables as well.
|
|
|
|
#
|
|
|
|
# See also the --root paramter.
|
|
|
|
|
|
|
|
DATA_PATH={default_data_path}
|
|
|
|
|
|
|
|
# Uncomment one or both of these to replace the packaged static assets and templates:
|
|
|
|
#
|
|
|
|
# STATIC_FILES_PATH={assets()}/public
|
|
|
|
# TEMPLATES_PATH={assets()}/templates
|
|
|
|
|
|
|
|
HOST={default_host}
|
|
|
|
PORT={default_port}
|
|
|
|
"""
|
|
|
|
|
2024-04-20 20:35:07 -07:00
|
|
|
db_app = typer.Typer()
|
2024-01-28 00:46:19 -08:00
|
|
|
app = typer.Typer()
|
2024-04-20 20:35:07 -07:00
|
|
|
app.add_typer(db_app, name="db", help="Manage the database.")
|
2024-01-28 00:46:19 -08:00
|
|
|
app_state = dict()
|
|
|
|
|
|
|
|
|
|
|
|
@app.callback()
|
2024-04-20 20:35:07 -07:00
|
|
|
@db_app.callback()
|
2024-01-28 00:46:19 -08:00
|
|
|
def main(
|
|
|
|
context: typer.Context,
|
|
|
|
root: Optional[Path] = typer.Option(
|
|
|
|
default_data_path,
|
|
|
|
help="Path to the TableTop Frog environment",
|
2024-03-26 00:53:21 -07:00
|
|
|
),
|
2024-01-28 00:46:19 -08:00
|
|
|
):
|
2024-03-26 00:53:21 -07:00
|
|
|
app_state["env"] = root.expanduser() / Path("defaults")
|
2024-01-28 00:46:19 -08:00
|
|
|
load_dotenv(stream=io.StringIO(SETUP_HELP))
|
2024-03-26 00:53:21 -07:00
|
|
|
load_dotenv(app_state["env"])
|
|
|
|
debug = os.getenv("DEBUG", None)
|
2024-01-28 00:46:19 -08:00
|
|
|
logging.basicConfig(
|
2024-03-26 00:53:21 -07:00
|
|
|
format="%(message)s",
|
2024-01-28 00:46:19 -08:00
|
|
|
level=logging.DEBUG if debug else logging.INFO,
|
2024-03-26 00:53:21 -07:00
|
|
|
handlers=[RichHandler(rich_tracebacks=True, tracebacks_suppress=[typer])],
|
2024-01-28 00:46:19 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@app.command()
|
|
|
|
def serve(
|
|
|
|
context: typer.Context,
|
|
|
|
host: str = typer.Argument(
|
|
|
|
default_host,
|
|
|
|
help="bind address",
|
|
|
|
),
|
|
|
|
port: int = typer.Argument(
|
|
|
|
default_port,
|
|
|
|
help="bind port",
|
|
|
|
),
|
2024-03-26 00:53:21 -07:00
|
|
|
debug: bool = typer.Option(False, help="Enable debugging output"),
|
2024-01-28 00:46:19 -08:00
|
|
|
):
|
|
|
|
"""
|
|
|
|
Start the TableTop Frog server.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# delay loading the app until we have configured our environment
|
2024-06-30 23:21:23 -07:00
|
|
|
from ttfrog.db.bootstrap import loader
|
2024-03-26 00:53:21 -07:00
|
|
|
from ttfrog.webserver import application
|
2024-01-28 00:46:19 -08:00
|
|
|
|
|
|
|
print("Starting TableTop Frog server...")
|
2024-06-30 23:21:23 -07:00
|
|
|
loader.load()
|
2024-01-28 00:46:19 -08:00
|
|
|
application.start(host=host, port=port, debug=debug)
|
|
|
|
|
|
|
|
|
2024-04-20 20:35:07 -07:00
|
|
|
@db_app.command()
|
|
|
|
def setup(context: typer.Context):
|
|
|
|
"""
|
|
|
|
(Re)Initialize TableTop Frog. Idempotent; will preserve any existing configuration.
|
|
|
|
"""
|
2024-06-30 23:21:23 -07:00
|
|
|
from ttfrog.db.bootstrap import loader
|
2024-04-20 20:35:07 -07:00
|
|
|
|
|
|
|
if not os.path.exists(app_state["env"]):
|
|
|
|
app_state["env"].parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
app_state["env"].write_text(dedent(SETUP_HELP))
|
|
|
|
print(f"Wrote defaults file {app_state['env']}.")
|
2024-06-30 23:21:23 -07:00
|
|
|
loader.load()
|
2024-04-20 20:35:07 -07:00
|
|
|
|
|
|
|
|
|
|
|
@db_app.command()
|
|
|
|
def list(context: typer.Context):
|
|
|
|
from ttfrog.db.manager import db
|
2024-04-20 20:35:24 -07:00
|
|
|
|
2024-04-20 20:35:07 -07:00
|
|
|
print("\n".join(sorted(db.tables.keys())))
|
|
|
|
|
|
|
|
|
|
|
|
@db_app.command(context_settings={"allow_extra_args": True, "ignore_unknown_options": True})
|
|
|
|
def dump(context: typer.Context):
|
|
|
|
"""
|
|
|
|
Dump tables (or the entire database) as a JSON blob.
|
|
|
|
"""
|
|
|
|
from ttfrog.db.manager import db
|
2024-04-20 20:35:24 -07:00
|
|
|
|
2024-04-23 00:15:13 -07:00
|
|
|
setup(context)
|
2024-04-20 20:35:07 -07:00
|
|
|
print(db.dump(context.args))
|
|
|
|
|
|
|
|
|
2024-03-26 00:53:21 -07:00
|
|
|
if __name__ == "__main__":
|
2024-01-28 00:46:19 -08:00
|
|
|
app()
|