2025-09-24 01:28:23 -07:00
|
|
|
|
2025-10-04 01:26:09 -07:00
|
|
|
from grung.types import BackReference, Collection, Field, Record, Pointer
|
2025-09-25 22:31:37 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class Page(Record):
|
2025-10-04 01:26:09 -07:00
|
|
|
"""
|
|
|
|
|
A page in the wiki. Just about everything in the databse is either a Page or a subclass of a Page.
|
|
|
|
|
"""
|
|
|
|
|
|
2025-09-28 14:14:16 -07:00
|
|
|
@classmethod
|
|
|
|
|
def fields(cls):
|
|
|
|
|
return [
|
2025-10-04 01:26:09 -07:00
|
|
|
*super().fields(), # Pick up the UID and whatever other non-optional fields exist
|
|
|
|
|
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
|
|
|
|
|
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.
|
|
|
|
|
# DateTime("last_modified"), # The last time the page was modified.
|
2025-09-28 14:14:16 -07:00
|
|
|
]
|
|
|
|
|
|
2025-10-03 16:44:25 -07:00
|
|
|
def before_insert(self, db):
|
2025-10-04 01:26:09 -07:00
|
|
|
"""
|
|
|
|
|
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.
|
|
|
|
|
"""
|
2025-10-03 16:44:25 -07:00
|
|
|
super().before_insert(db)
|
|
|
|
|
|
2025-10-04 01:26:09 -07:00
|
|
|
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(" ", "")
|
2025-09-28 14:14:16 -07:00
|
|
|
if not self.title:
|
2025-10-04 01:26:09 -07:00
|
|
|
self.title = self.name
|
2025-10-03 16:44:25 -07:00
|
|
|
|
2025-10-04 01:26:09 -07:00
|
|
|
self.uri = (self.parent.uri + "/" if self.parent and self.parent.uri != "/" else "") + self.name
|
2025-10-03 16:44:25 -07:00
|
|
|
|
|
|
|
|
def after_insert(self, db):
|
2025-10-04 01:26:09 -07:00
|
|
|
"""
|
|
|
|
|
After saving this record, ensure that any page in the members collection is updated with the
|
|
|
|
|
correct URI. This ensures that if a page is moved from one collection to another, the URI is updated.
|
|
|
|
|
"""
|
2025-10-03 16:44:25 -07:00
|
|
|
super().after_insert(db)
|
2025-10-04 01:26:09 -07:00
|
|
|
if not hasattr(self, 'members'):
|
|
|
|
|
return
|
|
|
|
|
for child in self.members:
|
2025-10-03 16:44:25 -07:00
|
|
|
obj = BackReference.dereference(child, db)
|
2025-10-04 01:26:09 -07:00
|
|
|
obj.uri = f"{self.uri}/{obj.name}"
|
2025-10-03 16:44:25 -07:00
|
|
|
child = db.save(obj)
|
|
|
|
|
|
|
|
|
|
def get_child(self, obj: Record):
|
2025-10-04 01:26:09 -07:00
|
|
|
for page in self.members:
|
2025-10-03 16:44:25 -07:00
|
|
|
if page.uid == obj.uid:
|
|
|
|
|
return page
|
|
|
|
|
return None
|
2025-10-04 01:26:09 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class User(Page):
|
|
|
|
|
"""
|
|
|
|
|
A website user, editable as a wiki page.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def fields(cls):
|
|
|
|
|
return [
|
|
|
|
|
field
|
|
|
|
|
for field in [
|
|
|
|
|
*super().fields(),
|
|
|
|
|
Field("email", unique=True)
|
|
|
|
|
] if field.name != "members"
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Group(Page):
|
|
|
|
|
"""
|
|
|
|
|
A set of users, editable as a wiki page.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class NPC(Page):
|
|
|
|
|
"""
|
|
|
|
|
An NPC, editable as a wiki page.
|
|
|
|
|
"""
|