public schedule

This commit is contained in:
Élie Bouttier 2017-08-15 20:52:12 +02:00
parent 7223dc4ef1
commit 3034798aef
9 changed files with 91 additions and 40 deletions

View File

@ -164,7 +164,7 @@ class UsersWidget(ModelSelect2MultipleWidget):
class ConferenceForm(forms.ModelForm): class ConferenceForm(forms.ModelForm):
class Meta: class Meta:
model = Conference model = Conference
fields = ['name', 'home', 'venue', 'city', 'contact_email', 'reply_email', 'secure_domain', 'staff',] fields = ['name', 'home', 'venue', 'city', 'contact_email', 'schedule_publishing_date', 'reply_email', 'secure_domain', 'staff',]
widgets = { widgets = {
'staff': UsersWidget(), 'staff': UsersWidget(),
} }

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.3 on 2017-08-15 18:24
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cfp', '0008_auto_20170811_2342'),
]
operations = [
migrations.AddField(
model_name='conference',
name='schedule_publishing_date',
field=models.DateTimeField(blank=True, default=None, null=True, verbose_name='Schedule publishing date'),
),
]

View File

@ -31,6 +31,7 @@ class Conference(models.Model):
reply_email = models.CharField(max_length=100, blank=True, verbose_name=_('Reply email')) reply_email = models.CharField(max_length=100, blank=True, verbose_name=_('Reply email'))
staff = models.ManyToManyField(User, blank=True, verbose_name=_('Staff members')) staff = models.ManyToManyField(User, blank=True, verbose_name=_('Staff members'))
secure_domain = models.BooleanField(default=True, verbose_name=_('Secure domain (HTTPS)')) secure_domain = models.BooleanField(default=True, verbose_name=_('Secure domain (HTTPS)'))
schedule_publishing_date = models.DateTimeField(null=True, blank=True, default=None, verbose_name=_('Schedule publishing date'))
custom_css = models.TextField(blank=True) custom_css = models.TextField(blank=True)
external_css_link = models.URLField(blank=True) external_css_link = models.URLField(blank=True)
@ -48,6 +49,10 @@ class Conference(models.Model):
.filter(Q(opening_date__isnull=True) | Q(opening_date__lte=now))\ .filter(Q(opening_date__isnull=True) | Q(opening_date__lte=now))\
.filter(Q(closing_date__isnull=True) | Q(closing_date__gte=now)) .filter(Q(closing_date__isnull=True) | Q(closing_date__gte=now))
@property
def schedule_available(self):
return self.schedule_publishing_date and self.schedule_publishing_date <= timezone.now()
def from_email(self): def from_email(self):
return self.name+' <'+self.contact_email+'>' return self.name+' <'+self.contact_email+'>'

View File

@ -217,31 +217,31 @@ class Program:
for speaker in talk.speakers.all(): for speaker in talk.speakers.all():
persons += ' <person id="%(person_id)s">%(person)s</person>\n' % { persons += ' <person id="%(person_id)s">%(person)s</person>\n' % {
'person_id': speaker.id, 'person_id': speaker.id,
'person': str(speaker.profile), 'person': str(speaker),
} }
links = '' links = ''
registration = '' registration = ''
if talk.registration_required and self.conference.subscriptions_open: #if talk.registration_required and self.conference.subscriptions_open:
links += mark_safe(""" # links += mark_safe("""
<link tag="registration">%(link)s</link>""" % { # <link tag="registration">%(link)s</link>""" % {
'link': reverse('register-for-a-talk', args=[talk.slug]), # 'link': reverse('register-for-a-talk', args=[talk.slug]),
}) # })
registration = """ # registration = """
<attendees_max>%(max)s</attendees_max> # <attendees_max>%(max)s</attendees_max>
<attendees_remain>%(remain)s</attendees_remain>""" % { # <attendees_remain>%(remain)s</attendees_remain>""" % {
'max': talk.attendees_limit, # 'max': talk.attendees_limit,
'remain': talk.remaining_attendees or 0, # 'remain': talk.remaining_attendees or 0,
} # }
if talk.materials: #if talk.materials:
links += mark_safe(""" # links += mark_safe("""
<link tag="slides">%(link)s</link>""" % { # <link tag="slides">%(link)s</link>""" % {
'link': talk.materials.url, # 'link': talk.materials.url,
}) # })
if talk.video: #if talk.video:
links += mark_safe(""" # links += mark_safe("""
<link tag="video">%(link)s</link>""" % { # <link tag="video">%(link)s</link>""" % {
'link': talk.video, # 'link': talk.video,
}) # })
days_xml += """ <event id="%(id)s"> days_xml += """ <event id="%(id)s">
<start>%(start)s</start> <start>%(start)s</start>
<duration>%(duration)s</duration> <duration>%(duration)s</duration>
@ -252,7 +252,6 @@ class Program:
<track>%(track)s</track> <track>%(track)s</track>
<type>%(type)s</type> <type>%(type)s</type>
<language/> <language/>
<abstract>%(abstract)s</abstract>
<description>%(description)s</description> <description>%(description)s</description>
<persons> <persons>
%(persons)s </persons> %(persons)s </persons>
@ -267,7 +266,6 @@ class Program:
'title': escape(talk.title), 'title': escape(talk.title),
'track': escape(talk.track or ''), 'track': escape(talk.track or ''),
'type': escape(talk.category.label), 'type': escape(talk.category.label),
'abstract': escape(talk.abstract),
'description': escape(talk.description), 'description': escape(talk.description),
'persons': persons, 'persons': persons,
'links': links, 'links': links,
@ -320,7 +318,7 @@ DTEND:{talk.dtend}
SUMMARY:{talk.title} SUMMARY:{talk.title}
LOCATION:{talk.room} LOCATION:{talk.room}
STATUS: CONFIRMED STATUS: CONFIRMED
DESCRIPTION:{talk.abstract}\n---\n\n{talk.description} DESCRIPTION:{talk.description}
UID:{site.domain}/{talk.id} UID:{site.domain}/{talk.id}
END:VEVENT END:VEVENT
""" """

