diff --git a/accounts/admin.py b/accounts/admin.py
index 5a90ca6..250b009 100644
--- a/accounts/admin.py
+++ b/accounts/admin.py
@@ -1,6 +1,6 @@
from django.contrib import admin
-from accounts.models import Profile, Participation
+from accounts.models import Participation, Profile
admin.site.register(Profile) # FIXME extend user admin
admin.site.register(Participation)
diff --git a/accounts/apps.py b/accounts/apps.py
index ea7a982..f4628d2 100644
--- a/accounts/apps.py
+++ b/accounts/apps.py
@@ -5,4 +5,4 @@ class AccountsConfig(AppConfig):
name = 'accounts'
def ready(self):
- import accounts.signals
+ import accounts.signals # noqa
diff --git a/accounts/migrations/0004_remove_participation_review_topics.py b/accounts/migrations/0004_remove_participation_review_topics.py
new file mode 100644
index 0000000..a729052
--- /dev/null
+++ b/accounts/migrations/0004_remove_participation_review_topics.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-06-19 20:26
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('accounts', '0003_auto_20160615_2031'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='participation',
+ name='review_topics',
+ ),
+ ]
diff --git a/accounts/models.py b/accounts/models.py
index 8218988..6cbf174 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -6,9 +6,9 @@ from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.db import models
-from .utils import enum_to_choices, generate_user_uid
-from proposals.models import Topic
+from ponyconf.utils import enum_to_choices
+from .utils import generate_user_uid
__all__ = ['Profile']
@@ -41,9 +41,6 @@ class Participation(models.Model):
connector = models.IntegerField(choices=enum_to_choices(CONNECTORS), blank=True, null=True)
constraints = models.TextField(blank=True)
- # Participe as reviewer for theses topics
- review_topics = models.ManyToManyField(Topic, blank=True)
-
objects = models.Manager()
on_site = CurrentSiteManager()
diff --git a/accounts/signals.py b/accounts/signals.py
index 34bc1e8..653aa91 100644
--- a/accounts/signals.py
+++ b/accounts/signals.py
@@ -1,14 +1,14 @@
-from django.contrib.auth.signals import user_logged_in, user_logged_out
-from django.dispatch import receiver
from django.contrib import messages
+from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.contrib.sites.shortcuts import get_current_site
+from django.dispatch import receiver
from .models import Participation
@receiver(user_logged_in)
-def on_user_logged_in(sender, request, **kwargs):
- Participation.on_site.get_or_create(user=request.user, site=get_current_site(request))
+def on_user_logged_in(sender, request, user, **kwargs):
+ Participation.on_site.get_or_create(user=user, site=get_current_site(request))
messages.success(request, 'Welcome!', fail_silently=True) # FIXME
diff --git a/accounts/templates/admin/participant.html b/accounts/templates/admin/participant.html
new file mode 100644
index 0000000..aa97fca
--- /dev/null
+++ b/accounts/templates/admin/participant.html
@@ -0,0 +1,20 @@
+{% extends 'base.html' %}
+
+{% load bootstrap3 %}
+
+{% block admintab %}active{% endblock %}
+
+{% block content %}
+
+
+
+
+ - User
- {{ participation.user.profil }}
+ - Arrival
- {{ participation.arrival }}
+
+
+
+
+{% endblock %}
diff --git a/accounts/tests.py b/accounts/tests.py
index 7e63be5..ede365f 100644
--- a/accounts/tests.py
+++ b/accounts/tests.py
@@ -3,7 +3,9 @@ from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.test import TestCase
-from .models import Profile, Participation
+from ponyconf.utils import full_link
+
+from .models import Participation, Profile
ROOT_URL = 'accounts'
@@ -19,7 +21,7 @@ class AccountTests(TestCase):
self.client.login(username='b', password='b')
for model in [Profile, Participation]:
item = model.objects.first()
- self.assertEqual(self.client.get(item.get_absolute_url()).status_code, 200)
+ self.assertEqual(self.client.get(full_link(item)).status_code, 200)
self.assertTrue(str(item))
def test_views(self):
@@ -40,3 +42,12 @@ class AccountTests(TestCase):
self.assertEqual(user.email, 'b@newdomain.com')
self.assertEqual(user.profile.biography, 'tester')
self.client.logout()
+
+ def test_participant_views(self):
+ self.assertEqual(self.client.get(reverse('participants')).status_code, 302)
+ self.client.login(username='b', password='b')
+ self.assertEqual(self.client.get(reverse('participants')).status_code, 403)
+ b = User.objects.get(username='b')
+ b.is_superuser = True
+ b.save()
+ self.assertEqual(self.client.get(reverse('participants')).status_code, 200)
diff --git a/accounts/urls.py b/accounts/urls.py
index 189fb36..10d0622 100644
--- a/accounts/urls.py
+++ b/accounts/urls.py
@@ -8,5 +8,6 @@ urlpatterns = [
url(r'^profile$', views.profile, name='profile'),
url(r'^logout/$', auth_views.logout, {'next_page': settings.LOGOUT_REDIRECT_URL}, name='logout'),
url(r'^admin/participants/$', views.participants, name='participants'),
+ url(r'^admin/participant/(?P[\w.@+-]+)$', views.participant, name='show-participation'),
url(r'', include('django.contrib.auth.urls')),
]
diff --git a/accounts/utils.py b/accounts/utils.py
index 166ecba..f78f926 100644
--- a/accounts/utils.py
+++ b/accounts/utils.py
@@ -1,8 +1,5 @@
from django.utils.crypto import get_random_string
-def enum_to_choices(enum):
- return ((item.value, item.name) for item in list(enum))
-
def generate_user_uid():
return get_random_string(length=12, allowed_chars='abcdefghijklmnopqrstuvwxyz0123456789')
diff --git a/accounts/views.py b/accounts/views.py
index 136c42d..0cd9bfe 100644
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -1,9 +1,7 @@
from django.contrib import messages
from django.contrib.auth.decorators import login_required
-from django.shortcuts import render
from django.core.exceptions import PermissionDenied
-from django.contrib.sites.shortcuts import get_current_site
-from django.contrib.auth.models import User
+from django.shortcuts import get_object_or_404, render
from .forms import ProfileForm, UserForm
from .models import Participation
@@ -35,3 +33,8 @@ def participants(request):
participation_list = Participation.on_site.all()
return render(request, 'admin/participants.html', {'participation_list': participation_list})
+
+
+def participant(request, username):
+ return render(request, 'admin/participant.html',
+ {'participant': get_object_or_404(Participation, user__username=username)})
diff --git a/conversations/admin.py b/conversations/admin.py
index 4565006..431bad1 100644
--- a/conversations/admin.py
+++ b/conversations/admin.py
@@ -1,7 +1,6 @@
from django.contrib import admin
-from .models import ConversationWithParticipant, ConversationAboutTalk, Message
-
+from .models import ConversationAboutTalk, ConversationWithParticipant, Message
admin.site.register(ConversationWithParticipant)
admin.site.register(ConversationAboutTalk)
diff --git a/conversations/apps.py b/conversations/apps.py
index 73892cf..7fc0e2b 100644
--- a/conversations/apps.py
+++ b/conversations/apps.py
@@ -5,4 +5,4 @@ class ConversationsConfig(AppConfig):
name = 'conversations'
def ready(self):
- import conversations.signals
+ import conversations.signals # noqa
diff --git a/conversations/emails.py b/conversations/emails.py
index e76052c..c7f2ff0 100644
--- a/conversations/emails.py
+++ b/conversations/emails.py
@@ -1,20 +1,18 @@
-from django.shortcuts import get_object_or_404
-from django.core.exceptions import PermissionDenied
-from django.views.decorators.http import require_http_methods
-from django.conf import settings
-from django.http import HttpResponse
-from django.views.decorators.csrf import csrf_exempt
-from django.http import Http404
-from django.contrib.auth.models import User
-from django.core.mail import mail_admins
-
-from .utils import hexdigest_sha256
-from .models import Message
-
import email
import re
from sys import version_info as python_version
+from django.conf import settings
+from django.contrib.auth.models import User
+from django.core.exceptions import PermissionDenied
+from django.http import Http404, HttpResponse
+from django.shortcuts import get_object_or_404
+from django.views.decorators.csrf import csrf_exempt
+from django.views.decorators.http import require_http_methods
+
+from .models import Message
+from .utils import hexdigest_sha256
+
@csrf_exempt
@require_http_methods(["POST"])
@@ -22,14 +20,14 @@ def email_recv(request):
if not hasattr(settings, 'REPLY_EMAIL') \
or not hasattr(settings, 'REPLY_KEY'):
- return HttpResponse(status=501) # Not Implemented
+ return HttpResponse(status=501) # Not Implemented
key = request.POST.get('key')
if key != settings.REPLY_KEY:
raise PermissionDenied
if 'email' not in request.FILES:
- raise HttpResponse(status=400) # Bad Request
+ raise HttpResponse(status=400) # Bad Request
msg = request.FILES['email']
if python_version < (3,):
@@ -37,10 +35,6 @@ def email_recv(request):
else:
msg = email.message_from_bytes(msg.read())
- mfrom = msg.get('From')
- mto = msg.get('To')
- subject = msg.get('Subject')
-
if msg.is_multipart():
msgs = msg.get_payload()
for m in msgs:
@@ -63,11 +57,11 @@ def email_recv(request):
regexp = '^%s\+(?P[a-z0-9]{12})(?P[a-z0-9]{60})(?P[a-z0-9]{12})@%s$' % (name, domain)
p = re.compile(regexp)
m = None
- for _mto in map(lambda x: x.strip(), mto.split(',')):
+ for _mto in map(lambda x: x.strip(), msg.get('To').split(',')):
m = p.match(_mto)
if m:
break
- if not m: # no one matches
+ if not m: # no one matches
raise Http404
author = get_object_or_404(User, profile__email_token=m.group('dest'))
diff --git a/conversations/forms.py b/conversations/forms.py
index 92c6b8e..d263b9f 100644
--- a/conversations/forms.py
+++ b/conversations/forms.py
@@ -2,9 +2,5 @@ from django.forms.models import modelform_factory
from .models import Message
-
MessageForm = modelform_factory(Message,
- fields=['content'])
-
-
-
+ fields=['content'])
diff --git a/conversations/models.py b/conversations/models.py
index a9e7568..1fe2efa 100644
--- a/conversations/models.py
+++ b/conversations/models.py
@@ -1,13 +1,14 @@
-from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
+from django.db import models
-from .utils import generate_message_token, notify_by_email
from accounts.models import Participation
from proposals.models import Talk
+from .utils import generate_message_token, notify_by_email
+
class Message(models.Model):
@@ -27,6 +28,9 @@ class Message(models.Model):
def __str__(self):
return "Message from %s" % self.author
+ def get_absolute_url(self):
+ return self.conversation.get_absolute_url()
+
class Conversation(models.Model):
@@ -36,7 +40,7 @@ class Conversation(models.Model):
abstract = True
-class ConversationWithParticipant(Conversation):
+class ConversationWithParticipant(Conversation):
participation = models.OneToOneField(Participation, related_name='conversation')
messages = GenericRelation(Message)
@@ -44,12 +48,15 @@ class ConversationWithParticipant(Conversation):
uri = 'inbox'
template = 'participant_message'
- def get_site(self):
- return self.participation.site
-
def __str__(self):
return "Conversation with %s" % self.participation.user
+ def get_absolute_url(self):
+ return reverse('conversation', kwargs={'username': self.participation.user.username})
+
+ def get_site(self):
+ return self.participation.site
+
def new_message(self, message):
site = self.get_site()
subject = '[%s] Conversation with %s' % (site.name, self.participation.user.profile)
@@ -84,12 +91,15 @@ class ConversationAboutTalk(Conversation):
uri = 'inbox'
template = 'talk_message'
- def get_site(self):
- return self.talk.site
-
def __str__(self):
return "Conversation about %s" % self.talk.title
+ def get_absolute_url(self):
+ self.talk.get_absolute_url()
+
+ def get_site(self):
+ return self.talk.site
+
def new_message(self, message):
site = self.get_site()
first = self.messages.first()
diff --git a/conversations/signals.py b/conversations/signals.py
index 561b29f..2103a07 100644
--- a/conversations/signals.py
+++ b/conversations/signals.py
@@ -1,15 +1,12 @@
-from django.db.models.signals import post_save, m2m_changed
-from django.dispatch import receiver
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django.contrib.sites.shortcuts import get_current_site
from django.contrib.auth.models import User
+from django.db.models.signals import post_save
+from django.dispatch import receiver
-from .models import ConversationWithParticipant, ConversationAboutTalk, Message
-from .utils import notify_by_email
-from proposals.models import Talk, Topic
-from proposals.signals import new_talk
from accounts.models import Participation
+from proposals.models import Talk
+from proposals.signals import new_talk
+
+from .models import ConversationAboutTalk, ConversationWithParticipant, Message
@receiver(post_save, sender=Participation, dispatch_uid="Create ConversationWithParticipant")
@@ -31,15 +28,14 @@ def create_conversation_about_talk(sender, instance, created, **kwargs):
@receiver(new_talk, dispatch_uid="Notify new talk")
def notify_new_talk(sender, instance, **kwargs):
# Subscribe reviewer for these topics to conversations
- topics = instance.topics.all()
- reviewers = User.objects.filter(participation__review_topics=topics).all()
+ reviewers = User.objects.filter(participation__topic__talk=instance)
instance.conversation.subscribers.add(*reviewers)
for user in instance.speakers.all():
participation = Participation.on_site.get(user=user)
participation.conversation.subscribers.add(*reviewers)
# Notification of this new talk
message = Message(conversation=instance.conversation, author=instance.proposer,
- content='The talk has been proposed.')
+ content='The talk has been proposed.')
message.save()
diff --git a/conversations/tests.py b/conversations/tests.py
index e860168..8a87855 100644
--- a/conversations/tests.py
+++ b/conversations/tests.py
@@ -1,27 +1,29 @@
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
+from django.core.urlresolvers import reverse
from django.test import TestCase
from accounts.models import Participation
-from .models import Conversation, Message
-from .utils import get_reply_addr
+from .models import ConversationWithParticipant, Message
class ConversationTests(TestCase):
def setUp(self):
- a, b = (User.objects.create_user(guy, email='%s@example.org' % guy, password=guy) for guy in 'ab')
- participation = Participation.objects.create(user=a, site=Site.objects.first())
- conversation = Conversation.objects.create(speaker=speaker)
- Message.objects.create(token='pipo', conversation=conversation, author=a, content='allo')
+ a, b, c = (User.objects.create_user(guy, email='%s@example.org' % guy, password=guy) for guy in 'abc')
+ pa, _ = Participation.objects.get_or_create(user=a, site=Site.objects.first())
+ conversation, _ = ConversationWithParticipant.objects.get_or_create(participation=pa)
+ Message.objects.create(content='allo', conversation=conversation, author=b)
def test_models(self):
- self.assertEqual(str(Conversation.objects.first()), 'Conversation with a')
- self.assertEqual(str(Message.objects.first()), 'Message from a')
+ self.assertEqual(str(ConversationWithParticipant.objects.first()), 'Conversation with a')
+ self.assertEqual(str(Message.objects.first()), 'Message from b')
def test_views(self):
- self.assertEqual(self.client.get(Conversation.objects.first().get_absolute_url()).status_code, 200)
-
- def test_utils(self):
- ret = ['pipo+ 11183704aabfddb3d694ff4f24c0daadfa2d8d2193336e345f92a6fd3ffb6a19e7@example.org']
- self.assertEqual(get_reply_addr(1, User.objects.first()), ret)
+ url = ConversationWithParticipant.objects.first().get_absolute_url()
+ self.assertEqual(self.client.get(url).status_code, 302)
+ self.client.login(username='c', password='c')
+ self.assertEqual(self.client.get(url).status_code, 403)
+ self.assertEqual(self.client.get(reverse('correspondents')).status_code, 200)
+ self.assertEqual(self.client.get(reverse('inbox')).status_code, 200)
+ self.client.post(reverse('inbox'), {'content': 'coucou'})
diff --git a/conversations/urls.py b/conversations/urls.py
index f9cd5e9..67b148b 100644
--- a/conversations/urls.py
+++ b/conversations/urls.py
@@ -1,7 +1,6 @@
from django.conf.urls import url
-from conversations import views, emails
-
+from conversations import emails, views
urlpatterns = [
url(r'^recv/$', emails.email_recv),
diff --git a/conversations/utils.py b/conversations/utils.py
index 23d1b33..1a48cda 100644
--- a/conversations/utils.py
+++ b/conversations/utils.py
@@ -1,11 +1,11 @@
-from django.conf import settings
-from django.utils.crypto import get_random_string
-from django.template.loader import render_to_string
-from django.core.mail import EmailMultiAlternatives
-from django.core import mail
-
import hashlib
+from django.conf import settings
+from django.core import mail
+from django.core.mail import EmailMultiAlternatives
+from django.template.loader import render_to_string
+from django.utils.crypto import get_random_string
+
def hexdigest_sha256(*args):
@@ -47,9 +47,7 @@ def notify_by_email(template, data, subject, sender, dests, message_id, ref=None
email=settings.DEFAULT_FROM_EMAIL)
# Generating headers
- headers = {
- 'Message-ID': "<%s.%s>" % (message_id, settings.DEFAULT_FROM_EMAIL),
- }
+ headers = {'Message-ID': "<%s.%s>" % (message_id, settings.DEFAULT_FROM_EMAIL)}
if ref:
# This email reference a previous one
headers.update({
@@ -68,7 +66,8 @@ def notify_by_email(template, data, subject, sender, dests, message_id, ref=None
messages = []
for subject, message, from_email, dest_emails, reply_to, headers in mails:
text_message, html_message = message
- msg = EmailMultiAlternatives(subject, text_message, from_email, dest_emails, reply_to=reply_to, headers=headers)
+ msg = EmailMultiAlternatives(subject, text_message, from_email, dest_emails, reply_to=reply_to,
+ headers=headers)
msg.attach_alternative(html_message, 'text/html')
messages += [msg]
with mail.get_connection() as connection:
diff --git a/conversations/views.py b/conversations/views.py
index dcc5d1d..5df8c50 100644
--- a/conversations/views.py
+++ b/conversations/views.py
@@ -1,15 +1,13 @@
-from django.shortcuts import render
-from django.shortcuts import get_object_or_404, redirect, render
-from django.contrib.sites.shortcuts import get_current_site
-from django.contrib.auth.decorators import login_required
from django.contrib import messages
-from django.core.exceptions import PermissionDenied
+from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
+from django.contrib.sites.shortcuts import get_current_site
+from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
-
+from django.shortcuts import get_object_or_404, redirect, render
from accounts.models import Participation
-from .models import Message
+
from .forms import MessageForm
@@ -64,8 +62,7 @@ def subscribe(request, username):
# TODO check admin
- participation = get_object_or_404(Participation, user__username=username,
- site=get_current_site(request))
+ participation = get_object_or_404(Participation, user__username=username, site=get_current_site(request))
participation.conversation.subscribers.add(request.user)
messages.success(request, 'Subscribed.')
@@ -79,8 +76,7 @@ def unsubscribe(request, username):
# TODO check admin
- participation = get_object_or_404(Participation, user__username=username,
- site=get_current_site(request))
+ participation = get_object_or_404(Participation, user__username=username, site=get_current_site(request))
participation.conversation.subscribers.remove(request.user)
messages.success(request, 'Unsubscribed.')
diff --git a/ponyconf/settings.py b/ponyconf/settings.py
index 63845e2..7b1551d 100644
--- a/ponyconf/settings.py
+++ b/ponyconf/settings.py
@@ -179,4 +179,4 @@ BOOTSTRAP3 = {
AUTHENTICATION_BACKENDS = ['yeouia.backends.YummyEmailOrUsernameInsensitiveAuth']
LOGOUT_REDIRECT_URL = 'home'
-ACCOUNT_ACTIVATION_DAYS = 7 # django-registration
+ACCOUNT_ACTIVATION_DAYS = 7 # django-registration
diff --git a/ponyconf/utils.py b/ponyconf/utils.py
new file mode 100644
index 0000000..dd7244b
--- /dev/null
+++ b/ponyconf/utils.py
@@ -0,0 +1,10 @@
+from django.contrib.sites.shortcuts import get_current_site
+
+
+def enum_to_choices(enum):
+ return ((item.value, item.name) for item in list(enum))
+
+
+def full_link(obj, request=None):
+ protocol = 'https' if request is None or request.is_secure() else 'http'
+ return '%s://%s%s' % (protocol, get_current_site(request), obj.get_absolute_url())
diff --git a/proposals/migrations/0002_topic_reviewers.py b/proposals/migrations/0002_topic_reviewers.py
new file mode 100644
index 0000000..be206db
--- /dev/null
+++ b/proposals/migrations/0002_topic_reviewers.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-06-19 20:26
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('accounts', '0004_remove_participation_review_topics'),
+ ('proposals', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='topic',
+ name='reviewers',
+ field=models.ManyToManyField(blank=True, to='accounts.Participation'),
+ ),
+ ]
diff --git a/proposals/models.py b/proposals/models.py
index 7abec75..7b27345 100644
--- a/proposals/models.py
+++ b/proposals/models.py
@@ -8,8 +8,8 @@ from django.db import models
from autoslug import AutoSlugField
-from accounts.utils import enum_to_choices
-
+from accounts.models import Participation
+from ponyconf.utils import enum_to_choices
__all__ = ['Topic', 'Talk', 'Speech']
@@ -19,6 +19,8 @@ class Topic(models.Model):
name = models.CharField(max_length=128, verbose_name='Name', unique=True)
slug = AutoSlugField(populate_from='name', unique=True)
+ reviewers = models.ManyToManyField(Participation, blank=True)
+
def __str__(self):
return self.name
@@ -54,13 +56,13 @@ class Talk(models.Model):
return True
if user == self.proposer:
return True
- if user in talk.speakers.all():
+ if user in self.speakers.all():
return True
try:
participation = Participation.on_site.get(user=user)
except Participation.DoesNotExists:
return False
- return self.topics.filter(pk=participation.review_topics.pk).exists()
+ return self.topics.filter(reviewers=participation).exists()
class Speech(models.Model):
diff --git a/proposals/signals.py b/proposals/signals.py
index 3713338..ddf438a 100644
--- a/proposals/signals.py
+++ b/proposals/signals.py
@@ -1,4 +1,3 @@
from django.dispatch import Signal
-
new_talk = Signal(providing_args=["sender", "instance"])
diff --git a/proposals/tests.py b/proposals/tests.py
index e0b442b..1cefa5b 100644
--- a/proposals/tests.py
+++ b/proposals/tests.py
@@ -1,20 +1,25 @@
from django.contrib.auth.models import User
+from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.test import TestCase
-from .models import Talk, Topic, Speech
+from accounts.models import Participation
+
+from .models import Speech, Talk, Topic
class ProposalsTests(TestCase):
def setUp(self):
- for guy in 'ab':
- User.objects.create_user(guy, email='%s@example.org' % guy, password=guy)
- Topic.objects.create(name='pipo')
+ a, b, c = (User.objects.create_user(guy, email='%s@example.org' % guy, password=guy) for guy in 'abc')
+ Participation.objects.create(user=a, site=Site.objects.first())
+ Topic.objects.create(name='topipo')
+ c.is_superuser = True
+ c.save()
def test_everything(self):
# talk-edit
self.client.login(username='a', password='a')
- self.client.post(reverse('add-talk'), {'title': 'super talk', 'description': 'super', 'event': 1})
+ self.client.post(reverse('add-talk'), {'title': 'super talk', 'description': 'super', 'event': 1, 'topics': 1})
self.assertEqual(str(Talk.on_site.first()), 'super talk')
self.client.post(reverse('edit-talk', kwargs={'talk': 'super-talk'}),
{'title': 'mega talk', 'description': 'mega', 'event': 1})
@@ -41,3 +46,9 @@ class ProposalsTests(TestCase):
self.assertEqual(self.client.get(item.get_absolute_url()).status_code, 200)
self.assertTrue(str(item))
self.assertEqual(Speech.objects.first().username(), 'a')
+
+ # Talkis_editable_by
+ a, b, c = User.objects.all()
+ self.assertTrue(talk.is_editable_by(c))
+ Speech.objects.create(talk=talk, speaker=b, order=2)
+ self.assertTrue(talk.is_editable_by(b))
diff --git a/proposals/views.py b/proposals/views.py
index 69f5745..c262a48 100644
--- a/proposals/views.py
+++ b/proposals/views.py
@@ -9,6 +9,7 @@ from django.views.generic import DetailView, ListView
from proposals.forms import TalkForm
from proposals.models import Speech, Talk, Topic
+
from .signals import new_talk
@@ -48,7 +49,7 @@ def talk_edit(request, talk=None):
talk = get_object_or_404(Talk, slug=talk)
if talk.site != get_current_site(request):
raise PermissionDenied()
- if not talk.has_perm(request.user):
+ if not talk.is_editable_by(request.user):
raise PermissionDenied()
form = TalkForm(request.POST or None, instance=talk)
if request.method == 'POST' and form.is_valid():
@@ -72,10 +73,9 @@ def talk_edit(request, talk=None):
class TalkDetail(LoginRequiredMixin, DetailView):
queryset = Talk.on_site.all()
+
def get_context_data(self, **kwargs):
- context = super(TalkDetail, self).get_context_data(**kwargs)
- context['edit_perm'] = self.object.is_editable_by(self.request.user)
- return context
+ return super().get_context_data(edit_perm=self.object.is_editable_by(self.request.user), **kwargs)
class TopicList(LoginRequiredMixin, ListView):