downloads talks, speakers and volunteers as CSV

This commit is contained in:
Élie Bouttier 2017-11-08 20:17:56 +01:00
parent bd5804fdd6
commit b72e9c9180
7 changed files with 222 additions and 128 deletions

View File

@ -13,6 +13,7 @@ from django.utils.html import escape, format_html
from autoslug import AutoSlugField from autoslug import AutoSlugField
from colorful.fields import RGBColorField from colorful.fields import RGBColorField
from functools import partial
import uuid import uuid
from datetime import timedelta from datetime import timedelta
@ -124,6 +125,9 @@ class Participant(PonyConfModel):
url = ('https' if self.site.conference.secure_domain else 'http') + '://' + self.site.domain + url url = ('https' if self.site.conference.secure_domain else 'http') + '://' + self.site.domain + url
return url return url
def get_csv_row(self):
return map(partial(getattr, self), ['pk', 'name', 'email', 'biography', 'twitter', 'linkedin', 'github', 'website', 'facebook', 'mastodon', 'phone_number', 'notes'])
class Meta: class Meta:
# A User can participe only once to a Conference (= Site) # A User can participe only once to a Conference (= Site)
unique_together = ('site', 'name') unique_together = ('site', 'name')
@ -392,6 +396,26 @@ class Talk(PonyConfModel):
def get_tags_html(self): def get_tags_html(self):
return mark_safe(' '.join(map(lambda tag: tag.link, self.tags.all()))) return mark_safe(' '.join(map(lambda tag: tag.link, self.tags.all())))
def get_csv_row(self):
return [
self.pk,
self.title,
self.description,
self.category,
self.track,
[speaker.pk for speaker in self.speakers.all()],
[speaker.name for speaker in self.speakers.all()],
[tag.name for tag in self.tags.all()],
1 if self.videotaped else 0,
self.video_licence,
1 if self.sound else 0,
self.estimated_duration,
self.room,
1 if self.plenary else 0,
self.materials,
self.video,
]
@property @property
def estimated_duration(self): def estimated_duration(self):
return self.duration or self.category.duration return self.duration or self.category.duration
@ -450,6 +474,16 @@ class Volunteer(PonyConfModel):
url = ('https' if self.site.conference.secure_domain else 'http') + '://' + self.site.domain + url url = ('https' if self.site.conference.secure_domain else 'http') + '://' + self.site.domain + url
return url return url
def get_csv_row(self):
return [
self.pk,
self.name,
self.email,
self.phone_number,
1 if self.sms_prefered else 0,
self.notes,
]
class Meta: class Meta:
# A volunteer can participe only once to a Conference (= Site) # A volunteer can participe only once to a Conference (= Site)
unique_together = ('site', 'email') unique_together = ('site', 'email')

View File

@ -39,7 +39,11 @@
</thead> </thead>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="7">{% trans "Contact:" %} <a href="{{ contact_link }}">{% trans "link" %}</a></td> <td colspan="7">
<a href="{{ contact_link }}">{% trans "contact by email" %}</a>
|
<a href="{{ csv_link }}">{% trans "download as csv" %}</a>
</td>
</tr> </tr>
</tfoot> </tfoot>
{% for participant in participant_list %} {% for participant in participant_list %}

View File

@ -48,6 +48,13 @@
<th class="text-center">{% trans "Status" %} <a href="?{{ sort_urls.status }}"><span class="glyphicon glyphicon-{{ sort_glyphicons.status }} pull-right"></span></a></th> <th class="text-center">{% trans "Status" %} <a href="?{{ sort_urls.status }}"><span class="glyphicon glyphicon-{{ sort_glyphicons.status }} pull-right"></span></a></th>
</tr> </tr>
</thead> </thead>
<tfoot>
<tr>
<td colspan="7">
<a href="{{ csv_link }}">{% trans "download as csv" %}</a>
</td>
</tr>
</tfoot>
{% for talk in talk_list %} {% for talk in talk_list %}
{% if forloop.first %} {% if forloop.first %}
<tbody> <tbody>

View File

@ -34,7 +34,11 @@
</thead> </thead>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="7">{% trans "Contact:" %} <a href="{{ contact_link }}">{% trans "link" %}</a></td> <td colspan="7">
<a href="{{ contact_link }}">{% trans "contact by email" %}</a>
|
<a href="{{ csv_link }}">{% trans "download as csv" %}</a>
</td>
</tr> </tr>
</tfoot> </tfoot>
{% for volunteer in volunteer_list %} {% for volunteer in volunteer_list %}

View File

