Source code for org.directives

from dectate import Action
from itertools import count


from typing import cast, Any, ClassVar, TYPE_CHECKING
if TYPE_CHECKING:
    from collections.abc import Callable
    from onegov.core.elements import LinkGroup
    from onegov.directory.models import DirectoryEntry
    from onegov.event.models import Occurrence
    from onegov.org.models import Boardlet as _Boardlet
    from onegov.org.request import OrgRequest
    from onegov.user import User
    from sqlalchemy.orm import Query
    from typing import Protocol, TypeAlias, TypeVar, TypedDict

[docs] DirectoryEntryT = TypeVar('DirectoryEntryT', bound=DirectoryEntry)
DirectorySearchWidgetRegistry: TypeAlias = dict[ str, type['RegisteredDirectorySearchWidget[Any]'] ] EventSearchWidgetRegistry: TypeAlias = dict[ str, type['RegisteredEventSearchWidget'] ] LinkGroupFactory: TypeAlias = Callable[[OrgRequest, User], LinkGroup] class HomepageWidget(Protocol): @property def template(self) -> str: ... class RegisteredHomepageWidget(HomepageWidget, Protocol): tag: str class DirectorySearchWidget(Protocol[DirectoryEntryT]): @property def search_query(self) -> Query[DirectoryEntryT]: ... def adapt( self, query: Query[DirectoryEntryT] ) -> Query[DirectoryEntryT]: ... class RegisteredDirectorySearchWidget( DirectorySearchWidget[DirectoryEntryT], Protocol[DirectoryEntryT] ): name: str class EventSearchWidget(Protocol): @property def search_query(self) -> Query[Occurrence]: ... def adapt( self, query: Query[Occurrence] ) -> Query[Occurrence]: ... class RegisteredEventSearchWidget(EventSearchWidget, Protocol): name: str class SettingsDict(TypedDict): name: str title: str order: int icon: str class BoardletConfig(TypedDict): cls: type[_Boardlet] order: tuple[int, int]
[docs] class HomepageWidgetAction(Action): """ Register a cronjob. """
[docs] config = { 'homepage_widget_registry': dict }
def __init__(self, tag: str) -> None:
[docs] self.tag = tag
[docs] def identifier( # type:ignore[override] self, homepage_widget_registry: dict[str, 'RegisteredHomepageWidget'] ) -> str: return self.tag
[docs] def perform( # type:ignore[override] self, func: 'Callable[[], HomepageWidget]', homepage_widget_registry: dict[str, 'RegisteredHomepageWidget'] ) -> None: widget = cast('RegisteredHomepageWidget', func()) widget.tag = self.tag # keep redundantly for ease of access homepage_widget_registry[self.tag] = widget
[docs] class ExportAction(Action): """ Register an export. """
[docs] config = { 'export_registry': dict }
def __init__(self, id: str, **kwargs: Any) -> None:
[docs] self.id = id
[docs] self.kwargs = kwargs
self.kwargs['id'] = id
[docs] def identifier( # type:ignore[override] self, export_registry: dict[str, Any] ) -> str: return self.id
[docs] def perform( # type:ignore[override] self, cls: 'Callable[..., Any]', export_registry: dict[str, Any] ) -> None: export_registry[self.id] = cls(**self.kwargs)
[docs] class UserlinkAction(Action): """ Registers a user link group. """
[docs] config = { 'linkgroup_registry': list }
[docs] counter: ClassVar = count(1)
def __init__(self) -> None:
[docs] self.name = next(self.counter)
[docs] def identifier( # type:ignore[override] self, linkgroup_registry: list['LinkGroupFactory'] ) -> int: return self.name
[docs] def perform( # type:ignore[override] self, func: 'LinkGroupFactory', linkgroup_registry: list['LinkGroupFactory'] ) -> None: linkgroup_registry.append(func)
[docs] class DirectorySearchWidgetAction(Action): """ Registers a directory search widget. """
[docs] config = { 'directory_search_widget_registry': dict }
def __init__(self, name: str) -> None:
[docs] self.name = name
[docs] def identifier( # type:ignore[override] self, directory_search_widget_registry: 'DirectorySearchWidgetRegistry' ) -> str: return self.name
[docs] def perform( # type:ignore[override] self, cls: type['DirectorySearchWidget[Any]'], directory_search_widget_registry: 'DirectorySearchWidgetRegistry' ) -> None: cls = cast('type[RegisteredDirectorySearchWidget[Any]]', cls) cls.name = self.name assert hasattr(cls, 'html') assert hasattr(cls, 'adapt') directory_search_widget_registry[self.name] = cls
[docs] class EventSearchWidgetAction(Action): """ Registers a text search widget. """
[docs] config = { 'event_search_widget_registry': dict }
def __init__(self, name: str) -> None:
[docs] self.name = name
[docs] def identifier( # type:ignore[override] self, event_search_widget_registry: 'EventSearchWidgetRegistry' ) -> str: return self.name
[docs] def perform( # type:ignore[override] self, cls: type['EventSearchWidget'], event_search_widget_registry: 'EventSearchWidgetRegistry' ) -> None: cls = cast('type[RegisteredEventSearchWidget]', cls) cls.name = self.name assert hasattr(cls, 'html') assert hasattr(cls, 'adapt') event_search_widget_registry[self.name] = cls
[docs] class SettingsView(Action): """ Registers a settings view. """
[docs] config = { 'settings_view_registry': dict }
def __init__( self, name: str, title: str, order: int = 0, icon: str = 'fa-cogs' ) -> None:
[docs] self.name = name
[docs] self.setting: SettingsDict = { 'name': name, 'title': title, 'order': order, 'icon': icon }
[docs] def identifier( # type:ignore[override] self, settings_view_registry: dict[str, 'SettingsDict'] ) -> str: return self.name
[docs] def perform( # type:ignore[override] self, func: Any, settings_view_registry: dict[str, 'SettingsDict'] ) -> None: settings_view_registry[self.name] = self.setting
[docs] class Boardlet(Action): """ Registers a boardlet on the Dashboard. """
[docs] config = { 'boardlets_registry': dict }
def __init__(self, name: str, order: tuple[int, int]): assert isinstance(order, tuple) and len(order) == 2, """ The order should consist of two values, a group and an order within the group. """
[docs] self.name = name
[docs] self.order = order
[docs] def identifier( # type:ignore[override] self, boardlets_registry: dict[str, 'BoardletConfig'] ) -> str: return self.name
[docs] def perform( # type:ignore[override] self, func: type['_Boardlet'], boardlets_registry: dict[str, 'BoardletConfig'] ) -> None: boardlets_registry[self.name] = { 'cls': func, 'order': self.order }