Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ update-docs:
@uv run --no-sync ../manage.py list_checks -s checks -o snippets/checks-autogenerated.rst
@uv run --no-sync ../manage.py list_checks -s flags -o snippets/check-flags-autogenerated.rst
@uv run --no-sync ../manage.py list_format_features -o snippets/format-features
@uv run --no-sync ../manage.py list_notification_config -o snippets/notifications-config.rst

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
Expand Down
29 changes: 29 additions & 0 deletions docs/admin/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,35 @@ DEFAULT_MERGE_STYLE
* :ref:`component`
* :ref:`component-merge_style`

.. setting:: DEFAULT_NOTIFICATIONS

DEFAULT_NOTIFICATIONS
---------------------

Default notification settings for every created user.

A list of 3-tuples consisting of notification scope, notification frequency and notification handler.

.. include:: /snippets/notifications-config.rst

.. note::

This setting affects only newly created users.

Example:

.. code-block:: python

DEFAULT_NOTIFICATIONS = [
(0, 1, "MentionCommentNotificaton"),
(10, 1, "LastAuthorCommentNotificaton"),
]

.. seealso::

* :ref:`notifications`


.. setting:: DEFAULT_SHARED_TM

DEFAULT_SHARED_TM
Expand Down
11 changes: 11 additions & 0 deletions docs/admin/install/docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,17 @@ Generic settings

Configures :setting:`DEFAULT_AUTO_WATCH`.

.. envvar:: WEBLATE_DEFAULT_NOTIFICATIONS

Configures :setting:`DEFAULT_NOTIFICATIONS`.

**Example:**

.. code-block:: yaml

environment:
WEBLATE_DEFAULT_NOTIFICATIONS: 0:1:MentionCommentNotificaton,10:1:LastAuthorCommentNotificaton

.. envvar:: WEBLATE_RATELIMIT_ATTEMPTS
.. envvar:: WEBLATE_RATELIMIT_LOCKOUT
.. envvar:: WEBLATE_RATELIMIT_WINDOW
Expand Down
11 changes: 11 additions & 0 deletions docs/admin/management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,17 @@ list_machinery

Lists automatic suggestions services in reStructuredText as a template for :doc:`/admin/machine`.

.. seealso::

:doc:`/contributing/documentation`

list_notification_config
------------------------

.. weblate-admin:: list_notification_config

Lists notification scopes, frequencies and handlers in reStructuredText as a template for :doc:`/admin/config`.

.. seealso::

:doc:`/contributing/documentation`
Expand Down
2 changes: 2 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Weblate 2026.7

.. rubric:: New features

* Added :setting:`DEFAULT_NOTIFICATIONS` to configure :ref:`notifications` settings for new users.

.. rubric:: Improvements

* Management interface access control is now more fine-grained with dedicated site-wide permissions.
Expand Down
89 changes: 89 additions & 0 deletions docs/snippets/notifications-config.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
Scopes:

.. AUTOGENERATED START: notification-scopes
.. This section is automatically generated by `./manage.py list_notification_config`. Do not edit manually.

``0``
:guilabel:`All`
``10``
:guilabel:`Watched`
``20``
:guilabel:`Administered`
``30``
:guilabel:`Project`
``40``
:guilabel:`Component`

.. AUTOGENERATED END: notification-scopes

Frequencies:

.. AUTOGENERATED START: notification-frequencies
.. This section is automatically generated by `./manage.py list_notification_config`. Do not edit manually.

``0``
:guilabel:`No notification`
``1``
:guilabel:`Instant notification`
``2``
:guilabel:`Daily digest`
``3``
:guilabel:`Weekly digest`
``4``
:guilabel:`Monthly digest`

.. AUTOGENERATED END: notification-frequencies

Handlers:

.. AUTOGENERATED START: notification-handlers
.. This section is automatically generated by `./manage.py list_notification_config`. Do not edit manually.