View File

@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% load i18n %}
{% block publicscheduletab %} class="active"{% endblock %}
{% block content %}
<h1>{% trans "Schedule" %}</h1>
{{ program }}
{% endblock %}

View File

@ -16,7 +16,7 @@
<li{% block speakerstab %}{% endblock %}><a href="{% url 'participant-list' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Speakers" %}</a></li> <li{% block speakerstab %}{% endblock %}><a href="{% url 'participant-list' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Speakers" %}</a></li>
<li{% block trackstab %}{% endblock %}><a href="{% url 'track-list' %}"><span class="glyphicon glyphicon-screenshot"></span>&nbsp;{% trans "Tracks" %}</a></li> <li{% block trackstab %}{% endblock %}><a href="{% url 'track-list' %}"><span class="glyphicon glyphicon-screenshot"></span>&nbsp;{% trans "Tracks" %}</a></li>
<li{% block roomstab %}{% endblock %}><a href="{% url 'room-list' %}"><span class="glyphicon glyphicon-tent"></span>&nbsp;{% trans "Rooms" %}</a></li> <li{% block roomstab %}{% endblock %}><a href="{% url 'room-list' %}"><span class="glyphicon glyphicon-tent"></span>&nbsp;{% trans "Rooms" %}</a></li>
<li{% block scheduletab %}{% endblock %}><a href="{% url 'schedule' %}"><span class="glyphicon glyphicon-calendar"></span>&nbsp;{% trans "Schedule" %}</a></li> <li{% block scheduletab %}{% endblock %}><a href="{% url 'staff-schedule' %}"><span class="glyphicon glyphicon-calendar"></span>&nbsp;{% trans "Schedule" %}</a></li>
<li{% block conferencetab %}{% endblock %}><a href="{% url 'conference' %}"><span class="glyphicon glyphicon-asterisk"></span>&nbsp;{% trans "Conference" %}</a></li> <li{% block conferencetab %}{% endblock %}><a href="{% url 'conference' %}"><span class="glyphicon glyphicon-asterisk"></span>&nbsp;{% trans "Conference" %}</a></li>
{% if request.user.is_staff %} {% if request.user.is_staff %}
<li><a href="{% url 'admin:index' %}"><span class="glyphicon glyphicon-dashboard"></span>&nbsp;Django-Admin</a></li> <li><a href="{% url 'admin:index' %}"><span class="glyphicon glyphicon-dashboard"></span>&nbsp;Django-Admin</a></li>

View File

@ -27,7 +27,8 @@ urlpatterns = [
url(r'^staff/rooms/(?P<slug>[-\w]+)/$', views.RoomDetail.as_view(), name='room-details'), url(r'^staff/rooms/(?P<slug>[-\w]+)/$', views.RoomDetail.as_view(), name='room-details'),
url(r'^staff/rooms/(?P<slug>[-\w]+)/edit/$', views.RoomUpdate.as_view(), name='room-edit'), url(r'^staff/rooms/(?P<slug>[-\w]+)/edit/$', views.RoomUpdate.as_view(), name='room-edit'),
url(r'^staff/add-user/$', views.create_user, name='create-user'), url(r'^staff/add-user/$', views.create_user, name='create-user'),
url(r'^staff/schedule/$', views.schedule, name='schedule'), url(r'^staff/schedule/((?P<program_format>[\w]+)/)?$', views.staff_schedule, name='staff-schedule'),
url(r'^staff/select2/$', views.Select2View.as_view(), name='django_select2-json'), url(r'^staff/select2/$', views.Select2View.as_view(), name='django_select2-json'),
url(r'^schedule/((?P<program_format>[\w]+)/)?$', views.public_schedule, name='public-schedule'),
#url(r'^markdown/$', views.markdown_preview, name='markdown'), #url(r'^markdown/$', views.markdown_preview, name='markdown'),
] ]

