Fix stuffs.

Maybe breaks other things, don't know, can't test mails for now.
This commit is contained in:
Guilhem Saurel 2016-06-20 01:00:08 +02:00
parent f4b7eb629d
commit b4490c8eee
27 changed files with 202 additions and 120 deletions

View File

@ -1,6 +1,6 @@
from django.contrib import admin 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(Profile) # FIXME extend user admin
admin.site.register(Participation) admin.site.register(Participation)

View File

@ -5,4 +5,4 @@ class AccountsConfig(AppConfig):
name = 'accounts' name = 'accounts'
def ready(self): def ready(self):
import accounts.signals import accounts.signals # noqa

View File

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

View File

@ -6,9 +6,9 @@ from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db import models from django.db import models
from .utils import enum_to_choices, generate_user_uid from ponyconf.utils import enum_to_choices
from proposals.models import Topic
from .utils import generate_user_uid
__all__ = ['Profile'] __all__ = ['Profile']
@ -41,9 +41,6 @@ class Participation(models.Model):
connector = models.IntegerField(choices=enum_to_choices(CONNECTORS), blank=True, null=True) connector = models.IntegerField(choices=enum_to_choices(CONNECTORS), blank=True, null=True)
constraints = models.TextField(blank=True) constraints = models.TextField(blank=True)
# Participe as reviewer for theses topics
review_topics = models.ManyToManyField(Topic, blank=True)
objects = models.Manager() objects = models.Manager()
on_site = CurrentSiteManager() on_site = CurrentSiteManager()

View File

@ -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 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.contrib.sites.shortcuts import get_current_site
from django.dispatch import receiver
from .models import Participation from .models import Participation
@receiver(user_logged_in) @receiver(user_logged_in)
def on_user_logged_in(sender, request, **kwargs): def on_user_logged_in(sender, request, user, **kwargs):
Participation.on_site.get_or_create(user=request.user, site=get_current_site(request)) Participation.on_site.get_or_create(user=user, site=get_current_site(request))
messages.success(request, 'Welcome!', fail_silently=True) # FIXME messages.success(request, 'Welcome!', fail_silently=True) # FIXME

View File

@ -0,0 +1,20 @@
{% extends 'base.html' %}
{% load bootstrap3 %}
{% block admintab %}active{% endblock %}
{% block content %}
<div class="page-header">
<h1>Participant: {{ participant }}</h1>
</div>
<dl class="dl-horizontal">
<dt>User</dt><dd>{{ participation.user.profil }}</dd>
<dt>Arrival</dt><dd>{{ participation.arrival }}</dd>
</dl>
<!-- TODO -->
{% endblock %}

View File

@ -3,7 +3,9 @@ from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test import TestCase from django.test import TestCase
from .models import Profile, Participation from ponyconf.utils import full_link
from .models import Participation, Profile
ROOT_URL = 'accounts' ROOT_URL = 'accounts'
@ -19,7 +21,7 @@ class AccountTests(TestCase):
self.client.login(username='b', password='b') self.client.login(username='b', password='b')
for model in [Profile, Participation]: for model in [Profile, Participation]:
item = model.objects.first() 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)) self.assertTrue(str(item))
def test_views(self): def test_views(self):
@ -40,3 +42,12 @@ class AccountTests(TestCase):
self.assertEqual(user.email, 'b@newdomain.com') self.assertEqual(user.email, 'b@newdomain.com')
self.assertEqual(user.profile.biography, 'tester') self.assertEqual(user.profile.biography, 'tester')
self.client.logout() 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)

View File

@ -8,5 +8,6 @@ urlpatterns = [
url(r'^profile$', views.profile, name='profile'), url(r'^profile$', views.profile, name='profile'),
url(r'^logout/$', auth_views.logout, {'next_page': settings.LOGOUT_REDIRECT_URL}, name='logout'), 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/participants/$', views.participants, name='participants'),
url(r'^admin/participant/(?P<username>[\w.@+-]+)$', views.participant, name='show-participation'),
url(r'', include('django.contrib.auth.urls')), url(r'', include('django.contrib.auth.urls')),
] ]

View File

@ -1,8 +1,5 @@
from django.utils.crypto import get_random_string 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(): def generate_user_uid():
return get_random_string(length=12, allowed_chars='abcdefghijklmnopqrstuvwxyz0123456789') return get_random_string(length=12, allowed_chars='abcdefghijklmnopqrstuvwxyz0123456789')

View File

