Skip to content

Commit

Permalink
Use full URLs in notifications (mozilla#3468)
Browse files Browse the repository at this point in the history
Some notification types (suggestions available for review, suggestions have been reviewed and new contributor has joined the team) use relative URLs. That means they won't work in emails. This patch fixes that.

It also:
* Moves notification content from multiline strings to HTML templates.
* Moves management commands for sending notifications to the messaging module.
* Moves notification template files to the messaging module.
  • Loading branch information
mathjazz authored Dec 3, 2024
1 parent a6195e4 commit 6273ecb
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<ul>"

for (locale, project), (approved, rejected) in notifyData.items():
url = reverse(
"pontoon.translate",
kwargs={
"locale": locale.code,
"project": project.slug,
"resource": "all-resources",
},
)
list = map(str, approved + rejected)
url += "?list=" + ",".join(list)

# Filter out rejections where the author's own suggestion replaced the previous
rejected = [x for x in rejected if x 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"

desc += (
f'\n<li><a href="{url}">{project.name} ({locale.code})</a>: {msg}</li>'
)

return desc + "\n</ul>"

def handle(self, *args, **options):
"""
This command sends notifications about newly reviewed
Expand All @@ -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)
Expand All @@ -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",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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},
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<a href="{{ full_url('pontoon.contributors.contributor.username', user.username) }}">{{ user.name_or_email }}</a> has
made their first contribution to <a href="{{ full_url('pontoon.teams.team', locale.code) }}">{{ locale.name }} ({{
locale.code }})</a>.

Please welcome them to the team, and make sure to <a
href="{{ full_url('pontoon.translate', locale.code, project.slug, entity.resource.path) }}?string={{ entity.pk }}">review
their suggestions</a>.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Your suggestions have been reviewed:
<ul>
{% for notification in notifications %}
{% set locale = notification.locale %}
{% set project = notification.project %}
{% set ids = notification.ids %}
{% set msg = notification.msg %}
<li><a href="{{ full_url('pontoon.translate', locale.code, project.slug, 'all-resources') }}?list={{ ids }}">{{
project.name }} ({{ locale.code }})</a>: {{ msg }}</a></li>
{% endfor %}
</ul>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Unreviewed suggestions have been submitted for the following projects:
<ul>
{% for project_locale in project_locales %}
<li>
<a
href="{{ full_url('pontoon.translate', project_locale.locale.code, project_locale.project.slug, 'all-resources') }}?status=unreviewed">{{
project_locale.project.name }}
</a>
</li>
{% endfor %}
</ul>
Empty file.
Empty file.

This file was deleted.

42 changes: 10 additions & 32 deletions pontoon/translations/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = """
<a href="{user_href}">{user}</a> has made their first contribution to
<a href="{locale_href}">{locale} ({locale_code})</a>.
Please welcome them to the team, and make sure to
<a href="{review_href}">review their suggestions</a>.
""".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(
Expand All @@ -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",
)

Expand Down

0 comments on commit 6273ecb

Please sign in to comment.