``ApprovedStringNotificaton``
:guilabel:`String was approved`
``ChangedStringNotificaton``
:guilabel:`String was changed`
``ComponentTranslatedNotificaton``
:guilabel:`Component was translated`
``LanguageTranslatedNotificaton``
:guilabel:`Language was translated`
``LastAuthorCommentNotificaton``
:guilabel:`Your translation received a comment`
``LicenseNotification``
:guilabel:`License was changed`
``LockNotification``
:guilabel:`Component was locked or unlocked`
``MentionCommentNotificaton``
:guilabel:`You were mentioned in a comment`
``MergeFailureNotification``
:guilabel:`Repository operation failed`
``NewAlertNotificaton``
:guilabel:`New alert emerged in a component`
``NewAnnouncementNotificaton``
:guilabel:`Announcement was published`
``NewCommentNotificaton``
:guilabel:`Comment was added`
``NewComponentNotificaton``
:guilabel:`New translation component was created`
``NewContributorNotificaton``
:guilabel:`Contributor made their first translation`
``NewStringNotificaton``
:guilabel:`String is available for translation`
``NewSuggestionNotificaton``
:guilabel:`Suggestion was added`
``NewTranslationNotificaton``
:guilabel:`New language was added or requested`
``ParseErrorNotification``
:guilabel:`Parse error occurred`
``PendingSuggestionsNotification``
:guilabel:`Pending suggestions exist`
``RepositoryNotification``
:guilabel:`Operation was performed in the repository`
``ToDoStringsNotification``
:guilabel:`Unfinished strings exist`
``TranslatedStringNotificaton``
:guilabel:`String was edited by user`
``TranslationActivitySummaryNotification``
:guilabel:`Translation activity summary`

.. AUTOGENERATED END: notification-handlers
71 changes: 0 additions & 71 deletions weblate/accounts/data.py

This file was deleted.

58 changes: 58 additions & 0 deletions weblate/accounts/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

from __future__ import annotations

from weblate.accounts.notifications import (
NotificationFrequency,
NotificationScope,
)

DEFAULT_ENABLE_AVATARS = True
DEFAULT_AVATAR_URL_PREFIX = "https://www.gravatar.com/"
DEFAULT_AVATAR_DEFAULT_IMAGE = "identicon"
Expand Down Expand Up @@ -43,3 +48,56 @@
(10, 3_600),
(50, 86_400),
)

DEFAULT_NOTIFICATIONS: list[tuple[int, int, str]] = [
(
NotificationScope.SCOPE_ALL,
NotificationFrequency.FREQ_INSTANT,
"MentionCommentNotificaton",
),
(
NotificationScope.SCOPE_WATCHED,
NotificationFrequency.FREQ_INSTANT,
"LastAuthorCommentNotificaton",
),
(
NotificationScope.SCOPE_WATCHED,
NotificationFrequency.FREQ_INSTANT,
"MentionCommentNotificaton",
),
(
NotificationScope.SCOPE_WATCHED,
NotificationFrequency.FREQ_INSTANT,
"NewAnnouncementNotificaton",
),
(
NotificationScope.SCOPE_WATCHED,
NotificationFrequency.FREQ_WEEKLY,
"TranslationActivitySummaryNotification",
),
(
NotificationScope.SCOPE_ADMIN,
NotificationFrequency.FREQ_INSTANT,
"MergeFailureNotification",
),
(
NotificationScope.SCOPE_ADMIN,
NotificationFrequency.FREQ_INSTANT,
"ParseErrorNotification",
),
(
NotificationScope.SCOPE_ADMIN,
NotificationFrequency.FREQ_INSTANT,
"NewTranslationNotificaton",
),
(
NotificationScope.SCOPE_ADMIN,
NotificationFrequency.FREQ_INSTANT,
"NewAlertNotificaton",
),
(
NotificationScope.SCOPE_ADMIN,
NotificationFrequency.FREQ_INSTANT,
"NewAnnouncementNotificaton",
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright © Michal Čihař <michal@weblate.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later

from __future__ import annotations

from typing import TYPE_CHECKING

from weblate.accounts.notifications import (
NOTIFICATIONS,
NotificationFrequency,
NotificationScope,
)
from weblate.utils.management.base import DocGeneratorCommand

if TYPE_CHECKING:
from collections.abc import Iterable

from weblate.accounts.notifications import (
Notification,
)


def sorted_handlers(
handlers: Iterable[type[Notification]],
) -> Iterable[type[Notification]]:
return sorted(handlers, key=lambda handler: handler.__name__)


class Command(DocGeneratorCommand):
help = "Lists notification scopes, frequencies and handlers"

def handle(self, *args, **options) -> None:
"""List notification scopes, frequencies and handlers."""
scope_content = []
for scope in NotificationScope:
scope_content.extend(
[f"``{scope.value}``", f" :guilabel:`{scope.label}`"]
)
self.add_section("notification-scopes", scope_content)

frequency_content = []
for frequency in NotificationFrequency:
frequency_content.extend(
[f"``{frequency.value}``", f" :guilabel:`{frequency.label}`"]
)
self.add_section("notification-frequencies", frequency_content)

handler_content = []
for handler in sorted_handlers(NOTIFICATIONS):
handler_content.extend(
[f"``{handler.__name__}``", f" :guilabel:`{handler.verbose}`"]
)
self.add_section("notification-handlers", handler_content)

self.write_sections(options.get("output"))
Loading
Loading