Notification emails #80
@ -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'))
|
||||||
|
@ -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
44
abuse/signals.py
Normal 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
10
constants/activity.py
Normal 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'
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user