From b6b7ff6d9b1c4622a3b815748047f9a9e5faa291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 31 Mar 2017 15:11:48 +0200 Subject: [PATCH] Adding live notifications configuration --- taiga/projects/notifications/admin.py | 2 +- .../0007_notifypolicy_live_notify_level.py | 21 ++++++++++++ taiga/projects/notifications/models.py | 1 + taiga/projects/notifications/serializers.py | 2 +- taiga/projects/notifications/services.py | 34 +++++++++++++------ 5 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 taiga/projects/notifications/migrations/0007_notifypolicy_live_notify_level.py diff --git a/taiga/projects/notifications/admin.py b/taiga/projects/notifications/admin.py index 1da3c97c..5e258235 100644 --- a/taiga/projects/notifications/admin.py +++ b/taiga/projects/notifications/admin.py @@ -32,5 +32,5 @@ class WatchedInline(GenericTabularInline): class NotifyPolicyInline(TabularInline): model = models.NotifyPolicy extra = 0 - readonly_fields = ("notify_level",) + readonly_fields = ("notify_level", "live_notify_level") raw_id_fields = ["user"] diff --git a/taiga/projects/notifications/migrations/0007_notifypolicy_live_notify_level.py b/taiga/projects/notifications/migrations/0007_notifypolicy_live_notify_level.py new file mode 100644 index 00000000..73a106cc --- /dev/null +++ b/taiga/projects/notifications/migrations/0007_notifypolicy_live_notify_level.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.6 on 2017-03-31 13:03 +from __future__ import unicode_literals + +from django.db import migrations, models +import taiga.projects.notifications.choices + + +class Migration(migrations.Migration): + + dependencies = [ + ('notifications', '0006_auto_20151103_0954'), + ] + + operations = [ + migrations.AddField( + model_name='notifypolicy', + name='live_notify_level', + field=models.SmallIntegerField(choices=[(taiga.projects.notifications.choices.NotifyLevel(1), 'Involved'), (taiga.projects.notifications.choices.NotifyLevel(2), 'All'), (taiga.projects.notifications.choices.NotifyLevel(3), 'None')], default=taiga.projects.notifications.choices.NotifyLevel(1)), + ), + ] diff --git a/taiga/projects/notifications/models.py b/taiga/projects/notifications/models.py index a8dc3e96..dbf67353 100644 --- a/taiga/projects/notifications/models.py +++ b/taiga/projects/notifications/models.py @@ -36,6 +36,7 @@ class NotifyPolicy(models.Model): project = models.ForeignKey("projects.Project", related_name="notify_policies") user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="notify_policies") notify_level = models.SmallIntegerField(choices=NOTIFY_LEVEL_CHOICES) + live_notify_level = models.SmallIntegerField(choices=NOTIFY_LEVEL_CHOICES, default=NotifyLevel.involved) created_at = models.DateTimeField(default=timezone.now) modified_at = models.DateTimeField() diff --git a/taiga/projects/notifications/serializers.py b/taiga/projects/notifications/serializers.py index 4387c19c..f55fa191 100644 --- a/taiga/projects/notifications/serializers.py +++ b/taiga/projects/notifications/serializers.py @@ -27,7 +27,7 @@ class NotifyPolicySerializer(serializers.ModelSerializer): class Meta: model = models.NotifyPolicy - fields = ('id', 'project', 'project_name', 'notify_level') + fields = ('id', 'project', 'project_name', 'notify_level', "live_notify_level") def get_project_name(self, obj): return obj.project.name diff --git a/taiga/projects/notifications/services.py b/taiga/projects/notifications/services.py index 2e597d36..eb676b92 100644 --- a/taiga/projects/notifications/services.py +++ b/taiga/projects/notifications/services.py @@ -55,7 +55,7 @@ def notify_policy_exists(project, user) -> bool: return qs.exists() -def create_notify_policy(project, user, level=NotifyLevel.involved): +def create_notify_policy(project, user, level=NotifyLevel.involved, live_level=NotifyLevel.all): """ Given a project and user, create notification policy for it. """ @@ -63,12 +63,13 @@ def create_notify_policy(project, user, level=NotifyLevel.involved): try: return model_cls.objects.create(project=project, user=user, - notify_level=level) + notify_level=level, + live_notify_level=live_level) except IntegrityError as e: raise exc.IntegrityError(_("Notify exists for specified user and project")) from e -def create_notify_policy_if_not_exists(project, user, level=NotifyLevel.involved): +def create_notify_policy_if_not_exists(project, user, level=NotifyLevel.involved, live_level=NotifyLevel.all): """ Given a project and user, create notification policy for it. """ @@ -76,7 +77,8 @@ def create_notify_policy_if_not_exists(project, user, level=NotifyLevel.involved try: result = model_cls.objects.get_or_create(project=project, user=user, - defaults={"notify_level": level}) + defaults={"notify_level": level, + "live_notify_level": live_level}) return result[0] except IntegrityError as e: raise exc.IntegrityError(_("Notify exists for specified user and project")) from e @@ -134,7 +136,7 @@ def _filter_notificable(user): return user.is_active and not user.is_system -def get_users_to_notify(obj, *, history=None, discard_users=None) -> list: +def get_users_to_notify(obj, *, history=None, discard_users=None, live=False) -> list: """ Get filtered set of users to notify for specified model instance and changer. @@ -146,6 +148,8 @@ def get_users_to_notify(obj, *, history=None, discard_users=None) -> list: def _check_level(project: object, user: object, levels: tuple) -> bool: policy = project.cached_notify_policy_for_user(user) + if live: + return policy.live_notify_level in levels return policy.notify_level in levels _can_notify_hard = partial(_check_level, project, @@ -235,7 +239,8 @@ def send_notifications(obj, *, history): if settings.CHANGE_NOTIFICATIONS_MIN_INTERVAL == 0: send_sync_notifications(notification.id) - for user in notify_users: + live_notify_users = get_users_to_notify(obj, history=history, discard_users=[notification.owner], live=True) + for user in live_notify_users: events.emit_live_notification_for_model(obj, user, history) @@ -420,7 +425,11 @@ def add_watcher(obj, user): project=obj.project) notify_policy, _ = apps.get_model("notifications", "NotifyPolicy").objects.get_or_create( - project=obj.project, user=user, defaults={"notify_level": NotifyLevel.involved}) + project=obj.project, + user=user, + defaults={"notify_level": NotifyLevel.involved, + "live_notify_level": NotifyLevel.involved} + ) return watched @@ -442,22 +451,25 @@ def remove_watcher(obj, user): qs.delete() -def set_notify_policy_level(notify_policy, notify_level): +def set_notify_policy_level(notify_policy, notify_level, live=False): """ Set notification level for specified policy. """ if notify_level not in [e.value for e in NotifyLevel]: raise exc.IntegrityError(_("Invalid value for notify level")) - notify_policy.notify_level = notify_level + if live: + notify_policy.live_notify_level = notify_level + else: + notify_policy.notify_level = notify_level notify_policy.save() -def set_notify_policy_level_to_ignore(notify_policy): +def set_notify_policy_level_to_ignore(notify_policy, live=False): """ Set notification level for specified policy. """ - set_notify_policy_level(notify_policy, NotifyLevel.none) + set_notify_policy_level(notify_policy, NotifyLevel.none, live=live) def make_ms_thread_index(msg_id, dt):