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 %} +
    +

    + {{ room }} +

    + {% 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',