@ -1,9 +1,7 @@
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.contrib.sites.shortcuts import get_current_site from django.shortcuts import get_object_or_404, render
from django.contrib.auth.models import User
from .forms import ProfileForm, UserForm from .forms import ProfileForm, UserForm
from .models import Participation from .models import Participation
@ -35,3 +33,8 @@ def participants(request):
participation_list = Participation.on_site.all() participation_list = Participation.on_site.all()
return render(request, 'admin/participants.html', {'participation_list': participation_list}) 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)})

View File

@ -1,7 +1,6 @@
from django.contrib import admin from django.contrib import admin
from .models import ConversationWithParticipant, ConversationAboutTalk, Message from .models import ConversationAboutTalk, ConversationWithParticipant, Message
admin.site.register(ConversationWithParticipant) admin.site.register(ConversationWithParticipant)
admin.site.register(ConversationAboutTalk) admin.site.register(ConversationAboutTalk)

View File

@ -5,4 +5,4 @@ class ConversationsConfig(AppConfig):
name = 'conversations' name = 'conversations'
def ready(self): def ready(self):
import conversations.signals import conversations.signals # noqa

View File

@ -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 email
import re import re
from sys import version_info as python_version 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 @csrf_exempt
@require_http_methods(["POST"]) @require_http_methods(["POST"])
@ -37,10 +35,6 @@ def email_recv(request):
else: else:
msg = email.message_from_bytes(msg.read()) msg = email.message_from_bytes(msg.read())
mfrom = msg.get('From')
mto = msg.get('To')
subject = msg.get('Subject')
if msg.is_multipart(): if msg.is_multipart():
msgs = msg.get_payload() msgs = msg.get_payload()
for m in msgs: for m in msgs:
@ -63,7 +57,7 @@ def email_recv(request):
regexp = '^%s\+(?P<dest>[a-z0-9]{12})(?P<token>[a-z0-9]{60})(?P<key>[a-z0-9]{12})@%s$' % (name, domain) regexp = '^%s\+(?P<dest>[a-z0-9]{12})(?P<token>[a-z0-9]{60})(?P<key>[a-z0-9]{12})@%s$' % (name, domain)
p = re.compile(regexp) p = re.compile(regexp)
m = None 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) m = p.match(_mto)
if m: if m:
break break

View File

@ -2,9 +2,5 @@ from django.forms.models import modelform_factory
from .models import Message from .models import Message
MessageForm = modelform_factory(Message, MessageForm = modelform_factory(Message,
fields=['content']) fields=['content'])

View File

@ -1,13 +1,14 @@
from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse 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 accounts.models import Participation
from proposals.models import Talk from proposals.models import Talk
from .utils import generate_message_token, notify_by_email
class Message(models.Model): class Message(models.Model):
@ -27,6 +28,9 @@ class Message(models.Model):
def __str__(self): def __str__(self):
return "Message from %s" % self.author return "Message from %s" % self.author
def get_absolute_url(self):
return self.conversation.get_absolute_url()
class Conversation(models.Model): class Conversation(models.Model):
@ -44,12 +48,15 @@ class ConversationWithParticipant(Conversation):
uri = 'inbox' uri = 'inbox'
template = 'participant_message' template = 'participant_message'
def get_site(self):
return self.participation.site
def __str__(self): def __str__(self):
return "Conversation with %s" % self.participation.user 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): def new_message(self, message):
site = self.get_site() site = self.get_site()
subject = '[%s] Conversation with %s' % (site.name, self.participation.user.profile) subject = '[%s] Conversation with %s' % (site.name, self.participation.user.profile)
@ -84,12 +91,15 @@ class ConversationAboutTalk(Conversation):
uri = 'inbox' uri = 'inbox'
template = 'talk_message' template = 'talk_message'
def get_site(self):
return self.talk.site
def __str__(self): def __str__(self):
return "Conversation about %s" % self.talk.title 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): def new_message(self, message):
site = self.get_site() site = self.get_site()
first = self.messages.first() first = self.messages.first()

View File

@ -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.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 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") @receiver(post_save, sender=Participation, dispatch_uid="Create ConversationWithParticipant")
@ -31,8 +28,7 @@ def create_conversation_about_talk(sender, instance, created, **kwargs):
@receiver(new_talk, dispatch_uid="Notify new talk") @receiver(new_talk, dispatch_uid="Notify new talk")
def notify_new_talk(sender, instance, **kwargs): def notify_new_talk(sender, instance, **kwargs):
# Subscribe reviewer for these topics to conversations # Subscribe reviewer for these topics to conversations
topics = instance.topics.all() reviewers = User.objects.filter(participation__topic__talk=instance)
reviewers = User.objects.filter(participation__review_topics=topics).all()
instance.conversation.subscribers.add(*reviewers) instance.conversation.subscribers.add(*reviewers)
for user in instance.speakers.all(): for user in instance.speakers.all():
participation = Participation.on_site.get(user=user) participation = Participation.on_site.get(user=user)

