diff --git a/pontoon/projects/management/commands/send_deadline_notifications.py b/pontoon/messaging/management/commands/send_deadline_notifications.py similarity index 100% rename from pontoon/projects/management/commands/send_deadline_notifications.py rename to pontoon/messaging/management/commands/send_deadline_notifications.py diff --git a/pontoon/projects/management/commands/send_review_notifications.py b/pontoon/messaging/management/commands/send_review_notifications.py similarity index 59% rename from pontoon/projects/management/commands/send_review_notifications.py rename to pontoon/messaging/management/commands/send_review_notifications.py index 5b417045ec..22103ea277 100644 --- a/pontoon/projects/management/commands/send_review_notifications.py +++ b/pontoon/messaging/management/commands/send_review_notifications.py @@ -5,7 +5,7 @@ from django.core.management.base import BaseCommand from django.db.models import Q -from django.urls import reverse +from django.template.loader import render_to_string from django.utils import timezone from pontoon.base.models import Translation @@ -14,37 +14,6 @@ class Command(BaseCommand): help = "Notify translators about their newly reviewed suggestions" - def get_description(self, notifyData): - desc = "Your suggestions have been reviewed:\n" - def handle(self, *args, **options): """ This command sends notifications about newly reviewed @@ -57,6 +26,7 @@ def handle(self, *args, **options): # (author) -> (locale, project) -> (approved, rejected) data = defaultdict(lambda: defaultdict(lambda: (list(), list()))) start = timezone.now() - timedelta(days=1) + for suggestion in Translation.objects.filter( (Q(approved_date__gt=start) | Q(rejected_date__gt=start)) & Q(user__profile__review_notifications=True) @@ -70,13 +40,41 @@ def handle(self, *args, **options): elif suggestion.rejected and suggestion.rejected_user != author: data[author][(locale, project)][1].append(suggestion.entity.pk) - for author, notifyData in data.items(): - desc = self.get_description(notifyData) + for author, notification_data in data.items(): + notifications = [] + + for (locale, project), (approved, rejected) in notification_data.items(): + # Filter out rejections where the author's own suggestion replaced the previous + rejected = [id for id in rejected if id not in approved] + + if len(approved) == 0: + msg = f"{len(rejected)} Rejected" + else: + msg = f"{len(approved)} Approved" + if len(rejected) > 0: + msg += f", {len(rejected)} Rejected" + + notifications.append( + { + "locale": locale, + "project": project, + "ids": ",".join(map(str, approved + rejected)), + "msg": msg, + } + ) + + description = render_to_string( + "messaging/notifications/suggestions_reviewed.html", + { + "notifications": notifications, + }, + ) + notify.send( sender=author, recipient=author, verb="has reviewed suggestions", - description=desc, + description=description, category="review", ) diff --git a/pontoon/projects/management/commands/send_suggestion_notifications.py b/pontoon/messaging/management/commands/send_suggestion_notifications.py similarity index 98% rename from pontoon/projects/management/commands/send_suggestion_notifications.py rename to pontoon/messaging/management/commands/send_suggestion_notifications.py index ae9014edff..a4b8ce29cc 100644 --- a/pontoon/projects/management/commands/send_suggestion_notifications.py +++ b/pontoon/messaging/management/commands/send_suggestion_notifications.py @@ -116,7 +116,7 @@ def handle(self, *args, **options): project_locales = data[recipient] description = render_to_string( - "projects/suggestion_notification.jinja", + "messaging/notifications/suggestions_submitted.html", {"project_locales": project_locales}, ) diff --git a/pontoon/messaging/templates/messaging/notifications/new_contributor.html b/pontoon/messaging/templates/messaging/notifications/new_contributor.html new file mode 100644 index 0000000000..5ce098268d --- /dev/null +++ b/pontoon/messaging/templates/messaging/notifications/new_contributor.html @@ -0,0 +1,7 @@ +{{ user.name_or_email }} has +made their first contribution to {{ locale.name }} ({{ + locale.code }}). + +Please welcome them to the team, and make sure to review + their suggestions. diff --git a/pontoon/messaging/templates/messaging/notifications/suggestions_reviewed.html b/pontoon/messaging/templates/messaging/notifications/suggestions_reviewed.html new file mode 100644 index 0000000000..01f1b95efe --- /dev/null +++ b/pontoon/messaging/templates/messaging/notifications/suggestions_reviewed.html @@ -0,0 +1,11 @@ +Your suggestions have been reviewed: + diff --git a/pontoon/messaging/templates/messaging/notifications/suggestions_submitted.html b/pontoon/messaging/templates/messaging/notifications/suggestions_submitted.html new file mode 100644 index 0000000000..285a7916ba --- /dev/null +++ b/pontoon/messaging/templates/messaging/notifications/suggestions_submitted.html @@ -0,0 +1,11 @@ +Unreviewed suggestions have been submitted for the following projects: + diff --git a/pontoon/projects/management/__init__.py b/pontoon/projects/management/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pontoon/projects/management/commands/__init__.py b/pontoon/projects/management/commands/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pontoon/projects/templates/projects/suggestion_notification.jinja b/pontoon/projects/templates/projects/suggestion_notification.jinja deleted file mode 100644 index 7110606a76..0000000000 --- a/pontoon/projects/templates/projects/suggestion_notification.jinja +++ /dev/null @@ -1,6 +0,0 @@ -Unreviewed suggestions have been submitted for the following projects: - diff --git a/pontoon/translations/views.py b/pontoon/translations/views.py index 2cb606cf70..726441cc03 100644 --- a/pontoon/translations/views.py +++ b/pontoon/translations/views.py @@ -5,7 +5,7 @@ from django.db import transaction from django.http import JsonResponse from django.shortcuts import get_object_or_404 -from django.urls import reverse +from django.template.loader import render_to_string from django.utils import timezone from django.utils.datastructures import MultiValueDictKeyError from django.views.decorators.http import require_POST @@ -128,36 +128,14 @@ def create_translation(request): # When user makes their first contribution to the team, notify team managers first_contribution = not project.system_project and user.is_new_contributor(locale) if first_contribution: - desc = """ - {user} has made their first contribution to - {locale} ({locale_code}). - Please welcome them to the team, and make sure to - review their suggestions. - """.format( - user=user.name_or_email, - user_href=reverse( - "pontoon.contributors.contributor.username", - kwargs={ - "username": user.username, - }, - ), - locale=locale.name, - locale_code=locale.code, - locale_href=reverse( - "pontoon.teams.team", - kwargs={ - "locale": locale.code, - }, - ), - review_href=reverse( - "pontoon.translate", - kwargs={ - "locale": locale.code, - "project": project.slug, - "resource": entity.resource.path, - }, - ) - + f"?string={entity.pk}", + description = render_to_string( + "messaging/notifications/new_contributor.html", + { + "entity": entity, + "locale": locale, + "project": project, + "user": user, + }, ) for manager in locale.managers_group.user_set.filter( @@ -167,7 +145,7 @@ def create_translation(request): sender=manager, recipient=manager, verb="has reviewed suggestions", # Triggers render of description only - description=desc, + description=description, category="new_contributor", )