users can disable notifications

This commit is contained in:
Élie Bouttier 2014-09-04 20:12:38 -07:00
parent 4a61d463bd
commit f420dd98ac
9 changed files with 82 additions and 22 deletions

View file

@ -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'])

View file

@ -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,
),
]

View file

@ -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)

View file

@ -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)

View file

@ -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 %}
<li><a href="{% url 'unsubscribe-project' project.name %}?next={{ request.get_full_path }}"><span class="glyphicon glyphicon-eye-close"></span> Unwatch</a></li>
{% else %}
<li><a href="{% url 'subscribe-project' project.name %}?next={{ request.get_full_path }}"><span class="glyphicon glyphicon-eye-open"></span> Watch</a></li>

View file

@ -193,15 +193,13 @@
</h5>
<div class="row">
<span style="display: inline-block; margin-left: 14px;"></span>
{% 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 %}
<a href="{% url 'unsubscribe-issue' project.name issue.id %}" class="btn btn-default"><span class="glyphicon glyphicon-eye-close"></span>&#160;Unsubscribe</a>
{% else %}
<a href="{% url 'subscribe-issue' project.name issue.id %}" class="btn btn-default"><span class="glyphicon glyphicon-eye-open"></span>&#160;Subscribe</a>
{% endif %}
{% endif %}
</div>
{% endif %}
</div>

View file

@ -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

View file

@ -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]))

View file

@ -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 '
'<a href="' + reverse('profile') + '">profile</a> in order '
'to watch this project.')
elif request.user.notifications == User.NOTIFICATIONS_NEVER:
messages.error(request, 'You must enable notifications in your '
'<a href="' + reverse('profile') + '">profile</a> 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 '
'<a href="' + reverse('profile') + '">profile</a> to subscribe.')
elif request.user.notifications == User.NOTIFICATIONS_NEVER:
messages.error(request, 'You must enable notifications in your '
'<a href="' + reverse('profile') + '">profile</a> 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)