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.orm.types import UUID
from onegov.core.utils import normalize_for_url
from onegov.file import AssociatedFiles, File, SearchableFile
from onegov.form import FormCollection
from onegov.org.observer import observes
from onegov.reservation import ResourceCollection
from onegov.org.models import AccessExtension
from onegov.search import SearchableContent
from sqlalchemy import Column, Text


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


[docs] class DocumentFormFile(File, SearchableFile):
[docs] __mapper_args__ = {'polymorphic_identity': 'document_form_file'}
[docs] es_type_name = 'document_form_file'
@property
[docs] def es_public(self) -> bool: return True
[docs] class FormDocument(Base, ContentMixin, TimestampMixin, AccessExtension, SearchableContent, AssociatedFiles):
[docs] __tablename__ = 'form_documents'
[docs] es_properties = { 'title': {'type': 'localized'}, 'lead': {'type': 'localized'}, }
#: An internal id for references (not public)
[docs] id: Column[uuid.UUID] = Column( UUID, # type:ignore[arg-type] primary_key=True, default=uuid4 )
#: A nice id for the url, readable by humans
[docs] name: Column[str] = Column(Text, nullable=False, unique=True)
[docs] title: Column[str] = Column(Text, nullable=False)
#: 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: Column[str | None] = Column(Text, nullable=True)
[docs] group: Column[str | None] = Column(Text, nullable=True)
#: The normalized title for sorting
[docs] order: Column[str] = Column(Text, nullable=False, 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] es_type_name = 'document_pages'
[docs] es_id = '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)