Staff area

This commit is contained in:
Élie Bouttier 2017-07-30 16:57:38 +02:00
parent 53389bad4f
commit 9f151c90b6
25 changed files with 854 additions and 216 deletions

View File

@ -0,0 +1,5 @@
from .utils import get_current_conf
def conference(request):
return {'conference': get_current_conf(request)}

17
cfp/decorators.py Normal file
View File

@ -0,0 +1,17 @@
from functools import wraps
from django.core.exceptions import PermissionDenied
from django.contrib.auth.decorators import login_required
from cfp.utils import is_staff
def staff_required(view_func):
def _is_staff(request, *args, **kwargs):
if not request.user.is_authenticated():
return login_required(view_func)(request, *args, **kwargs)
elif is_staff(request, request.user):
return view_func(request, *args, **kwargs)
else:
raise PermissionDenied
return wraps(view_func)(_is_staff)

10
cfp/middleware.py Normal file
View File

@ -0,0 +1,10 @@
from django.core.exceptions import ImproperlyConfigured
from .utils import get_current_conf
class ConferenceMiddleware:
def process_view(self, request, view, view_args, view_kwargs):
if view.__module__ != 'cfp.views':
return
view_kwargs['conference'] = get_current_conf(request)

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.3 on 2017-07-29 23:30
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cfp', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='conference',
name='staff',
field=models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL, verbose_name='Staff'),
),
]

View File

@ -8,7 +8,7 @@ from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import Q
from django.db.models import Q, Avg
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from django.utils import timezone
@ -18,8 +18,6 @@ from ponyconf.utils import PonyConfModel
from autoslug import AutoSlugField
from colorful.fields import RGBColorField
from .utils import query_sum
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
@ -40,6 +38,7 @@ class Conference(models.Model):
venue = models.TextField(blank=True, default="")
city = models.CharField(max_length=64, blank=True, default="")
contact_email = models.CharField(max_length=100, blank=True)
staff = models.ManyToManyField(User, verbose_name=_('Staff'), blank=True)
custom_css = models.TextField(blank=True)
external_css_link = models.URLField(blank=True)
@ -117,15 +116,15 @@ class Participant(PonyConfModel):
#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)
#@property
#def pending_talk_set(self):
# return self.talk_set.filter(accepted=None)
#@property
#def refused_talk_set(self):
# return self.talk_set.filter(accepted=False)
@property
def accepted_talk_set(self):
return self.talk_set.filter(accepted=True)
@property
def pending_talk_set(self):
return self.talk_set.filter(accepted=None)
@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)
@ -268,14 +267,11 @@ class Talk(PonyConfModel):
def estimated_duration(self):
return self.duration or self.category.duration
#def get_absolute_url(self):
# return reverse('show-talk', kwargs={'slug': self.slug})
def get_absolute_url(self):
return reverse('talk-details', kwargs={'talk_id': self.token})
def score(self):
if self.vote_set.exists():
return query_sum(self.vote_set, 'vote') / len(self.vote_set.all())
else:
return 0
return self.vote_set.aggregate(Avg('vote'))['vote__avg'] or 0
@property
def end_date(self):

View File

@ -16,9 +16,9 @@
<p>{% trans "Thanks for your proposal" %} {{ participant }} !</p>
<p>{% trans "You can at anytime:" %}
<ul>
<li>{% trans "Edit your talk:" %} <a href="{% url 'talk-proposal-edit' talk.token participant.token %}">{% if request.is_secure %}https{% else %}http{% endif %}://{{ site.domain }}{% url 'talk-proposal-edit' talk.token participant.token %}</a></li>
<li>{% trans "add an additionnal speaker:" %} <a href="{% url 'talk-proposal-speaker-add' talk.token %}">{% if request.is_secure %}https{% else %}http{% endif %}://{{ site.domain }}{% url 'talk-proposal-speaker-add' talk.token %}</a></li>
<li>{% trans "You can edit your profile:" %} <a href="{% url 'talk-proposal-speaker-edit' talk.token participant.token %}">{% if request.is_secure %}https{% else %}http{% endif %}://{{ site.domain }}{% url 'talk-proposal-speaker-edit' talk.token participant.token %}</a></li>
<li>{% trans "Edit your talk:" %} <a href="{% url 'talk-proposal-edit' talk.token participant.token %}">{% if request.is_secure %}https{% else %}http{% endif %}://{{ conference.site.domain }}{% url 'talk-proposal-edit' talk.token participant.token %}</a></li>
<li>{% trans "add an additionnal speaker:" %} <a href="{% url 'talk-proposal-speaker-add' talk.token %}">{% if request.is_secure %}https{% else %}http{% endif %}://{{ conference.site.domain }}{% url 'talk-proposal-speaker-add' talk.token %}</a></li>
<li>{% trans "You can edit your profile:" %} <a href="{% url 'talk-proposal-speaker-edit' talk.token participant.token %}">{% if request.is_secure %}https{% else %}http{% endif %}://{{ conference.site.domain }}{% url 'talk-proposal-speaker-edit' talk.token participant.token %}</a></li>
</ul>
</p>
<p>{% trans "An email has been sent to you with those URLs" %}</p>

View File

@ -6,6 +6,6 @@
{% block content %}
{% markdown site.conference.home %}
{% markdown conference.home %}
{% endblock %}

View File

@ -6,16 +6,23 @@
{% block navbar %}
{{ block.super }}
<ul class="nav nav-tabs nav-justified subnav">
{% comment %}
<li{% block topicstab %}{% endblock %}><a href="{% url 'list-topics' %}"><span class="glyphicon glyphicon-tag"></span>&nbsp;{% trans "Topics" %}</a></li>
<li{% block trackstab %}{% endblock %}><a href="{% url 'list-tracks' %}"><span class="glyphicon glyphicon-screenshot"></span>&nbsp;{% trans "Tracks" %}</a></li>
<li{% block talkstab %}{% endblock %}><a href="{% url 'list-talks' %}"><span class="glyphicon glyphicon-blackboard"></span>&nbsp;{% trans "Talks" %}</a></li>
<li{% block speakerstab %}{% endblock %}><a href="{% url 'list-speakers' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Speakers" %}</a></li>
<li{% block volunteerstab %}{% endblock %}><a href="{% url 'list-volunteers' %}"><span class="glyphicon glyphicon-thumbs-up"></span>&nbsp;{% trans "Volunteers" %}</a></li>
<li{% block roomstab %}{% endblock %}><a href="{% url 'list-rooms' %}"><span class="glyphicon glyphicon-tent"></span>&nbsp;{% trans "Rooms" %}</a></li>
<li{% block scheduletab %}{% endblock %}><a href="{% url 'show-schedule' %}"><span class="glyphicon glyphicon-calendar"></span>&nbsp;{% trans "Schedule" %}</a></li>
<li{% block participantstab %}{% endblock %}><a href="{% url 'list-participants' %}"><span class="glyphicon glyphicon-user"></span>&nbsp;{% trans "Participants" %}</a></li>
<li{% block correspondentstab %}{% endblock %}><a href="{% url 'list-correspondents' %}"><span class="glyphicon glyphicon-envelope"></span>&nbsp;{% trans "Correspondents" %}</a></li>
<li{% block conferencetab %}{% endblock %}><a href="{% url 'edit-conference' %}"><span class="glyphicon glyphicon-cog"></span>&nbsp;{% trans "Conference" %}</a></li>
{% endcomment %}
<li{% block talkstab %}{% endblock %}><a href="{% url 'talk-list' %}"><span class="glyphicon glyphicon-blackboard"></span>&nbsp;{% trans "Talks" %}</a></li>
<li{% block speakerstab %}{% endblock %}><a href="{% url 'participant-list' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Speakers" %}</a></li>
{% if request.user.is_staff %}
<li><a href="{% url 'admin:index' %}"><span class="glyphicon glyphicon-dashboard"></span>&nbsp;Django-Admin</a></li>
{% endif %}
</ul>
{% endblock %}
{% block content %}
{% trans "Please select a category." %}
{% endblock %}

