From 1f635cb379d44da6efdbc70ed6a9e564a1b95124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lie=20Bouttier?= Date: Sat, 24 Sep 2016 18:24:47 +0200 Subject: [PATCH] allow to close the CFP --- proposals/forms.py | 2 +- proposals/migrations/0013_conference_cfp.py | 20 +++++++ proposals/models.py | 12 ++++- proposals/templates/proposals/conference.html | 53 +++++++++---------- .../templates/proposals/participate.html | 6 +++ proposals/views.py | 22 +++++--- 6 files changed, 79 insertions(+), 36 deletions(-) create mode 100644 proposals/migrations/0013_conference_cfp.py diff --git a/proposals/forms.py b/proposals/forms.py index e905cc9..9f35612 100644 --- a/proposals/forms.py +++ b/proposals/forms.py @@ -120,4 +120,4 @@ class TopicForm(forms.ModelForm): return name -ConferenceForm = modelform_factory(Conference, fields=['home']) +ConferenceForm = modelform_factory(Conference, fields=['cfp', 'home']) diff --git a/proposals/migrations/0013_conference_cfp.py b/proposals/migrations/0013_conference_cfp.py new file mode 100644 index 0000000..7c649a1 --- /dev/null +++ b/proposals/migrations/0013_conference_cfp.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10 on 2016-09-24 12:08 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('proposals', '0012_topic_track'), + ] + + operations = [ + migrations.AddField( + model_name='conference', + name='cfp', + field=models.IntegerField(choices=[(0, 'Forthcoming (closed)'), (1, 'Open'), (2, 'Completed (closed)')], default=0), + ), + ] diff --git a/proposals/models.py b/proposals/models.py index d7cb8ec..496637e 100644 --- a/proposals/models.py +++ b/proposals/models.py @@ -18,8 +18,18 @@ from .utils import query_sum class Conference(models.Model): - site = models.OneToOneField(Site, on_delete=models.CASCADE) + CFP_FORTHCOMING = 0 + CFP_OPEN = 1 + CFP_COMPLETED = 2 + CFP_CHOICES = [ + (CFP_FORTHCOMING, _('Forthcoming (closed)')), + (CFP_OPEN, _('Open')), + (CFP_COMPLETED, _('Completed (closed)')), + ] + + site = models.OneToOneField(Site, on_delete=models.CASCADE, related_name='conference') home = models.TextField(blank=True, default="") + cfp = models.IntegerField(choices=CFP_CHOICES, default=0, verbose_name=_('Call for Participation')) def __str__(self): return str(self.site) diff --git a/proposals/templates/proposals/conference.html b/proposals/templates/proposals/conference.html index ccdc890..c472078 100644 --- a/proposals/templates/proposals/conference.html +++ b/proposals/templates/proposals/conference.html @@ -2,39 +2,38 @@ {% load bootstrap3 staticfiles i18n %} -{% block talktab %} class="active"{% endblock %} +{% block admintab %} class="active"{% endblock %} {% block content %} -

{% trans "Conference settings" %}

-
-
-

{% trans "Home page" %}

-
-
-
- {% csrf_token %} - -
-
-
- -
+
+

{% trans "Home page" %}

-
-
+
+ + {% csrf_token %} + {% bootstrap_field form.cfp %} + +
+
+
+ +
+
+
+
+
+
+ +
+
+
-
- -
-
- -
{% endblock %} diff --git a/proposals/templates/proposals/participate.html b/proposals/templates/proposals/participate.html index d715b15..622d859 100644 --- a/proposals/templates/proposals/participate.html +++ b/proposals/templates/proposals/participate.html @@ -19,6 +19,12 @@ {% endif %}
+{% if conf.cfp == conf.CFP_FORTHCOMING %} +{% trans "The Call for Participation is not yet open." %} +{% elif conf.cfp == conf.CFP_OPEN %} {% trans "Propose a talk" %} +{% elif conf.cfp == conf.CFP_COMPLETED %} +{% trans "The Call for Participation is completed." %} +{% endif %} {% endblock %} diff --git a/proposals/views.py b/proposals/views.py index 94e636d..e9d1d21 100644 --- a/proposals/views.py +++ b/proposals/views.py @@ -17,7 +17,7 @@ from django.http import HttpResponse from accounts.models import Participation from accounts.mixins import OrgaRequiredMixin, StaffRequiredMixin from accounts.decorators import orga_required, staff_required -from accounts.utils import is_staff +from accounts.utils import is_orga, is_staff from conversations.models import ConversationWithParticipant, ConversationAboutTalk, Message @@ -53,12 +53,14 @@ def conference(request): @login_required def participate(request): - talks = Talk.objects.filter(site=get_current_site(request)) + site = get_current_site(request) + talks = Talk.objects.filter(site=site) my_talks = talks.filter(speakers=request.user) proposed_talks = talks.exclude(speakers=request.user).filter(proposer=request.user) return render(request, 'proposals/participate.html', { 'my_talks': my_talks, 'proposed_talks': proposed_talks, + 'conf': site.conference, }) @staff_required @@ -135,18 +137,24 @@ def talk_list(request): @login_required def talk_edit(request, talk=None): - if talk: - talk = get_object_or_404(Talk, slug=talk, site=get_current_site(request)) + site = get_current_site(request) + if talk: # edit existing talk + talk = get_object_or_404(Talk, slug=talk, site=site) if not talk.is_editable_by(request.user): raise PermissionDenied() - form = TalkForm(request.POST or None, instance=talk, site=get_current_site(request)) - if not is_staff(request, request.user): - form.fields.pop('track') + else: # add new talk + if site.conference.cfp != Conference.CFP_OPEN and not is_orga(request, request.user): + raise PermissionDenied() + form = TalkForm(request.POST or None, instance=talk, site=site) if talk: form.fields['title'].disabled = True form.fields['topics'].disabled = True + if not talk.is_editable_by(request.user): + form.fields.pop('track') else: form.fields['speakers'].initial = [request.user] + if not is_orga(request, request.user): + form.fields.pop('track') if request.method == 'POST' and form.is_valid(): if hasattr(talk, 'id'): talk = form.save()