From 8fd28cf8b1ebea7cc52558d4170852bedba958b1 Mon Sep 17 00:00:00 2001 From: evilchili Date: Sat, 18 Oct 2025 17:26:21 -0700 Subject: [PATCH] body is now a TextFilePointer --- src/ttfrog/app.py | 6 +++--- src/ttfrog/bootstrap.py | 16 +++++++-------- src/ttfrog/schema.py | 44 ++++++++++++++++++++--------------------- src/ttfrog/web.py | 12 ++--------- test/test_db.py | 13 +++++++----- 5 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/ttfrog/app.py b/src/ttfrog/app.py index 90a21cd..ff967c6 100644 --- a/src/ttfrog/app.py +++ b/src/ttfrog/app.py @@ -90,15 +90,15 @@ VIEW_URI=/ if db: self.db = db elif self.config.IN_MEMORY_DB: - self.db = GrungDB.with_schema(schema, storage=MemoryStorage) + self.db = GrungDB.with_schema(schema, path=None, storage=MemoryStorage) else: self.db = GrungDB.with_schema( - schema, self.path.database, sort_keys=True, indent=4, separators=(",", ": ") + schema, path=self.path.database, sort_keys=True, indent=4, separators=(",", ": ") ) self.theme = Path(__file__).parent / "themes" / self.config.THEME - self.web = Flask(self.config.NAME, template_folder=self.theme, static_folder=self.theme / 'static') + self.web = Flask(self.config.NAME, template_folder=self.theme, static_folder=self.theme / "static") self.web.config["SECRET_KEY"] = self.config.SECRET_KEY self.web.config["SEND_FILE_MAX_AGE_DEFAULT"] = 0 self.web.config["DEBUG"] = True diff --git a/src/ttfrog/bootstrap.py b/src/ttfrog/bootstrap.py index 48d3103..eb6631a 100644 --- a/src/ttfrog/bootstrap.py +++ b/src/ttfrog/bootstrap.py @@ -40,25 +40,25 @@ def bootstrap(): app.check_state() # create the top-level pages - root = app.db.save(schema.Page(name=app.config.VIEW_URI, title="Home", body="This is the home page")) + root = app.db.save(schema.Page(name=app.config.VIEW_URI, body=b"This is the home page")) - users = root.add_member(schema.Page(name="User", title="Users", body="users go here.")) - groups = root.add_member(schema.Page(name="Group", title="Groups", body="groups go here.")) - npcs = root.add_member(schema.Page(name="NPC", title="NPCS!", body="NPCS!")) - wiki = root.add_member(schema.Page(name="Wiki", title="Wiki", body=TEMPLATE)) + users = root.add_member(schema.Page(name="User", body=b"# Users\nusers go here.")) + groups = root.add_member(schema.Page(name="Group", body=b"# Groups\ngroups go here.")) + npcs = root.add_member(schema.Page(name="NPC", body=b"# NPCS!")) + wiki = root.add_member(schema.Page(name="Wiki", body=TEMPLATE.encode())) # create the NPCs npcs.add_member(schema.NPC(name="Sabetha", body="")) npcs.add_member(schema.NPC(name="John", body="")) # create the users - guest = users.add_member(schema.User(name="guest")) + guest = users.add_member(schema.User(name="guest", body=b"# guest")) admin = users.add_member( - schema.User(name=app.config.ADMIN_USERNAME, password="fnord", email=app.config.ADMIN_EMAIL) + schema.User(name=app.config.ADMIN_USERNAME, password="fnord", email=app.config.ADMIN_EMAIL, body=b"# fnord") ) # create the admin user and admins group - admins = groups.add_member(schema.Group(name="administrators", members=[admin])) + admins = groups.add_member(schema.Group(name="administrators", members=[admin], body=b"# administrators")) # admins get full access root.set_permissions( diff --git a/src/ttfrog/schema.py b/src/ttfrog/schema.py index 2bbc113..969a68b 100644 --- a/src/ttfrog/schema.py +++ b/src/ttfrog/schema.py @@ -1,10 +1,21 @@ from __future__ import annotations from datetime import datetime -from typing import List from enum import StrEnum +from typing import List -from grung.types import BackReference, Collection, DateTime, Dict, Field, Password, Pointer, Record, Timestamp +from grung.types import ( + BackReference, + Collection, + DateTime, + Dict, + Field, + Password, + Pointer, + Record, + TextFilePointer, + Timestamp, +) from tinydb import where @@ -26,8 +37,7 @@ class Page(Record): *super().fields(), Field("uri", unique=True), # The URI for the page, relative to the app's VIEW_URI Field("name"), # The portion of the URI after the last / - Field("title"), # The page title - Field("body"), # The main content blob of the page + TextFilePointer("body", extension='.md'), # The main content blob of the page Collection("members", Page), # The pages that exist below this page's URI BackReference("parent", value_type=Page), # The page that exists above this page's URI Pointer("author", value_type=User), # The last user to touch the page. @@ -35,27 +45,23 @@ class Page(Record): Timestamp("last_modified"), # The last time the page was modified. Dict("acl"), ] - # fmt: on + + # fmt: on def before_insert(self, db): """ Make the following adjustments before saving this record: - * Derive the name from the title, or the title from the name * Derive the URI from the hierarchy of the parent. """ + if not self.name: + raise Exception("Must provide a name") + super().before_insert(db) now = datetime.utcnow() if not self.doc_id and self.created < now: self.created = now - if not self.name and not self.title: - raise Exception("Must provide either a name or a title!") - if not self.name: - self.name = self.title.title().replace(" ", "") - if not self.title: - self.title = self.name - self.uri = (self.parent.uri + "/" if self.parent and self.parent.uri != "/" else "") + self.name def after_insert(self, db): @@ -127,14 +133,9 @@ class Page(Record): class Entity(Page): - @classmethod def fields(cls): - inherited = [ - field - for field in super().fields() - if field.name not in ("members", "uid") - ] + inherited = [field for field in super().fields() if field.name not in ("members", "uid")] return inherited + [ Field("name", primary_key=True), ] @@ -175,11 +176,10 @@ class Group(Entity): """ A set of users, editable as a wiki page. """ + @classmethod def fields(cls): - return super().fields() + [ - Collection("members", Entity) - ] + return super().fields() + [Collection("members", Entity)] class NPC(Page): diff --git a/src/ttfrog/web.py b/src/ttfrog/web.py index 2cc5bf3..f16698f 100644 --- a/src/ttfrog/web.py +++ b/src/ttfrog/web.py @@ -61,15 +61,7 @@ def rendered(page: schema.Record, template: str = "page.html"): if not page: return Response("Page not found", status=404) - return render_template( - template, - page=page, - app=app, - breadcrumbs=breadcrumbs(), - root=g.root, - user=g.user, - g=g - ) + return render_template(template, page=page, app=app, breadcrumbs=breadcrumbs(), root=g.root, user=g.user, g=g) def breadcrumbs(): @@ -148,7 +140,7 @@ def edit(table, path): @app.web.before_request def before_request(): g.messages = [] - if not request.path.startswith('/static'): + if not request.path.startswith("/static"): user_id = session.get("user_id", 1) g.user = app.db.User.get(doc_id=user_id) session["user_id"] = user_id diff --git a/test/test_db.py b/test/test_db.py index ea96011..4bcb400 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -1,3 +1,5 @@ +from tempfile import TemporaryDirectory + import pytest from grung.db import GrungDB from tinydb import where @@ -9,11 +11,12 @@ from ttfrog import schema @pytest.fixture def app(): - fixture_db = GrungDB.with_schema(schema, storage=MemoryStorage) - ttfrog.app.load_config(defaults=None, IN_MEMORY_DB=1) - ttfrog.app.initialize(db=fixture_db, force=True) - yield ttfrog.app - ttfrog.app.db.truncate() + with TemporaryDirectory() as path: + fixture_db = GrungDB.with_schema(schema, path=path, storage=MemoryStorage) + ttfrog.app.load_config(defaults=None, IN_MEMORY_DB=1) + ttfrog.app.initialize(db=fixture_db, force=True) + yield ttfrog.app + ttfrog.app.db.truncate() def test_create(app):