per Event opening / closing dates

This fixes #37
This commit is contained in:
Élie Bouttier 2016-11-13 23:14:53 +01:00
parent dc6b1f7cb7
commit b4ed4663e8
7 changed files with 155 additions and 113 deletions

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-11-12 01:57+0000\n"
"POT-Creation-Date: 2016-11-13 22:35+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -89,7 +89,7 @@ msgstr "Licence vidéo"
#: accounts/models.py:80
#: accounts/templates/accounts/participant_details.html:71
#: proposals/models.py:144 proposals/templates/proposals/talk_detail.html:90
#: proposals/models.py:148 proposals/templates/proposals/talk_detail.html:94
msgid "Notes"
msgstr "Notes"
@ -140,7 +140,7 @@ msgid "Contact"
msgstr "Contacter"
#: accounts/templates/accounts/participant_details.html:15
#: proposals/templates/proposals/talk_detail.html:12
#: proposals/templates/proposals/talk_detail.html:16
msgid "Edit"
msgstr "Éditer"
@ -466,8 +466,8 @@ msgstr "Sinscrire"
msgid "Powered by"
msgstr "Propulsé par"
#: ponyconf/templates/staff.html:9 proposals/models.py:142
#: proposals/templates/proposals/talk_detail.html:22
#: ponyconf/templates/staff.html:9 proposals/models.py:146
#: proposals/templates/proposals/talk_detail.html:26
#: proposals/templates/proposals/talk_list.html:48
#: proposals/templates/proposals/topic_list.html:9
msgid "Topics"
@ -478,9 +478,9 @@ msgstr "Thèmes"
msgid "Tracks"
msgstr "Sessions"
#: ponyconf/templates/staff.html:12 proposals/models.py:137
#: ponyconf/templates/staff.html:12 proposals/models.py:141
#: proposals/templates/proposals/speaker_list.html:9
#: proposals/templates/proposals/talk_detail.html:64
#: proposals/templates/proposals/talk_detail.html:68
#: proposals/templates/proposals/talk_list.html:47
msgid "Speakers"
msgstr "Orateurs"
@ -490,132 +490,136 @@ msgstr "Orateurs"
msgid "Volunteers"
msgstr "Bénévoles"
#: proposals/forms.py:37
#: ponyconf/templates/staff.html:18
msgid "Conference"
msgstr "conférence"
#: proposals/forms.py:43
msgid "Should be less than 255 characters"
msgstr "Texte court, moins de 255 caractères"
#: proposals/forms.py:38
#: proposals/forms.py:44
msgid "If you want to add some precisions for the organizers."
msgstr "Si vous souhaitez apporter des précisions à l'équipe d'organisation."
#: proposals/forms.py:63
#: proposals/forms.py:69
msgid "Filter talks you already / not yet voted for"
msgstr ""
"Filtrer les propositions pour lesquelles vous avez déjà voté / pas encore "
"voté"
#: proposals/forms.py:64
#: proposals/forms.py:70
msgid "Filter talks already / not yet affected to a room"
msgstr "Filtrer les exposés déjà / pas encore affectées à une salle"
#: proposals/forms.py:65
#: proposals/forms.py:71
msgid "Filter talks already / not yet scheduled"
msgstr "Filtrer les exposés déjà / pas encore planifiées"
#: proposals/forms.py:80
#: proposals/forms.py:86
msgid "Accept talk?"
msgstr "Accepter la proposition ?"
#: proposals/forms.py:81
#: proposals/forms.py:87
msgid "Assign to a track"
msgstr "Assigner à une session"
#: proposals/forms.py:82
#: proposals/forms.py:88
msgid "Put in a room"
msgstr "Assigner à une salle"
#: proposals/forms.py:184
#: proposals/forms.py:190
msgid "Name or nickname"
msgstr "Nom ou pseudo"
#: proposals/forms.py:185
#: proposals/forms.py:191
msgid "How much is 3+4?"
msgstr "Combien font 3+4 ?"
#: proposals/forms.py:185
#: proposals/forms.py:191
msgid "Anti-bot"
msgstr "Anti-robot"
#: proposals/forms.py:190
#: proposals/forms.py:196
msgid "Please re-do the maths."
msgstr "Refaites les calculs."
#: proposals/models.py:49 proposals/models.py:72 proposals/models.py:119
#: proposals/models.py:43 proposals/models.py:66 proposals/models.py:123
#: volunteers/models.py:12
msgid "Name"
msgstr "Nom"
#: proposals/models.py:51 proposals/models.py:74 proposals/models.py:141
#: proposals/templates/proposals/talk_detail.html:60 volunteers/models.py:14
#: proposals/models.py:45 proposals/models.py:68 proposals/models.py:145
#: proposals/templates/proposals/talk_detail.html:64 volunteers/models.py:14
msgid "Description"
msgstr "Description"
#: proposals/models.py:53
#: proposals/models.py:47
msgid "Managers"
msgstr "Responsables"
#: proposals/models.py:75
#: proposals/models.py:69
msgid "Destination track"
msgstr "Session de destination"
#: proposals/models.py:77
#: proposals/models.py:71
msgid "Reviewers"
msgstr "Responsables"
#: proposals/models.py:93
#: proposals/models.py:87
msgid "Default duration (min)"
msgstr "Durée par défaut (min)"
#: proposals/models.py:94
#: proposals/models.py:88
msgid "Color on program"
msgstr "Couleur sur le programme"
#: proposals/models.py:95
#: proposals/models.py:89
msgid "Label on program"
msgstr "Label dans le xml du programme"
#: proposals/models.py:126
#: proposals/models.py:130
msgid "Email"
msgstr ""
#: proposals/models.py:138 proposals/templates/proposals/talk_list.html:45
#: proposals/models.py:142 proposals/templates/proposals/talk_list.html:45
msgid "Title"
msgstr "Titre"
#: proposals/models.py:138
#: proposals/models.py:142
msgid "After submission, title can only be changed by the staff."
msgstr ""
"Après soumission, le titre ne peut être modifié que par léquipe "
"dorganisation."
#: proposals/models.py:140
#: proposals/models.py:144
msgid "Abstract"
msgstr "Résumé"
#: proposals/models.py:142
#: proposals/models.py:146
msgid "The topics can not be changed after submission."
msgstr "Les thèmes ne peuvent pas être modifiés après soumission."
#: proposals/models.py:143 proposals/templates/proposals/talk_detail.html:29
#: proposals/templates/proposals/talk_detail.html:77
#: proposals/models.py:147 proposals/templates/proposals/talk_detail.html:33
#: proposals/templates/proposals/talk_detail.html:81
#: proposals/templates/proposals/talk_list.html:49
#: proposals/templates/proposals/track_form.html:14
msgid "Track"
msgstr "Session"
#: proposals/models.py:145 proposals/templates/proposals/talk_list.html:46
#: proposals/models.py:149 proposals/templates/proposals/talk_list.html:46
msgid "Intervention kind"
msgstr "Type dintervention"
#: proposals/models.py:148
#: proposals/models.py:152
msgid "Duration (min)"
msgstr "Durée (min)"
#: proposals/models.py:152 proposals/templates/proposals/talk_detail.html:119
#: proposals/models.py:156 proposals/templates/proposals/talk_detail.html:123
msgid "Attendees"
msgstr "Inscrits"
#: proposals/models.py:153
#: proposals/models.py:157
msgid "Max. number of attendees"
msgstr "Nombre maximum dinscrits"
@ -674,7 +678,7 @@ msgid "Proposed talks for others speakers:"
msgstr "Exposés proposés pour un tier :"
#: proposals/templates/proposals/participate.html:23
#: proposals/templates/proposals/talk_propose.html:9
#: proposals/templates/proposals/talk_edit.html:10
msgid "Propose a talk"
msgstr "Proposer un exposé"
@ -773,87 +777,87 @@ msgstr "Accepter la proposition"
msgid "Decline the proposal"
msgstr "Décliner la proposition"
#: proposals/templates/proposals/talk_detail.html:15
#: proposals/templates/proposals/talk_detail.html:19
msgid "No abstract provided."
msgstr "Aucun résumé fourni."
#: proposals/templates/proposals/talk_detail.html:20
#: proposals/templates/proposals/talk_detail.html:24
msgid "Format"
msgstr "Format"
#: proposals/templates/proposals/talk_detail.html:26
#: proposals/templates/proposals/talk_detail.html:30
#: proposals/templates/proposals/topic_list.html:31
msgid "No topics."
msgstr "Aucun thème."
#: proposals/templates/proposals/talk_detail.html:33
#: proposals/templates/proposals/talk_detail.html:78
#: proposals/templates/proposals/talk_detail.html:37
#: proposals/templates/proposals/talk_detail.html:82
msgid "No assigned yet."
msgstr "Pas encore assigné."
#: proposals/templates/proposals/talk_detail.html:40
#: proposals/templates/proposals/talk_detail.html:48
#: proposals/templates/proposals/talk_detail.html:44
#: proposals/templates/proposals/talk_detail.html:52
msgid "not defined"
msgstr "non défini"
#: proposals/templates/proposals/talk_detail.html:52
#: proposals/templates/proposals/talk_detail.html:56
msgid "Registrations"
msgstr "Inscriptions"
#: proposals/templates/proposals/talk_detail.html:53
#: proposals/templates/proposals/talk_detail.html:57
msgid "required but unlimited"
msgstr "requis mais non limité"
#: proposals/templates/proposals/talk_detail.html:62
#: proposals/templates/proposals/talk_detail.html:66
msgid "No description provided."
msgstr "Aucune description fournie."
#: proposals/templates/proposals/talk_detail.html:71
#: proposals/templates/proposals/talk_detail.html:75
msgid "No speakers."
msgstr "Aucun orateur."
#: proposals/templates/proposals/talk_detail.html:82
#: proposals/templates/proposals/talk_detail.html:86
msgid "Assign to"
msgstr "Assigner à"
#: proposals/templates/proposals/talk_detail.html:92
#: proposals/templates/proposals/talk_detail.html:96
msgid "No notes."
msgstr "Aucune note."
#: proposals/templates/proposals/talk_detail.html:96
#: proposals/templates/proposals/talk_detail.html:100
msgid "Moderation"
msgstr "Modération"
#: proposals/templates/proposals/talk_detail.html:98
#: proposals/templates/proposals/talk_detail.html:102
#: proposals/templates/proposals/talk_list.html:50
msgid "Status"
msgstr "Statut"
#: proposals/templates/proposals/talk_detail.html:103
#: proposals/templates/proposals/talk_detail.html:107
msgid "Vote"
msgstr "Vote"
#: proposals/templates/proposals/talk_detail.html:112
#: proposals/templates/proposals/talk_detail.html:116
msgid "vote"
msgstr "vote"
#: proposals/templates/proposals/talk_detail.html:112
#: proposals/templates/proposals/talk_detail.html:116
msgid "average:"
msgstr "moyenne :"
#: proposals/templates/proposals/talk_detail.html:126
#: proposals/templates/proposals/talk_detail.html:130
msgid "No attendees yet."
msgstr "Il ny a pas encore dinscrit."
#: proposals/templates/proposals/talk_detail.html:131
#: proposals/templates/proposals/talk_detail.html:135
msgid "Messages"
msgstr "Messages"
#: proposals/templates/proposals/talk_detail.html:132
#: proposals/templates/proposals/talk_detail.html:136
msgid "These messages are for organization team only."
msgstr "Ces messages sont à destination de la team dorganisation seulement."
#: proposals/templates/proposals/talk_edit.html:9
#: proposals/templates/proposals/talk_edit.html:10
msgid "Edit a talk"
msgstr "Éditer un exposé"
@ -932,46 +936,46 @@ msgstr "responsable"
msgid "No tracks."
msgstr "Aucune session."
#: proposals/views.py:208
#: proposals/views.py:201
#, python-format
msgid "Note: the room %(room)s has %(capacity)s seat."
msgid_plural "Note: the room %(room)s has %(capacity)s seats."
msgstr[0] "Note : la salle %(room)s a %(capacity)s place."
msgstr[1] "Note : la salle %(room)s a %(capacity)s places."
#: proposals/views.py:228
#: proposals/views.py:211
msgid "Talk modified successfully!"
msgstr "Exposé modifié avec succès !"
#: proposals/views.py:234
#: proposals/views.py:217
msgid "Talk proposed successfully!"
msgstr "Exposé proposé avec succès !"
#: proposals/views.py:249
#: proposals/views.py:234
msgid "Talk assigned to track successfully!"
msgstr "Exposé assigné à la session avec succès !"
#: proposals/views.py:318
#: proposals/views.py:307
msgid "Vote successfully created"
msgstr "A voté !"
#: proposals/views.py:318
#: proposals/views.py:307
msgid "Vote successfully updated"
msgstr "Vote mis à jour"
#: proposals/views.py:344
#: proposals/views.py:333
msgid "Decision taken in account"
msgstr "Décision enregistrée"
#: proposals/views.py:440
#: proposals/views.py:429
msgid "Unregistered :-("
msgstr "Vous avez été désinscrit :-("
#: proposals/views.py:442
#: proposals/views.py:431
msgid "Already registered!"
msgstr "Vous êtes déjà inscrit !"
#: proposals/views.py:447
#: proposals/views.py:436
msgid "Registered!"
msgstr "Vous avez été inscrit !"

