Notification emails #80

Merged
Oleg-Komarov merged 31 commits from notifications into main 2024-04-18 16:11:20 +02:00
7 changed files with 75 additions and 2 deletions
Showing only changes of commit 2a6f6c144b - Show all commits

View File

@ -4,3 +4,9 @@ from django.apps import AppConfig
class AbuseConfig(AppConfig): class AbuseConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = 'django.db.models.BigAutoField'
name = 'abuse' name = 'abuse'
def ready(self):
import extensions.signals # noqa: F401
from actstream import registry
registry.register(self.get_model('AbuseReport'))

View File

@ -34,6 +34,7 @@ class AbuseReport(CreatedModifiedMixin, TrackChangesMixin, SoftDeleteMixin, mode
) )
# NULL if the reporter is anonymous. # NULL if the reporter is anonymous.
# FIXME? make non-null
reporter = models.ForeignKey( reporter = models.ForeignKey(
User, User,
null=True, null=True,

44
abuse/signals.py Normal file
View File

@ -0,0 +1,44 @@
import logging
from actstream import action
from django.db.models.signals import post_save
from django.dispatch import receiver
from abuse.models import AbuseReport
from constants.activity import Verb
from constants.base import (
ABUSE_TYPE_EXTENSION,
ABUSE_TYPE_REVIEW,
ABUSE_TYPE_USER,
)
logger = logging.getLogger(__name__)
@receiver(post_save, sender=AbuseReport)
def create_action_from_report(
sender: object,
instance: AbuseReport,
created: bool,
**kwargs: object,
) -> None:
if not created:
return
if instance.type == ABUSE_TYPE_EXTENSION:
verb = Verb.REPORTED_EXTENSION
elif instance.type == ABUSE_TYPE_REVIEW:
verb = Verb.REPORTED_REVIEW
elif instance.type == ABUSE_TYPE_USER:
# TODO?
pass
else:
logger.warning("ignoring an unexpected AbuseReport type={instance.type}")
return
action.send(
instance.reporter,
verb=verb,
target=instance.extension,
action_object=instance,
)

10
constants/activity.py Normal file
View File

@ -0,0 +1,10 @@
class Verb:
SUBMITTED_FOR_REVIEW = 'submitted for review'
REPORTED_EXTENSION = 'reported extension'
REPORTED_REVIEW = 'reported review'
APPROVED = 'approved'
COMMENTED = 'commented'
REQUESTED_CHANGES = 'requested changes'
REQUESTED_REVIEW = 'requested review'

View File

@ -18,6 +18,7 @@ from .mixins import (
DraftVersionMixin, DraftVersionMixin,
DraftMixin, DraftMixin,
) )
from constants.activity import Verb
from extensions.forms import ( from extensions.forms import (
EditPreviewFormSet, EditPreviewFormSet,
AddPreviewFormSet, AddPreviewFormSet,
@ -405,7 +406,7 @@ class DraftExtensionView(
if 'submit_draft' in self.request.POST: if 'submit_draft' in self.request.POST:
action.send( action.send(
self.request.user, self.request.user,
verb='submitted for review', # FIXME map the type into a "registered" verb verb=Verb.SUBMITTED_FOR_REVIEW,
target=extension_form.instance, target=extension_form.instance,
) )
return super().form_valid(form) return super().form_valid(form)

View File

@ -7,6 +7,7 @@ from django.views.generic.list import ListView
from django.views.generic import DetailView, FormView from django.views.generic import DetailView, FormView
from django.shortcuts import reverse from django.shortcuts import reverse
from constants.activity import Verb
from files.models import File from files.models import File
from extensions.models import Extension from extensions.models import Extension
from reviewers.forms import CommentForm from reviewers.forms import CommentForm
@ -78,14 +79,23 @@ class ExtensionsApprovalFormView(LoginRequiredMixin, FormView):
form.instance.extension = Extension.objects.get(slug=self.kwargs['slug']) form.instance.extension = Extension.objects.get(slug=self.kwargs['slug'])
form.save() form.save()
self.approve_if_allowed(form) self.approve_if_allowed(form)
# automatically follow after ineraction # automatically follow after ineraction
# if a user had unfollowed this extension before, # if a user had unfollowed this extension before,
# we unfortunately are making them a follower again # we unfortunately are making them a follower again
follow(self.request.user, form.instance.extension, send_action=False) follow(self.request.user, form.instance.extension, send_action=False)
activity_type2verb = {
ApprovalActivity.ActivityType.APPROVED: Verb.APPROVED,
ApprovalActivity.ActivityType.AWAITING_CHANGES: Verb.REQUESTED_CHANGES,
ApprovalActivity.ActivityType.AWAITING_REVIEW: Verb.REQUESTED_REVIEW,
ApprovalActivity.ActivityType.COMMENT: Verb.COMMENTED,
}
action.send( action.send(
self.request.user, self.request.user,
verb=form.cleaned_data['type'], # FIXME map the type into a "registered" verb verb=activity_type2verb.get(form.cleaned_data['type']),
action_object=form.instance, action_object=form.instance,
target=form.instance.extension, target=form.instance.extension,
) )
return super().form_valid(form) return super().form_valid(form)

View File

@ -44,6 +44,7 @@ def create_notification(sender: object, instance: Action, created: bool, **kwarg
return return
if not instance.target: if not instance.target:
logger.warning('ignoring an unexpected Action without a target, verb={instance.verb}')
return return
audience = filter(lambda f: f != instance.actor, followers(instance.target)) audience = filter(lambda f: f != instance.actor, followers(instance.target))