diff --git a/cfp/forms.py b/cfp/forms.py
index dfe5352..efb5122 100644
--- a/cfp/forms.py
+++ b/cfp/forms.py
@@ -9,7 +9,7 @@ from django.utils.crypto import get_random_string
from django_select2.forms import ModelSelect2MultipleWidget
-from .models import Participant, Talk, TalkCategory, Track, Conference
+from .models import Participant, Talk, TalkCategory, Track, Conference, Room
STATUS_CHOICES = [
@@ -45,7 +45,7 @@ class TalkStaffForm(TalkForm):
self.fields['track'].queryset = tracks
class Meta(TalkForm.Meta):
- fields = ('category', 'track', 'title', 'description','notes')
+ fields = ('category', 'track', 'title', 'description', 'notes', 'start_date', 'duration', 'room',)
labels = {
'category': _('Category'),
'title': _('Title'),
@@ -80,6 +80,14 @@ class TalkFilterForm(forms.Form):
label=_('Vote'),
help_text=_('Filter talks you already / not yet voted for'),
)
+ room = forms.NullBooleanField(
+ label=_('Room'),
+ help_text=_('Filter talks already / not yet affected to a room'),
+ )
+ scheduled = forms.NullBooleanField(
+ label=_('Scheduled'),
+ help_text=_('Filter talks already / not yet scheduled'),
+ )
def __init__(self, *args, **kwargs):
site = kwargs.pop('site')
@@ -150,11 +158,7 @@ class CreateUserForm(forms.ModelForm):
return user
-class TrackForm(forms.ModelForm):
- class Meta:
- model = Track
- fields = ['name', 'description']
-
+class OnSiteNamedModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.conference = kwargs.pop('conference')
super().__init__(*args, **kwargs)
@@ -168,8 +172,20 @@ class TrackForm(forms.ModelForm):
return name
def save(self, commit=True):
- track = super().save(commit=False)
- track.site = self.conference.site
+ obj = super().save(commit=False)
+ obj.site = self.conference.site
if commit:
- track.save()
- return track
+ obj.save()
+ return obj
+
+
+class TrackForm(OnSiteNamedModelForm):
+ class Meta:
+ model = Track
+ fields = ['name', 'description']
+
+
+class RoomForm(OnSiteNamedModelForm):
+ class Meta:
+ model = Room
+ fields = ['name', 'label', 'capacity']
diff --git a/planning/migrations/0001_initial.py b/cfp/migrations/0008_auto_20170811_2342.py
similarity index 60%
rename from planning/migrations/0001_initial.py
rename to cfp/migrations/0008_auto_20170811_2342.py
index fff5ab1..62effac 100644
--- a/planning/migrations/0001_initial.py
+++ b/cfp/migrations/0008_auto_20170811_2342.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Generated by Django 1.10.3 on 2017-01-13 10:49
+# Generated by Django 1.11.3 on 2017-08-11 23:42
from __future__ import unicode_literals
import autoslug.fields
@@ -9,10 +9,9 @@ import django.db.models.deletion
class Migration(migrations.Migration):
- initial = True
-
dependencies = [
('sites', '0002_alter_domain_unique'),
+ ('cfp', '0007_conference_secure_domain'),
]
operations = [
@@ -30,6 +29,21 @@ class Migration(migrations.Migration):
'ordering': ['name'],
},
),
+ migrations.AddField(
+ model_name='talk',
+ name='start_date',
+ field=models.DateTimeField(blank=True, default=None, null=True, verbose_name='Beginning date and time'),
+ ),
+ migrations.AlterField(
+ model_name='conference',
+ name='secure_domain',
+ field=models.BooleanField(default=True, verbose_name='Secure domain (HTTPS)'),
+ ),
+ migrations.AddField(
+ model_name='talk',
+ name='room',
+ field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='cfp.Room'),
+ ),
migrations.AlterUniqueTogether(
name='room',
unique_together=set([('site', 'name')]),
diff --git a/cfp/models.py b/cfp/models.py
index 9db1c75..cd72dc9 100644
--- a/cfp/models.py
+++ b/cfp/models.py
@@ -115,27 +115,6 @@ class Participant(PonyConfModel):
def __str__(self):
return str(self.name)
- #def get_absolute_url(self):
- # return reverse('show-participant', kwargs={'username': self.user.username})
-
- #def is_orga(self):
- # return self.orga
-
- #def is_staff(self):
- # return self.is_orga() or self.topic_set.exists() or self.track_set.exists()
-
- #@property
- #def topic_set(self):
- # return self.user.topic_set.filter(site=self.site)
-
- #@property
- #def track_set(self):
- # return self.user.track_set.filter(site=self.site)
-
- #@property
- #def talk_set(self):
- # return self.user.talk_set.filter(site=self.site)
-
@property
def accepted_talk_set(self):
return self.talk_set.filter(accepted=True)
@@ -145,9 +124,6 @@ class Participant(PonyConfModel):
@property
def refused_talk_set(self):
return self.talk_set.filter(accepted=False)
- #@property
- #def not_refused_talk_set(self): # accepted + pending
- # return self.talk_set.exclude(accepted=False)
class Track(PonyConfModel):
@@ -173,6 +149,37 @@ class Track(PonyConfModel):
return reverse('talk-list') + '?track=%s' % self.slug
+class Room(models.Model):
+
+ site = models.ForeignKey(Site, on_delete=models.CASCADE)
+ slug = AutoSlugField(populate_from='name')
+ name = models.CharField(max_length=256, blank=True, default="")
+ label = models.CharField(max_length=256, blank=True, default="")
+ capacity = models.IntegerField(default=0)
+
+ class Meta:
+ unique_together = ['site', 'name']
+ ordering = ['name']
+
+ def __str__(self):
+ return self.name
+
+ def get_absolute_url(self):
+ return reverse('room-details', kwargs={'slug': self.slug})
+
+ @property
+ def talks(self):
+ return self.talk_set.exclude(accepted=False)
+
+ @property
+ def talks_by_date(self):
+ return self.talks.filter(start_date__isnull=False).exclude(duration=0, category__duration=0).order_by('start_date').all()
+
+ @property
+ def unscheduled_talks(self):
+ return self.talks.filter(Q(start_date__isnull=True) | Q(duration=0, category__duration=0)).all()
+
+
class TalkCategory(models.Model): # type of talk (conf 30min, 1h, stand, …)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
@@ -200,8 +207,8 @@ class TalkCategory(models.Model): # type of talk (conf 30min, 1h, stand, …)
def __str__(self):
return ugettext(self.name)
- #def get_absolute_url(self):
- # return reverse('list-talks') + '?kind=%d' % self.pk
+ def get_absolute_url(self):
+ return reverse('talk-list') + '?category=%d' % self.pk
#class Attendee(PonyConfModel):
@@ -252,7 +259,6 @@ class Talk(PonyConfModel):
site = models.ForeignKey(Site, on_delete=models.CASCADE)
- #proposer = models.ForeignKey(User, related_name='+')
speakers = models.ManyToManyField(Participant, verbose_name=_('Speakers'))
title = models.CharField(max_length=128, verbose_name=_('Talk Title'))
slug = AutoSlugField(populate_from='title', unique=True)
@@ -265,9 +271,9 @@ class Talk(PonyConfModel):
video_licence = models.CharField(choices=LICENCES, default='CC-BY-SA', max_length=10, verbose_name=_("Video licence"))
sound = models.BooleanField(_("I need sound"), default=False)
accepted = models.NullBooleanField(default=None)
- #start_date = models.DateTimeField(null=True, blank=True, default=None)
+ start_date = models.DateTimeField(null=True, blank=True, default=None, verbose_name=_('Beginning date and time'))
duration = models.PositiveIntegerField(default=0, verbose_name=_('Duration (min)'))
- #room = models.ForeignKey(Room, blank=True, null=True, default=None)
+ room = models.ForeignKey(Room, blank=True, null=True, default=None)
plenary = models.BooleanField(default=False)
#materials = models.FileField(null=True, upload_to=talk_materials_destination, verbose_name=_('Materials'),
# help_text=_('You can use this field to share some materials related to your intervention.'))
@@ -287,7 +293,7 @@ class Talk(PonyConfModel):
return self.title
def get_speakers_str(self):
- speakers = [str(Participant.objects.get(site=self.site, user=speaker)) for speaker in self.speakers.all()]
+ speakers = list(map(str, self.speakers.all()))
if len(speakers) == 0:
return 'superman'
elif len(speakers) == 1:
@@ -309,13 +315,13 @@ class Talk(PonyConfModel):
else:
return None
- #@property
- #def dtstart(self):
- # return self.start_date.strftime('%Y%m%dT%H%M%SZ')
+ @property
+ def dtstart(self):
+ return self.start_date.strftime('%Y%m%dT%H%M%SZ')
- #@property
- #def dtend(self):
- # return self.end_date.strftime('%Y%m%dT%H%M%SZ')
+ @property
+ def dtend(self):
+ return self.end_date.strftime('%Y%m%dT%H%M%SZ')
#@property
#def materials_name(self):
@@ -337,5 +343,5 @@ class Vote(PonyConfModel):
def __str__(self):
return "%+i by %s for %s" % (self.vote, self.user, self.talk)
- #def get_absolute_url(self):
- # return self.talk.get_absolute_url()
+ def get_absolute_url(self):
+ return self.talk.get_absolute_url()
diff --git a/cfp/templates/cfp/staff/base.html b/cfp/templates/cfp/staff/base.html
index c9be51d..fd50435 100644
--- a/cfp/templates/cfp/staff/base.html
+++ b/cfp/templates/cfp/staff/base.html
@@ -9,7 +9,6 @@
{% comment %}
{% trans "Topics" %}
{% trans "Volunteers" %}
- {% trans "Rooms" %}
{% trans "Schedule" %}
{% trans "Correspondents" %}
{% trans "Conference" %}
@@ -17,6 +16,7 @@
{% trans "Talks" %}
{% trans "Speakers" %}
{% trans "Tracks" %}
+ {% trans "Rooms" %}
{% trans "Conference" %}
{% if request.user.is_staff %}
Django-Admin
diff --git a/cfp/templates/cfp/staff/room_details.html b/cfp/templates/cfp/staff/room_details.html
new file mode 100644
index 0000000..5c309ab
--- /dev/null
+++ b/cfp/templates/cfp/staff/room_details.html
@@ -0,0 +1,48 @@
+{% extends 'cfp/staff/base.html' %}
+
+{% load bootstrap3 cfp_tags i18n %}
+
+{% block roomstab %} class="active"{% endblock %}
+
+{% block content %}
+
+{{ room.name }}
+ {{ room.label }}
+
+
+{% trans "Scheduled talks" %}
+{% for talk in room.talks_by_date %}
+{% if forloop.first %}{% endif %}
+-
+ {{ talk }}
+ {% for participant in talk.speakers.all %}
+ {% if forloop.first %} – {% endif %}
+ {{ participant }}
+ {% if forloop.revcounter == 2 %} {% trans "and" %} {% elif not forloop.last %}, {% endif %}
+ {% if forloop.last %}{% endif %}
+ {% endfor %}
+ – {{ talk.start_date }} – {% if talk.end_date %}{{ talk.end_date|date:"H:i" }}{% else %}?{% endif %}
+
+{% if forloop.last %}
{% endif %}
+{% empty %}
+{% trans "No talks." %}
+{% endfor %}
+
+{% trans "Unscheduled talks" %}
+{% for talk in room.unscheduled_talks %}
+{% if forloop.first %}{% endif %}
+-
+ {{ talk }}
+ {% for participant in talk.speakers.all %}
+ {% if forloop.first %} – {% endif %}
+ {{ participant }}
+ {% if forloop.revcounter == 2 %} {% trans "and" %} {% elif not forloop.last %}, {% endif %}
+ {% if forloop.last %}{% endif %}
+ {% endfor %}
+
+{% if forloop.last %}
{% endif %}
+{% empty %}
+{% trans "No talks." %}
+{% endfor %}
+
+{% endblock %}
diff --git a/cfp/templates/cfp/staff/room_form.html b/cfp/templates/cfp/staff/room_form.html
new file mode 100644
index 0000000..393955d
--- /dev/null
+++ b/cfp/templates/cfp/staff/room_form.html
@@ -0,0 +1,23 @@
+{% extends 'cfp/staff/base.html' %}
+
+{% load bootstrap3 i18n %}
+
+{% block roomstab %} class="active"{% endblock %}
+
+{% block css %}
+{{ block.super }}
+{{ form.media.css }}
+{% endblock %}
+
+{% block content %}
+
+{% trans "Room" %}
+
+{% include "_form.html" %}
+
+{% endblock %}
+
+{% block js_end %}
+{{ block.super }}
+{{ form.media.js }}
+{% endblock %}
diff --git a/cfp/templates/cfp/staff/room_list.html b/cfp/templates/cfp/staff/room_list.html
new file mode 100644
index 0000000..0016d1d
--- /dev/null
+++ b/cfp/templates/cfp/staff/room_list.html
@@ -0,0 +1,46 @@
+{% extends 'cfp/staff/base.html' %}
+
+{% load bootstrap3 cfp_tags i18n %}
+
+{% block roomstab %} class="active"{% endblock %}
+
+{% block content %}
+
+{% trans "Rooms" %}
+
+{% trans "Add a room" %}
+
+
+ {% for room in room_list %}
+
+
+ {% if room.label %}
{{ room.label }}
{% endif %}
+
+ {{ room.capacity }} {% trans "place" %}{{ room.capacity|pluralize }}
+ |
+
+ {{ room.talks.count }} {% trans "talk" %}{{ room.talks.count|pluralize }}
+
+ |
+ {% bootstrap_icon "pencil" %}
+
+
+ {% cycle '' '
' %}
+ {% cycle '' '' '
' %}
+ {% empty %}
+
{% trans "No rooms." %}
+ {% endfor %}
+
+
+{% endblock %}
+
+{% block js_end %}
+{{ block.super }}
+
+{% endblock %}
diff --git a/cfp/templates/cfp/staff/talk_details.html b/cfp/templates/cfp/staff/talk_details.html
index 365e819..5d9c21d 100644
--- a/cfp/templates/cfp/staff/talk_details.html
+++ b/cfp/templates/cfp/staff/talk_details.html
@@ -9,36 +9,30 @@
{% trans "Edit" %}
-{% if talk.abstract %}{{ talk.abstract }}{% else %}{% trans "No abstract provided." %}{% endif %}
-
-{% comment %}
-{% if moderate_perm %}
+{% trans "Information" %}
- - {% trans "Format" %}
- - {{ talk.event }}
- - {% trans "Topics" %}
- - {% for topic in talk.topics.all %}
- {{ topic }}{% if not forloop.last %}, {% endif %}
- {% empty %}
- {% trans "No topics." %}
- {% endfor %}
+ - {% trans "Category" %}
+ - {{ talk.category }}
+
+ - {% trans "Status" %}
+ - {{ talk.accepted|yesno:"Accepted,Declined,Pending decision" }}
- {% trans "Track" %}
- {% if talk.track %}
{{ talk.track }}
{% else %}
- {% trans "No assigned yet." %}
+ {% trans "No assigned yet." context "session" %}
{% endif %}
- - Horaire
+ - {% trans "Timeslot" %}
- {% if talk.start_date %}
{{ talk.start_date|date:"l d b" }},
{{ talk.start_date|date:"H:i" }} – {% if talk.end_date %}{{ talk.end_date|date:"H:i" }}{% else %}?{% endif %}
{% else %}{% trans "not defined" %}
{% endif %}
- - Salle
+ - {% trans "Room" %}
- {% if talk.room %}
{{ talk.room }}
@@ -46,6 +40,7 @@
{% else %}{% trans "not defined" %}
{% endif %}
+ {% comment %}
{% if talk.registration_required %}
- {% trans "Registrations" %}
- {% if talk.attendees_limit %}{{ talk.attendees.count }} / {{ talk.attendees_limit }}{% else %}{% trans "required but unlimited" %}{% endif %}
@@ -58,16 +53,10 @@
- {% trans "Video" %}
- {% trans "download" %}
{% endif %}
+ {% endcomment %}
-{% endif %}
-{% endcomment %}
-
-{% trans "Category" %}
-
-{{ talk.category }}
-
{% trans "Description" %}
{% if talk.description %}{{ talk.description|linebreaksbr }}{% else %}{% trans "No description provided." %}{% endif %}
@@ -82,13 +71,6 @@
{% trans "No speakers." %}
{% endfor %}
-{% trans "Track" %}
-{% if talk.track %}
-{{ talk.track }}
-{% else %}
-{% trans "No assigned yet." context "session" %}
-{% endif %}
-
{% trans "Notes" %}
{% if talk.notes %}{{ talk.notes|linebreaksbr }}{% else %}{% trans "No notes." %}{% endif %}
@@ -97,8 +79,6 @@
{% trans "Status" %}
-{{ talk.accepted|yesno:"Accepted,Declined,Pending decision" }}
-
{% if talk.accepted == None %}
{% trans "Vote" %}
diff --git a/cfp/templates/cfp/staff/talk_list.html b/cfp/templates/cfp/staff/talk_list.html
index 5276f0d..6503f4c 100644
--- a/cfp/templates/cfp/staff/talk_list.html
+++ b/cfp/templates/cfp/staff/talk_list.html
@@ -19,6 +19,8 @@
{% bootstrap_field filter_form.status layout="horizontal" %}
{% bootstrap_field filter_form.category layout="horizontal" %}
{% bootstrap_field filter_form.vote layout="horizontal" %}
+ {% bootstrap_field filter_form.scheduled layout="horizontal" %}
+ {% bootstrap_field filter_form.room layout="horizontal" %}
{% bootstrap_field filter_form.track layout="horizontal" %}
diff --git a/cfp/urls.py b/cfp/urls.py
index f80929c..fb0cd70 100644
--- a/cfp/urls.py
+++ b/cfp/urls.py
@@ -22,6 +22,10 @@ urlpatterns = [
url(r'^staff/tracks/$', views.TrackList.as_view(), name='track-list'),
url(r'^staff/tracks/add/$', views.TrackCreate.as_view(), name='track-add'),
url(r'^staff/tracks/(?P[-\w]+)/edit/$', views.TrackUpdate.as_view(), name='track-edit'),
+ url(r'^staff/rooms/$', views.RoomList.as_view(), name='room-list'),
+ url(r'^staff/rooms/add/$', views.RoomCreate.as_view(), name='room-add'),
+ url(r'^staff/rooms/(?P[-\w]+)/$', views.RoomDetail.as_view(), name='room-details'),
+ url(r'^staff/rooms/(?P[-\w]+)/edit/$', views.RoomUpdate.as_view(), name='room-edit'),
url(r'^staff/add-user/$', views.create_user, name='create-user'),
url(r'^staff/select2/$', views.Select2View.as_view(), name='django_select2-json'),
diff --git a/cfp/views.py b/cfp/views.py
index 0b1e9f0..7cbb1ed 100644
--- a/cfp/views.py
+++ b/cfp/views.py
@@ -17,8 +17,8 @@ from mailing.forms import MessageForm
from .decorators import staff_required
from .mixins import StaffRequiredMixin, OnSiteMixin
from .utils import is_staff
-from .models import Participant, Talk, TalkCategory, Vote, Track
-from .forms import TalkForm, TalkStaffForm, TalkFilterForm, ParticipantForm, ParticipantStaffForm, ConferenceForm, CreateUserForm, STATUS_VALUES, TrackForm
+from .models import Participant, Talk, TalkCategory, Vote, Track, Room
+from .forms import TalkForm, TalkStaffForm, TalkFilterForm, ParticipantForm, ParticipantStaffForm, ConferenceForm, CreateUserForm, STATUS_VALUES, TrackForm, RoomForm
def home(request, conference):
@@ -147,6 +147,12 @@ def talk_list(request, conference):
if len(data['status']):
show_filters = True
talks = talks.filter(reduce(lambda x, y: x | y, [Q(accepted=dict(STATUS_VALUES)[status]) for status in data['status']]))
+ if data['room'] != None:
+ show_filters = True
+ talks = talks.filter(room__isnull=not data['room'])
+ if data['scheduled'] != None:
+ show_filters = True
+ talks = talks.filter(start_date__isnull=not data['scheduled'])
if len(data['track']):
show_filters = True
q = Q()
@@ -380,6 +386,39 @@ class TrackUpdate(StaffRequiredMixin, TrackFormMixin, UpdateView):
pass
+class RoomMixin(OnSiteMixin):
+ model = Room
+
+
+class RoomList(StaffRequiredMixin, RoomMixin, ListView):
+ template_name = 'cfp/staff/room_list.html'
+
+
+class RoomDetail(StaffRequiredMixin, RoomMixin, DetailView):
+ template_name = 'cfp/staff/room_details.html'
+
+
+class RoomFormMixin(RoomMixin):
+ template_name = 'cfp/staff/room_form.html'
+ form_class = RoomForm
+ success_url = reverse_lazy('room-list')
+
+ def get_form_kwargs(self):
+ kwargs = super().get_form_kwargs()
+ kwargs.update({
+ 'conference': self.kwargs['conference'],
+ })
+ return kwargs
+
+
+class RoomCreate(StaffRequiredMixin, RoomFormMixin, CreateView):
+ pass
+
+
+class RoomUpdate(StaffRequiredMixin, RoomFormMixin, UpdateView):
+ pass
+
+
@staff_required
def create_user(request, conference):
form = CreateUserForm(request.POST or None)
diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo
index 1bffd0a..b25001e 100644
Binary files a/locale/fr/LC_MESSAGES/django.mo and b/locale/fr/LC_MESSAGES/django.mo differ
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index 8a4924b..2db855c 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-08-11 22:51+0000\n"
+"POT-Creation-Date: 2017-08-12 00:02+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -107,7 +107,7 @@ msgid "Biography"
msgstr "Biographie"
#: accounts/templates/accounts/participant_details.html:27
-#: cfp/templates/cfp/staff/base.html:18
+#: cfp/templates/cfp/staff/base.html:17
#: cfp/templates/cfp/staff/participant_details.html:33
#: cfp/templates/cfp/staff/talk_list.html:8
#: proposals/templates/proposals/talk_list.html:9
@@ -115,6 +115,7 @@ msgid "Talks"
msgstr "Exposés"
#: accounts/templates/accounts/participant_details.html:32
+#: cfp/templates/cfp/staff/talk_details.html:12
msgid "Information"
msgstr "Informations"
@@ -176,7 +177,7 @@ msgstr "Contraintes"
#: accounts/templates/accounts/participant_details.html:71 cfp/forms.py:53
#: cfp/models.py:100 cfp/templates/cfp/staff/participant_details.html:16
-#: cfp/templates/cfp/staff/talk_details.html:92 proposals/models.py:161
+#: cfp/templates/cfp/staff/talk_details.html:75 proposals/models.py:161
#: proposals/templates/proposals/talk_detail.html:102
msgid "Notes"
msgstr "Notes"
@@ -292,27 +293,27 @@ msgstr "%(name)s est déjà participant"
msgid "Pending decision"
msgstr "Décision en attente"
-#: cfp/forms.py:17 cfp/templates/cfp/staff/talk_list.html:64
+#: cfp/forms.py:17 cfp/templates/cfp/staff/talk_list.html:66
#: proposals/templates/proposals/talk_list.html:78
msgid "Accepted"
msgstr "Accepté"
-#: cfp/forms.py:18 cfp/templates/cfp/staff/talk_list.html:66
+#: cfp/forms.py:18 cfp/templates/cfp/staff/talk_list.html:68
#: proposals/templates/proposals/talk_list.html:80
msgid "Declined"
msgstr "Décliné"
-#: cfp/forms.py:50 cfp/forms.py:62 cfp/templates/cfp/staff/talk_details.html:67
+#: cfp/forms.py:50 cfp/forms.py:62 cfp/templates/cfp/staff/talk_details.html:15
msgid "Category"
msgstr "Catégorie"
-#: cfp/forms.py:51 cfp/templates/cfp/staff/talk_list.html:38
+#: cfp/forms.py:51 cfp/templates/cfp/staff/talk_list.html:40
#: proposals/models.py:155 proposals/templates/proposals/talk_list.html:47
msgid "Title"
msgstr "Titre"
-#: cfp/forms.py:52 cfp/models.py:159
-#: cfp/templates/cfp/staff/talk_details.html:71 proposals/models.py:54
+#: cfp/forms.py:52 cfp/models.py:135
+#: cfp/templates/cfp/staff/talk_details.html:61 proposals/models.py:54
#: proposals/models.py:77 proposals/models.py:158
#: proposals/templates/proposals/talk_detail.html:72 volunteers/models.py:14
msgid "Description"
@@ -322,16 +323,17 @@ msgstr "Description"
msgid "Visible by speakers"
msgstr "Visible par les orateurs"
-#: cfp/forms.py:68 cfp/templates/cfp/staff/talk_details.html:98
-#: cfp/templates/cfp/staff/talk_list.html:42
+#: cfp/forms.py:68 cfp/templates/cfp/staff/talk_details.html:18
+#: cfp/templates/cfp/staff/talk_details.html:81
+#: cfp/templates/cfp/staff/talk_list.html:44
#: proposals/templates/proposals/talk_detail.html:110
#: proposals/templates/proposals/talk_list.html:52
msgid "Status"
msgstr "Statut"
-#: cfp/forms.py:74 cfp/models.py:261
-#: cfp/templates/cfp/staff/talk_details.html:85
-#: cfp/templates/cfp/staff/talk_list.html:41
+#: cfp/forms.py:74 cfp/models.py:267
+#: cfp/templates/cfp/staff/talk_details.html:21
+#: cfp/templates/cfp/staff/talk_list.html:43
#: cfp/templates/cfp/staff/track_form.html:14 proposals/models.py:160
#: proposals/templates/proposals/talk_detail.html:33
#: proposals/templates/proposals/talk_detail.html:89
@@ -340,7 +342,7 @@ msgstr "Statut"
msgid "Track"
msgstr "Session"
-#: cfp/forms.py:80 cfp/templates/cfp/staff/talk_details.html:103
+#: cfp/forms.py:80 cfp/templates/cfp/staff/talk_details.html:84
#: proposals/templates/proposals/talk_detail.html:115
msgid "Vote"
msgstr "Vote"
@@ -351,27 +353,44 @@ msgstr ""
"Filtrer les propositions pour lesquelles vous avez déjà voté / pas encore "
"voté"
-#: cfp/forms.py:90
+#: cfp/forms.py:84 cfp/templates/cfp/staff/room_form.html:14
+#: cfp/templates/cfp/staff/talk_details.html:35
+msgid "Room"
+msgstr "Salle"
+
+#: cfp/forms.py:85 proposals/forms.py:73
+msgid "Filter talks already / not yet affected to a room"
+msgstr "Filtrer les exposés déjà / pas encore affectées à une salle"
+
+#: cfp/forms.py:88
+msgid "Scheduled"
+msgstr "Programmé"
+
+#: cfp/forms.py:89 proposals/forms.py:74
+msgid "Filter talks already / not yet scheduled"
+msgstr "Filtrer les exposés déjà / pas encore planifiées"
+
+#: cfp/forms.py:98
msgid "Not assigned"
msgstr "Pas encore assignée."
-#: cfp/forms.py:99 cfp/models.py:157
+#: cfp/forms.py:107 cfp/models.py:133
#: cfp/templates/cfp/staff/participant_list.html:49 proposals/models.py:52
#: proposals/models.py:75 proposals/models.py:132 volunteers/models.py:12
msgid "Name"
msgstr "Nom"
-#: cfp/forms.py:116
+#: cfp/forms.py:124
msgid "New staff members will be informed of their new position by e-mail."
msgstr ""
"Les nouveaux membres du staff seront informés de leur nouveau rôle par "
"courrier électronique."
-#: cfp/forms.py:136
+#: cfp/forms.py:144
msgid "An user with that firstname and that lastname already exists."
msgstr "Un utilisateur avec ce prénom et ce nom existe déjà."
-#: cfp/forms.py:141
+#: cfp/forms.py:149
msgid "A user with that email already exists."
msgstr "Un utilisateur avec cet email existe déjà."
@@ -424,41 +443,41 @@ msgstr "Votre Nom"
msgid "This field is only visible by organizers."
msgstr "Ce champs est uniquement visible par les organisateurs."
-#: cfp/models.py:180 proposals/models.py:96
+#: cfp/models.py:187 proposals/models.py:96
msgid "Default duration (min)"
msgstr "Durée par défaut (min)"
-#: cfp/models.py:181 proposals/models.py:97
+#: cfp/models.py:188 proposals/models.py:97
msgid "Color on program"
msgstr "Couleur sur le programme"
-#: cfp/models.py:182 proposals/models.py:98
+#: cfp/models.py:189 proposals/models.py:98
msgid "Label on program"
msgstr "Label dans le xml du programme"
-#: cfp/models.py:256 cfp/templates/cfp/staff/base.html:19
+#: cfp/models.py:262 cfp/templates/cfp/staff/base.html:18
#: cfp/templates/cfp/staff/participant_list.html:8
-#: cfp/templates/cfp/staff/talk_details.html:75
-#: cfp/templates/cfp/staff/talk_list.html:40 proposals/models.py:154
+#: cfp/templates/cfp/staff/talk_details.html:65
+#: cfp/templates/cfp/staff/talk_list.html:42 proposals/models.py:154
#: proposals/templates/proposals/speaker_list.html:9
#: proposals/templates/proposals/talk_detail.html:76
#: proposals/templates/proposals/talk_list.html:49
msgid "Speakers"
msgstr "Orateurs"
-#: cfp/models.py:257
+#: cfp/models.py:263
msgid "Talk Title"
msgstr "Titre de votre proposition:"
-#: cfp/models.py:260
+#: cfp/models.py:266
msgid "Description of your talk"
msgstr "Description de votre proposition"
-#: cfp/models.py:262
+#: cfp/models.py:268
msgid "Message to organizers"
msgstr "Message aux organisateurs"
-#: cfp/models.py:262
+#: cfp/models.py:268
msgid ""
"If you have any constraint or if you have anything that may help you to "
"select your talk, like a video or slides of your talk, please write it down "
@@ -468,23 +487,27 @@ msgstr ""
"votre proposition, comme une vidéo, des slides, n'hésitez pas à les ajouter "
"ici."
-#: cfp/models.py:263
+#: cfp/models.py:269
msgid "Talk Category"
msgstr "Catégorie de proposition"
-#: cfp/models.py:264
+#: cfp/models.py:270
msgid "I'm ok to be recorded on video"
msgstr "J’accepte d’être enregistré en vidéo"
-#: cfp/models.py:265
+#: cfp/models.py:271
msgid "Video licence"
msgstr "Licence vidéo"
-#: cfp/models.py:266
+#: cfp/models.py:272
msgid "I need sound"
msgstr "J’ai besoin de son"
-#: cfp/models.py:269 proposals/models.py:165
+#: cfp/models.py:274
+msgid "Beginning date and time"
+msgstr "Date et heure de début"
+
+#: cfp/models.py:275 proposals/models.py:165
msgid "Duration (min)"
msgstr "Durée (min)"
@@ -547,12 +570,18 @@ msgstr "Un mail vous a été envoyé avec toutes les URLs"
msgid "Save"
msgstr "Envoyer"
-#: cfp/templates/cfp/staff/base.html:20
+#: cfp/templates/cfp/staff/base.html:19
#: cfp/templates/cfp/staff/track_list.html:9
#: proposals/templates/proposals/track_list.html:9
msgid "Tracks"
msgstr "Sessions"
+#: cfp/templates/cfp/staff/base.html:20
+#: cfp/templates/cfp/staff/room_list.html:9
+#: planning/templates/planning/room_list.html:9
+msgid "Rooms"
+msgstr "Salles"
+
#: cfp/templates/cfp/staff/base.html:21
#: cfp/templates/cfp/staff/conference.html:8
msgid "Conference"
@@ -613,7 +642,9 @@ msgid "by"
msgstr "par"
#: cfp/templates/cfp/staff/participant_details.html:43
-#: cfp/templates/cfp/staff/talk_list.html:57
+#: cfp/templates/cfp/staff/room_details.html:21
+#: cfp/templates/cfp/staff/room_details.html:39
+#: cfp/templates/cfp/staff/talk_list.html:59
#: proposals/templates/proposals/_talk_list.html:11
#: proposals/templates/proposals/_talk_list.html:17
#: proposals/templates/proposals/talk_list.html:66
@@ -631,7 +662,7 @@ msgid "No talks"
msgstr "Aucun exposé"
#: cfp/templates/cfp/staff/participant_details.html:55
-#: cfp/templates/cfp/staff/talk_details.html:133
+#: cfp/templates/cfp/staff/talk_details.html:114
msgid "Messaging"
msgstr "Messagerie"
@@ -648,7 +679,7 @@ msgid "Edit a speaker"
msgstr "Éditer un orateur"
#: cfp/templates/cfp/staff/participant_list.html:45
-#: cfp/templates/cfp/staff/talk_list.html:33
+#: cfp/templates/cfp/staff/talk_list.html:35
#: proposals/templates/proposals/speaker_list.html:44
#: proposals/templates/proposals/talk_list.html:43
#: volunteers/templates/volunteers/volunteer_list.html:25
@@ -686,6 +717,54 @@ msgid_plural "refused: %(refused)s"
msgstr[0] "refusé : %(refused)s"
msgstr[1] "refusés : %(refused)s"
+#: cfp/templates/cfp/staff/room_details.html:13
+#: planning/templates/planning/room_detail.html:14
+msgid "Scheduled talks"
+msgstr "Exposés planifiés"
+
+#: cfp/templates/cfp/staff/room_details.html:28
+#: cfp/templates/cfp/staff/room_details.html:45
+#: planning/templates/planning/room_detail.html:23
+#: planning/templates/planning/room_detail.html:34
+msgid "No talks."
+msgstr "Aucun exposé."
+
+#: cfp/templates/cfp/staff/room_details.html:31
+#: planning/templates/planning/room_detail.html:26
+msgid "Unscheduled talks"
+msgstr "Exposés non planifiés"
+
+#: cfp/templates/cfp/staff/room_list.html:11
+#: planning/templates/planning/room_form.html:14
+#: planning/templates/planning/room_list.html:12
+msgid "Add a room"
+msgstr "Ajouter une salle"
+
+#: cfp/templates/cfp/staff/room_list.html:21
+#: planning/templates/planning/room_list.html:24
+msgid "place"
+msgstr "place"
+
+#: cfp/templates/cfp/staff/room_list.html:23
+#: planning/templates/planning/room_list.html:27
+msgid "Some talks are not scheduled yet."
+msgstr "Certains exposés ne sont pas encore planifiés."
+
+#: cfp/templates/cfp/staff/room_list.html:24
+#: cfp/templates/cfp/staff/talk_list.html:35
+#: cfp/templates/cfp/staff/track_list.html:21
+#: planning/templates/planning/room_list.html:28
+#: proposals/templates/proposals/talk_list.html:43
+#: proposals/templates/proposals/topic_list.html:23
+#: proposals/templates/proposals/track_list.html:23
+msgid "talk"
+msgstr "exposé"
+
+#: cfp/templates/cfp/staff/room_list.html:33
+#: planning/templates/planning/room_list.html:40
+msgid "No rooms."
+msgstr "Aucune salle."
+
#: cfp/templates/cfp/staff/talk_decide.html:8
#: proposals/templates/proposals/talk_decide.html:9
msgid "Are you sure to accept this proposals?"
@@ -736,47 +815,53 @@ msgstr "Accepter la proposition"
msgid "Decline the proposal"
msgstr "Décliner la proposition"
-#: cfp/templates/cfp/staff/talk_details.html:12
-#: proposals/templates/proposals/talk_detail.html:19
-msgid "No abstract provided."
-msgstr "Aucun résumé fourni."
-
-#: cfp/templates/cfp/staff/talk_details.html:73
-#: proposals/templates/proposals/talk_detail.html:74
-msgid "No description provided."
-msgstr "Aucune description fournie."
-
-#: cfp/templates/cfp/staff/talk_details.html:82
-#: proposals/templates/proposals/talk_detail.html:83
-msgid "No speakers."
-msgstr "Aucun orateur."
-
-#: cfp/templates/cfp/staff/talk_details.html:89
+#: cfp/templates/cfp/staff/talk_details.html:25
msgctxt "session"
msgid "No assigned yet."
msgstr "Pas encore assignée."
-#: cfp/templates/cfp/staff/talk_details.html:94
+#: cfp/templates/cfp/staff/talk_details.html:28
+msgid "Timeslot"
+msgstr "Créneau"
+
+#: cfp/templates/cfp/staff/talk_details.html:32
+#: cfp/templates/cfp/staff/talk_details.html:40
+#: proposals/templates/proposals/talk_detail.html:44
+#: proposals/templates/proposals/talk_detail.html:52
+msgid "not defined"
+msgstr "non défini"
+
+#: cfp/templates/cfp/staff/talk_details.html:63
+#: proposals/templates/proposals/talk_detail.html:74
+msgid "No description provided."
+msgstr "Aucune description fournie."
+
+#: cfp/templates/cfp/staff/talk_details.html:72
+#: proposals/templates/proposals/talk_detail.html:83
+msgid "No speakers."
+msgstr "Aucun orateur."
+
+#: cfp/templates/cfp/staff/talk_details.html:77
#: proposals/templates/proposals/talk_detail.html:104
msgid "No notes."
msgstr "Aucune note."
-#: cfp/templates/cfp/staff/talk_details.html:96
+#: cfp/templates/cfp/staff/talk_details.html:79
#: proposals/templates/proposals/talk_detail.html:108
msgid "Moderation"
msgstr "Modération"
-#: cfp/templates/cfp/staff/talk_details.html:112
+#: cfp/templates/cfp/staff/talk_details.html:93
#: proposals/templates/proposals/talk_detail.html:124
msgid "vote"
msgstr "vote"
-#: cfp/templates/cfp/staff/talk_details.html:112
+#: cfp/templates/cfp/staff/talk_details.html:93
#: proposals/templates/proposals/talk_detail.html:124
msgid "average:"
msgstr "moyenne :"
-#: cfp/templates/cfp/staff/talk_details.html:137
+#: cfp/templates/cfp/staff/talk_details.html:118
msgid ""
"Comment this talk – this message will be received by the staff team "
"only"
@@ -796,28 +881,19 @@ msgstr "Éditer un exposé"
msgid "Show filtering options…"
msgstr "Afficher les options de filtrage…"
-#: cfp/templates/cfp/staff/talk_list.html:27
+#: cfp/templates/cfp/staff/talk_list.html:29
#: proposals/templates/proposals/speaker_list.html:38
#: proposals/templates/proposals/talk_list.html:35
#: volunteers/templates/volunteers/volunteer_list.html:19
msgid "Filter"
msgstr "Filtrer"
-#: cfp/templates/cfp/staff/talk_list.html:33
-#: cfp/templates/cfp/staff/track_list.html:21
-#: planning/templates/planning/room_list.html:28
-#: proposals/templates/proposals/talk_list.html:43
-#: proposals/templates/proposals/topic_list.html:23
-#: proposals/templates/proposals/track_list.html:23
-msgid "talk"
-msgstr "exposé"
-
-#: cfp/templates/cfp/staff/talk_list.html:39 proposals/models.py:162
+#: cfp/templates/cfp/staff/talk_list.html:41 proposals/models.py:162
#: proposals/templates/proposals/talk_list.html:48
msgid "Intervention kind"
msgstr "Type d’intervention"
-#: cfp/templates/cfp/staff/talk_list.html:68
+#: cfp/templates/cfp/staff/talk_list.html:70
#: proposals/templates/proposals/talk_list.html:82
#, python-format
msgid "Pending, score: %(score)s"
@@ -878,35 +954,35 @@ msgstr ""
"{}\n"
"\n"
-#: cfp/views.py:218 cfp/views.py:278
+#: cfp/views.py:224 cfp/views.py:286
msgid "Message sent!"
msgstr "Message envoyé !"
-#: cfp/views.py:231 proposals/views.py:321
+#: cfp/views.py:237 proposals/views.py:321
msgid "Vote successfully created"
msgstr "A voté !"
-#: cfp/views.py:231 proposals/views.py:321
+#: cfp/views.py:237 proposals/views.py:321
msgid "Vote successfully updated"
msgstr "Vote mis à jour"
-#: cfp/views.py:246
+#: cfp/views.py:252
msgid "The talk has been accepted."
msgstr "L’exposé a été accepté."
-#: cfp/views.py:248
+#: cfp/views.py:254
msgid "The talk has been declined."
msgstr "L’exposé a été décliné."
-#: cfp/views.py:252 proposals/views.py:347
+#: cfp/views.py:258 proposals/views.py:347
msgid "Decision taken in account"
msgstr "Décision enregistrée"
-#: cfp/views.py:306
+#: cfp/views.py:314
msgid "[{}] You have been added to the staff team"
msgstr "[{}] Vous avez été ajouté aux membres du staff"
-#: cfp/views.py:307
+#: cfp/views.py:315
msgid ""
"Hi {},\n"
"\n"
@@ -930,11 +1006,11 @@ msgstr ""
"{}\n"
"\n"
-#: cfp/views.py:328
+#: cfp/views.py:336
msgid "Modifications successfully saved."
msgstr "Modification enregistrée avec succès."
-#: cfp/views.py:387
+#: cfp/views.py:428
msgid "User created successfully."
msgstr "Utilisateur créé avec succès."
@@ -956,49 +1032,15 @@ msgstr "Aucun message."
msgid "Schedule"
msgstr "Programme"
-#: planning/templates/planning/room_detail.html:14
-msgid "Scheduled talks"
-msgstr "Exposés planifiés"
-
-#: planning/templates/planning/room_detail.html:23
-#: planning/templates/planning/room_detail.html:34
-msgid "No talks."
-msgstr "Aucun exposé."
-
-#: planning/templates/planning/room_detail.html:26
-msgid "Unscheduled talks"
-msgstr "Exposés non planifiés"
-
#: planning/templates/planning/room_form.html:14
msgid "Modify the room"
msgstr "Modifier la salle"
-#: planning/templates/planning/room_form.html:14
-#: planning/templates/planning/room_list.html:12
-msgid "Add a room"
-msgstr "Ajouter une salle"
-
-#: planning/templates/planning/room_list.html:9
-msgid "Rooms"
-msgstr "Salles"
-
-#: planning/templates/planning/room_list.html:24
-msgid "place"
-msgstr "place"
-
-#: planning/templates/planning/room_list.html:27
-msgid "Some talks are not scheduled yet."
-msgstr "Certains exposés ne sont pas encore planifiés."
-
-#: planning/templates/planning/room_list.html:40
-msgid "No rooms."
-msgstr "Aucune salle."
-
-#: ponyconf/settings.py:146
+#: ponyconf/settings.py:145
msgid "English"
msgstr "Anglais"
-#: ponyconf/settings.py:147
+#: ponyconf/settings.py:146
msgid "French"
msgstr "Français"
@@ -1016,7 +1058,7 @@ msgstr "Staff"
#: ponyconf/templates/base.html:48
msgid "Logout"
-msgstr ""
+msgstr "Déconnection"
#: ponyconf/templates/base.html:67
msgid "Powered by"
@@ -1044,7 +1086,7 @@ msgstr "Changement de mot de passe"
#: ponyconf/urls.py:27
msgid "Email address"
-msgstr ""
+msgstr "Adresse e-mail"
#: proposals/forms.py:46
msgid "Should be less than 255 characters"
@@ -1054,14 +1096,6 @@ msgstr "Texte court, moins de 255 caractères"
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:73
-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:74
-msgid "Filter talks already / not yet scheduled"
-msgstr "Filtrer les exposés déjà / pas encore planifiées"
-
#: proposals/forms.py:75
msgid "Filter talks with / without materials"
msgstr "Filtrer les exposés avec / sans supports"
@@ -1237,6 +1271,10 @@ msgstr "Contacter :"
msgid "link"
msgstr "lien"
+#: proposals/templates/proposals/talk_detail.html:19
+msgid "No abstract provided."
+msgstr "Aucun résumé fourni."
+
#: proposals/templates/proposals/talk_detail.html:24
msgid "Format"
msgstr "Format"
@@ -1251,11 +1289,6 @@ msgstr "Aucun thème."
msgid "No assigned yet."
msgstr "Pas encore assigné."
-#: 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:56
msgid "Registrations"
msgstr "Inscriptions"
diff --git a/planning/forms.py b/planning/forms.py
index 3f4c12f..95443d0 100644
--- a/planning/forms.py
+++ b/planning/forms.py
@@ -4,16 +4,17 @@ from .models import Room
class RoomForm(forms.ModelForm):
+ class Meta:
+ model = Room
+ fields = ['name', 'label', 'capacity']
+
def __init__(self, *args, **kwargs):
self.site = kwargs.pop('site')
super().__init__(*args, **kwargs)
- class Meta:
- model = Room
- fields = ['name', 'label', 'capacity', 'sound']
-
def clean_name(self):
name = self.cleaned_data['name']
- if self.instance and name != self.instance.name and Room.objects.filter(site=self.site, name=name).exists():
+ if (not self.instance or self.instance.name != name) \
+ and Room.objects.filter(site=self.site, name=name).exists():
raise self.instance.unique_error_message(self._meta.model, ['name'])
return name
diff --git a/planning/migrations/0002_room_sound.py b/planning/migrations/0002_room_sound.py
deleted file mode 100644
index c6106dd..0000000
--- a/planning/migrations/0002_room_sound.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.7 on 2017-05-26 11:18
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('planning', '0001_initial'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='room',
- name='sound',
- field=models.BooleanField(default=False),
- ),
- ]
diff --git a/planning/models.py b/planning/models.py
index 4cebb46..4454805 100644
--- a/planning/models.py
+++ b/planning/models.py
@@ -14,7 +14,6 @@ class Room(models.Model):
name = models.CharField(max_length=256, blank=True, default="")
label = models.CharField(max_length=256, blank=True, default="")
capacity = models.IntegerField(default=0)
- sound = models.BooleanField(default=False)
class Meta:
unique_together = ['site', 'name']
diff --git a/ponyconf/settings.py b/ponyconf/settings.py
index f1a67d4..f6664dd 100644
--- a/ponyconf/settings.py
+++ b/ponyconf/settings.py
@@ -42,7 +42,6 @@ INSTALLED_APPS = [
'cfp',
'mailing',
#'proposals',
- #'conversations',
#'planning',
#'volunteers',