View File

@ -0,0 +1,54 @@
{% extends 'cfp/staff/base.html' %}
{% load i18n %}
{% block speakerstab %} class="active"{% endblock %}
{% block content %}
<h1>{{ participant }}</h1>
<h2>{% trans "Biography" %}</h2>
<p>{{ participant.biography }}</p>
<h2>{% trans "Informations" %}</h2>
<ul>
<li><b>{% trans "E-mail:" %}</b> <a href="mailto:{{ participant.email }}">{{ participant.email }}</a></li>
{% if participant.twitter %}<li><b>{% trans "Twitter:" %}</b> <a href="{{ participant.twitter }}">{{ participant.twitter }}</a></li>{% endif %}
{% if participant.linkedin %}<li><b>{% trans "LinkedIn:" %}</b> <a href="{{ participant.linkedin }}">{{ participant.linkedin }}</a></li>{% endif %}
{% if participant.github %}<li><b>{% trans "Github:" %}</b> <a href="{{ participant.github }}">{{ participant.github }}</a></li>{% endif %}
{% if participant.website %}<li><b>{% trans "Website:" %}</b> <a href="{{ participant.website }}">{{ participant.website }}</a></li>{% endif %}
{% if participant.facebook %}<li><b>{% trans "Facebook:" %}</b> <a href="{{ participant.facebook }}">{{ participant.facebook }}</a></li>{% endif %}
{% if participant.mastodon %}<li><b>{% trans "Mastodon:" %}</b> <a href="{{ participant.mastodon }}">{{ participant.mastodon }}</a></li>{% endif %}
{% if participant.phone_number %}<li><b>{% trans "Phone number:" %}</b> {{ participant.phone_number }}</li>{% endif %}
{% if participant.language %}<li><b>{% trans "Language:" %}</b> {{ participant.language }}</li>{% endif %}
</ul>
{% if participant.notes %}
<h2>{% trans "Notes" %}</h2>
<em>{% trans "This field is only visible by organizers." %}</em>
<p>{{ participant.notes }}</p>
{% endif %}
<h2>{% trans "Talks" %}</h2>
{% regroup participant.talk_set.all by category as category_list %}
{% for category in category_list %}
<h3>{{ category.list.0.category }}</h3>
<ul>{% for talk in category.list %}
<li>
<a href="{% url 'talk-details' talk.token %}">{{ talk }}</a>
<i>{% trans "by" %}</i>
{% for p in talk.speakers.all %}
{% if p == participant %}{{ p }}{% else %}<a href="{% url 'participant-details' p.token %}">{{ p }}</a>{% endif %}
{% if forloop.revcounter == 2 %} {% trans "and" %} {% elif not forloop.last %}, {% endif %}
{% endfor %}
{% if talk.track %}
<i>{% trans "in" %}</i>
{{ talk.track }}
{% endif %}
</li>
{% endfor %}
</ul>
{% empty %}{% trans "No talks" %}
{% endfor %}
{% endblock %}

View File

@ -0,0 +1,99 @@
{% extends 'cfp/staff/base.html' %}
{% load bootstrap3 i18n %}
{% block speakerstab %} class="active"{% endblock %}
{% block content %}
<h1>{% trans "Speakers" %}</h1>
{% comment %}
<a class="btn btn-primary" role="button" data-toggle="collapse" href="#filter" aria-expanded="{{ show_filters|yesno:"true,false" }}" aria-controles="filter">{% trans "Show filtering options…" %}</a>
<br /><br />
<div class="collapse{{ show_filters|yesno:" in," }}" id="filter">
<div class="well">
<form class="form-horizontal" method="get">
<div class="row">
<div class="col-md-6">
{% bootstrap_field filter_form.transport layout="horizontal" %}
{% bootstrap_field filter_form.transport_booked layout="horizontal" %}
{% bootstrap_field filter_form.sound layout="horizontal" %}
</div>
<div class="col-md-6">
{% bootstrap_field filter_form.accommodation layout="horizontal" %}
{% bootstrap_field filter_form.accommodation_booked layout="horizontal" %}
{% bootstrap_field filter_form.status layout="horizontal" %}
</div>
</div>
<div class="row">
<div class="col-md-6">
{% bootstrap_field filter_form.topic layout="horizontal" %}
</div>
<div class="col-md-6">
{% bootstrap_field filter_form.track layout="horizontal" %}
</div>
</div>
<input type="submit" class="btn btn-success" value="{% trans "Filter" %}">
</form>
</div>
</div>
{% endcomment %}
<table class="table table-bordered table-hover">
<caption>{% trans "Total:" %} {{ participant_list|length }} {% trans "speaker" %}{{ participant_list|length|pluralize }}
</caption>
<thead>
<tr>
<th class="text-center">{% trans "Name" %}</th>
<th class="text-center">{% trans "Talk count" %}</th>
{% comment %}<th class="text-center"></th>{% endcomment %}
</tr>
</thead>
{% comment %}
<tfoot>
<tr>
<td colspan="7">{% trans "Contact:" %} <a href="{{ contact_link }}">{% trans "link" %}</a></td>
</tr>
</tfoot>
{% endcomment %}
{% for participant in participant_list %}
{% if forloop.first %}
<tbody>
{% endif %}
<tr>
<td><a href="{% url 'participant-details' participant.token %}">{{ participant }}</a></td>
<td>
<span class="text-success">{% blocktrans count accepted=participant.accepted_talk_set.count %}accepted: {{ accepted }}{% plural %}accepted: {{ accepted }}{% endblocktrans %}</span>
<span class="text-warning">{% blocktrans count pending=participant.pending_talk_set.count %}pending: {{ pending }}{% plural %}pending: {{ pending }}{% endblocktrans %}</span>
<span class="text-danger">{% blocktrans count refused=participant.refused_talk_set.count %}refused: {{ refused }}{% plural %}refused: {{ refused }}{% endblocktrans %}</span>
</td>
{% comment %}
<td>
<a class="btn btn-{% if speaker.conversation.messages.last.author == speaker.user %}primary{% else %}default{% endif %}" href="{% url 'user-conversation' speaker.user.username %}">{% trans "Contact" %}</a>
</td>
{% endcomment %}
</tr>
{% if forloop.last %}
</tbody>
{% endif %}
{% endfor %}
</table>
{% endblock %}
{% comment %}
{% block js_end %}
<script type="text/javascript">
jQuery(document).ready(function($) {
var anchor = window.location.hash.replace("#", "");
if (anchor == "filter") {
$("#filter").collapse('show');
}
});
</script>
{% endblock %}
{% endcomment %}

View File

