extensions-website/notifications/signals.py
Oleg Komarov 012845c712 Abuse reports: moderator form for resolving/dismissing + notification (#173)
It is possible to submit the form update the note and status multiple times,
e.g. a report that was initially dismissed, can be resolved later.
Each valid form submission will generate a notification for the reporter.

Once a note is saved, it becomes visible to the reporter.

The migration in this PR replaces the AbuseReport status Confirmed(=2)
that wasn't used in production with Dismissed(=2). Assuming that this is
a minor sin while the project is still in beta.

Reviewed-on: #173
Reviewed-by: Anna Sirota <annasirota@noreply.localhost>
2024-06-07 17:04:52 +02:00

61 lines
1.8 KiB
Python

import logging
from actstream.models import Action, Follow
from django.contrib.auth import get_user_model
from django.db.models.signals import post_save
from django.dispatch import receiver
from constants.activity import Flag, Verb
from notifications.models import Notification
logger = logging.getLogger(__name__)
VERB2FLAGS = {
Verb.APPROVED: [Flag.AUTHOR, Flag.REVIEWER],
Verb.COMMENTED: [Flag.AUTHOR, Flag.REVIEWER],
Verb.DISMISSED_ABUSE_REPORT: [Flag.REPORTER],
Verb.RATED_EXTENSION: [Flag.AUTHOR],
Verb.REPORTED_EXTENSION: [Flag.MODERATOR],
Verb.REPORTED_RATING: [Flag.MODERATOR],
Verb.REQUESTED_CHANGES: [Flag.AUTHOR, Flag.REVIEWER],
Verb.REQUESTED_REVIEW: [Flag.MODERATOR, Flag.REVIEWER],
Verb.RESOLVED_ABUSE_REPORT: [Flag.REPORTER],
Verb.UPLOADED_NEW_VERSION: [],
}
@receiver(post_save, sender=Action)
def _create_notifications(
sender: object,
instance: Action,
created: bool,
raw: bool,
**kwargs: object,
) -> None:
if raw:
return
if not created:
return
if not instance.target:
logger.warning(f'ignoring an unexpected Action without a target, verb={instance.verb}')
return
notifications = []
flags = VERB2FLAGS.get(instance.verb, None)
if flags is None:
logger.warning(f'no follower flags for verb={instance.verb}, nobody will be notified')
return
followers = Follow.objects.for_object(instance.target).filter(flag__in=flags)
user_ids = followers.values_list('user', flat=True)
followers = get_user_model().objects.filter(id__in=user_ids)
for recipient in followers:
if recipient == instance.actor:
continue
notifications.append(Notification(recipient=recipient, action=instance))
if len(notifications) > 0:
Notification.objects.bulk_create(notifications)