org.app ======= .. py:module:: org.app .. autoapi-nested-parse:: Contains the base application used by other applications. Classes ------- .. autoapisummary:: org.app.OrgApp org.app.KeyLookupWithMTANHook Functions --------- .. autoapisummary:: org.app.get_shared_assets_path org.app.get_i18n_used_locales org.app.get_i18n_localedirs org.app.get_i18n_default_locale org.app.get_locale_negotiator org.app.get_static_directory org.app.get_template_directory org.app.get_theme org.app.org_content_security_policy org.app.get_create_new_organisation_factory org.app.get_status_mail_roles org.app.get_ticket_manager_roles org.app.get_require_complete_userprofile org.app.get_is_complete_userprofile_handler org.app.get_default_directory_search_widget org.app.get_default_event_search_widget org.app.get_public_ticket_messages org.app.get_disabled_extensions org.app.enable_iframes_tween_factory org.app.get_js_path org.app.get_css_path org.app.get_webasset_output org.app.get_sortable_asset org.app.get_fullcalendar_asset org.app.get_reservation_list_asset org.app.get_code_editor_asset org.app.get_editor_asset org.app.get_timeline_asset org.app.get_redactor_asset org.app.get_upload_asset org.app.get_editalttext_asset org.app.get_prompt org.app.get_photoswipe_asset org.app.get_tags_input org.app.get_filehash org.app.get_monthly_view org.app.get_common_asset org.app.get_fontpreview_asset org.app.get_scroll_to_username_asset org.app.get_all_blank_asset org.app.people_select_asset org.app.wrap_with_mtan_hook Module Contents --------------- .. py:class:: OrgApp Bases: :py:obj:`onegov.core.Framework`, :py:obj:`onegov.reservation.LibresIntegration`, :py:obj:`onegov.search.ElasticsearchApp`, :py:obj:`onegov.gis.MapboxApp`, :py:obj:`onegov.file.DepotApp`, :py:obj:`onegov.pay.PayApp`, :py:obj:`onegov.form.FormApp`, :py:obj:`onegov.user.UserApp`, :py:obj:`onegov.websockets.WebsocketsApp` Baseclass for Morepath OneGov applications. .. py:attribute:: serve_static_files :value: True Returns True if ``/static`` files should be served. Needs to be enabled manually. Note that even if the static files are not served, ``/static`` path is still served, it just won't return anything but a 404. Note also that static files are served **publicly**. You can override this in your application, but doing that and testing for it is on you! See also: :mod:`onegov.core.static`. .. py:attribute:: request_class The class of the Request to create. Must be a subclass of :class:`morepath.Request`. By default the request class is :class:`morepath.Request` .. py:attribute:: homepage_widget .. py:attribute:: export .. py:attribute:: userlinks .. py:attribute:: directory_search_widget .. py:attribute:: event_search_widget .. py:attribute:: settings_view .. py:attribute:: boardlet .. py:attribute:: send_ticket_statistics :value: True .. py:method:: is_allowed_application_id(application_id: str) -> bool Stops onegov.server from ever passing the request to the org application, if the schema does not exist. This way we can host onegov.org in a way that allows all requests to ``*.example.org``. If the schema for ``newyork.example.org`` exists, the request is handled. If the schema does not exist, the request is not handled. Here we basically decide if an org exists or not. .. py:method:: configure_application(**cfg: Any) -> None Configures the application. This function calls all methods on the current class which start with ``configure_``, passing the configuration as keyword arguments. The core itself supports the following parameters. Additional parameters are made available by extra ``configure_`` methods. :dsn: The database connection to use. May be None. See :meth:`onegov.core.orm.session_manager.setup` :base: The declarative base class used. By default, :attr:`onegov.core.orm.Base` is used. :identity_secure: True if the identity cookie is only transmitted over https. Only set this to False during development! :identity_secret: A random string used to sign the identity. By default a random string is generated. The drawback of this is the fact that users will be logged out every time the application restarts. So provide your own if you don't want that, but be sure to have a really long, really random key that you will never share with anyone! :redis_url: The redis url used (default is 'redis://localhost:6379/0'). :file_storage: The file_storage module to use. See ``_ :file_storage_options: A dictionary of options passed to the ``__init__`` method of the file_storage class. The file storage is expected to work as is. For example, if ``fs.osfs.OSFS`` is used, the root_path is expected exist. The file storage can be shared between different onegov.core applications. Each application automatically gets its own namespace inside this space. :always_compile_theme: If true, the theme is always compiled - no caching is employed. :allow_shift_f5_comple: If true, the theme is recompiled if shift+f5 is done on the browser (or shift + reload button click). :csrf_secret: A random string used to sign the csrf token. Make sure this differs from ``identity_secret``! The algorithms behind identity_secret and the csrf protection differ. If the same secret is used we might leak information about said secret. By default a random string is generated. The drawback of this is the fact that users won't be able to submit their forms if the app is restarted in the background. So provide your own, but be sure to have a really long, really random string that you will never share with anyone! :csrf_time_limit: The csrf time limit in seconds. Basically the amount of time a user has to submit a form, from the time it's rendered. Defaults to 1'200s (20 minutes). :mail: A dictionary keyed by e-mail category (i.e. 'marketing', 'transactional') with the following subkeys: - host: The mail server to send e-mails from. - port: The port used for the mail server. - force_tls: True if TLS should be forced. - username: The mail username - password: The mail password - sender: The mail sender - use_directory: True if a mail directory should be used - directory: Path to the directory that should be used :mail_use_directory: If true, mails are stored in the maildir defined through ``mail_directory``. There, some other process is supposed to pick up the e-mails and send them. :mail_directory: The directory (maildir) where mails are stored if if ``mail_use_directory`` is set to True. :sql_query_report: Prints out a report sql queries for each request, unless False. Valid values are: * 'summary' (only show the number of queries) * 'redundant' (show summary and the actual redundant queries) * 'all' (show summary and all executed queries) Do not use in production! :profile: If true, profiles the request and stores the result in the profiles folder with the following format: ``YYYY-MM-DD hh:mm:ss.profile`` Do not use in production! :print_exceptions: If true, exceptions are printed to stderr. Note that you should usually configure logging through onegov.server. This is mainly used for certain unit tests where we use WSGI more directly. .. py:method:: configure_organisation(*, enable_user_registration: bool = False, enable_yubikey: bool = False, disable_password_reset: bool = False, **cfg: Any) -> None .. py:method:: configure_mtan_hook(**cfg: Any) -> None This inserts an mtan hook by wrapping the callable we receive from the key lookup on get_view. We only need to do this once per application instance and we don't risk contaminating other applications, since each instance has its own dispatch callable. This relies heavily on implementation details of `reg.dispatch_method` and is thus a little bit fragile, take care when upgrading to newer versions of reg! .. py:method:: org() -> onegov.org.models.Organisation .. py:method:: _homepage_template_str() -> str .. py:property:: homepage_template :type: onegov.core.templates.PageTemplate .. py:method:: ticket_count() -> onegov.ticket.collection.TicketCount .. py:method:: ticket_permissions() -> dict[str, dict[str | None, list[str]]] .. py:method:: publications_count() -> int .. py:method:: prepare_email(reply_to: email.headerregistry.Address | str | None = None, category: Literal['marketing', 'transactional'] = 'marketing', receivers: onegov.core.types.SequenceOrScalar[email.headerregistry.Address | str] = (), cc: onegov.core.types.SequenceOrScalar[email.headerregistry.Address | str] = (), bcc: onegov.core.types.SequenceOrScalar[email.headerregistry.Address | str] = (), subject: str | None = None, content: str | None = None, attachments: collections.abc.Iterable[onegov.core.mail.Attachment | _typeshed.StrPath] = (), headers: dict[str, str] | None = None, plaintext: str | None = None) -> onegov.core.types.EmailJsonDict Wraps :meth:`onegov.core.framework.Framework.prepare_email`, setting the reply_to address by using the reply address from the organisation settings. .. py:property:: theme_options :type: dict[str, Any] Returns the application-bound theme options. .. py:property:: font_family :type: str | None .. py:property:: custom_event_tags :type: list[str] | None .. py:method:: load_custom_event_tags() -> list[str] | None .. py:property:: custom_texts :type: dict[str, str] | None .. py:method:: load_custom_texts() -> dict[str, str] | None Customer specific texts are specified in `puppet` repo, see loxo https://gitea.seantis.ch/operations/puppet/src/branch/master/nodes/loxo.seantis.ch.yaml#L183,193 Remember to create customtexts.yml in your local dev setup `/usr/local/var/onegov/files//customtexts.yml` Example customtexts.yml: ```yaml custom texts: (en) Custom admission course agreement: I agree to attend the .. (de) Custom admission course agreement: Ich erkläre mich bereit, .. ``` .. py:property:: allowed_iframe_domains :type: list[str] .. py:method:: load_allowed_iframe_domains() -> list[str] | None .. py:property:: hashed_identity_key :type: bytes Take the sha-256 because we want a key that is 32 bytes long. .. py:property:: custom_event_form_lead :type: str | None .. py:method:: load_custom_event_form_lead() -> str | None .. py:method:: checkout_button(button_label: str, title: str, price: onegov.pay.Price | None, email: str, complete_url: str, request: onegov.org.request.OrgRequest) -> str | None .. py:method:: redirect_after_login(identity: morepath.authentication.Identity | morepath.authentication.NoIdentity, request: onegov.org.request.OrgRequest, default: str) -> str | None Returns the path to redirect after login, given the request and the default login path, which is usually the current path. Returns a path or None, if the default should be used. .. py:function:: get_shared_assets_path() -> str .. py:function:: get_i18n_used_locales() -> set[str] .. py:function:: get_i18n_localedirs() -> list[str] .. py:function:: get_i18n_default_locale() -> str .. py:function:: get_locale_negotiator() -> collections.abc.Callable[[collections.abc.Sequence[str], onegov.org.request.OrgRequest], str | None] .. py:function:: get_static_directory() -> str .. py:function:: get_template_directory() -> str .. py:function:: get_theme() -> onegov.org.theme.OrgTheme .. py:function:: org_content_security_policy() -> more.content_security.ContentSecurityPolicy .. py:function:: get_create_new_organisation_factory() -> collections.abc.Callable[[OrgApp, str], onegov.org.models.Organisation] .. py:function:: get_status_mail_roles() -> collections.abc.Collection[str] .. py:function:: get_ticket_manager_roles() -> collections.abc.Collection[str] .. py:function:: get_require_complete_userprofile() -> bool .. py:function:: get_is_complete_userprofile_handler() -> collections.abc.Callable[[onegov.org.request.OrgRequest, str], bool] .. py:function:: get_default_directory_search_widget() -> None .. py:function:: get_default_event_search_widget() -> None .. py:function:: get_public_ticket_messages() -> collections.abc.Collection[str] Returns a list of message types which are availble on the ticket status page, visible to anyone that knows the unguessable url. .. py:function:: get_disabled_extensions() -> collections.abc.Collection[str] .. py:function:: enable_iframes_tween_factory(app: OrgApp, handler: collections.abc.Callable[[onegov.org.request.OrgRequest], webob.Response]) -> collections.abc.Callable[[onegov.org.request.OrgRequest], webob.Response] .. py:function:: get_js_path() -> str .. py:function:: get_css_path() -> str .. py:function:: get_webasset_output() -> str .. py:function:: get_sortable_asset() -> collections.abc.Iterator[str] .. py:function:: get_fullcalendar_asset() -> collections.abc.Iterator[str] .. py:function:: get_reservation_list_asset() -> collections.abc.Iterator[str] .. py:function:: get_code_editor_asset() -> collections.abc.Iterator[str] .. py:function:: get_editor_asset() -> collections.abc.Iterator[str] .. py:function:: get_timeline_asset() -> collections.abc.Iterator[str] .. py:function:: get_redactor_asset() -> collections.abc.Iterator[str] .. py:function:: get_upload_asset() -> collections.abc.Iterator[str] .. py:function:: get_editalttext_asset() -> collections.abc.Iterator[str] .. py:function:: get_prompt() -> collections.abc.Iterator[str] .. py:function:: get_photoswipe_asset() -> collections.abc.Iterator[str] .. py:function:: get_tags_input() -> collections.abc.Iterator[str] .. py:function:: get_filehash() -> collections.abc.Iterator[str] .. py:function:: get_monthly_view() -> collections.abc.Iterator[str] .. py:function:: get_common_asset() -> collections.abc.Iterator[str] .. py:function:: get_fontpreview_asset() -> collections.abc.Iterator[str] .. py:function:: get_scroll_to_username_asset() -> collections.abc.Iterator[str] .. py:function:: get_all_blank_asset() -> collections.abc.Iterator[str] .. py:function:: people_select_asset() -> collections.abc.Iterator[str] .. py:function:: wrap_with_mtan_hook(func: collections.abc.Callable[[OrgApp, Any, onegov.org.request.OrgRequest], Any]) -> collections.abc.Callable[[OrgApp, Any, onegov.org.request.OrgRequest], Any] .. py:class:: KeyLookupWithMTANHook(key_lookup: reg.dispatch._KeyLookup) .. py:attribute:: key_lookup .. py:method:: component(key: collections.abc.Sequence[Any]) -> collections.abc.Callable[Ellipsis, Any] | None .. py:method:: fallback(key: collections.abc.Sequence[Any]) -> collections.abc.Callable[Ellipsis, Any] | None .. py:method:: all(key: collections.abc.Sequence[Any]) -> collections.abc.Iterator[collections.abc.Callable[Ellipsis, Any]]