@ -17,6 +17,7 @@ from django.forms import modelform_factory
from django_select2.views import AutoResponseView from django_select2.views import AutoResponseView
from functools import reduce from functools import reduce
import csv
from mailing.models import Message from mailing.models import Message
from mailing.forms import MessageForm from mailing.forms import MessageForm
@ -106,9 +107,9 @@ def volunteer_update_activity(request, volunteer, activity, join):
@staff_required @staff_required
def volunteer_list(request): def volunteer_list(request):
site = request.conference.site site = request.conference.site
show_filters = False
filter_form = VolunteerFilterForm(request.GET or None, site=site) filter_form = VolunteerFilterForm(request.GET or None, site=site)
# Filtering # Filtering
show_filters = False
volunteers = Volunteer.objects.filter(site=site).order_by('pk').distinct().prefetch_related('activities') volunteers = Volunteer.objects.filter(site=site).order_by('pk').distinct().prefetch_related('activities')
if filter_form.is_valid(): if filter_form.is_valid():
data = filter_form.cleaned_data data = filter_form.cleaned_data
@ -121,13 +122,25 @@ def volunteer_list(request):
if len(data['activity']): if len(data['activity']):
q |= Q(activities__slug__in=data['activity']) q |= Q(activities__slug__in=data['activity'])
volunteers = volunteers.filter(q) volunteers = volunteers.filter(q)
contact_link = 'mailto:' + ','.join([volunteer.email for volunteer in volunteers.all()]) if request.GET.get('format') == 'csv':
return render(request, 'cfp/staff/volunteer_list.html', { response = HttpResponse(content_type='text/csv')
'volunteer_list': volunteers, response['Content-Disposition'] = 'attachment; filename="volunteers.csv"'
'filter_form': filter_form, writer = csv.writer(response)
'show_filters': show_filters, for volunteer in volunteers:
'contact_link': contact_link, writer.writerow(volunteer.get_csv_row())
}) return response
else:
contact_link = 'mailto:' + ','.join([volunteer.email for volunteer in volunteers.all()])
csv_query_dict = request.GET.copy()
csv_query_dict['format'] = 'csv'
csv_link = '?' + csv_query_dict.urlencode()
return render(request, 'cfp/staff/volunteer_list.html', {
'volunteer_list': volunteers,
'filter_form': filter_form,
'show_filters': show_filters,
'contact_link': contact_link,
'csv_link': csv_link,
})
@staff_required @staff_required
@ -538,6 +551,16 @@ def talk_list(request):
talks = talks.exclude(video__exact='') talks = talks.exclude(video__exact='')
else: else:
talks = talks.filter(video__exact='') talks = talks.filter(video__exact='')
talks = talks.prefetch_related('category', 'speakers', 'track', 'tags')
if request.GET.get('format') == 'csv':
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="talks.csv"'
writer = csv.writer(response)
for talk in talks:
writer.writerow(talk.get_csv_row())
return response
# Action # Action
action_form = TalkActionForm(request.POST or None, talks=talks, site=request.conference.site) action_form = TalkActionForm(request.POST or None, talks=talks, site=request.conference.site)
if request.method == 'POST' and action_form.is_valid(): if request.method == 'POST' and action_form.is_valid():
@ -592,7 +615,9 @@ def talk_list(request):
glyphicon = 'sort' glyphicon = 'sort'
sort_urls[c] = url.urlencode() sort_urls[c] = url.urlencode()
sort_glyphicons[c] = glyphicon sort_glyphicons[c] = glyphicon
talks = talks.prefetch_related('category', 'speakers', 'track', 'tags') csv_query_dict = request.GET.copy()
csv_query_dict['format'] = 'csv'
csv_link = '?' + csv_query_dict.urlencode()
return render(request, 'cfp/staff/talk_list.html', { return render(request, 'cfp/staff/talk_list.html', {
'show_filters': show_filters, 'show_filters': show_filters,
'talk_list': talks, 'talk_list': talks,
@ -600,6 +625,7 @@ def talk_list(request):
'action_form': action_form, 'action_form': action_form,
'sort_urls': sort_urls, 'sort_urls': sort_urls,
'sort_glyphicons': sort_glyphicons, 'sort_glyphicons': sort_glyphicons,
'csv_link': csv_link,
}) })
@ -691,13 +717,25 @@ def participant_list(request):
q |= Q(track__slug__in=data['track']) q |= Q(track__slug__in=data['track'])
talks = talks.filter(q) talks = talks.filter(q)
participants = participants.filter(talk__in=talks) participants = participants.filter(talk__in=talks)
contact_link = 'mailto:' + ','.join([participant.email for participant in participants.all()]) if request.GET.get('format') == 'csv':
return render(request, 'cfp/staff/participant_list.html', { response = HttpResponse(content_type='text/csv')
'filter_form': filter_form, response['Content-Disposition'] = 'attachment; filename="participants.csv"'
'participant_list': participants, writer = csv.writer(response)
'show_filters': show_filters, for participant in participants:
'contact_link': contact_link, writer.writerow(participant.get_csv_row())
}) return response
else:
contact_link = 'mailto:' + ','.join([participant.email for participant in participants.all()])
csv_query_dict = request.GET.copy()
csv_query_dict['format'] = 'csv'
csv_link = '?' + csv_query_dict.urlencode()
return render(request, 'cfp/staff/participant_list.html', {
'filter_form': filter_form,
'participant_list': participants,
'show_filters': show_filters,
'contact_link': contact_link,
'csv_link': csv_link,
})
@staff_required @staff_required

Binary file not shown.

View File