View File

@ -7,6 +7,9 @@ from django.views.generic import FormView, TemplateView
from django.contrib import messages from django.contrib import messages
from django.db.models import Q from django.db.models import Q
from django.views.generic import CreateView, DetailView, ListView, UpdateView from django.views.generic import CreateView, DetailView, ListView, UpdateView
from django.http import HttpResponse, Http404
from django.utils import timezone
from django.core.exceptions import PermissionDenied
from django_select2.views import AutoResponseView from django_select2.views import AutoResponseView
@ -468,18 +471,29 @@ def create_user(request):
}) })
@staff_required def schedule(request, program_format, pending, cache, template):
def schedule(request): program = Program(site=request.conference.site, pending=pending, cache=cache)
program = Program(site=request.conference.site, pending=True, cache=False) if program_format is None:
output = request.GET.get('format', 'html') return render(request, template, {'program': program.render('html')})
if output == 'html': elif program_format == 'html':
return render(request, 'cfp/staff/schedule.html', {'program': program.render('html')}) return HttpResponse(program.render('html'))
elif output == 'xml': elif program_format == 'xml':
return HttpResponse(program.render('xml'), content_type="application/xml") return HttpResponse(program.render('xml'), content_type="application/xml")
elif output == 'ics': elif program_format == 'ics':
return HttpResponse(program.render('ics'), content_type="text/calendar") return HttpResponse(program.render('ics'), content_type="text/calendar")
else: else:
raise Http404("Format not available") raise Http404(_("Format '%s' not available" % program_format))
def public_schedule(request, program_format):
if not request.conference.schedule_available:
raise PermissionDenied
return schedule(request, program_format=program_format, pending=False, cache=True, template='cfp/schedule.html')
@staff_required
def staff_schedule(request, program_format):
return schedule(request, program_format=program_format, pending=True, cache=False, template='cfp/staff/schedule.html')
class Select2View(StaffRequiredMixin, AutoResponseView): class Select2View(StaffRequiredMixin, AutoResponseView):

View File

@ -21,6 +21,9 @@
<li{% block hometab %}{% endblock %}><a href="{% url 'home' %}"><span class="glyphicon glyphicon-home"></span>&nbsp;{% trans "Home" %}</a></li> <li{% block hometab %}{% endblock %}><a href="{% url 'home' %}"><span class="glyphicon glyphicon-home"></span>&nbsp;{% trans "Home" %}</a></li>
{% endif %} {% endif %}
<li{% block proposetab %}{% endblock %}><a href="{% url 'talk-proposal' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Call for participation" %}</a></li> <li{% block proposetab %}{% endblock %}><a href="{% url 'talk-proposal' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Call for participation" %}</a></li>
{% if conference.schedule_available %}
<li{% block publicscheduletab %}{% endblock %}><a href="{% url 'public-schedule' %}"><span class="glyphicon glyphicon-calendar"></span>&nbsp;{% trans "Schedule" %}</a></li>
{% endif %}
{% comment %} {% comment %}
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<li{% block exhibitortab %}{% endblock %}><a href="{% url 'participate-as-speaker' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Exhibitor" %}</a></li> <li{% block exhibitortab %}{% endblock %}><a href="{% url 'participate-as-speaker' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Exhibitor" %}</a></li>
@ -39,9 +42,6 @@
<li{% block speakerstab %}{% endblock %}><a href="{% url 'participant-list' %}"><span class="glyphicon glyphicon-bullhorn"></span>&nbsp;{% trans "Speakers" %}</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 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> <li{% block profiletab %}{% endblock %}><a href="{% url 'profile' %}"><span class="glyphicon glyphicon-user"></span>&nbsp;{% trans "Profile" %}</a></li>
{% if request.user.is_staff %}
<li><a href="{% url 'admin:index' %}"><span class="glyphicon glyphicon-cog"></span>&nbsp; Administration</a></li>
{% endif %}
{% endcomment %} {% endcomment %}
<li><a href="{% url 'logout' %}"><span class="glyphicon glyphicon-log-out"></span>&nbsp;{% trans "Logout" %}</a></li> <li><a href="{% url 'logout' %}"><span class="glyphicon glyphicon-log-out"></span>&nbsp;{% trans "Logout" %}</a></li>
{% else %} {% else %}