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 49 additions and 3 deletions
Showing only changes of commit 6ee84610b4 - Show all commits

View File

@ -1,5 +1,4 @@
""" """Django settings for blender_extensions project.
Django settings for blender_extensions project.
Generated by 'django-admin startproject' using Django 4.0.6. Generated by 'django-admin startproject' using Django 4.0.6.
@ -74,6 +73,7 @@ INSTALLED_APPS = [
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.flatpages', 'django.contrib.flatpages',
'django.contrib.humanize', 'django.contrib.humanize',
'actstream',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -320,3 +320,7 @@ EMAIL_HOST = os.getenv('EMAIL_HOST')
EMAIL_PORT = os.getenv('EMAIL_PORT', '587') EMAIL_PORT = os.getenv('EMAIL_PORT', '587')
EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER') EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD') EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD')
ACTSTREAM_SETTINGS = {
'MANAGER': 'actstream.managers.ActionManager',
}

View File

@ -7,3 +7,6 @@ class ExtensionsConfig(AppConfig):
def ready(self): def ready(self):
import extensions.signals # noqa: F401 import extensions.signals # noqa: F401
from actstream import registry
registry.register(self.get_model('Extension'))

View File

@ -12,6 +12,7 @@ click==8.1.3
colorhash==1.0.4 colorhash==1.0.4
Django==4.2.11 Django==4.2.11
dj-database-url==1.0.0 dj-database-url==1.0.0
django-activity-stream==2.0.0
django-admin-rangefilter==0.8.5 django-admin-rangefilter==0.8.5
django-background-tasks-updated @ git+https://projects.blender.org/infrastructure/django-background-tasks.git@2e60c4ec2fd1e7155bc3f041e0ea4875495a476b django-background-tasks-updated @ git+https://projects.blender.org/infrastructure/django-background-tasks.git@2e60c4ec2fd1e7155bc3f041e0ea4875495a476b
django-compat==1.0.15 django-compat==1.0.15

View File

@ -4,3 +4,8 @@ from django.apps import AppConfig
class ReviewersConfig(AppConfig): class ReviewersConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = 'django.db.models.BigAutoField'
name = 'reviewers' name = 'reviewers'
def ready(self) -> None:
from actstream import registry
registry.register(self.get_model('ApprovalActivity'))

View File

@ -1,5 +1,7 @@
import logging import logging
from actstream import action
from actstream.actions import follow
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.list import ListView from django.views.generic.list import ListView
from django.views.generic import DetailView, FormView from django.views.generic import DetailView, FormView
@ -76,4 +78,14 @@ 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
# if a user had unfollowed this extension before,
# we unfortunately are making them a follower again
follow(self.request.user, form.instance.extension, send_action=False)
action.send(
self.request.user,
verb=form.cleaned_data['type'], # FIXME map the type into a "registered" verb
action_object=form.instance,
target=form.instance.extension,
)
return super().form_valid(form) return super().form_valid(form)

View File

@ -7,3 +7,7 @@ class UsersConfig(AppConfig):
def ready(self) -> None: def ready(self) -> None:
import users.signals # noqa: F401 import users.signals # noqa: F401
from actstream import registry
from django.contrib.auth import get_user_model
registry.register(get_user_model())

View File

@ -1,8 +1,9 @@
from typing import Dict from typing import Dict
import logging import logging
from actstream.models import Action, followers
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db.models.signals import pre_save from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver from django.dispatch import receiver
from blender_id_oauth_client import signals as bid_signals from blender_id_oauth_client import signals as bid_signals
@ -35,3 +36,19 @@ def update_user(
bid.copy_avatar_from_blender_id(user=instance) bid.copy_avatar_from_blender_id(user=instance)
bid.copy_badges_from_blender_id(user=instance) bid.copy_badges_from_blender_id(user=instance)
@receiver(post_save, sender=Action)
def create_notification(sender: object, instance: Action, created: bool, **kwargs: object) -> None:
if not created:
return
if not instance.target:
return
audience = filter(lambda f: f != instance.actor, followers(instance.target))
for recipient in audience:
print(
f'create notification for {recipient}: ',
f'{instance.actor} {instance.verb} {instance.target}',
)