View File

@ -28,8 +28,10 @@ class TalkForm(forms.ModelForm):
super(TalkForm, self).__init__(*args, **kwargs)
self.fields['topics'].queryset = Topic.objects.filter(site=site)
self.fields['track'].queryset = Track.objects.filter(site=site)
self.fields['event'].queryset = Event.objects.filter(site=site)
if not staff:
if staff:
self.fields['event'].queryset = Event.objects.filter(site=site)
else:
self.fields['event'].queryset = Conference.objects.get(site=site).opened_events
for field in ['track', 'duration', 'start_date', 'room', 'registration_required', 'attendees_limit']:
self.fields.pop(field)
if self.instance.pk is not None:
@ -198,9 +200,7 @@ class SubscribeForm(forms.Form):
ConferenceForm = modelform_factory(Conference,
fields=['cfp_opening_date', 'cfp_closing_date', 'subscriptions_open', 'venue', 'city', 'home'],
fields=['subscriptions_open', 'venue', 'city', 'home'],
widgets={
'cfp_opening_date': forms.TextInput(),
'cfp_closing_date': forms.TextInput(),
'venue': forms.Textarea(attrs={'rows': 4}),
})

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-11-13 22:04
from __future__ import unicode_literals
from django.db import migrations, models
def migrate_opening_closing_dates(apps, schema_editor):
db_alias = schema_editor.connection.alias
Conference = apps.get_model('proposals', 'Conference')
Event = apps.get_model('proposals', 'Event')
for conf in Conference.objects.all():
for event in Event.objects.filter(site=conf.site).all():
event.opening_date = conf.cfp_opening_date
event.closing_date = conf.cfp_closing_date
event.save()
class Migration(migrations.Migration):
dependencies = [
('proposals', '0027_conference_subscriptions_open'),
]
operations = [
migrations.AddField(
model_name='event',
name='closing_date',
field=models.DateTimeField(blank=True, default=None, null=True),
),
migrations.AddField(
model_name='event',
name='opening_date',
field=models.DateTimeField(blank=True, default=None, null=True),
),
migrations.RunPython(migrate_opening_closing_dates),
migrations.RemoveField(
model_name='conference',
name='cfp_closing_date',
),
migrations.RemoveField(
model_name='conference',
name='cfp_opening_date',
),
]

