Source code for org.models.document_form

from __future__ import annotations

from uuid import uuid4

from onegov.chat.models.message import associated
from onegov.core.collection import GenericCollection
from onegov.core.orm import Base
from onegov.core.orm.mixins import (
    ContentMixin, TimestampMixin, dict_property, content_property,
    meta_property)
from onegov.core.orm.mixins.content import dict_markup_property
from onegov.core.utils import normalize_for_url
from onegov.file import File, MultiAssociatedFiles
from onegov.form import FormCollection
from onegov.org.i18n import _
from onegov.org.models.extensions import PersonLinkExtension
from onegov.org.observer import observes
from onegov.reservation import ResourceCollection
from onegov.org.models import (AccessExtension, ContactExtension,
                               CoordinatesExtension, GeneralFileLinkExtension,
                               HoneyPotExtension)
from onegov.search import SearchableContent
from sqlalchemy.orm import mapped_column, Mapped
from uuid import UUID


from typing import Any, TYPE_CHECKING
if TYPE_CHECKING:
    from sqlalchemy.orm import Query, Session


[docs] class DocumentFormFile(File):
[docs] __mapper_args__ = {'polymorphic_identity': 'document_form_file'}
[docs] class FormDocument(Base, ContentMixin, TimestampMixin, AccessExtension, SearchableContent, MultiAssociatedFiles, ContactExtension, PersonLinkExtension, HoneyPotExtension, CoordinatesExtension, GeneralFileLinkExtension):
[docs] __tablename__ = 'form_documents'
[docs] fts_type_title = _('Forms')
[docs] fts_title_property = 'title'
[docs] fts_properties = { 'title': {'type': 'localized', 'weight': 'A'}, 'lead': {'type': 'localized', 'weight': 'B'}, 'pdf_extract': {'type': 'localized', 'weight': 'C'}, }
#: An internal id for references (not public)
[docs] id: Mapped[UUID] = mapped_column( primary_key=True, default=uuid4 )
#: A nice id for the url, readable by humans
[docs] name: Mapped[str] = mapped_column(unique=True)
[docs] title: Mapped[str]
#: Describes the document briefly
[docs] lead: dict_property[str | None] = meta_property()
#: Describes the document in detail
[docs] text = dict_markup_property('content')
[docs] pdf = associated( DocumentFormFile, 'pdf', 'one-to-one', uselist=False, backref_suffix='pdf')
# The collection name this model should appear in
[docs] member_of: Mapped[str | None]
[docs] group: Mapped[str | None]
#: The normalized title for sorting
[docs] order: Mapped[str] = mapped_column(index=True)
[docs] pdf_extract: dict_property[str | None] = content_property()
@observes('pdf')
[docs] def pdf_observer(self, pdf: DocumentFormFile | None) -> None: self.pdf_extract = pdf.extract if pdf is not None else None
@observes('title')
[docs] def title_observer(self, title: str) -> None: self.order = normalize_for_url(title)
[docs] class FormDocumentCollection(GenericCollection[FormDocument]):
[docs] supported_collections = { 'form': FormCollection, 'resource': ResourceCollection }
def __init__( self, session: Session, member_of: str | None = None, group: str | None = None, type: str | None = None ): super().__init__(session)
[docs] self.member_of = member_of
[docs] self.group = group
[docs] self.type = type
@staticmethod
[docs] def translatable_name(model_class: type[object]) -> str: """ Most collections have a base model whose name can be guessed from the collection name. """ name = model_class.__name__.lower() name = name.replace('collection', '').rstrip('s') return f'{name.capitalize()}s'
[docs] def form_choices(self) -> tuple[tuple[str, str], ...]: if self.type in self.supported_collections: collection = self.supported_collections[self.type] return ( (collection.__name__, self.translatable_name(collection)), ) else: return tuple( (m.__name__, self.translatable_name(m)) for m in self.supported_collections.values() )
[docs] def by_name(self, name: str) -> FormDocument | None: """ Returns the given form by name or None. """ return self.query().filter(FormDocument.name == name).first()
@classmethod
[docs] def collection_by_name(cls) -> dict[str, type[GenericCollection[Any]]]: return {m.__name__: m for m in cls.supported_collections.values()}
@property
[docs] def model_class(self) -> type[FormDocument]: return FormDocument
@classmethod
[docs] def target( cls, external_link: FormDocument ) -> type[GenericCollection[Any]]: assert external_link.member_of is not None return cls.collection_by_name()[external_link.member_of]
[docs] def query(self) -> Query[FormDocument]: return self.session.query(FormDocument)