talk materials (file upload)

This commit is contained in:
Élie Bouttier 2016-11-24 00:39:19 +01:00
parent dbadfebad3
commit 530b99b1fe
9 changed files with 109 additions and 63 deletions

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-11-23 17:45+0000\n" "POT-Creation-Date: 2016-11-23 23:36+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -93,7 +93,7 @@ msgstr "Licence vidéo"
#: accounts/models.py:81 #: accounts/models.py:81
#: accounts/templates/accounts/participant_details.html:71 #: accounts/templates/accounts/participant_details.html:71
#: proposals/models.py:156 proposals/templates/proposals/talk_detail.html:94 #: proposals/models.py:161 proposals/templates/proposals/talk_detail.html:98
msgid "Notes" msgid "Notes"
msgstr "Notes" msgstr "Notes"
@ -470,7 +470,7 @@ msgstr "Sinscrire"
msgid "Powered by" msgid "Powered by"
msgstr "Propulsé par" msgstr "Propulsé par"
#: ponyconf/templates/staff.html:9 proposals/models.py:154 #: ponyconf/templates/staff.html:9 proposals/models.py:159
#: proposals/templates/proposals/talk_detail.html:26 #: proposals/templates/proposals/talk_detail.html:26
#: proposals/templates/proposals/talk_list.html:48 #: proposals/templates/proposals/talk_list.html:48
#: proposals/templates/proposals/topic_list.html:9 #: proposals/templates/proposals/topic_list.html:9
@ -482,9 +482,9 @@ msgstr "Thèmes"
msgid "Tracks" msgid "Tracks"
msgstr "Sessions" msgstr "Sessions"
#: ponyconf/templates/staff.html:12 proposals/models.py:149 #: ponyconf/templates/staff.html:12 proposals/models.py:154
#: proposals/templates/proposals/speaker_list.html:9 #: proposals/templates/proposals/speaker_list.html:9
#: proposals/templates/proposals/talk_detail.html:68 #: proposals/templates/proposals/talk_detail.html:72
#: proposals/templates/proposals/talk_list.html:47 #: proposals/templates/proposals/talk_list.html:47
msgid "Speakers" msgid "Speakers"
msgstr "Orateurs" msgstr "Orateurs"
@ -498,135 +498,144 @@ msgstr "Bénévoles"
msgid "Conference" msgid "Conference"
msgstr "Conférence" msgstr "Conférence"
#: proposals/forms.py:45 #: proposals/forms.py:46
msgid "Should be less than 255 characters" msgid "Should be less than 255 characters"
msgstr "Texte court, moins de 255 caractères" msgstr "Texte court, moins de 255 caractères"
#: proposals/forms.py:46 #: proposals/forms.py:47
msgid "If you want to add some precisions for the organizers." msgid "If you want to add some precisions for the organizers."
msgstr "Si vous souhaitez apporter des précisions à l'équipe d'organisation." msgstr "Si vous souhaitez apporter des précisions à l'équipe d'organisation."
#: proposals/forms.py:71 #: proposals/forms.py:72
msgid "Filter talks you already / not yet voted for" msgid "Filter talks you already / not yet voted for"
msgstr "" msgstr ""
"Filtrer les propositions pour lesquelles vous avez déjà voté / pas encore " "Filtrer les propositions pour lesquelles vous avez déjà voté / pas encore "
"voté" "voté"
#: proposals/forms.py:72 #: proposals/forms.py:73
msgid "Filter talks already / not yet affected to a room" msgid "Filter talks already / not yet affected to a room"
msgstr "Filtrer les exposés déjà / pas encore affectées à une salle" msgstr "Filtrer les exposés déjà / pas encore affectées à une salle"
#: proposals/forms.py:73 #: proposals/forms.py:74
msgid "Filter talks already / not yet scheduled" msgid "Filter talks already / not yet scheduled"
msgstr "Filtrer les exposés déjà / pas encore planifiées" msgstr "Filtrer les exposés déjà / pas encore planifiées"
#: proposals/forms.py:88 #: proposals/forms.py:89
msgid "Accept talk?" msgid "Accept talk?"
msgstr "Accepter la proposition ?" msgstr "Accepter la proposition ?"
#: proposals/forms.py:89 #: proposals/forms.py:90
msgid "Assign to a track" msgid "Assign to a track"
msgstr "Assigner à une session" msgstr "Assigner à une session"
#: proposals/forms.py:90 #: proposals/forms.py:91
msgid "Put in a room" msgid "Put in a room"
msgstr "Assigner à une salle" msgstr "Assigner à une salle"
#: proposals/forms.py:192 #: proposals/forms.py:193
msgid "Name or nickname" msgid "Name or nickname"
msgstr "Nom ou pseudo" msgstr "Nom ou pseudo"
#: proposals/forms.py:193 #: proposals/forms.py:194
msgid "How much is 3+4?" msgid "How much is 3+4?"
msgstr "Combien font 3+4 ?" msgstr "Combien font 3+4 ?"
#: proposals/forms.py:193 #: proposals/forms.py:194
msgid "Anti-bot" msgid "Anti-bot"
msgstr "Anti-robot" msgstr "Anti-robot"
#: proposals/forms.py:198 #: proposals/forms.py:199
msgid "Please re-do the maths." msgid "Please re-do the maths."
msgstr "Refaites les calculs." msgstr "Refaites les calculs."
#: proposals/models.py:51 proposals/models.py:74 proposals/models.py:131 #: proposals/models.py:52 proposals/models.py:75 proposals/models.py:132
#: volunteers/models.py:12 #: volunteers/models.py:12
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
#: proposals/models.py:53 proposals/models.py:76 proposals/models.py:153 #: proposals/models.py:54 proposals/models.py:77 proposals/models.py:158
#: proposals/templates/proposals/talk_detail.html:64 volunteers/models.py:14 #: proposals/templates/proposals/talk_detail.html:68 volunteers/models.py:14
msgid "Description" msgid "Description"
msgstr "Description" msgstr "Description"
#: proposals/models.py:55 #: proposals/models.py:56
msgid "Managers" msgid "Managers"
msgstr "Responsables" msgstr "Responsables"
#: proposals/models.py:77 #: proposals/models.py:78
msgid "Destination track" msgid "Destination track"
msgstr "Session de destination" msgstr "Session de destination"
#: proposals/models.py:79 #: proposals/models.py:80
msgid "Reviewers" msgid "Reviewers"
msgstr "Responsables" msgstr "Responsables"
#: proposals/models.py:95 #: proposals/models.py:96
msgid "Default duration (min)" msgid "Default duration (min)"
msgstr "Durée par défaut (min)" msgstr "Durée par défaut (min)"
#: proposals/models.py:96 #: proposals/models.py:97
msgid "Color on program" msgid "Color on program"
msgstr "Couleur sur le programme" msgstr "Couleur sur le programme"
#: proposals/models.py:97 #: proposals/models.py:98
msgid "Label on program" msgid "Label on program"
msgstr "Label dans le xml du programme" msgstr "Label dans le xml du programme"
#: proposals/models.py:138 #: proposals/models.py:139
msgid "Email" msgid "Email"
msgstr "E-mail" msgstr "E-mail"
#: proposals/models.py:150 proposals/templates/proposals/talk_list.html:45 #: proposals/models.py:155 proposals/templates/proposals/talk_list.html:45
msgid "Title" msgid "Title"
msgstr "Titre" msgstr "Titre"
#: proposals/models.py:150 #: proposals/models.py:155
msgid "After submission, title can only be changed by the staff." msgid "After submission, title can only be changed by the staff."
msgstr "" msgstr ""
"Après soumission, le titre ne peut être modifié que par léquipe " "Après soumission, le titre ne peut être modifié que par léquipe "
"dorganisation." "dorganisation."
#: proposals/models.py:152 #: proposals/models.py:157
msgid "Abstract" msgid "Abstract"
msgstr "Résumé" msgstr "Résumé"
#: proposals/models.py:154 #: proposals/models.py:159
msgid "The topics can not be changed after submission." msgid "The topics can not be changed after submission."
msgstr "Les thèmes ne peuvent pas être modifiés après soumission." msgstr "Les thèmes ne peuvent pas être modifiés après soumission."
#: proposals/models.py:155 proposals/templates/proposals/talk_detail.html:33 #: proposals/models.py:160 proposals/templates/proposals/talk_detail.html:33
#: proposals/templates/proposals/talk_detail.html:81 #: proposals/templates/proposals/talk_detail.html:85
#: proposals/templates/proposals/talk_list.html:49 #: proposals/templates/proposals/talk_list.html:49
#: proposals/templates/proposals/track_form.html:14 #: proposals/templates/proposals/track_form.html:14
msgid "Track" msgid "Track"
msgstr "Session" msgstr "Session"
#: proposals/models.py:157 proposals/templates/proposals/talk_list.html:46 #: proposals/models.py:162 proposals/templates/proposals/talk_list.html:46
msgid "Intervention kind" msgid "Intervention kind"
msgstr "Type dintervention" msgstr "Type dintervention"
#: proposals/models.py:160 #: proposals/models.py:165
msgid "Duration (min)" msgid "Duration (min)"
msgstr "Durée (min)" msgstr "Durée (min)"
#: proposals/models.py:164 proposals/templates/proposals/talk_detail.html:123 #: proposals/models.py:169 proposals/templates/proposals/talk_detail.html:127
msgid "Attendees" msgid "Attendees"
msgstr "Inscrits" msgstr "Inscrits"
#: proposals/models.py:165 #: proposals/models.py:170
msgid "Max. number of attendees" msgid "Max. number of attendees"
msgstr "Nombre maximum dinscrits" msgstr "Nombre maximum dinscrits"
#: proposals/models.py:171 proposals/templates/proposals/talk_detail.html:60
msgid "Materials"
msgstr "Supports"
#: proposals/models.py:172
msgid ""
"You can use this field to share some materials related to your intervention."
msgstr "Vous pouvez utiliser ce champs pour partager les supports de votre intervention."
#: proposals/signals.py:28 #: proposals/signals.py:28
msgid "conference (short)" msgid "conference (short)"
msgstr "conférence (courte)" msgstr "conférence (courte)"
@ -814,7 +823,7 @@ msgid "No topics."
msgstr "Aucun thème." msgstr "Aucun thème."
#: proposals/templates/proposals/talk_detail.html:37 #: proposals/templates/proposals/talk_detail.html:37
#: proposals/templates/proposals/talk_detail.html:82 #: proposals/templates/proposals/talk_detail.html:86
msgid "No assigned yet." msgid "No assigned yet."
msgstr "Pas encore assigné." msgstr "Pas encore assigné."
@ -831,52 +840,52 @@ msgstr "Inscriptions"
msgid "required but unlimited" msgid "required but unlimited"
msgstr "requis mais non limité" msgstr "requis mais non limité"
#: proposals/templates/proposals/talk_detail.html:66 #: proposals/templates/proposals/talk_detail.html:70
msgid "No description provided." msgid "No description provided."
msgstr "Aucune description fournie." msgstr "Aucune description fournie."
#: proposals/templates/proposals/talk_detail.html:75 #: proposals/templates/proposals/talk_detail.html:79
msgid "No speakers." msgid "No speakers."
msgstr "Aucun orateur." msgstr "Aucun orateur."
#: proposals/templates/proposals/talk_detail.html:86 #: proposals/templates/proposals/talk_detail.html:90
msgid "Assign to" msgid "Assign to"
msgstr "Assigner à" msgstr "Assigner à"
#: proposals/templates/proposals/talk_detail.html:96 #: proposals/templates/proposals/talk_detail.html:100
msgid "No notes." msgid "No notes."
msgstr "Aucune note." msgstr "Aucune note."
#: proposals/templates/proposals/talk_detail.html:100 #: proposals/templates/proposals/talk_detail.html:104
msgid "Moderation" msgid "Moderation"
msgstr "Modération" msgstr "Modération"
#: proposals/templates/proposals/talk_detail.html:102 #: proposals/templates/proposals/talk_detail.html:106
#: proposals/templates/proposals/talk_list.html:50 #: proposals/templates/proposals/talk_list.html:50
msgid "Status" msgid "Status"
msgstr "Statut" msgstr "Statut"
#: proposals/templates/proposals/talk_detail.html:107 #: proposals/templates/proposals/talk_detail.html:111
msgid "Vote" msgid "Vote"
msgstr "Vote" msgstr "Vote"
#: proposals/templates/proposals/talk_detail.html:116 #: proposals/templates/proposals/talk_detail.html:120
msgid "vote" msgid "vote"
msgstr "vote" msgstr "vote"
#: proposals/templates/proposals/talk_detail.html:116 #: proposals/templates/proposals/talk_detail.html:120
msgid "average:" msgid "average:"
msgstr "moyenne :" msgstr "moyenne :"
#: proposals/templates/proposals/talk_detail.html:130 #: proposals/templates/proposals/talk_detail.html:134
msgid "No attendees yet." msgid "No attendees yet."
msgstr "Il ny a pas encore dinscrit." msgstr "Il ny a pas encore dinscrit."
#: proposals/templates/proposals/talk_detail.html:135 #: proposals/templates/proposals/talk_detail.html:139
msgid "Messages" msgid "Messages"
msgstr "Messages" msgstr "Messages"
#: proposals/templates/proposals/talk_detail.html:136 #: proposals/templates/proposals/talk_detail.html:140
msgid "These messages are for organization team only." msgid "These messages are for organization team only."
msgstr "Ces messages sont à destination de la team dorganisation seulement." msgstr "Ces messages sont à destination de la team dorganisation seulement."
@ -966,39 +975,39 @@ msgid_plural "Note: the room %(room)s has %(capacity)s seats."
msgstr[0] "Note : la salle %(room)s a %(capacity)s place." msgstr[0] "Note : la salle %(room)s a %(capacity)s place."
msgstr[1] "Note : la salle %(room)s a %(capacity)s places." msgstr[1] "Note : la salle %(room)s a %(capacity)s places."
#: proposals/views.py:211 #: proposals/views.py:212
msgid "Talk modified successfully!" msgid "Talk modified successfully!"
msgstr "Exposé modifié avec succès !" msgstr "Exposé modifié avec succès !"
#: proposals/views.py:217 #: proposals/views.py:218
msgid "Talk proposed successfully!" msgid "Talk proposed successfully!"
msgstr "Exposé proposé avec succès !" msgstr "Exposé proposé avec succès !"
#: proposals/views.py:234 #: proposals/views.py:235
msgid "Talk assigned to track successfully!" msgid "Talk assigned to track successfully!"
msgstr "Exposé assigné à la session avec succès !" msgstr "Exposé assigné à la session avec succès !"
#: proposals/views.py:307 #: proposals/views.py:308
msgid "Vote successfully created" msgid "Vote successfully created"
msgstr "A voté !" msgstr "A voté !"
#: proposals/views.py:307 #: proposals/views.py:308
msgid "Vote successfully updated" msgid "Vote successfully updated"
msgstr "Vote mis à jour" msgstr "Vote mis à jour"
#: proposals/views.py:333 #: proposals/views.py:334
msgid "Decision taken in account" msgid "Decision taken in account"
msgstr "Décision enregistrée" msgstr "Décision enregistrée"
#: proposals/views.py:431 #: proposals/views.py:432
msgid "Unregistered :-(" msgid "Unregistered :-("
msgstr "Vous avez été désinscrit :-(" msgstr "Vous avez été désinscrit :-("
#: proposals/views.py:433 #: proposals/views.py:434
msgid "Already registered!" msgid "Already registered!"
msgstr "Vous êtes déjà inscrit !" msgstr "Vous êtes déjà inscrit !"
#: proposals/views.py:438 #: proposals/views.py:439
msgid "Registered!" msgid "Registered!"
msgstr "Vous avez été inscrit !" msgstr "Vous avez été inscrit !"