@ -0,0 +1,28 @@
{% extends 'cfp/staff/base.html' %}
{% load i18n %}
{% block talkstab %} class="active"{% endblock %}
{% block content %}
<h1>{% if accept %}{% trans "Are you sure to accept this proposals?" %}{% else %}{% trans "Are you sure to decline this proposals?" %}{% endif %}</h1>
<h3>{% trans "Information about the proposals" %}</h3>
<b>{% trans "Title:" %}</b> {{ talk.title }}<br />
<b>{% trans "Kind:" %}</b> {{ talk.category }}<br />
<br />
{% comment %}<h3>{% trans "Information for the proposer" %}</h3>{% endcomment %}
<form action="" method="post">
{% csrf_token %}
{% comment %}
<div class="form-group">
<label for="message">{% trans "If you want to send a message to the proposer, please enter it below. Remember to indicate which talk your message is reffering." %}</label>
<textarea name="message" class="form-control" rows="5"></textarea>
</div>
{% endcomment %}
<button type="submit" class="btn btn-{% if accept %}success{% else %}danger{% endif %}">{% if accept %}{% trans "Accept the proposal" %}{% else %}{% trans "Decline the proposal" %}{% endif %}</button>
<a class="btn btn-default" href="{% url 'talk-details' talk.token %}">{% trans "Cancel" %}</a>
</form>
{% endblock %}

View File

@ -0,0 +1,143 @@
{% extends 'cfp/staff/base.html' %}
{% load bootstrap3 i18n %}
{% block talkstab %} class="active"{% endblock %}
{% block content %}
<h1>{{ talk.title }}</h1>
{% comment %}
{% if edit_perm %}
<a class="btn btn-success" href="{% url 'edit-talk' talk.slug %}">{% trans "Edit" %}</a><br />
{% endif %}
{% endcomment %}
<p>{% if talk.abstract %}{{ talk.abstract }}{% else %}<i>{% trans "No abstract provided." %}</i>{% endif %}</p>
{% comment %}
{% if moderate_perm %}
<dl class="dl-horizontal">
<dt>{% trans "Format" %}</dt>
<dd><a href="{{ talk.event.get_absolute_url }}">{{ talk.event }}</a></dd>
<dt>{% trans "Topics" %}</dt>
<dd>{% for topic in talk.topics.all %}
<a href="{{ topic.get_absolute_url }}">{{ topic }}</a>{% if not forloop.last %}, {% endif %}
{% empty %}
<i>{% trans "No topics." %}</i>
{% endfor %}</dd>
<dt>{% trans "Track" %}</dt>
<dd>{% if talk.track %}
<a href="{{ talk.track.get_absolute_url }}">{{ talk.track }}</a>
{% else %}
<em>{% trans "No assigned yet." %}</em>
{% endif %}</dd>
<dt>Horaire</dt>
<dd>{% if talk.start_date %}
<span class="date">{{ talk.start_date|date:"l d b" }}</span>,
<span class="time">{{ talk.start_date|date:"H:i" }} &ndash; {% if talk.end_date %}{{ talk.end_date|date:"H:i" }}{% else %}?{% endif %}</span>
{% else %}<em>{% trans "not defined" %}</em>
{% endif %}
</dd>
<dt>Salle</dt>
<dd>{% if talk.room %}
<a href="{{ talk.room.get_absolute_url }}">
<span class="label label-info">{{ talk.room }}</span>
</a>
{% else %}<em>{% trans "not defined" %}</em>
{% endif %}
</dd>
{% if talk.registration_required %}
<dt>{% trans "Registrations" %}</dt>
<dd>{% if talk.attendees_limit %}{{ talk.attendees.count }} / {{ talk.attendees_limit }}{% else %}{% trans "required but unlimited" %}{% endif %}</dd>
{% endif %}
{% if talk.materials %}
<dt>{% trans "Materials" %}</dt>
<dd><a href="{{ talk.materials.url }}">{{ talk.materials_name }}</a></dd>
{% endif %}
{% if talk.video %}
<dt>{% trans "Video" %}</dt>
<dd><a href="{{ talk.video }}">{% trans "download" %}</a></dd>
{% endif %}
</dl>
{% endif %}
{% endcomment %}
<h3>{% trans "Description" %}</h3>
<p>{% if talk.description %}{{ talk.description|linebreaksbr }}{% else %}<i>{% trans "No description provided." %}</i>{% endif %}</p>
<h3>{% trans "Speakers" %}</h3>
{% for participant in talk.speakers.all %}
{% if forloop.first %}<ul>{% endif %}
<li><a href="{% url 'participant-details' participant.token %}">{{ participant }}</a></li>
{% if forloop.last %}</ul>{% endif %}
{% empty %}
<i>{% trans "No speakers." %}</i>
{% endfor %}
<h3>{% trans "Track" %}</h3>
{% if talk.track %}
<p>{{ talk.track }}</p>
{% else %}
<p><em>{% trans "No assigned yet." context "session" %}</em></p>
{% endif %}
<h3>{% trans "Notes" %}</h3>
<p>{% if talk.notes %}{{ talk.notes|linebreaksbr }}{% else %}<i>{% trans "No notes." %}</i>{% endif %}</p>
<h2>{% trans "Moderation" %}</h2>
<h3>{% trans "Status" %}</h3>
<span class="label label-{{ talk.accepted|yesno:"success,danger,warning" }}">{{ talk.accepted|yesno:"Accepted,Declined,Pending decision" }}</span><br />
{% if talk.accepted == None %}
<h3>{% trans "Vote" %}</h3>
<div class="btn-group" role="group" aria-label="vote">
<a class="btn {% if vote.vote == -2 %} active {% endif %}btn-danger" href="{% url 'talk-vote' talk.token '-2' %}">-2</a>
<a class="btn {% if vote.vote == -1 %} active {% endif %}btn-warning" href="{% url 'talk-vote' talk.token '-1' %}">-1</a>
<a class="btn {% if vote.vote == 0 %} active {% endif %}btn-default" href="{% url 'talk-vote' talk.token '0' %}"> 0</a>
<a class="btn {% if vote.vote == 1 %} active {% endif %}btn-info" href="{% url 'talk-vote' talk.token '+1' %}">+1</a>
<a class="btn {% if vote.vote == 2 %} active {% endif %}btn-success" href="{% url 'talk-vote' talk.token '+2' %}">+2</a>
</div>
<br /><br />
<p>{{ talk.vote_set.count }} {% trans "vote" %}{{ talk.vote_set.count|pluralize }}, {% trans "average:" %} {{ talk.score|floatformat:1 }}</p>
<a href="{% url 'talk-accept' talk.token %}" class="btn btn-success">Accept</a>
<a href="{% url 'talk-decline' talk.token %}" class="btn btn-danger">Decline</a>
{% endif %}
{% comment %}
{% if talk.registration_required %}
<h3>{% trans "Attendees" %}</h3>
{% for attendee in talk.attendees.all %}
{% if forloop.first %}<ol>{% endif %}
<li><a href="mailto:{{ attendee.get_email }}">{{ attendee.get_name }}</a></li>
{% if forloop.last %}</ol>{% endif %}
{% empty %}
<em>{% trans "No attendees yet." %}</em>
{% endfor %}
{% endif %}
{% endcomment %}
{% comment %}
<h3>{% trans "Messages" %}</h3>
{% trans "These messages are for organization team only." %}<br /><br />
{% for message in talk.conversation.messages.all %}
{% include 'conversations/_message_detail.html' %}
{% endfor %}
{% include 'conversations/_message_form.html' %}
{% endcomment %}
{% endblock %}

