diff --git a/accounts/forms.py b/accounts/forms.py
index 026b12d..6d2b23e 100644
--- a/accounts/forms.py
+++ b/accounts/forms.py
@@ -7,7 +7,7 @@ from accounts.models import *
__all__ = ['UserForm', 'UserFormWithoutUsername', 'ProfileForm', 'GroupForm', 'TeamForm']
-user_fields=['first_name', 'last_name', 'email']
+user_fields=['first_name', 'last_name', 'email', 'notifications']
UserForm = modelform_factory(User,
fields=['username']+user_fields+['is_superuser'])
diff --git a/accounts/migrations/0003_user_notifications.py b/accounts/migrations/0003_user_notifications.py
new file mode 100644
index 0000000..a0df08c
--- /dev/null
+++ b/accounts/migrations/0003_user_notifications.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('accounts', '0002_auto_20140905_0229'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='user',
+ name='notifications',
+ field=models.IntegerField(choices=[(0, 'Never'), (1, 'Ignore my actions'), (2, 'Always')], default=1),
+ preserve_default=True,
+ ),
+ ]
diff --git a/accounts/models.py b/accounts/models.py
index 5f2913c..b586026 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -14,6 +14,18 @@ class User(AbstractUser):
class Meta:
ordering = ['username']
+ NOTIFICATIONS_NEVER = 0 # do not change: used as boolean value
+ NOTIFICATIONS_OTHERS = 1
+ NOTIFICATIONS_ALWAYS = 2
+ NOTIFICATIONS_CHOICES = (
+ (NOTIFICATIONS_NEVER, 'Never'),
+ (NOTIFICATIONS_OTHERS, 'Ignore my actions'),
+ (NOTIFICATIONS_ALWAYS, 'Always'),
+ )
+
+ notifications = models.IntegerField(choices=NOTIFICATIONS_CHOICES,
+ default=NOTIFICATIONS_OTHERS)
+
@property
def teams(self):
query = Q(groups__in=self.groups.all()) | Q(users=self)
diff --git a/accounts/tests.py b/accounts/tests.py
index 9c0da4d..1b454a1 100644
--- a/accounts/tests.py
+++ b/accounts/tests.py
@@ -20,6 +20,7 @@ class TestViews(TestCase):
self.assertEqual(response.status_code, 200)
response = self.client.post(reverse('profile'), {
'first_name': 'newfirstname',
+ 'notifications': User.NOTIFICATIONS_OTHERS,
}, follow=True)
self.assertRedirects(response, reverse('profile'))
self.assertContains(response, 'successfully')
@@ -46,6 +47,7 @@ class TestViews(TestCase):
user_count = User.objects.count()
response = self.client.post(reverse('add-user'), {
'username': 'newuser',
+ 'notifications': User.NOTIFICATIONS_OTHERS,
})
self.assertEqual(User.objects.count(), user_count + 1)
user = User.objects.get(username='newuser')
@@ -63,6 +65,7 @@ class TestViews(TestCase):
response = self.client.post(reverse('edit-user', args=[user.id]), {
'username': user.username,
'first_name': 'newfirstname',
+ 'notifications': User.NOTIFICATIONS_OTHERS,
})
self.assertRedirects(response, reverse('show-user', args=[user.id]))
user = User.objects.get(pk=user.pk)
diff --git a/templates/base_project.html b/templates/base_project.html
index 9b9b11a..5bbbcf4 100644
--- a/templates/base_project.html
+++ b/templates/base_project.html
@@ -20,7 +20,7 @@
{% endcomment %}
{% if request.user.is_authenticated %}
-{% if request.user.email and request.user in project.subscribers.all %}
+{% if request.user.email and request.user.notifications and request.user in project.subscribers.all %}
Unwatch
{% else %}
Watch
diff --git a/templates/tracker/issue_details.html b/templates/tracker/issue_details.html
index d9afa86..7f0df19 100644
--- a/templates/tracker/issue_details.html
+++ b/templates/tracker/issue_details.html
@@ -193,15 +193,13 @@
- {% if request.user.email and request.user in project.subscribers.all %}
+ {% if request.user.email and request.user.notifications and request.user in project.subscribers.all %}
Subscribed to the project
- {% else %}
- {% if request.user in issue.subscribers.all %}
+ {% elif request.user.notifications and request.user in issue.subscribers.all %}
Unsubscribe
{% else %}
Subscribe
{% endif %}
- {% endif %}
{% endif %}
diff --git a/tracker/notifications.py b/tracker/notifications.py
index 8d02f05..92df90f 100644
--- a/tracker/notifications.py
+++ b/tracker/notifications.py
@@ -9,6 +9,8 @@ if 'djcelery' in settings.INSTALLED_APPS:
else:
from django.core.mail import send_mass_mail
+from accounts.models import User
+
__all__ = [
'notify_new_issue', 'notify_new_comment',
@@ -31,9 +33,11 @@ def notify_new_issue(issue):
data = []
for dest in dests:
- if dest == issue.author:
+ if dest.notifications == User.NOTIFICATIONS_NEVER:
+ continue
+ if dest == issue.author \
+ and dest.notifications == User.NOTIFICATIONS_OTHERS:
continue
-
dest_addr = dest.email
if not dest_addr:
continue
@@ -87,9 +91,11 @@ def notify_event(event, template):
for dest in dests:
- if dest == event.author:
+ if dest.notifications == User.NOTIFICATIONS_NEVER:
+ continue
+ if dest == issue.author \
+ and dest.notifications == User.NOTIFICATIONS_OTHERS:
continue
-
dest_addr = dest.email
if not dest_addr:
continue
diff --git a/tracker/tests.py b/tracker/tests.py
index cfcf8e8..b97479a 100644
--- a/tracker/tests.py
+++ b/tracker/tests.py
@@ -127,9 +127,16 @@ class TestViews(TestCase):
response = self.client.get(reverse('unsubscribe-project', args=[project.name]), follow=True)
self.assertRedirects(response, reverse('list-issue', args=[project.name]))
self.assertContains(response, 'not subscribed to this project')
- response = self.client.get(reverse('subscribe-project', args=[project.name]))
- self.assertRedirects(response, reverse('profile'))
+ response = self.client.get(reverse('subscribe-project', args=[project.name]), follow=True)
+ self.assertRedirects(response, reverse('list-issue', args=[project.name]))
+ self.assertContains(response, 'must set an email')
user.email = 'user@example.com'
+ user.notifications = User.NOTIFICATIONS_NEVER
+ user.save()
+ response = self.client.get(reverse('subscribe-project', args=[project.name]), follow=True)
+ self.assertRedirects(response, reverse('list-issue', args=[project.name]))
+ self.assertContains(response, 'must enable notifications')
+ user.notifications = User.NOTIFICATIONS_OTHERS
user.save()
response = self.client.get(reverse('subscribe-project', args=[project.name]))
self.assertRedirects(response, reverse('list-issue', args=[project.name]))
@@ -343,9 +350,16 @@ class TestViews(TestCase):
response = self.client.get(reverse('unsubscribe-issue', args=[project.name, issue.id]), follow=True)
self.assertRedirects(response, reverse('show-issue', args=[project.name, issue.id]))
self.assertContains(response, 'not subscribed to this issue')
- response = self.client.get(reverse('subscribe-issue', args=[project.name, issue.id]))
- self.assertRedirects(response, reverse('profile'))
+ response = self.client.get(reverse('subscribe-issue', args=[project.name, issue.id]), follow=True)
+ self.assertRedirects(response, reverse('show-issue', args=[project.name, issue.id]))
+ self.assertContains(response, 'must set an email')
user.email = 'user@example.com'
+ user.notifications = User.NOTIFICATIONS_NEVER
+ user.save()
+ response = self.client.get(reverse('subscribe-issue', args=[project.name, issue.id]), follow=True)
+ self.assertRedirects(response, reverse('show-issue', args=[project.name, issue.id]))
+ self.assertContains(response, 'must enable notifications')
+ user.notifications = User.NOTIFICATIONS_OTHERS
user.save()
response = self.client.get(reverse('subscribe-issue', args=[project.name, issue.id]))
self.assertRedirects(response, reverse('show-issue', args=[project.name, issue.id]))
diff --git a/tracker/views.py b/tracker/views.py
index 5dd7ea3..3e9c918 100644
--- a/tracker/views.py
+++ b/tracker/views.py
@@ -4,6 +4,7 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
from django.conf import settings
+from django.core.urlresolvers import reverse
from tracker.forms import *
from tracker.models import *
@@ -130,10 +131,14 @@ def project_delete(request, project):
def project_subscribe(request, project):
if not request.user.email:
- messages.error(request, 'You must set an email address in order to receive notifications.')
- return redirect('profile')
-
- if project.subscribers.filter(pk=request.user.pk).exists():
+ messages.error(request, 'You must set an email address in your '
+ 'profile in order '
+ 'to watch this project.')
+ elif request.user.notifications == User.NOTIFICATIONS_NEVER:
+ messages.error(request, 'You must enable notifications in your '
+ 'profile in order '
+ 'to watch this project.')
+ elif project.subscribers.filter(pk=request.user.pk).exists():
messages.warning(request,
'You are already subscribed to this project.')
else:
@@ -544,10 +549,12 @@ def issue_subscribe(request, project, issue):
issue = get_object_or_404(Issue, project=project, id=issue)
if not request.user.email:
- messages.error(request, 'You must set an email address in order to receive notifications.')
- return redirect('profile')
-
- if issue.subscribers.filter(pk=request.user.pk).exists():
+ messages.error(request, 'You must set an email address in your '
+ 'profile to subscribe.')
+ elif request.user.notifications == User.NOTIFICATIONS_NEVER:
+ messages.error(request, 'You must enable notifications in your '
+ 'profile to subscribe.')
+ elif issue.subscribers.filter(pk=request.user.pk).exists():
messages.warning(request, 'You are already subscribed to this issue.')
else:
issue.subscribers.add(request.user)