body is now a TextFilePointer

This commit is contained in:
evilchili 2025-10-18 17:26:21 -07:00
parent 51795c8f7c
commit 8fd28cf8b1
5 changed files with 43 additions and 48 deletions

View File

@ -90,15 +90,15 @@ VIEW_URI=/
if db: if db:
self.db = db self.db = db
elif self.config.IN_MEMORY_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: else:
self.db = GrungDB.with_schema( 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.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["SECRET_KEY"] = self.config.SECRET_KEY
self.web.config["SEND_FILE_MAX_AGE_DEFAULT"] = 0 self.web.config["SEND_FILE_MAX_AGE_DEFAULT"] = 0
self.web.config["DEBUG"] = True self.web.config["DEBUG"] = True

View File

@ -40,25 +40,25 @@ def bootstrap():
app.check_state() app.check_state()
# create the top-level pages # 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.")) users = root.add_member(schema.Page(name="User", body=b"# Users\nusers go here."))
groups = root.add_member(schema.Page(name="Group", title="Groups", body="groups go here.")) groups = root.add_member(schema.Page(name="Group", body=b"# Groups\ngroups go here."))
npcs = root.add_member(schema.Page(name="NPC", title="NPCS!", body="NPCS!")) npcs = root.add_member(schema.Page(name="NPC", body=b"# NPCS!"))
wiki = root.add_member(schema.Page(name="Wiki", title="Wiki", body=TEMPLATE)) wiki = root.add_member(schema.Page(name="Wiki", body=TEMPLATE.encode()))
# create the NPCs # create the NPCs
npcs.add_member(schema.NPC(name="Sabetha", body="")) npcs.add_member(schema.NPC(name="Sabetha", body=""))
npcs.add_member(schema.NPC(name="John", body="")) npcs.add_member(schema.NPC(name="John", body=""))
# create the users # 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( 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 # 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 # admins get full access
root.set_permissions( root.set_permissions(

View File

@ -1,10 +1,21 @@
from __future__ import annotations from __future__ import annotations
from datetime import datetime from datetime import datetime
from typing import List
from enum import StrEnum 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 from tinydb import where
@ -26,8 +37,7 @@ class Page(Record):
*super().fields(), *super().fields(),
Field("uri", unique=True), # The URI for the page, relative to the app's VIEW_URI 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("name"), # The portion of the URI after the last /
Field("title"), # The page title TextFilePointer("body", extension='.md'), # The main content blob of the page
Field("body"), # The main content blob of the page
Collection("members", Page), # The pages that exist below this page's URI 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 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. 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. Timestamp("last_modified"), # The last time the page was modified.
Dict("acl"), Dict("acl"),
] ]
# fmt: on # fmt: on
def before_insert(self, db): def before_insert(self, db):
""" """
Make the following adjustments before saving this record: 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. * Derive the URI from the hierarchy of the parent.
""" """
if not self.name:
raise Exception("Must provide a name")
super().before_insert(db) super().before_insert(db)
now = datetime.utcnow() now = datetime.utcnow()
if not self.doc_id and self.created < now: if not self.doc_id and self.created < now:
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 self.uri = (self.parent.uri + "/" if self.parent and self.parent.uri != "/" else "") + self.name
def after_insert(self, db): def after_insert(self, db):
@ -127,14 +133,9 @@ class Page(Record):
class Entity(Page): class Entity(Page):
@classmethod @classmethod
def fields(cls): def fields(cls):
inherited = [ inherited = [field for field in super().fields() if field.name not in ("members", "uid")]
field
for field in super().fields()
if field.name not in ("members", "uid")
]
return inherited + [ return inherited + [
Field("name", primary_key=True), Field("name", primary_key=True),
] ]
@ -175,11 +176,10 @@ class Group(Entity):
""" """
A set of users, editable as a wiki page. A set of users, editable as a wiki page.
""" """
@classmethod @classmethod
def fields(cls): def fields(cls):
return super().fields() + [ return super().fields() + [Collection("members", Entity)]
Collection("members", Entity)
]
class NPC(Page): class NPC(Page):

View File

@ -61,15 +61,7 @@ def rendered(page: schema.Record, template: str = "page.html"):
if not page: if not page:
return Response("Page not found", status=404) return Response("Page not found", status=404)
return render_template( return render_template(template, page=page, app=app, breadcrumbs=breadcrumbs(), root=g.root, user=g.user, g=g)
template,
page=page,
app=app,
breadcrumbs=breadcrumbs(),
root=g.root,
user=g.user,
g=g
)
def breadcrumbs(): def breadcrumbs():
@ -148,7 +140,7 @@ def edit(table, path):
@app.web.before_request @app.web.before_request
def before_request(): def before_request():
g.messages = [] g.messages = []
if not request.path.startswith('/static'): if not request.path.startswith("/static"):
user_id = session.get("user_id", 1) user_id = session.get("user_id", 1)
g.user = app.db.User.get(doc_id=user_id) g.user = app.db.User.get(doc_id=user_id)
session["user_id"] = user_id session["user_id"] = user_id

View File

@ -1,3 +1,5 @@
from tempfile import TemporaryDirectory
import pytest import pytest
from grung.db import GrungDB from grung.db import GrungDB
from tinydb import where from tinydb import where
@ -9,7 +11,8 @@ from ttfrog import schema
@pytest.fixture @pytest.fixture
def app(): def app():
fixture_db = GrungDB.with_schema(schema, storage=MemoryStorage) 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.load_config(defaults=None, IN_MEMORY_DB=1)
ttfrog.app.initialize(db=fixture_db, force=True) ttfrog.app.initialize(db=fixture_db, force=True)
yield ttfrog.app yield ttfrog.app