View File

@ -0,0 +1,54 @@
{% extends 'cfp/staff/base.html' %}
{% load bootstrap3 i18n %}
{% block talkstab %} class="active"{% endblock %}
{% block content %}
<h1>{% trans "Talks" %}</h1>
<table class="table table-bordered table-hover">
<caption>{% trans "Total:" %} {{ talk_list|length }} {% trans "talk" %}{{ talk_list|length|pluralize }}</caption>
<thead>
<tr>
{% comment %}<th></th>{% endcomment %}
<th class="text-center">{% trans "Title" %} <a href="?{{ sort_urls.title }}"><span class="glyphicon glyphicon-{{ sort_glyphicons.title }} pull-right"></span></a></th>
<th class="text-center">{% trans "Intervention kind" %} <a href="?{{ sort_urls.kind }}"><span class="glyphicon glyphicon-{{ sort_glyphicons.kind }} pull-right"></span></a></th>
<th class="text-center">{% trans "Speakers" %}</th>
<th class="text-center">{% trans "Track" %}</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>
</thead>
{% for talk in talk_list %}
{% if forloop.first %}
<tbody>
{% endif %}
<tr class="{{ talk.accepted|yesno:"success,danger,warning" }}">
{% comment %}<td><input type="checkbox" name="talks" value="{{ talk.slug }}"></td>{% endcomment %}
<td><a href="{% url 'talk-details' talk.token %}">{{ talk.title }}</a></td>
<td>{{ talk.category }}</td>
<td>
{% for participant in talk.speakers.all %}
<a href="{% url 'participant-details' participant.token %}">{{ participant }}</a>
{% if forloop.revcounter == 2 %} {% trans "and" %} {% elif not forloop.last %}, {% endif %}
{% empty %}
{% endfor %}
</td>
<td>{{ talk.track|default:"" }}</td>
<td>
{% if talk.accepted == True %}
{% trans "Accepted" %}
{% elif talk.accepted == False %}
{% trans "Declined" %}
{% else %}
{% blocktrans with score=talk.score|floatformat:1 %}Pending, score: {{ score }}{% endblocktrans %}
{% endif %}
</td>
</tr>
{% if forloop.last%}
</tbody>
{% endif %}
{% endfor %}
</table>
{% endblock %}

View File

View File

@ -0,0 +1,11 @@
from django import template
from cfp.utils import is_staff
register = template.Library()
@register.filter
def staff(request):
return is_staff(request, request.user)

View File

@ -3,10 +3,20 @@ from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.talk_proposal, name='talk-proposal'),
url(r'^(?P<talk_id>[\w\-]+)/speaker/add/$', views.talk_proposal_speaker_edit, name='talk-proposal-speaker-add'),
url(r'^(?P<talk_id>[\w\-]+)/speaker/(?P<participant_id>[\w\-]+)/$', views.talk_proposal_speaker_edit, name='talk-proposal-speaker-edit'),
url(r'^(?P<talk_id>[\w\-]+)/(?P<participant_id>[\w\-]+)/$', views.talk_proposal, name='talk-proposal-edit'),
url(r'^$', views.home, name='home'),
url(r'^cfp/$', views.talk_proposal, name='talk-proposal'),
url(r'^cfp/(?P<talk_id>[\w\-]+)/speaker/add/$', views.talk_proposal_speaker_edit, name='talk-proposal-speaker-add'),
url(r'^cfp/(?P<talk_id>[\w\-]+)/speaker/(?P<participant_id>[\w\-]+)/$', views.talk_proposal_speaker_edit, name='talk-proposal-speaker-edit'),
url(r'^cfp/(?P<talk_id>[\w\-]+)/(?P<participant_id>[\w\-]+)/$', views.talk_proposal, name='talk-proposal-edit'),
url(r'^staff/$', views.staff, name='staff'),
url(r'^staff/talks/$', views.talk_list, name='talk-list'),
url(r'^staff/talks/(?P<talk_id>[\w\-]+)/$', views.talk_details, name='talk-details'),
url(r'^staff/talks/(?P<talk_id>[\w\-]+)/vote/(?P<score>[-+0-2]+)/$', views.talk_vote, name='talk-vote'),
url(r'^staff/talks/(?P<talk_id>[\w\-]+)/accept/$', views.talk_decide, {'accept': True}, name='talk-accept'),
url(r'^staff/talks/(?P<talk_id>[\w\-]+)/decline/$', views.talk_decide, {'accept': False}, name='talk-decline'),
url(r'^staff/speakers/$', views.participant_list, name='participant-list'),
url(r'^staff/speakers/(?P<participant_id>[\w\-]+)/$', views.participant_details, name='participant-details'),
#url(r'^markdown/$', views.markdown_preview, name='markdown'),
#url(r'^$', views.home, name='home'),
#url(r'^staff/$', views.staff, name='staff'),

View File

@ -1,31 +1,40 @@
from django.utils.crypto import get_random_string
def generate_user_uid():
return get_random_string(length=12, allowed_chars='abcdefghijklmnopqrstuvwxyz0123456789')
from django.contrib.sites.shortcuts import get_current_site
from django.db.models import Q, Sum
from django.db.models.functions import Coalesce
from django.utils.safestring import mark_safe
#from accounts.models import Participation
from markdown import markdown
import bleach
from .models import Conference
def get_current_conf(request):
site = get_current_site(request)
return Conference.objects.get(site=site)
def query_sum(queryset, field):
return queryset.aggregate(s=Coalesce(Sum(field), 0))['s']
def generate_user_uid():
return get_random_string(length=12, allowed_chars='abcdefghijklmnopqrstuvwxyz0123456789')
def allowed_talks(talks, request):
if not Participation.objects.get(site=get_current_site(request), user=request.user).is_orga():
talks = talks.filter(Q(topics__reviewers=request.user) | Q(speakers=request.user) | Q(proposer=request.user))
return talks.distinct()
def markdown_to_html(md):
html = markdown(md)
allowed_tags = bleach.ALLOWED_TAGS + ['p', 'pre', 'span' ] + ['h%d' % i for i in range(1, 7) ]
html = bleach.clean(html, tags=allowed_tags)
return mark_safe(html)
def is_staff(request, user):
return user.is_authenticated and (user.is_superuser or user in site.conference.staff)

View File