View File

@ -1,5 +1,5 @@
{% load bootstrap3 i18n %} {% load bootstrap3 i18n %}
<form action="" method="post" class="form-horizontal"> <form action="" method="post" class="form-horizontal"{% if multipart %} enctype=multipart/form-data{% endif %}>
{% csrf_token %} {% csrf_token %}
{% block beforeform %}{% endblock %} {% block beforeform %}{% endblock %}
{% if form %} {% if form %}

View File

@ -28,6 +28,7 @@ class TalkForm(forms.ModelForm):
super(TalkForm, self).__init__(*args, **kwargs) super(TalkForm, self).__init__(*args, **kwargs)
self.fields['topics'].queryset = Topic.objects.filter(site=site) self.fields['topics'].queryset = Topic.objects.filter(site=site)
self.fields['track'].queryset = Track.objects.filter(site=site) self.fields['track'].queryset = Track.objects.filter(site=site)
self.fields['materials'].required = False
if staff: if staff:
self.fields['event'].queryset = Event.objects.filter(site=site) self.fields['event'].queryset = Event.objects.filter(site=site)
else: else:
@ -39,7 +40,7 @@ class TalkForm(forms.ModelForm):
class Meta: class Meta:
model = Talk model = Talk
fields = ['title', 'abstract', 'description', 'topics', 'track', 'notes', 'event', 'speakers', 'duration', 'start_date', 'room', 'registration_required', 'attendees_limit'] fields = ['title', 'abstract', 'description', 'topics', 'track', 'notes', 'event', 'speakers', 'materials', 'duration', 'start_date', 'room', 'registration_required', 'attendees_limit']
widgets = {'topics': forms.CheckboxSelectMultiple(), 'speakers': Select2TagWidget()} widgets = {'topics': forms.CheckboxSelectMultiple(), 'speakers': Select2TagWidget()}
help_texts = { help_texts = {
'abstract': _('Should be less than 255 characters'), 'abstract': _('Should be less than 255 characters'),

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-11-23 22:36
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('proposals', '0028_auto_20161113_2204'),
]
operations = [
migrations.AddField(
model_name='talk',
name='materials',
field=models.FileField(help_text='You can use this field to share some materials related to your intervention.', null=True, upload_to='', verbose_name='Materials'),
),
]

View File

@ -1,5 +1,6 @@
from enum import IntEnum from enum import IntEnum
from datetime import timedelta from datetime import timedelta
from os.path import join, basename
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
@ -141,6 +142,10 @@ class Attendee(PonyConfModel):
return self.get_name() return self.get_name()
def talk_materials_destination(talk, filename):
return join(talk.site.name, talk.slug, filename)
class Talk(PonyConfModel): class Talk(PonyConfModel):
site = models.ForeignKey(Site, on_delete=models.CASCADE) site = models.ForeignKey(Site, on_delete=models.CASCADE)
@ -163,6 +168,8 @@ class Talk(PonyConfModel):
registration_required = models.BooleanField(default=False) registration_required = models.BooleanField(default=False)
attendees = models.ManyToManyField(Attendee, verbose_name=_('Attendees')) attendees = models.ManyToManyField(Attendee, verbose_name=_('Attendees'))
attendees_limit = models.PositiveIntegerField(default=0, verbose_name=_('Max. number of attendees')) attendees_limit = models.PositiveIntegerField(default=0, verbose_name=_('Max. number of attendees'))
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.'))
class Meta: class Meta:
ordering = ('title',) ordering = ('title',)
@ -232,6 +239,10 @@ class Talk(PonyConfModel):
def dtend(self): def dtend(self):
return self.end_date.strftime('%Y%m%dT%H%M%SZ') return self.end_date.strftime('%Y%m%dT%H%M%SZ')
@property
def materials_name(self):
return basename(self.materials.name)
class Meta: class Meta:
ordering = ('event__id',) ordering = ('event__id',)

View File

@ -56,6 +56,10 @@
<dt>{% trans "Registrations" %}</dt> <dt>{% trans "Registrations" %}</dt>
<dd>{% if talk.attendees_limit %}{{ talk.attendees.count }} / {{ talk.attendees_limit }}{% else %}{% trans "required but unlimited" %}{% endif %}</dd> <dd>{% if talk.attendees_limit %}{{ talk.attendees.count }} / {{ talk.attendees_limit }}{% else %}{% trans "required but unlimited" %}{% endif %}</dd>
{% endif %} {% endif %}
{% if talk.materials %}
<dt>{% trans "Materials" %}</dt>
<dd><a href="{{ talk.materials.url }}">{{ talk.materials_name }}</a></dd>
{% endif %}
</dl> </dl>

View File

@ -9,7 +9,7 @@
<h1>{% if talk %}{% trans "Edit a talk" %}{% else %}{% trans "Propose a talk" %}{% endif %}</h1> <h1>{% if talk %}{% trans "Edit a talk" %}{% else %}{% trans "Propose a talk" %}{% endif %}</h1>
{% include "_form.html" %} {% include "_form.html" with multipart=True %}
{% endblock %} {% endblock %}

View File

@ -191,7 +191,7 @@ def talk_edit(request, talk=None):
if not is_orga(request, request.user) and not conf.cfp_is_open(): if not is_orga(request, request.user) and not conf.cfp_is_open():
raise PermissionDenied raise PermissionDenied
staff = talk.is_moderable_by(request.user) if talk else is_orga(request, request.user) staff = talk.is_moderable_by(request.user) if talk else is_orga(request, request.user)
form = TalkForm(request.POST or None, instance=talk, site=site, staff=staff) form = TalkForm(request.POST or None, request.FILES or None, instance=talk, site=site, staff=staff)
if talk: if talk:
form.fields['topics'].disabled = True form.fields['topics'].disabled = True
if 'duration' in form.fields and talk.event.duration: if 'duration' in form.fields and talk.event.duration:
@ -202,6 +202,7 @@ def talk_edit(request, talk=None):
"Note: the room %(room)s has %(capacity)s seats.", "Note: the room %(room)s has %(capacity)s seats.",
talk.room.capacity) % {'room': talk.room.name, 'capacity': talk.room.capacity} talk.room.capacity) % {'room': talk.room.name, 'capacity': talk.room.capacity}
else: else:
form.fields.pop('materials')
form.fields['speakers'].initial = [request.user] form.fields['speakers'].initial = [request.user]
if request.method == 'POST' and form.is_valid(): if request.method == 'POST' and form.is_valid():
if hasattr(talk, 'id'): if hasattr(talk, 'id'):