diff --git a/src/ttfrog/app.py b/src/ttfrog/app.py index 96976f9..b584c44 100644 --- a/src/ttfrog/app.py +++ b/src/ttfrog/app.py @@ -6,6 +6,7 @@ from types import SimpleNamespace from dotenv import dotenv_values from flask import Flask from grung.db import GrungDB +from grung.exceptions import UniqueConstraintError from tinydb.storages import MemoryStorage from ttfrog import schema @@ -41,6 +42,8 @@ DATA_ROOT=~/.dnd/ttfrog/ ADMIN_USERNAME=admin ADMIN_EMAIL= +THEME=default + """ def __init__(self): @@ -85,7 +88,9 @@ ADMIN_EMAIL= else: self.db = GrungDB.with_schema(schema, self.path.database) - self.web = Flask(self.config.NAME) + self.theme = Path(__file__).parent / 'themes' / "default" + + self.web = Flask(self.config.NAME, template_folder=self.theme) self.web.config["SECRET_KEY"] = self.config.SECRET_KEY self._initialized = True @@ -99,10 +104,19 @@ ADMIN_EMAIL= Bootstrap the database entries by populating the first Page, the Admin user and the Admins group. """ self.check_state() - self.db.save(schema.Page(parent_id=None, stub="", title="_", body="")) - admin = schema.User(name=self.config.ADMIN_USERNAME, email=self.config.ADMIN_EMAIL) - self.db.save(admin) - self.db.save(schema.Group(name="admins", users=[admin])) + try: + self.db.save(schema.Page(parent_id=None, stub="", title="_", body="")) + except UniqueConstraintError: + pass + try: + admin = self.db.save(schema.User(name=self.config.ADMIN_USERNAME, email=self.config.ADMIN_EMAIL)) + except UniqueConstraintError: + pass + + try: + self.db.save(schema.Group(name="admins", users=[admin])) + except UniqueConstraintError: + pass sys.modules[__name__] = ApplicationContext() diff --git a/src/ttfrog/cli.py b/src/ttfrog/cli.py index 1bdfd34..9488851 100644 --- a/src/ttfrog/cli.py +++ b/src/ttfrog/cli.py @@ -61,6 +61,7 @@ def run(context: typer.Context): """ The default CLI entrypoint is ttfrog.cli.run(). """ + import ttfrog.web ttfrog.app.web.run() diff --git a/src/ttfrog/schema.py b/src/ttfrog/schema.py index eeea97e..3fe4966 100644 --- a/src/ttfrog/schema.py +++ b/src/ttfrog/schema.py @@ -1,6 +1,4 @@ -from typing import List - -from grung.types import Field, Record +from grung.types import Collection, Field, Record class User(Record): @@ -8,7 +6,7 @@ class User(Record): class Group(Record): - _fields = [Field("name", unique=True), Field("users", List[User])] + _fields = [Field("name", unique=True), Collection("users", User)] class Page(Record): diff --git a/src/ttfrog/themes/default/base.html b/src/ttfrog/themes/default/base.html new file mode 100644 index 0000000..73492ce --- /dev/null +++ b/src/ttfrog/themes/default/base.html @@ -0,0 +1,34 @@ + + + + {% block head %} + + {% block title %}TTFROG{% endblock %} + + {% block styles %} + + {% endblock %} + {% endblock %} + + + + +
+ {% for message in get_flashed_messages() %} +
+ {{ message }} +
+ {% endfor %} + {% block content %}{% endblock %} +
+ +{% block scripts %}{% endblock %} + + diff --git a/src/ttfrog/themes/default/index.html b/src/ttfrog/themes/default/index.html new file mode 100644 index 0000000..c1e3b52 --- /dev/null +++ b/src/ttfrog/themes/default/index.html @@ -0,0 +1 @@ +HI diff --git a/src/ttfrog/themes/default/page.html b/src/ttfrog/themes/default/page.html new file mode 100644 index 0000000..33c4c5d --- /dev/null +++ b/src/ttfrog/themes/default/page.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} + +{% block content %} +

{{ page.title }}

+ {{ page.content }} +{% endblock %} diff --git a/src/ttfrog/web.py b/src/ttfrog/web.py index 745c643..f6cadfe 100644 --- a/src/ttfrog/web.py +++ b/src/ttfrog/web.py @@ -1,9 +1,22 @@ -from ttfrog.app import initialize - -_context = initialize() -app = _context.flask +from ttfrog import app +from flask import Response, render_template +from tinydb import where +import logging -@app.route("/", defaults={"path": ""}) -def serve(path): - return "HELLO" +logger = logging.getLogger(__name__) + + +@app.web.route("/") +def index(): + page = app.db.Page.search(where('stub') == "") + return render_template("page.html", page=page[0]) + + +@app.web.route("/") +def page_view(stub): + page = app.db.Page.search(where('stub') == stub) + if not page: + logger.info(f"No page found for {stub = }") + return Response(f"{stub}: not found", status=404) + return render_template("page.html", page=page[0])