View File

@ -1,27 +1,29 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.test import TestCase from django.test import TestCase
from accounts.models import Participation from accounts.models import Participation
from .models import Conversation, Message from .models import ConversationWithParticipant, Message
from .utils import get_reply_addr
class ConversationTests(TestCase): class ConversationTests(TestCase):
def setUp(self): def setUp(self):
a, b = (User.objects.create_user(guy, email='%s@example.org' % guy, password=guy) for guy in 'ab') a, b, c = (User.objects.create_user(guy, email='%s@example.org' % guy, password=guy) for guy in 'abc')
participation = Participation.objects.create(user=a, site=Site.objects.first()) pa, _ = Participation.objects.get_or_create(user=a, site=Site.objects.first())
conversation = Conversation.objects.create(speaker=speaker) conversation, _ = ConversationWithParticipant.objects.get_or_create(participation=pa)
Message.objects.create(token='pipo', conversation=conversation, author=a, content='allo') Message.objects.create(content='allo', conversation=conversation, author=b)
def test_models(self): def test_models(self):
self.assertEqual(str(Conversation.objects.first()), 'Conversation with a') self.assertEqual(str(ConversationWithParticipant.objects.first()), 'Conversation with a')
self.assertEqual(str(Message.objects.first()), 'Message from a') self.assertEqual(str(Message.objects.first()), 'Message from b')
def test_views(self): def test_views(self):
self.assertEqual(self.client.get(Conversation.objects.first().get_absolute_url()).status_code, 200) url = ConversationWithParticipant.objects.first().get_absolute_url()
self.assertEqual(self.client.get(url).status_code, 302)
def test_utils(self): self.client.login(username='c', password='c')
ret = ['pipo+ 11183704aabfddb3d694ff4f24c0daadfa2d8d2193336e345f92a6fd3ffb6a19e7@example.org'] self.assertEqual(self.client.get(url).status_code, 403)
self.assertEqual(get_reply_addr(1, User.objects.first()), ret) 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'})

View File