@ -1,5 +1,3 @@
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import send_mail
from django.core.urlresolvers import reverse_lazy
from django.forms.models import modelform_factory
@ -7,13 +5,22 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.views.generic import FormView, TemplateView
from django.contrib import messages
from .models import Participant, Talk
from cfp.decorators import staff_required
from .models import Participant, Talk, Vote
def talk_proposal(request, talk_id=None, participant_id=None):
def home(request, conference):
if conference.home:
return render(request, 'cfp/home.html')
else:
return redirect(reverse('talk-proposal'))
site = get_current_site(request)
def talk_proposal(request, conference, talk_id=None, participant_id=None):
site = conference.site
talk = None
participant = None
@ -44,7 +51,7 @@ def talk_proposal(request, talk_id=None, participant_id=None):
url_talk_proposal_edit = base_url + reverse('talk-proposal-edit', args=[talk.token, participant.token])
url_talk_proposal_speaker_add = base_url + reverse('talk-proposal-speaker-add', args=[talk.token])
url_talk_proposal_speaker_edit = base_url + reverse('talk-proposal-speaker-edit', args=[talk.token, participant.token])
msg_title = _('Your talk "{}" has been submitted for {}').format(talk.title, site.conference.name)
msg_title = _('Your talk "{}" has been submitted for {}').format(talk.title, conference.name)
msg_body = _("""Hi {},
Your talk has been submitted for {}.
@ -64,12 +71,12 @@ Thanks!
{}
""").format(participant.name, site.conference.name, talk.title, talk.description, url_talk_proposal_edit, url_talk_proposal_speaker_add, url_talk_proposal_speaker_edit, site.conference.name)
""").format(participant.name, conference.name, talk.title, talk.description, url_talk_proposal_edit, url_talk_proposal_speaker_add, url_talk_proposal_speaker_edit, conference.name)
send_mail(
msg_title,
msg_body,
site.conference.from_email(),
conference.from_email(),
[participant.email],
fail_silently=False,
)
@ -83,21 +90,20 @@ Thanks!
})
def talk_proposal_speaker_edit(request, talk_id, participant_id=None):
def talk_proposal_speaker_edit(request, conference, talk_id, participant_id=None):
site = get_current_site(request)
talk = get_object_or_404(Talk, token=talk_id, site=site)
talk = get_object_or_404(Talk, token=talk_id, site=conference.site)
participant = None
if participant_id:
participant = get_object_or_404(Participant, token=participant_id, site=site)
participant = get_object_or_404(Participant, token=participant_id, site=conference.site)
ParticipantForm = modelform_factory(Participant, fields=('name','email', 'biography'))
participant_form = ParticipantForm(request.POST or None, instance=participant)
if request.method == 'POST' and participant_form.is_valid():
participant, created = Participant.objects.get_or_create(email=participant_form.cleaned_data['email'], site=site)
participant, created = Participant.objects.get_or_create(email=participant_form.cleaned_data['email'], site=conference.site)
participant_form = ParticipantForm(request.POST, instance=participant)
participant = participant_form.save()
participant.save()
@ -108,6 +114,78 @@ def talk_proposal_speaker_edit(request, talk_id, participant_id=None):
return render(request, 'cfp/speaker.html', {
'participant_form': participant_form,
'site': site,
})
@staff_required
def staff(request, conference):
return render(request, 'cfp/staff/base.html')
@staff_required
def talk_list(request, conference):
talks = Talk.objects.filter(site=conference.site)
return render(request, 'cfp/staff/talk_list.html', {
'talk_list': talks,
})
@staff_required
def talk_details(request, conference, talk_id):
talk = get_object_or_404(Talk, token=talk_id, site=conference.site)
return render(request, 'cfp/staff/talk_details.html', {
'talk': talk,
})
@staff_required
def talk_vote(request, conference, talk_id, score):
talk = get_object_or_404(Talk, token=talk_id, site=conference.site)
vote, created = Vote.objects.get_or_create(talk=talk, user=request.user)
vote.vote = int(score)
vote.save()
messages.success(request, _('Vote successfully created') if created else _('Vote successfully updated'))
return redirect(talk.get_absolute_url())
@staff_required
def talk_decide(request, conference, talk_id, accept):
talk = get_object_or_404(Talk, token=talk_id, site=conference.site)
if request.method == 'POST':
# # Does we need to send a notification to the proposer?
# m = request.POST.get('message', '').strip()
# if m:
# participation = Participation.objects.get(site=site, user=talk.proposer)
# conversation = ConversationWithParticipant.objects.get(participation=participation)
# Message.objects.create(conversation=conversation, author=request.user, content=m)
# # Save the decision in the talk's conversation
# conversation = ConversationAboutTalk.objects.get(talk=talk)
if accept:
note = "The talk has been accepted."
else:
note = "The talk has been declined."
#Message.objects.create(conversation=conversation, author=request.user, content=note)
talk.accepted = accept
talk.save()
messages.success(request, _('Decision taken in account'))
return redirect(talk.get_absolute_url())
return render(request, 'cfp/staff/talk_decide.html', {
'talk': talk,
'accept': accept,
})
@staff_required
def participant_list(request, conference):
participants = Participant.objects.filter(site=conference.site)
return render(request, 'cfp/staff/participant_list.html', {
'participant_list': participants,
})
@staff_required
def participant_details(request, conference, participant_id):
participant = get_object_or_404(Participant, token=participant_id, site=conference.site)
return render(request, 'cfp/staff/participant_details.html', {
'participant': participant,
})

Binary file not shown.

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-06 21:13+0000\n"
"POT-Creation-Date: 2017-07-30 14:00+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -24,31 +24,31 @@ msgstr ""
"Par exemple, vous devez rentrer le samedi soir, vous ne pouvez pas manger de "
"viande, etc."
#: accounts/models.py:18 cfp/models.py:84
#: accounts/models.py:18 cfp/models.py:83
msgid "Phone number"
msgstr "Numéro de téléphone"
#: accounts/models.py:20 cfp/models.py:77
#: accounts/models.py:20 cfp/models.py:76
msgid "Twitter"
msgstr ""
#: accounts/models.py:21 cfp/models.py:78
#: accounts/models.py:21 cfp/models.py:77
msgid "LinkedIn"
msgstr ""
#: accounts/models.py:22 cfp/models.py:79
#: accounts/models.py:22 cfp/models.py:78
msgid "Github"
msgstr ""
#: accounts/models.py:23 cfp/models.py:80
#: accounts/models.py:23 cfp/models.py:79
msgid "Website"
msgstr ""
#: accounts/models.py:24 cfp/models.py:81
#: accounts/models.py:24 cfp/models.py:80
msgid "Facebook"
msgstr ""
#: accounts/models.py:25 cfp/models.py:82
#: accounts/models.py:25 cfp/models.py:81
msgid "Mastodon"
msgstr ""
@ -99,12 +99,15 @@ msgstr "Contacter"
msgid "Edit"
msgstr "Éditer"
#: accounts/templates/accounts/participant_details.html:20 cfp/models.py:74
#: accounts/templates/accounts/participant_details.html:20 cfp/models.py:73
#: cfp/templates/cfp/staff/participant_details.html:10
msgid "Biography"
msgstr "Biographie"
#: accounts/templates/accounts/participant_details.html:27
#: ponyconf/templates/staff.html:11
#: cfp/templates/cfp/staff/base.html:20
#: cfp/templates/cfp/staff/participant_details.html:32
#: cfp/templates/cfp/staff/talk_list.html:8
#: proposals/templates/proposals/talk_list.html:9
msgid "Talks"
msgstr "Exposés"
@ -169,8 +172,10 @@ msgstr "Licence vidéo :"
msgid "Constraints"
msgstr "Contraintes"
#: accounts/templates/accounts/participant_details.html:71 cfp/models.py:88
#: proposals/models.py:161 proposals/templates/proposals/talk_detail.html:102
#: accounts/templates/accounts/participant_details.html:71 cfp/models.py:87
#: cfp/templates/cfp/staff/participant_details.html:27
#: cfp/templates/cfp/staff/talk_details.html:92 proposals/models.py:161
#: proposals/templates/proposals/talk_detail.html:102
msgid "Notes"
msgstr "Notes"
@ -179,8 +184,7 @@ msgstr "Notes"
msgid "%(profile)s's profile"
msgstr "Profil de %(profile)s"
#: accounts/templates/accounts/participant_list.html:9
#: ponyconf/templates/staff.html:16 volunteers/models.py:15
#: accounts/templates/accounts/participant_list.html:9 volunteers/models.py:15
msgid "Participants"
msgstr "Participants"
@ -282,53 +286,62 @@ msgstr "%(name)s a été ajouté aux participants"
msgid "%(name)s is already a participant"
msgstr "%(name)s est déjà participant"
#: cfp/models.py:71
#: cfp/models.py:41 ponyconf/templates/base.html:36
msgid "Staff"
msgstr ""
#: cfp/models.py:70
msgid "Your Name"
msgstr "Votre Nom"
#: cfp/models.py:88
#: cfp/models.py:87 cfp/templates/cfp/staff/participant_details.html:28
msgid "This field is only visible by organizers."
msgstr "Ce champs est uniquement visible par les organisateurs."
#: cfp/models.py:138 proposals/models.py:52 proposals/models.py:75
#: proposals/models.py:132 volunteers/models.py:12
#: cfp/models.py:137 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/models.py:140 proposals/models.py:54 proposals/models.py:77
#: proposals/models.py:158 proposals/templates/proposals/talk_detail.html:72
#: volunteers/models.py:14
#: cfp/models.py:139 cfp/templates/cfp/staff/talk_details.html:71
#: 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"
msgstr "Description"
#: cfp/models.py:161 proposals/models.py:96
#: cfp/models.py:160 proposals/models.py:96
msgid "Default duration (min)"
msgstr "Durée par défaut (min)"
#: cfp/models.py:162 proposals/models.py:97
#: cfp/models.py:161 proposals/models.py:97
msgid "Color on program"
msgstr "Couleur sur le programme"
#: cfp/models.py:163 proposals/models.py:98
#: cfp/models.py:162 proposals/models.py:98
msgid "Label on program"
msgstr "Label dans le xml du programme"
#: cfp/models.py:230 ponyconf/templates/staff.html:12 proposals/models.py:154
#: cfp/models.py:229 cfp/templates/cfp/staff/base.html:21
#: cfp/templates/cfp/staff/participant_list.html:8
#: cfp/templates/cfp/staff/talk_details.html:75
#: cfp/templates/cfp/staff/talk_list.html:18 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:231
#: cfp/models.py:230
msgid "Talk Title"
msgstr "Titre de votre proposition:"
#: cfp/models.py:234
#: cfp/models.py:233
msgid "Description of your talk"
msgstr "Description de votre proposition"
#: cfp/models.py:235 proposals/models.py:160
#: cfp/models.py:234 cfp/templates/cfp/staff/talk_details.html:85
#: cfp/templates/cfp/staff/talk_list.html:19 proposals/models.py:160
#: proposals/templates/proposals/talk_detail.html:33
#: proposals/templates/proposals/talk_detail.html:89
#: proposals/templates/proposals/talk_list.html:51
@ -336,11 +349,11 @@ msgstr "Description de votre proposition"
msgid "Track"
msgstr "Session"
#: cfp/models.py:236
#: cfp/models.py:235
msgid "Message to organizers"
msgstr "Message aux organisateurs"
#: cfp/models.py:236
#: cfp/models.py:235
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 "
@ -350,23 +363,23 @@ msgstr ""
"votre proposition, comme une vidéo, des slides, n'hésitez pas à les ajouter "
"ici."
#: cfp/models.py:237
#: cfp/models.py:236
msgid "Talk Category"
msgstr "Catégorie de proposition"
#: cfp/models.py:238
#: cfp/models.py:237
msgid "I'm ok to be recorded on video"
msgstr "Jaccepte dêtre enregistré en vidéo"
#: cfp/models.py:239
#: cfp/models.py:238
msgid "Video licence"
msgstr "Licence vidéo"
#: cfp/models.py:240
#: cfp/models.py:239
msgid "I need sound"
msgstr "Jai besoin de son"
#: cfp/models.py:243 proposals/models.py:165
#: cfp/models.py:242 proposals/models.py:165
msgid "Duration (min)"
msgstr "Durée (min)"
@ -407,11 +420,182 @@ msgstr "Participer"
msgid "Save"
msgstr "Envoyer"
#: cfp/views.py:47
#: cfp/templates/cfp/staff/base.html:29
msgid "Please select a category."
msgstr "Veuillez sélectionner une catégorie."
#: cfp/templates/cfp/staff/participant_details.html:13
msgid "Informations"
msgstr "Informations"
#: cfp/templates/cfp/staff/participant_details.html:15
msgid "E-mail:"
msgstr "E-mail :"
#: cfp/templates/cfp/staff/participant_details.html:16
msgid "Twitter:"
msgstr "Twitter :"
#: cfp/templates/cfp/staff/participant_details.html:17
msgid "LinkedIn:"
msgstr "LinkedIn :"
#: cfp/templates/cfp/staff/participant_details.html:18
msgid "Github:"
msgstr "Github :"
#: cfp/templates/cfp/staff/participant_details.html:19
msgid "Website:"
msgstr "Website :"
#: cfp/templates/cfp/staff/participant_details.html:20
msgid "Facebook:"
msgstr "Facebook :"
#: cfp/templates/cfp/staff/participant_details.html:21
msgid "Mastodon:"
msgstr "Mastodon :"
#: cfp/templates/cfp/staff/participant_details.html:22
msgid "Phone number:"
msgstr "Numéro de téléphone :"
#: cfp/templates/cfp/staff/participant_details.html:23
msgid "Language:"
msgstr "Langue :"
#: cfp/templates/cfp/staff/participant_details.html:39
#: proposals/templates/proposals/_talk_list.html:8
msgid "by"
msgstr "par"
#: cfp/templates/cfp/staff/participant_details.html:42
#: cfp/templates/cfp/staff/talk_list.html:35
#: proposals/templates/proposals/_talk_list.html:11
#: proposals/templates/proposals/_talk_list.html:17
#: proposals/templates/proposals/talk_list.html:66
msgid "and"
msgstr "et"
#: cfp/templates/cfp/staff/participant_details.html:45
#: proposals/templates/proposals/_talk_list.html:14
msgid "in"
msgstr "dans la session"
#: cfp/templates/cfp/staff/participant_details.html:51
#: proposals/templates/proposals/_talk_list.html:23
msgid "No talks"
msgstr "Aucun exposé"
#: cfp/templates/cfp/staff/participant_list.html:45
#: cfp/templates/cfp/staff/talk_list.html:11
#: proposals/templates/proposals/speaker_list.html:44
#: proposals/templates/proposals/talk_list.html:43
#: volunteers/templates/volunteers/volunteer_list.html:25
msgid "Total:"
msgstr "Total :"
#: cfp/templates/cfp/staff/participant_list.html:45
#: proposals/templates/proposals/speaker_list.html:44
msgid "speaker"
msgstr "orateur"
#: cfp/templates/cfp/staff/participant_list.html:50
#: proposals/templates/proposals/speaker_list.html:50
msgid "Talk count"
msgstr "Nombre dexposé"
#: cfp/templates/cfp/staff/participant_list.html:70
#, python-format
msgid "accepted: %(accepted)s"
msgid_plural "accepted: %(accepted)s"
msgstr[0] "accepté : %(accepted)s"
msgstr[1] "acceptés : %(accepted)s"
#: cfp/templates/cfp/staff/participant_list.html:72
#, python-format
msgid "pending: %(pending)s"
msgid_plural "pending: %(pending)s"
msgstr[0] "en attente : %(pending)s"
msgstr[1] "en attente : %(pending)s"
#: cfp/templates/cfp/staff/participant_list.html:74
#, python-format
msgid "refused: %(refused)s"
msgid_plural "refused: %(refused)s"
msgstr[0] "refusé : %(refused)s"
msgstr[1] "refusés : %(refused)s"
#: cfp/templates/cfp/staff/talk_details.html:16
#: 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
msgctxt "session"
msgid "No assigned yet."
msgstr "Pas encore assignée."
#: cfp/templates/cfp/staff/talk_details.html:94
#: proposals/templates/proposals/talk_detail.html:104
msgid "No notes."
msgstr "Aucune note."
#: cfp/templates/cfp/staff/talk_list.html:11
#: 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:16 proposals/models.py:155
#: proposals/templates/proposals/talk_list.html:47
msgid "Title"
msgstr "Titre"
#: cfp/templates/cfp/staff/talk_list.html:17 proposals/models.py:162
#: proposals/templates/proposals/talk_list.html:48
msgid "Intervention kind"
msgstr "Type dintervention"
#: cfp/templates/cfp/staff/talk_list.html:20
#: proposals/templates/proposals/talk_detail.html:110
#: proposals/templates/proposals/talk_list.html:52
msgid "Status"
msgstr "Statut"
#: cfp/templates/cfp/staff/talk_list.html:42
#: proposals/templates/proposals/talk_list.html:78
msgid "Accepted"
msgstr "Accepté"
#: cfp/templates/cfp/staff/talk_list.html:44
#: proposals/templates/proposals/talk_list.html:80
msgid "Declined"
msgstr "Décliné"
#: cfp/templates/cfp/staff/talk_list.html:46
#: proposals/templates/proposals/talk_list.html:82
#, python-format
msgid "Pending, score: %(score)s"
msgstr "En cours, score : %(score)s"
#: cfp/views.py:53
msgid "Your talk \"{}\" has been submitted for {}"
msgstr "Votre proposition \"{}\" a été transmise à {}"
#: cfp/views.py:48
#: cfp/views.py:54
msgid ""
"Hi {},\n"
"\n"
@ -465,7 +649,6 @@ msgid "Conversation with %(correspondent)s"
msgstr "Conversation avec %(correspondent)s"
#: conversations/templates/conversations/correspondent_list.html:9
#: ponyconf/templates/staff.html:17
msgid "Correspondents"
msgstr "Correspondants"
@ -487,7 +670,7 @@ msgid "Message sent!"
msgstr "Message envoyé !"
#: planning/templates/planning/public-program.html:8
#: planning/templates/planning/schedule.html:9 ponyconf/templates/staff.html:15
#: planning/templates/planning/schedule.html:9
msgid "Schedule"
msgstr "Programme"
@ -514,7 +697,6 @@ msgid "Add a room"
msgstr "Ajouter une salle"
#: planning/templates/planning/room_list.html:9
#: ponyconf/templates/staff.html:14
msgid "Rooms"
msgstr "Salles"
@ -526,39 +708,32 @@ msgstr "place"
msgid "Some talks are not scheduled yet."
msgstr "Certains exposés ne sont pas encore planifiés."
#: 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é"
#: planning/templates/planning/room_list.html:40
msgid "No rooms."
msgstr "Aucune salle."
#: ponyconf/settings.py:143
#: ponyconf/settings.py:145
msgid "English"
msgstr "Anglais"
#: ponyconf/settings.py:144
#: ponyconf/settings.py:146
msgid "French"
msgstr "Français"
#: ponyconf/templates/base.html:20
#: ponyconf/templates/base.html:21
msgid "Home"
msgstr "Accueil"
#: ponyconf/templates/base.html:21
#: ponyconf/templates/base.html:23
msgid "Call for participation"
msgstr "Appel à participation"
#: ponyconf/templates/base.html:46
#: ponyconf/templates/base.html:50
#: ponyconf/templates/registration/login.html:10
msgid "Login"
msgstr "Se connecter"
#: ponyconf/templates/base.html:63
#: ponyconf/templates/base.html:67
msgid "Powered by"
msgstr "Propulsé par"
@ -566,27 +741,6 @@ msgstr "Propulsé par"
msgid "Password Change"
msgstr "Changement de mot de passe"
#: ponyconf/templates/staff.html:9 proposals/models.py:159
#: proposals/templates/proposals/talk_detail.html:26
#: proposals/templates/proposals/talk_list.html:50
#: proposals/templates/proposals/topic_list.html:9
msgid "Topics"
msgstr "Thèmes"
#: ponyconf/templates/staff.html:10
#: proposals/templates/proposals/track_list.html:9
msgid "Tracks"
msgstr "Sessions"
#: ponyconf/templates/staff.html:13
#: volunteers/templates/volunteers/volunteer_list.html:9
msgid "Volunteers"
msgstr "Bénévoles"
#: ponyconf/templates/staff.html:18
msgid "Conference"
msgstr "Conférence"
#: proposals/forms.py:46
msgid "Should be less than 255 characters"
msgstr "Texte court, moins de 255 caractères"
@ -661,10 +815,6 @@ msgstr "Responsables"
msgid "Email"
msgstr "E-mail"
#: proposals/models.py:155 proposals/templates/proposals/talk_list.html:47
msgid "Title"
msgstr "Titre"
#: proposals/models.py:155
msgid "After submission, title can only be changed by the staff."
msgstr ""
@ -675,14 +825,16 @@ msgstr ""
msgid "Abstract"
msgstr "Résumé"
#: proposals/models.py:159 proposals/templates/proposals/talk_detail.html:26
#: proposals/templates/proposals/talk_list.html:50
#: proposals/templates/proposals/topic_list.html:9
msgid "Topics"
msgstr "Thèmes"
#: proposals/models.py:159
msgid "The topics can not be changed after submission."
msgstr "Les thèmes ne peuvent pas être modifiés après soumission."
#: proposals/models.py:162 proposals/templates/proposals/talk_list.html:48
msgid "Intervention kind"
msgstr "Type dintervention"
#: proposals/models.py:169 proposals/templates/proposals/talk_detail.html:131
msgid "Attendees"
msgstr "Inscrits"
@ -722,24 +874,6 @@ msgstr "stand"
msgid "other"
msgstr "autre"
#: proposals/templates/proposals/_talk_list.html:8
msgid "by"
msgstr "par"
#: proposals/templates/proposals/_talk_list.html:11
#: proposals/templates/proposals/_talk_list.html:17
#: proposals/templates/proposals/talk_list.html:66
msgid "and"
msgstr "et"
#: proposals/templates/proposals/_talk_list.html:14
msgid "in"
msgstr "portant sur"
#: proposals/templates/proposals/_talk_list.html:23
msgid "No talks"
msgstr "Aucun exposé"
#: proposals/templates/proposals/conference.html:11
msgid "Home page"
msgstr "Page daccueil"
@ -784,16 +918,6 @@ msgstr "Afficher les options de filtrage…"
msgid "Filter"
msgstr "Filtrer"
#: proposals/templates/proposals/speaker_list.html:44
#: proposals/templates/proposals/talk_list.html:43
#: volunteers/templates/volunteers/volunteer_list.html:25
msgid "Total:"
msgstr "Total :"
#: proposals/templates/proposals/speaker_list.html:44
msgid "speaker"
msgstr "orateur"
#: proposals/templates/proposals/speaker_list.html:48
#: volunteers/templates/volunteers/volunteer_list.html:29
msgid "Username"
@ -804,10 +928,6 @@ msgstr "Nom dutilisateur"
msgid "Fullname"
msgstr "Prénom et nom"
#: proposals/templates/proposals/speaker_list.html:50
msgid "Talk count"
msgstr "Nombre dexposé"
#: proposals/templates/proposals/speaker_list.html:51
msgctxt "table column title"
msgid "Need transport?"
@ -871,10 +991,6 @@ msgstr "Accepter la proposition"
msgid "Decline the proposal"
msgstr "Décliner la proposition"
#: 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"
@ -910,31 +1026,14 @@ msgstr "Vidéo"
msgid "download"
msgstr "Télécharger"
#: proposals/templates/proposals/talk_detail.html:74
msgid "No description provided."
msgstr "Aucune description fournie."
#: proposals/templates/proposals/talk_detail.html:83
msgid "No speakers."
msgstr "Aucun orateur."
#: proposals/templates/proposals/talk_detail.html:94
msgid "Assign to"
msgstr "Assigner à"
#: proposals/templates/proposals/talk_detail.html:104
msgid "No notes."
msgstr "Aucune note."
#: proposals/templates/proposals/talk_detail.html:108
msgid "Moderation"
msgstr "Modération"
#: proposals/templates/proposals/talk_detail.html:110
#: proposals/templates/proposals/talk_list.html:52
msgid "Status"
msgstr "Statut"
#: proposals/templates/proposals/talk_detail.html:115
msgid "Vote"
msgstr "Vote"
@ -963,19 +1062,6 @@ msgstr "Ces messages sont à destination de la team dorganisation seulement."
msgid "Edit a talk"
msgstr "Éditer un exposé"
#: proposals/templates/proposals/talk_list.html:78
msgid "Accepted"
msgstr "Accepté"
#: proposals/templates/proposals/talk_list.html:80
msgid "Declined"
msgstr "Décliné"
#: proposals/templates/proposals/talk_list.html:82
#, python-format
msgid "Pending, score: %(score)s"
msgstr "En cours, score : %(score)s"
#: proposals/templates/proposals/talk_list.html:95
msgid "For selected talks:"
msgstr "Pour les exposés sélectionnés :"
@ -1030,6 +1116,10 @@ msgstr "Ajouter un thème"
msgid "reviewer"
msgstr "Responsable"
#: proposals/templates/proposals/track_list.html:9
msgid "Tracks"
msgstr "Sessions"
#: proposals/templates/proposals/track_list.html:12
msgid "Add a track"
msgstr "Ajouter une session"
@ -1112,6 +1202,13 @@ msgstr ""
"Nous ne sommes pas encore en recherche de bénévoles … mais revenez plus "
"tard !"
#: volunteers/templates/volunteers/volunteer_list.html:9
msgid "Volunteers"
msgstr "Bénévoles"
#: volunteers/templates/volunteers/volunteer_list.html:25
msgid "volunteer"
msgstr "bénévole"
#~ msgid "Conference"
#~ msgstr "Conférence"

View File

@ -72,6 +72,8 @@ MIDDLEWARE_CLASSES = [
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'cfp.middleware.ConferenceMiddleware',
]
ROOT_URLCONF = 'ponyconf.urls'
@ -88,8 +90,8 @@ TEMPLATES = [
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'ponyconf.context_processors.site',
#'proposals.context_processors.conference',
#'ponyconf.context_processors.site',
'cfp.context_processors.conference',
],
},
},

View File

@ -8,7 +8,7 @@
{% comment %}<link rel="icon" href="{% static 'favicon.ico' %}">{% endcomment %}
<title>{% block title %}{{ site.name }}{% endblock %}</title>
<title>{% block title %}{{ conference.name }}{% endblock %}</title>
{% bootstrap_css %}
<link href="{% static 'css/ponyconf.css' %}" rel="stylesheet">
@ -16,8 +16,8 @@
{% block js %}{% endblock %}
{% if site.conference.external_css_link %}
<link href="{{ site.conference.external_css_link }}" rel="stylesheet">
{% if conference.external_css_link %}
<link href="{{ conference.external_css_link }}" rel="stylesheet">
{% endif %}
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->

View File

@ -1,5 +1,5 @@
{% extends '_base.html' %}
{% load i18n bootstrap3 %}
{% load i18n bootstrap3 cfp_tags %}
{% block body %}
@ -13,11 +13,13 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{% url 'home' %}">{{ site.name }}</a>
<a class="navbar-brand" href="{% url 'home' %}">{{ conference.name }}</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
{% if conference.home %}
<li{% block hometab %}{% endblock %}><a href="{% url 'home' %}"><span class="glyphicon glyphicon-home"></span>&nbsp;{% trans "Home" %}</a></li>
{% endif %}
<li{% block proposetab %}{% endblock %}><a href="{% url 'talk-proposal' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Call for participation" %}</a></li>
{% comment %}
{% if request.user.is_authenticated %}
@ -29,16 +31,18 @@
</ul>
<ul class="nav navbar-nav navbar-right">
{% if request.user.is_authenticated %}
{% comment %}
{% if request|staff %}
<li{% block stafftab %}{% endblock %}><a href="{% url 'staff' %}"><span class="glyphicon glyphicon-cog"></span>&nbsp;{% trans "Staff" %}</a></li>
{% endif %}
{% comment %}
<li{% block talkstab %}{% endblock %}><a href="{% url 'talk-list' %}"><span class="glyphicon glyphicon-blackboard"></span>&nbsp;{% trans "Talks" %}</a></li>
<li{% block speakerstab %}{% endblock %}><a href="{% url 'participant-list' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Speakers" %}</a></li>
<li{% block inboxtab %}{% endblock %}><a href="{% url 'inbox' %}"><span class="glyphicon glyphicon-envelope"></span>&nbsp;Inbox</a></li>
<li{% block profiletab %}{% endblock %}><a href="{% url 'profile' %}"><span class="glyphicon glyphicon-user"></span>&nbsp;{% trans "Profile" %}</a></li>
{% endcomment %}
{% if request.user.is_staff %}
<li><a href="{% url 'admin:index' %}"><span class="glyphicon glyphicon-cog"></span>&nbsp; Administration</a></li>
{% endif %}
{% endcomment %}
<li><a href="{% url 'logout' %}" data-toggle="tooltip" data-placement="bottom" title="Logout"><span class="glyphicon glyphicon-log-out"></span></a></li>
{% else %}
<li{% block logintab %}{% endblock %}><a href="{% url 'login' %}"><span class="glyphicon glyphicon-log-in"></span>&nbsp;{% trans "Login" %}</a></li>

View File

@ -18,14 +18,11 @@ from django.contrib import admin
#from django.conf.urls.static import static
#from django.conf import settings
from . import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('accounts.urls')),
url(r'^cfp/', include('cfp.urls')),
url(r'^$', views.home, name='home'),
url(r'^', include('cfp.urls')),
#url(r'', include('proposals.urls')),
#url(r'', include('planning.urls')),
#url(r'^volunteers/', include('volunteers.urls')),

View File

@ -1,5 +0,0 @@
from django.shortcuts import render
def home(request):
return render(request, 'ponyconf/home.html')