@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-11-07 23:13+0000\n" "POT-Creation-Date: 2017-11-08 19:16+0000\n"
"PO-Revision-Date: 2017-11-08 00:14+0100\n" "PO-Revision-Date: 2017-11-08 20:17+0100\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: fr\n" "Language: fr\n"
@ -34,15 +34,15 @@ msgstr "Décliné"
msgid "Waiting" msgid "Waiting"
msgstr "En attente" msgstr "En attente"
#: cfp/forms.py:29 cfp/forms.py:130 cfp/forms.py:227 cfp/models.py:369 #: cfp/forms.py:29 cfp/forms.py:130 cfp/forms.py:227 cfp/models.py:373
msgid "Confirmed" msgid "Confirmed"
msgstr "Confirmé" msgstr "Confirmé"
#: cfp/forms.py:30 cfp/models.py:371 #: cfp/forms.py:30 cfp/models.py:375
msgid "Cancelled" msgid "Cancelled"
msgstr "Annulé" msgstr "Annulé"
#: cfp/forms.py:62 cfp/models.py:470 #: cfp/forms.py:62 cfp/models.py:504
msgid "Activity" msgid "Activity"
msgstr "Activité" msgstr "Activité"
@ -65,13 +65,13 @@ msgstr "Catégorie"
msgid "Title" msgid "Title"
msgstr "Titre" msgstr "Titre"
#: cfp/forms.py:108 cfp/models.py:154 cfp/models.py:465 #: cfp/forms.py:108 cfp/models.py:158 cfp/models.py:499
#: cfp/templates/cfp/proposal_talk_details.html:75 #: cfp/templates/cfp/proposal_talk_details.html:75
#: cfp/templates/cfp/staff/talk_details.html:64 #: cfp/templates/cfp/staff/talk_details.html:64
msgid "Description" msgid "Description"
msgstr "Description" msgstr "Description"
#: cfp/forms.py:109 cfp/models.py:111 cfp/models.py:440 #: cfp/forms.py:109 cfp/models.py:112 cfp/models.py:464
#: cfp/templates/cfp/staff/participant_details.html:19 #: cfp/templates/cfp/staff/participant_details.html:19
#: cfp/templates/cfp/staff/talk_details.html:78 #: cfp/templates/cfp/staff/talk_details.html:78
#: cfp/templates/cfp/staff/volunteer_details.html:22 #: cfp/templates/cfp/staff/volunteer_details.html:22
@ -82,7 +82,7 @@ msgstr "Notes"
msgid "Visible by speakers" msgid "Visible by speakers"
msgstr "Visible par les orateurs" msgstr "Visible par les orateurs"
#: cfp/forms.py:136 cfp/forms.py:233 cfp/models.py:326 #: cfp/forms.py:136 cfp/forms.py:233 cfp/models.py:330
#: cfp/templates/cfp/staff/talk_details.html:21 #: cfp/templates/cfp/staff/talk_details.html:21
#: cfp/templates/cfp/staff/talk_list.html:46 #: cfp/templates/cfp/staff/talk_list.html:46
#: cfp/templates/cfp/staff/track_form.html:14 #: cfp/templates/cfp/staff/track_form.html:14
@ -120,7 +120,7 @@ msgstr "Programmé"
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"
#: cfp/forms.py:160 cfp/models.py:343 #: cfp/forms.py:160 cfp/models.py:347
#: cfp/templates/cfp/staff/talk_details.html:54 #: cfp/templates/cfp/staff/talk_details.html:54
msgid "Materials" msgid "Materials"
msgstr "Supports" msgstr "Supports"
@ -161,7 +161,7 @@ msgstr "Assigner à une salle"
msgid "Notify by mail?" msgid "Notify by mail?"
msgstr "Notifier par e-mail ?" msgstr "Notifier par e-mail ?"
#: cfp/forms.py:249 cfp/models.py:435 #: cfp/forms.py:249 cfp/models.py:459
#: cfp/templates/cfp/staff/volunteer_list.html:30 #: cfp/templates/cfp/staff/volunteer_list.html:30
msgid "Email" msgid "Email"
msgstr "E-mail" msgstr "E-mail"
@ -180,63 +180,63 @@ msgstr "Un utilisateur avec ce prénom et ce nom existe déjà."
msgid "A user with that email already exists." msgid "A user with that email already exists."
msgstr "Un utilisateur avec cet email existe déjà." msgstr "Un utilisateur avec cet email existe déjà."
#: cfp/models.py:29 #: cfp/models.py:30
msgid "Conference name" msgid "Conference name"
msgstr "Nom de la conférence" msgstr "Nom de la conférence"
#: cfp/models.py:30 #: cfp/models.py:31
msgid "Homepage (markdown)" msgid "Homepage (markdown)"
msgstr "Page daccueil (markdown)" msgstr "Page daccueil (markdown)"
#: cfp/models.py:31 #: cfp/models.py:32
msgid "Venue information" msgid "Venue information"
msgstr "Informations sur le lieu" msgstr "Informations sur le lieu"
#: cfp/models.py:32 #: cfp/models.py:33
msgid "City" msgid "City"
msgstr "Ville" msgstr "Ville"
#: cfp/models.py:33 #: cfp/models.py:34
msgid "Contact email" msgid "Contact email"
msgstr "Email de contact" msgstr "Email de contact"
#: cfp/models.py:34 #: cfp/models.py:35
msgid "Reply email" msgid "Reply email"
msgstr "Adresse de réponse" msgstr "Adresse de réponse"
#: cfp/models.py:35 #: cfp/models.py:36
msgid "Staff members" msgid "Staff members"
msgstr "Membres du staff" msgstr "Membres du staff"
#: cfp/models.py:36 #: cfp/models.py:37
msgid "Secure domain (HTTPS)" msgid "Secure domain (HTTPS)"
msgstr "Domaine sécurisé (HTTPS)" msgstr "Domaine sécurisé (HTTPS)"
#: cfp/models.py:37 #: cfp/models.py:38
msgid "Acceptances disclosure date" msgid "Acceptances disclosure date"
msgstr "Date de divulgation des acceptations" msgstr "Date de divulgation des acceptations"
#: cfp/models.py:38 #: cfp/models.py:39
msgid "Schedule publishing date" msgid "Schedule publishing date"
msgstr "Date de publication du programme" msgstr "Date de publication du programme"
#: cfp/models.py:39 #: cfp/models.py:40
msgid "Schedule redirection URL" msgid "Schedule redirection URL"
msgstr "URL de redirection du programme" msgstr "URL de redirection du programme"
#: cfp/models.py:40 #: cfp/models.py:41
msgid "If specified, schedule tab will redirect to this URL." msgid "If specified, schedule tab will redirect to this URL."
msgstr "Si spécifiée, longlet programme redirigera vers cette URL." msgstr "Si spécifiée, longlet programme redirigera vers cette URL."
#: cfp/models.py:41 #: cfp/models.py:42
msgid "Volunteers enrollment opening date" msgid "Volunteers enrollment opening date"
msgstr "Date douverture de lappel à bénévole" msgstr "Date douverture de lappel à bénévole"
#: cfp/models.py:42 #: cfp/models.py:43
msgid "Volunteers enrollment closing date" msgid "Volunteers enrollment closing date"
msgstr "Date de fermeture de lappel à bénévole" msgstr "Date de fermeture de lappel à bénévole"
#: cfp/models.py:79 #: cfp/models.py:80
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"The reply email should be a formatable string accepting a token argument (e." "The reply email should be a formatable string accepting a token argument (e."
@ -245,74 +245,74 @@ msgstr ""
"Ladresse de réponse doit être une chaine de texte formatable avec un " "Ladresse de réponse doit être une chaine de texte formatable avec un "
"argument « token » (e.g. ponyconf+{token}@exemple.com)." "argument « token » (e.g. ponyconf+{token}@exemple.com)."
#: cfp/models.py:99 cfp/models.py:152 cfp/models.py:204 cfp/models.py:463 #: cfp/models.py:100 cfp/models.py:156 cfp/models.py:208 cfp/models.py:497
#: cfp/templates/cfp/staff/participant_list.html:35 #: cfp/templates/cfp/staff/participant_list.html:35
#: cfp/templates/cfp/staff/volunteer_list.html:29 #: cfp/templates/cfp/staff/volunteer_list.html:29
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
#: cfp/models.py:101 cfp/templates/cfp/proposal_dashboard.html:33 #: cfp/models.py:102 cfp/templates/cfp/proposal_dashboard.html:33
#: cfp/templates/cfp/staff/participant_details.html:15 #: cfp/templates/cfp/staff/participant_details.html:15
msgid "Biography" msgid "Biography"
msgstr "Biographie" msgstr "Biographie"
#: cfp/models.py:103 #: cfp/models.py:104
msgid "Twitter" msgid "Twitter"
msgstr "Twitter" msgstr "Twitter"
#: cfp/models.py:104 #: cfp/models.py:105
msgid "LinkedIn" msgid "LinkedIn"
msgstr "LinkedIn" msgstr "LinkedIn"
#: cfp/models.py:105 #: cfp/models.py:106
msgid "Github" msgid "Github"
msgstr "Github" msgstr "Github"
#: cfp/models.py:106 #: cfp/models.py:107
msgid "Website" msgid "Website"
msgstr "Site web" msgstr "Site web"
#: cfp/models.py:107 #: cfp/models.py:108
msgid "Facebook" msgid "Facebook"
msgstr "Facebook" msgstr "Facebook"
#: cfp/models.py:108 #: cfp/models.py:109
msgid "Mastodon" msgid "Mastodon"
msgstr "Mastodon" msgstr "Mastodon"
#: cfp/models.py:109 cfp/models.py:437 #: cfp/models.py:110 cfp/models.py:461
msgid "Phone number" msgid "Phone number"
msgstr "Numéro de téléphone" msgstr "Numéro de téléphone"
#: cfp/models.py:112 cfp/models.py:325 #: cfp/models.py:113 cfp/models.py:329
msgid "This field is only visible by organizers." msgid "This field is only visible by organizers."
msgstr "Ce champs est uniquement visible par les organisateurs." msgstr "Ce champs est uniquement visible par les organisateurs."
#: cfp/models.py:113 cfp/templates/cfp/staff/participant_details.html:25 #: cfp/models.py:114 cfp/templates/cfp/staff/participant_details.html:25
msgid "Invited speaker" msgid "Invited speaker"
msgstr "Orateur invité" msgstr "Orateur invité"
#: cfp/models.py:206 #: cfp/models.py:210
msgid "Color" msgid "Color"
msgstr "Couleur" msgstr "Couleur"
#: cfp/models.py:208 #: cfp/models.py:212
msgid "Show the tag on the program" msgid "Show the tag on the program"
msgstr "Afficher létiquette sur le programme" msgstr "Afficher létiquette sur le programme"
#: cfp/models.py:244 #: cfp/models.py:248
msgid "Default duration (min)" msgid "Default duration (min)"
msgstr "Durée par défaut (min)" msgstr "Durée par défaut (min)"
#: cfp/models.py:245 #: cfp/models.py:249
msgid "Color on program" msgid "Color on program"
msgstr "Couleur sur le programme" msgstr "Couleur sur le programme"
#: cfp/models.py:246 #: cfp/models.py:250
msgid "Label on program" msgid "Label on program"
msgstr "Label dans le xml du programme" msgstr "Label dans le xml du programme"
#: cfp/models.py:320 cfp/templates/cfp/proposal_talk_details.html:53 #: cfp/models.py:324 cfp/templates/cfp/proposal_talk_details.html:53
#: cfp/templates/cfp/staff/base.html:11 #: cfp/templates/cfp/staff/base.html:11
#: cfp/templates/cfp/staff/participant_list.html:8 #: cfp/templates/cfp/staff/participant_list.html:8
#: cfp/templates/cfp/staff/talk_details.html:68 #: cfp/templates/cfp/staff/talk_details.html:68
@ -320,19 +320,19 @@ msgstr "Label dans le xml du programme"
msgid "Speakers" msgid "Speakers"
msgstr "Orateurs" msgstr "Orateurs"
#: cfp/models.py:321 #: cfp/models.py:325
msgid "Talk Title" msgid "Talk Title"
msgstr "Titre de la proposition" msgstr "Titre de la proposition"
#: cfp/models.py:324 #: cfp/models.py:328
msgid "Description of your talk" msgid "Description of your talk"
msgstr "Description de votre proposition" msgstr "Description de votre proposition"
#: cfp/models.py:328 cfp/templates/cfp/proposal_talk_details.html:85 #: cfp/models.py:332 cfp/templates/cfp/proposal_talk_details.html:85
msgid "Message to organizers" msgid "Message to organizers"
msgstr "Message aux organisateurs" msgstr "Message aux organisateurs"
#: cfp/models.py:329 #: cfp/models.py:333
msgid "" msgid ""
"If you have any constraint or if you have anything that may help you to " "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 " "select your talk, like a video or slides of your talk, please write it down "
@ -342,67 +342,67 @@ msgstr ""
"votre proposition, comme une vidéo, des slides, n'hésitez pas à les ajouter " "votre proposition, comme une vidéo, des slides, n'hésitez pas à les ajouter "
"ici." "ici."
#: cfp/models.py:332 #: cfp/models.py:336
msgid "Talk Category" msgid "Talk Category"
msgstr "Catégorie de proposition" msgstr "Catégorie de proposition"
#: cfp/models.py:333 #: cfp/models.py:337
msgid "I'm ok to be recorded on video" msgid "I'm ok to be recorded on video"
msgstr "Jaccepte dêtre enregistré en vidéo" msgstr "Jaccepte dêtre enregistré en vidéo"
#: cfp/models.py:335 #: cfp/models.py:339
msgid "Video licence" msgid "Video licence"
msgstr "Licence vidéo" msgstr "Licence vidéo"
#: cfp/models.py:336 #: cfp/models.py:340
msgid "I need sound" msgid "I need sound"
msgstr "Jai besoin de son" msgstr "Jai besoin de son"
#: cfp/models.py:339 #: cfp/models.py:343
msgid "Beginning date and time" msgid "Beginning date and time"
msgstr "Date et heure de début" msgstr "Date et heure de début"
#: cfp/models.py:340 #: cfp/models.py:344
msgid "Duration (min)" msgid "Duration (min)"
msgstr "Durée (min)" msgstr "Durée (min)"
#: cfp/models.py:344 #: cfp/models.py:348
msgid "" msgid ""
"You can use this field to share some materials related to your intervention." "You can use this field to share some materials related to your intervention."
msgstr "" msgstr ""
"Vous pouvez utiliser ce champs pour partager les supports de votre " "Vous pouvez utiliser ce champs pour partager les supports de votre "
"intervention." "intervention."
#: cfp/models.py:373 #: cfp/models.py:377
msgid "Waiting confirmation" msgid "Waiting confirmation"
msgstr "En attente de confirmation" msgstr "En attente de confirmation"
#: cfp/models.py:375 #: cfp/models.py:379
msgid "Refused" msgid "Refused"
msgstr "Refusé" msgstr "Refusé"
#: cfp/models.py:377 #: cfp/models.py:381
#, python-format #, python-format
msgid "Pending decision, score: %(score).1f" msgid "Pending decision, score: %(score).1f"
msgstr "En cours, score : %(score).1f" msgstr "En cours, score : %(score).1f"
#: cfp/models.py:434 #: cfp/models.py:458
msgid "Your Name" msgid "Your Name"
msgstr "Votre Nom" msgstr "Votre Nom"
#: cfp/models.py:438 #: cfp/models.py:462
msgid "SMS prefered" msgid "SMS prefered"
msgstr "SMS préférés" msgstr "SMS préférés"
#: cfp/models.py:441 #: cfp/models.py:465
msgid "If you have some constraints, you can indicate them here." msgid "If you have some constraints, you can indicate them here."
msgstr "Si vous avez des contraintes, vous pouvez les indiquer ici." msgstr "Si vous avez des contraintes, vous pouvez les indiquer ici."
#: cfp/models.py:466 cfp/templates/cfp/staff/volunteer_details.html:8 #: cfp/models.py:500 cfp/templates/cfp/staff/volunteer_details.html:8
msgid "Volunteer" msgid "Volunteer"
msgstr "Bénévole" msgstr "Bénévole"
#: cfp/models.py:471 cfp/templates/cfp/admin/activity_list.html:9 #: cfp/models.py:505 cfp/templates/cfp/admin/activity_list.html:9
#: cfp/templates/cfp/admin/base.html:13 #: cfp/templates/cfp/admin/base.html:13
#: cfp/templates/cfp/staff/volunteer_details.html:27 #: cfp/templates/cfp/staff/volunteer_details.html:27
#: cfp/templates/cfp/staff/volunteer_list.html:32 #: cfp/templates/cfp/staff/volunteer_list.html:32
@ -603,7 +603,7 @@ msgstr "avec"
#: cfp/templates/cfp/staff/participant_details.html:48 #: cfp/templates/cfp/staff/participant_details.html:48
#: cfp/templates/cfp/staff/room_details.html:21 #: cfp/templates/cfp/staff/room_details.html:21
#: cfp/templates/cfp/staff/room_details.html:39 #: cfp/templates/cfp/staff/room_details.html:39
#: cfp/templates/cfp/staff/talk_list.html:62 #: cfp/templates/cfp/staff/talk_list.html:69
msgid "and" msgid "and"
msgstr "et" msgstr "et"
@ -830,31 +830,32 @@ msgstr "orateur"
msgid "Talk count" msgid "Talk count"
msgstr "Nombre dexposé" msgstr "Nombre dexposé"
#: cfp/templates/cfp/staff/participant_list.html:43 #: cfp/templates/cfp/staff/participant_list.html:44
#: cfp/templates/cfp/staff/volunteer_list.html:37 #: cfp/templates/cfp/staff/volunteer_list.html:38
msgid "Contact:" msgid "contact by email"
msgstr "Contacter :" msgstr "contacter par e-mail"
#: cfp/templates/cfp/staff/participant_list.html:43 #: cfp/templates/cfp/staff/participant_list.html:46
#: cfp/templates/cfp/staff/volunteer_list.html:37 #: cfp/templates/cfp/staff/talk_list.html:54
msgid "link" #: cfp/templates/cfp/staff/volunteer_list.html:40
msgstr "lien" msgid "download as csv"
msgstr "télécharger au format CSV"
#: cfp/templates/cfp/staff/participant_list.html:56 #: cfp/templates/cfp/staff/participant_list.html:60
#, python-format #, python-format
msgid "accepted: %(accepted)s" msgid "accepted: %(accepted)s"
msgid_plural "accepted: %(accepted)s" msgid_plural "accepted: %(accepted)s"
msgstr[0] "accepté : %(accepted)s" msgstr[0] "accepté : %(accepted)s"
msgstr[1] "acceptés : %(accepted)s" msgstr[1] "acceptés : %(accepted)s"
#: cfp/templates/cfp/staff/participant_list.html:58 #: cfp/templates/cfp/staff/participant_list.html:62
#, python-format #, python-format
msgid "pending: %(pending)s" msgid "pending: %(pending)s"
msgid_plural "pending: %(pending)s" msgid_plural "pending: %(pending)s"
msgstr[0] "en attente : %(pending)s" msgstr[0] "en attente : %(pending)s"
msgstr[1] "en attente : %(pending)s" msgstr[1] "en attente : %(pending)s"
#: cfp/templates/cfp/staff/participant_list.html:60 #: cfp/templates/cfp/staff/participant_list.html:64
#, python-format #, python-format
msgid "refused: %(refused)s" msgid "refused: %(refused)s"
msgid_plural "refused: %(refused)s" msgid_plural "refused: %(refused)s"
@ -1016,11 +1017,11 @@ msgstr "Éditer un exposé"
msgid "Intervention kind" msgid "Intervention kind"
msgstr "Type dintervention" msgstr "Type dintervention"
#: cfp/templates/cfp/staff/talk_list.html:80 #: cfp/templates/cfp/staff/talk_list.html:87
msgid "For selected talks:" msgid "For selected talks:"
msgstr "Pour les exposés sélectionnés :" msgstr "Pour les exposés sélectionnés :"
#: cfp/templates/cfp/staff/talk_list.html:85 #: cfp/templates/cfp/staff/talk_list.html:92
msgid "Apply" msgid "Apply"
msgstr "Appliquer" msgstr "Appliquer"
@ -1078,7 +1079,7 @@ msgstr ""
msgid "We are looking for help with the following activities:" msgid "We are looking for help with the following activities:"
msgstr "Nous cherchons de laide pour les activités suivantes :" msgstr "Nous cherchons de laide pour les activités suivantes :"
#: cfp/views.py:51 #: cfp/views.py:52
msgid "" msgid ""
"Hi {},\n" "Hi {},\n"
"\n" "\n"
@ -1106,26 +1107,26 @@ msgstr ""
"{}\n" "{}\n"
"\n" "\n"
#: cfp/views.py:71 #: cfp/views.py:72
msgid "Thank you for your help!" msgid "Thank you for your help!"
msgstr "Merci pour votre aide !" msgstr "Merci pour votre aide !"
#: cfp/views.py:76 #: cfp/views.py:77
msgid "" msgid ""
"Thank you for your participation! You can now subscribe to some activities." "Thank you for your participation! You can now subscribe to some activities."
msgstr "" msgstr ""
"Merci pour votre participation ! Vous pouvez maintenant vous inscrire à une " "Merci pour votre participation ! Vous pouvez maintenant vous inscrire à une "
"ou plusieurs activités." "ou plusieurs activités."
#: cfp/views.py:98 #: cfp/views.py:99
msgid "Thank you for your participation!" msgid "Thank you for your participation!"
msgstr "Merci pour votre participation !" msgstr "Merci pour votre participation !"
#: cfp/views.py:102 #: cfp/views.py:103
msgid "Okay, no problem!" msgid "Okay, no problem!"
msgstr "Ok, pas de soucis !" msgstr "Ok, pas de soucis !"
#: cfp/views.py:174 #: cfp/views.py:187
msgid "" msgid ""
"Hi {},\n" "Hi {},\n"
"\n" "\n"
@ -1165,15 +1166,15 @@ msgstr ""
"{}\n" "{}\n"
"\n" "\n"
#: cfp/views.py:204 cfp/views.py:288 #: cfp/views.py:217 cfp/views.py:301
msgid "You proposition have been successfully submitted!" msgid "You proposition have been successfully submitted!"
msgstr "Votre proposition a été transmise avec succès !" msgstr "Votre proposition a été transmise avec succès !"
#: cfp/views.py:218 #: cfp/views.py:231
msgid "Sorry, we do not know this email." msgid "Sorry, we do not know this email."
msgstr "Désolé, nous ne connaissons pas cette e-mail." msgstr "Désolé, nous ne connaissons pas cette e-mail."
#: cfp/views.py:223 #: cfp/views.py:236
msgid "" msgid ""
"Hi {},\n" "Hi {},\n"
"\n" "\n"
@ -1204,41 +1205,41 @@ msgstr ""
"{}\n" "{}\n"
"\n" "\n"
#: cfp/views.py:243 #: cfp/views.py:256
msgid "A email have been sent with a link to access to your profil." msgid "A email have been sent with a link to access to your profil."
msgstr "Un e-mail vous a été envoyé avec un lien pour accéder à votre profil." msgstr "Un e-mail vous a été envoyé avec un lien pour accéder à votre profil."
#: cfp/views.py:284 cfp/views.py:357 #: cfp/views.py:297 cfp/views.py:370
msgid "Changes saved." msgid "Changes saved."
msgstr "Modifications sauvegardées." msgstr "Modifications sauvegardées."
#: cfp/views.py:305 #: cfp/views.py:318
msgid "You already confirmed your participation to this talk." msgid "You already confirmed your participation to this talk."
msgstr "Vous avez déjà confirmé votre participation à cet exposé." msgstr "Vous avez déjà confirmé votre participation à cet exposé."
#: cfp/views.py:307 #: cfp/views.py:320
msgid "You already cancelled your participation to this talk." msgid "You already cancelled your participation to this talk."
msgstr "Vous avez déjà annulé votre participation à cet exposé." msgstr "Vous avez déjà annulé votre participation à cet exposé."
#: cfp/views.py:312 #: cfp/views.py:325
msgid "Your participation has been taken into account, thank you!" msgid "Your participation has been taken into account, thank you!"
msgstr "Votre participation a été prise en compte, merci !" msgstr "Votre participation a été prise en compte, merci !"
#: cfp/views.py:313 #: cfp/views.py:326
#, python-format #, python-format
msgid "Speaker %(speaker)s confirmed his/her participation." msgid "Speaker %(speaker)s confirmed his/her participation."
msgstr "Lintervenant %(speaker)s a confirmé sa participation." msgstr "Lintervenant %(speaker)s a confirmé sa participation."
#: cfp/views.py:315 #: cfp/views.py:328
msgid "We have noted your unavailability." msgid "We have noted your unavailability."
msgstr "Nous avons enregistré votre indisponibilité." msgstr "Nous avons enregistré votre indisponibilité."
#: cfp/views.py:316 #: cfp/views.py:329
#, python-format #, python-format
msgid "Speaker %(speaker)s CANCELLED his/her participation." msgid "Speaker %(speaker)s CANCELLED his/her participation."
msgstr "Lintervenant %(speaker)s a ANNULÉ sa participation." msgstr "Lintervenant %(speaker)s a ANNULÉ sa participation."
#: cfp/views.py:364 #: cfp/views.py:377
msgid "" msgid ""
"Hi {},\n" "Hi {},\n"
"\n" "\n"
@ -1278,59 +1279,59 @@ msgstr ""
"{}\n" "{}\n"
"\n" "\n"
#: cfp/views.py:395 cfp/views.py:415 #: cfp/views.py:408 cfp/views.py:428
msgid "Co-speaker successfully added to the talk." msgid "Co-speaker successfully added to the talk."
msgstr "Co-intervenant ajouté à lexposé avec succès." msgstr "Co-intervenant ajouté à lexposé avec succès."
#: cfp/views.py:428 #: cfp/views.py:441
msgid "Co-speaker successfully removed from the talk." msgid "Co-speaker successfully removed from the talk."
msgstr "Co-intervenant supprimé de lexposé avec succès." msgstr "Co-intervenant supprimé de lexposé avec succès."
#: cfp/views.py:470 #: cfp/views.py:483
msgid "The speaker confirmation have been noted." msgid "The speaker confirmation have been noted."
msgstr "La confirmation de lorateur a été notée." msgstr "La confirmation de lorateur a été notée."
#: cfp/views.py:471 #: cfp/views.py:484
msgid "The talk have been confirmed." msgid "The talk have been confirmed."
msgstr "Lexposé a été confirmé." msgstr "Lexposé a été confirmé."
#: cfp/views.py:473 #: cfp/views.py:486
msgid "The speaker unavailability have been noted." msgid "The speaker unavailability have been noted."
msgstr "Lindisponibilité de lintervenant a été notée." msgstr "Lindisponibilité de lintervenant a été notée."
#: cfp/views.py:474 #: cfp/views.py:487
msgid "The talk have been cancelled." msgid "The talk have been cancelled."
msgstr "Lexposé a été annulé." msgstr "Lexposé a été annulé."
#: cfp/views.py:549 cfp/views.py:651 #: cfp/views.py:572 cfp/views.py:677
msgid "The talk has been accepted." msgid "The talk has been accepted."
msgstr "Lexposé a été accepté." msgstr "Lexposé a été accepté."
#: cfp/views.py:551 cfp/views.py:653 #: cfp/views.py:574 cfp/views.py:679
msgid "The talk has been declined." msgid "The talk has been declined."
msgstr "Lexposé a été décliné." msgstr "Lexposé a été décliné."
#: cfp/views.py:620 cfp/views.py:713 #: cfp/views.py:646 cfp/views.py:751
msgid "Message sent!" msgid "Message sent!"
msgstr "Message envoyé !" msgstr "Message envoyé !"
#: cfp/views.py:634 #: cfp/views.py:660
msgid "Vote successfully created" msgid "Vote successfully created"
msgstr "A voté !" msgstr "A voté !"
#: cfp/views.py:634 #: cfp/views.py:660
msgid "Vote successfully updated" msgid "Vote successfully updated"
msgstr "Vote mis à jour" msgstr "Vote mis à jour"
#: cfp/views.py:655 #: cfp/views.py:681
msgid "Decision taken in account" msgid "Decision taken in account"
msgstr "Décision enregistrée" msgstr "Décision enregistrée"
#: cfp/views.py:748 #: cfp/views.py:786
msgid "[{}] You have been added to the staff team" msgid "[{}] You have been added to the staff team"
msgstr "[{}] Vous avez été ajouté aux membres du staff" msgstr "[{}] Vous avez été ajouté aux membres du staff"
#: cfp/views.py:749 #: cfp/views.py:787
msgid "" msgid ""
"Hi {},\n" "Hi {},\n"
"\n" "\n"
@ -1354,15 +1355,15 @@ msgstr ""
"{}\n" "{}\n"
"\n" "\n"
#: cfp/views.py:770 #: cfp/views.py:808
msgid "Modifications successfully saved." msgid "Modifications successfully saved."
msgstr "Modification enregistrée avec succès." msgstr "Modification enregistrée avec succès."
#: cfp/views.py:934 #: cfp/views.py:972
msgid "User created successfully." msgid "User created successfully."
msgstr "Utilisateur créé avec succès." msgstr "Utilisateur créé avec succès."
#: cfp/views.py:955 #: cfp/views.py:993
#, python-format #, python-format
msgid "Format '%s' not available" msgid "Format '%s' not available"
msgstr "Format '%s' non disponible" msgstr "Format '%s' non disponible"
@ -1444,6 +1445,12 @@ msgstr "Changement de mot de passe"
msgid "Email address" msgid "Email address"
msgstr "Adresse e-mail" msgstr "Adresse e-mail"
#~ msgid "Contact:"
#~ msgstr "Contacter :"
#~ msgid "link"
#~ msgstr "lien"
#~ msgid "The volunteer made a few remarks to the staff." #~ msgid "The volunteer made a few remarks to the staff."
#~ msgstr "Le bénévole a fait quelques remarques au staff." #~ msgstr "Le bénévole a fait quelques remarques au staff."