@ -1,7 +1,6 @@
from django.conf.urls import url from django.conf.urls import url
from conversations import views, emails from conversations import emails, views
urlpatterns = [ urlpatterns = [
url(r'^recv/$', emails.email_recv), url(r'^recv/$', emails.email_recv),

View File

@ -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 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): 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) email=settings.DEFAULT_FROM_EMAIL)
# Generating headers # Generating headers
headers = { headers = {'Message-ID': "<%s.%s>" % (message_id, settings.DEFAULT_FROM_EMAIL)}
'Message-ID': "<%s.%s>" % (message_id, settings.DEFAULT_FROM_EMAIL),
}
if ref: if ref:
# This email reference a previous one # This email reference a previous one
headers.update({ headers.update({
@ -68,7 +66,8 @@ def notify_by_email(template, data, subject, sender, dests, message_id, ref=None
messages = [] messages = []
for subject, message, from_email, dest_emails, reply_to, headers in mails: for subject, message, from_email, dest_emails, reply_to, headers in mails:
text_message, html_message = message 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') msg.attach_alternative(html_message, 'text/html')
messages += [msg] messages += [msg]
with mail.get_connection() as connection: with mail.get_connection() as connection:

View File

@ -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.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.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.core.urlresolvers import reverse
from django.shortcuts import get_object_or_404, redirect, render
from accounts.models import Participation from accounts.models import Participation
from .models import Message
from .forms import MessageForm from .forms import MessageForm
@ -64,8 +62,7 @@ def subscribe(request, username):
# TODO check admin # TODO check admin
participation = get_object_or_404(Participation, user__username=username, participation = get_object_or_404(Participation, user__username=username, site=get_current_site(request))
site=get_current_site(request))
participation.conversation.subscribers.add(request.user) participation.conversation.subscribers.add(request.user)
messages.success(request, 'Subscribed.') messages.success(request, 'Subscribed.')
@ -79,8 +76,7 @@ def unsubscribe(request, username):
# TODO check admin # TODO check admin
participation = get_object_or_404(Participation, user__username=username, participation = get_object_or_404(Participation, user__username=username, site=get_current_site(request))
site=get_current_site(request))
participation.conversation.subscribers.remove(request.user) participation.conversation.subscribers.remove(request.user)
messages.success(request, 'Unsubscribed.') messages.success(request, 'Unsubscribed.')

10
ponyconf/utils.py Normal file
View File

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

View File

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

View File

@ -8,8 +8,8 @@ from django.db import models
from autoslug import AutoSlugField 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'] __all__ = ['Topic', 'Talk', 'Speech']
@ -19,6 +19,8 @@ class Topic(models.Model):
name = models.CharField(max_length=128, verbose_name='Name', unique=True) name = models.CharField(max_length=128, verbose_name='Name', unique=True)
slug = AutoSlugField(populate_from='name', unique=True) slug = AutoSlugField(populate_from='name', unique=True)
reviewers = models.ManyToManyField(Participation, blank=True)
def __str__(self): def __str__(self):
return self.name return self.name
@ -54,13 +56,13 @@ class Talk(models.Model):
return True return True
if user == self.proposer: if user == self.proposer:
return True return True
if user in talk.speakers.all(): if user in self.speakers.all():
return True return True
try: try:
participation = Participation.on_site.get(user=user) participation = Participation.on_site.get(user=user)
except Participation.DoesNotExists: except Participation.DoesNotExists:
return False return False
return self.topics.filter(pk=participation.review_topics.pk).exists() return self.topics.filter(reviewers=participation).exists()
class Speech(models.Model): class Speech(models.Model):

View File

@ -1,4 +1,3 @@
from django.dispatch import Signal from django.dispatch import Signal
new_talk = Signal(providing_args=["sender", "instance"]) new_talk = Signal(providing_args=["sender", "instance"])

View File

@ -1,20 +1,25 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test import TestCase 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): class ProposalsTests(TestCase):
def setUp(self): def setUp(self):
for guy in 'ab': a, b, c = (User.objects.create_user(guy, email='%s@example.org' % guy, password=guy) for guy in 'abc')
User.objects.create_user(guy, email='%s@example.org' % guy, password=guy) Participation.objects.create(user=a, site=Site.objects.first())
Topic.objects.create(name='pipo') Topic.objects.create(name='topipo')
c.is_superuser = True
c.save()
def test_everything(self): def test_everything(self):
# talk-edit # talk-edit
self.client.login(username='a', password='a') 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.assertEqual(str(Talk.on_site.first()), 'super talk')
self.client.post(reverse('edit-talk', kwargs={'talk': 'super-talk'}), self.client.post(reverse('edit-talk', kwargs={'talk': 'super-talk'}),
{'title': 'mega talk', 'description': 'mega', 'event': 1}) {'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.assertEqual(self.client.get(item.get_absolute_url()).status_code, 200)
self.assertTrue(str(item)) self.assertTrue(str(item))
self.assertEqual(Speech.objects.first().username(), 'a') 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))

View File

@ -9,6 +9,7 @@ from django.views.generic import DetailView, ListView
from proposals.forms import TalkForm from proposals.forms import TalkForm
from proposals.models import Speech, Talk, Topic from proposals.models import Speech, Talk, Topic
from .signals import new_talk from .signals import new_talk
@ -48,7 +49,7 @@ def talk_edit(request, talk=None):
talk = get_object_or_404(Talk, slug=talk) talk = get_object_or_404(Talk, slug=talk)
if talk.site != get_current_site(request): if talk.site != get_current_site(request):
raise PermissionDenied() raise PermissionDenied()
if not talk.has_perm(request.user): if not talk.is_editable_by(request.user):
raise PermissionDenied() raise PermissionDenied()
form = TalkForm(request.POST or None, instance=talk) form = TalkForm(request.POST or None, instance=talk)
if request.method == 'POST' and form.is_valid(): if request.method == 'POST' and form.is_valid():
@ -72,10 +73,9 @@ def talk_edit(request, talk=None):
class TalkDetail(LoginRequiredMixin, DetailView): class TalkDetail(LoginRequiredMixin, DetailView):
queryset = Talk.on_site.all() queryset = Talk.on_site.all()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(TalkDetail, self).get_context_data(**kwargs) return super().get_context_data(edit_perm=self.object.is_editable_by(self.request.user), **kwargs)
context['edit_perm'] = self.object.is_editable_by(self.request.user)
return context
class TopicList(LoginRequiredMixin, ListView): class TopicList(LoginRequiredMixin, ListView):