from dataclasses import dataclass, field from functools import cached_property import logging from flask import g from grung.types import BackReference, Collection, Pointer, Record, Timestamp from ttfrog import schema READ_ONLY_FIELD_TYPES = [Collection, Pointer, BackReference, Timestamp] logger = logging.getLogger(__name__) @dataclass class Form: """ The base Form controller for the web UI. """ record: Record data: field(default_factory=dict) @cached_property def read_only(self) -> set: return [ name for (name, attr) in self.record._metadata.fields.items() if type(attr) in READ_ONLY_FIELD_TYPES ] + ["uid", "acl"] def prepare(self): for key, value in self.data.items(): # filter out fields that cannot be set by the user if key in self.read_only: continue if self.record[key] != value: logger.debug(f"Updating {self.record.__class__.__name__}[{self.record.doc_id}] {key}={value}") self.record[key] = value self.record.author = g.user return self.record @dataclass class Page(Form): """ A form for creating and updating Page records. """ record: schema.Page @dataclass class Wiki(Form): """ A form for creating and updating Wiki records. """ record: schema.Page @dataclass class NPC(Page): """ A form for creating and updating Page records. """ record: schema.NPC @dataclass class User(Page): """ A form for creating and updating Page records. """ record: schema.NPC @dataclass class Group(Page): """ A form for creating and updating Page records. """ record: schema.NPC