View File

@ -6,6 +6,7 @@ from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from django.utils import timezone
@ -26,17 +27,18 @@ class Conference(models.Model):
home = models.TextField(blank=True, default="")
venue = models.TextField(blank=True, default="")
city = models.CharField(max_length=64, blank=True, default="")
cfp_opening_date = models.DateTimeField(null=True, blank=True, default=None)
cfp_closing_date = models.DateTimeField(null=True, blank=True, default=None)
subscriptions_open = models.BooleanField(default=False)
subscriptions_open = models.BooleanField(default=False) # workshop subscription
def cfp_is_open(self):
events = Event.objects.filter(site=self.site)
return any(map(lambda x: x.is_open(), events))
@property
def opened_events(self):
now = timezone.now()
if self.cfp_opening_date and now < self.cfp_opening_date:
return False
if self.cfp_closing_date and now > self.cfp_closing_date:
return False
return True
return Event.objects.filter(site=self.site)\
.filter(Q(opening_date__isnull=True) | Q(opening_date__lte=now))\
.filter(Q(closing_date__isnull=True) | Q(closing_date__gte=now))
def __str__(self):
return str(self.site)
@ -93,6 +95,16 @@ class Event(models.Model):
duration = models.PositiveIntegerField(default=0, verbose_name=_('Default duration (min)'))
color = RGBColorField(default='#ffffff', verbose_name=_("Color on program"))
label = models.CharField(max_length=64, verbose_name=_("Label on program"), blank=True, default="")
opening_date = models.DateTimeField(null=True, blank=True, default=None)
closing_date = models.DateTimeField(null=True, blank=True, default=None)
def is_open(self):
now = timezone.now()
if self.opening_date and now < self.opening_date:
return False
if self.closing_date and now > self.closing_date:
return False
return True
class Meta:
unique_together = ('site', 'name')

