diff --git a/notifications/signals.py b/notifications/signals.py index 3de9da7d693992434fe902bc69c23086237f0910..af8be2f2807ae3a16573f49e4319d49b5a615dac 100644 --- a/notifications/signals.py +++ b/notifications/signals.py @@ -1,11 +1,34 @@ -from django.dispatch import Signal +from django.dispatch import receiver, Signal + +from .models import Notification + notify = Signal(providing_args=[ - 'recipient', 'actor', 'verb', 'action_object', 'target', 'description', - 'timestamp', 'level' + 'recipient', 'actor', 'verb', 'action_object', 'target', 'description', 'level' ]) +@receiver(notify) +def notify_receiver(sender, **kwargs): + if not type(kwargs['recipient']) == list: + recipient = [kwargs['recipient']] + else: + recipient = kwargs['recipient'] + + for user in recipient: + notification = Notification( + recipient=user, + actor=kwargs['actor'], + verb=kwargs['verb'], + action_object=kwargs.get('action_object'), + target=kwargs.get('target'), + description=kwargs.get('description'), + level=kwargs.get('level', 'info') + ) + notification.save() + print("Request finished!") + + # Basic working method to send a notification to a user using signals: # --- # from notifications.signals import notify diff --git a/notifications/views.py b/notifications/views.py index c5a5f196c220a847675116f10f1e72735689cd98..2716461f857a1b8188fda7eedee03aba75fc8fab 100644 --- a/notifications/views.py +++ b/notifications/views.py @@ -1,4 +1,5 @@ from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User from django.forms import model_to_dict from django.http import JsonResponse from django.shortcuts import get_object_or_404, redirect @@ -123,7 +124,10 @@ def live_notification_list(request): struct = model_to_dict(n) struct['slug'] = id2slug(n.id) if n.actor: - struct['actor'] = '{f} {l}'.format(f=n.actor.first_name, l=n.actor.last_name) + if isinstance(n.actor, User): + struct['actor'] = '{f} {l}'.format(f=n.actor.first_name, l=n.actor.last_name) + else: + struct['actor'] = str(n.actor) if n.target: struct['target'] = str(n.target) struct['forward_link'] = n.get_absolute_url() diff --git a/production/__init__.py b/production/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2418e502e4286e2cfcb4845419fa9fee9ea0e4cb 100644 --- a/production/__init__.py +++ b/production/__init__.py @@ -0,0 +1 @@ +default_app_config = 'production.apps.ProductionConfig' diff --git a/production/apps.py b/production/apps.py index d8fba60df00793d7fbaff3cf230a0ba937c9576a..549c6bd6bb6fac43a2edebae72c2e580cb66bb11 100644 --- a/production/apps.py +++ b/production/apps.py @@ -1,5 +1,14 @@ from django.apps import AppConfig +from django.db.models.signals import post_save class ProductionConfig(AppConfig): name = 'production' + + def ready(self): + super().ready() + + from .models import ProductionStream, ProductionEvent + from .signals import notify_new_stream, notify_new_event + post_save.connect(notify_new_stream, sender=ProductionStream) + post_save.connect(notify_new_event, sender=ProductionEvent) diff --git a/production/models.py b/production/models.py index 6b515e8c2b2f8c2c11e8396f6969210cb5554106..3d94ddaa295504fbb05aa1224937ee7436f2093b 100644 --- a/production/models.py +++ b/production/models.py @@ -5,12 +5,6 @@ from django.core.urlresolvers import reverse from .constants import PRODUCTION_STREAM_STATUS, PRODUCTION_STREAM_ONGOING, PRODUCTION_EVENTS from .managers import ProductionStreamManager, ProductionEventManager -from scipost.models import Contributor - - -############## -# Production # -############## class ProductionStream(models.Model): submission = models.OneToOneField('submissions.Submission', on_delete=models.CASCADE) @@ -22,7 +16,8 @@ class ProductionStream(models.Model): objects = ProductionStreamManager() def __str__(self): - return str(self.submission) + return '{arxiv}, {title}'.format(arxiv=self.submission.arxiv_identifier_w_vn_nr, + title=self.submission.title) def get_absolute_url(self): if self.status == PRODUCTION_STREAM_ONGOING: @@ -39,7 +34,7 @@ class ProductionEvent(models.Model): event = models.CharField(max_length=64, choices=PRODUCTION_EVENTS) comments = models.TextField(blank=True, null=True) noted_on = models.DateTimeField(default=timezone.now) - noted_by = models.ForeignKey(Contributor, on_delete=models.CASCADE) + noted_by = models.ForeignKey('scipost.Contributor', on_delete=models.CASCADE) duration = models.DurationField(blank=True, null=True) objects = ProductionEventManager() @@ -48,7 +43,7 @@ class ProductionEvent(models.Model): ordering = ['noted_on'] def __str__(self): - return '%s: %s' % (str(self.stream.submission), self.get_event_display()) + return '%s: %s' % (self.stream, self.get_event_display()) def get_absolute_url(self): return self.stream.get_absolute_url() diff --git a/production/signals.py b/production/signals.py new file mode 100644 index 0000000000000000000000000000000000000000..6a3102f9249f4a5a71f1a9603974a7590b1b4a31 --- /dev/null +++ b/production/signals.py @@ -0,0 +1,33 @@ +from django.contrib.auth.models import Group, User + +from notifications.signals import notify + + +def notify_new_stream(sender, instance, created, **kwargs): + """ + Notify the production team about a new Production Stream created. + """ + if created: + production_officers = User.objects.filter(groups__name='Production Officers') + editorial_college = Group.objects.get(name='Editorial College') + for user in production_officers: + notify.send(sender=sender, recipient=user, actor=editorial_college, verb=' accepted a submission. A new productionstream has been started.', target=instance) + + +def notify_new_event(sender, instance, created, **kwargs): + """ + Notify the production team about a new Production Event created. + """ + if created: + production_officers = User.objects.filter(groups__name='Production Officers') + for user in production_officers: + notify.send(sender=sender, recipient=user, actor=instance.noted_by.user, verb=' created a new Production Event ', target=instance) + + +def notify_stream_completed(sender, instance, **kwargs): + """ + Notify the production team about a Production Stream being completed. + """ + production_officers = User.objects.filter(groups__name='Production Officers') + for user in production_officers: + notify.send(sender=sender, recipient=user, actor=sender, verb=' marked Production Stream as completed.', target=instance) diff --git a/production/views.py b/production/views.py index 06c723470234e8d9acf18dddf4a589860526be55..517c09c116ecdd90c20cc0dcdc5ba199f194a202 100644 --- a/production/views.py +++ b/production/views.py @@ -13,6 +13,7 @@ from guardian.decorators import permission_required from .constants import PRODUCTION_STREAM_COMPLETED from .models import ProductionStream, ProductionEvent from .forms import ProductionEventForm +from .signals import notify_stream_completed from scipost.models import Contributor @@ -107,6 +108,8 @@ def mark_as_completed(request, stream_id): stream.status = PRODUCTION_STREAM_COMPLETED stream.closed = timezone.now() stream.save() + + notify_stream_completed(request.user, stream) return redirect(reverse('production:production')) diff --git a/scipost/models.py b/scipost/models.py index d6cac15fd9be45affe5c0bfbe9e9ba47ace74861..31ad4a40f60bb649e49f8819bd5fd17f9a286558 100644 --- a/scipost/models.py +++ b/scipost/models.py @@ -7,7 +7,6 @@ from django.core.urlresolvers import reverse from django.contrib.auth.models import User from django.contrib.postgres.fields import ArrayField from django.db import models -from django.template import Template, Context from django.utils import timezone from django_countries.fields import CountryField