View File

@ -13,9 +13,7 @@
<div class="panel-body">
<form method="post" role="form">
{% csrf_token %}
{% bootstrap_field form.cfp_opening_date addon_after='<span class="glyphicon glyphicon-calendar"></span>' %}
{% bootstrap_field form.cfp_closing_date addon_after='<span class="glyphicon glyphicon-calendar"></span>' %}
{% bootstrap_form form exclude='cfp_opening_date,cfp_closing_date,home' %}
{% bootstrap_form form exclude='home' %}
<ul class="nav nav-tabs" role="tablist">
<li class="active"><a href="#editor" role="tab" data-toggle="tab">Editor</a></li>
<li><a href="#preview" role="tab" data-toggle="tab">Preview</a></li>
@ -43,7 +41,6 @@
{% block css %}
{{ block.super }}
{{ form.media.css }}
<link rel="stylesheet" href="{% static 'eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css' %}" />
{% endblock css %}
{% block js_end %}
@ -52,28 +49,5 @@
<script type="text/javascript">
var markdown_preview_url = "{% url 'markdown' %}";
</script>
<script src="{% static 'moment/min/moment.min.js' %}"></script>
<script src="{% static 'eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js' %}"></script>
<script src="{% static 'jquery.cookie/jquery.cookie.js' %}"></script>
<script src="{% static 'js/markdown-preview.js' %}"></script>
<script type="text/javascript">
$(function() {
$("#id_cfp_opening_date").datetimepicker({
"format": "YYYY-MM-DD HH:mm",
"widgetPositioning": {
"horizontal": "right",
"vertical": "auto"
},
"showClear": true
});
$("#id_cfp_closing_date").datetimepicker({
"format": "YYYY-MM-DD HH:mm",
"widgetPositioning": {
"horizontal": "right",
"vertical": "auto"
},
"showClear": true
});
});
</script>
{% endblock js_end %}

View File

@ -19,7 +19,14 @@
{% endif %}
<br />
{% if conference.cfp_is_open or request|orga %}
{% if conference.cfp_is_open %}
{% trans "The Call for Participation is currently open for following categories:" %}
{% for event in conference.opened_events.all %}
{% if forloop.first %}<ul>{% endif %}
<li>{{ event }}{% if event.closing_date %} ({% blocktrans with closing_date=event.closing_date|date:"DATETIME_FORMAT" %}until {{ closing_date }}{% endblocktrans %}){% endif %}</li>
{% if forloop.last %}</ul>{% endif %}
{% endfor %}
<br />
<a class="btn btn-{% if conference.cfp_is_open %}success{% else %}danger{% endif %}" href="{% url 'add-talk' %}">{% trans "Propose a talk" %}</a>
{% else %}
{% trans "Sorry, the Call for Participation is closed." %}