generate ICS with iCalendar package

This commit is contained in:
Élie Bouttier 2017-09-18 14:01:27 +02:00
parent f63b0b9cda
commit 0a1442b450
7 changed files with 29 additions and 43 deletions

View File

@ -320,18 +320,6 @@ class Talk(PonyConfModel):
else:
return None
@property
def dtstart(self):
return self.start_date.strftime('%Y%m%dT%H%M%SZ')
@property
def dtend(self):
return self.end_date.strftime('%Y%m%dT%H%M%SZ')
@property
def dtstamp(self):
return self.updated.strftime('%Y%m%dT%H%M%SZ')
#@property
#def materials_name(self):
# return basename(self.materials.name)

View File

@ -5,6 +5,7 @@ from django.utils.timezone import localtime
from django.core.cache import cache
from django.core.urlresolvers import reverse
from django.template.loader import get_template
from django.conf import settings
from datetime import datetime, timedelta
from copy import deepcopy
@ -12,6 +13,7 @@ from collections import OrderedDict, namedtuple
from itertools import islice
from zlib import adler32
import xml.etree.ElementTree as ET
from icalendar import Calendar as iCalendar, Event as iEvent
from .models import Conference, Talk, Room
@ -252,7 +254,27 @@ class Program:
def _as_ics(self):
if not self.initialized:
self._lazy_init()
return get_template('cfp/planning.ics').render({'site': self.site, 'talks': self.talks})
cal = iCalendar()
cal.add('prodid', '-//PonyConf.io//PonyConf//FR')
cal.add('version', '2.0')
cal.add('x-wr-calname', self.conference.name)
cal.add('x-wr-timezone', settings.TIME_ZONE)
cal.add('calscale', 'GREGORIAN')
for talk in self.talks.all():
event = iEvent()
event.add('dtstart', talk.start_date)
if not talk.end_date:
continue
event.add('dtend', talk.end_date)
event.add('dtstamp', talk.updated)
event.add('summary', talk.title)
if talk.room:
event.add('location', talk.room)
event.add('status', 'CONFIRMED' if talk.accepted else 'TENTATIVE')
event.add('description', talk.description)
event.add('uid', '%s/%s' % (self.site.domain, talk.id))
cal.add_component(event)
return cal.to_ical()
def render(self, output='html'):
if self.cache:

View File

@ -1,18 +0,0 @@
BEGIN:VCALENDAR
PRODID:-//{{ site.domain }}//{{ site.name }}//FR
X-WR-CALNAME:{{ site.name }}
X-WR-TIMEZONE:Europe/Paris
VERSION:2.0
CALSCALE:GREGORIAN
{% for talk in talks %}
BEGIN:VEVENT
DTSTAMP:{{ talk.dtstamp }}
DTSTART:{{ talk.dtstart }}
DTEND:{{ talk.dtend }}
SUMMARY:{{ talk.title }}
LOCATION:{{ talk.room }}
STATUS:{% if talk.accepted %}CONFIRMED{% else %}TENTATIVE{% endif %}
DESCRIPTION:{{ talk.description|linebreaksbr }}
UID:{{ site.domain }}/{{ talk.id }}
END:VEVENT{% endfor %}
END:VCALENDAR

View File

@ -481,17 +481,8 @@ def schedule(request, program_format, pending, cache, template):
elif program_format == 'xml':
return HttpResponse(program.render('xml'), content_type="application/xml")
elif program_format == 'ics':
response = HttpResponse('', content_type='text/plain')
response = HttpResponse(program.render('ics'), content_type='text/calendar')
response['Content-Disposition'] = 'attachment; filename="planning.ics"'
ics = []
for line in program.render('ics').split('\n'):
line = line.strip().replace('<br />', '')
if len(line) < 50:
ics.append(line)
else: # https://icalendar.org/iCalendar-RFC-5545/3-1-content-lines.html
for i in range(ceil(len(line) / 50)):
ics.append((' ' if i > 0 else '') + line[i * 50:(i + 1) * 50])
response.write('\r\n'.join([line for line in ics if line]).strip() + '\r\n')
return response
else:
raise Http404(_("Format '%s' not available" % program_format))

View File

@ -10,3 +10,4 @@ django-colorful
markdown
bleach
chardet
icalendar

View File

@ -15,7 +15,9 @@ django-crispy-forms==1.6.1
django-select2==5.11.1
django==1.11.5
html5lib==0.999999999 # via bleach
icalendar==3.11.7
markdown==2.6.9
pytz==2017.2 # via django
six==1.10.0 # via bleach, django-bower, html5lib
python-dateutil==2.6.1 # via icalendar
pytz==2017.2 # via django, icalendar
six==1.10.0 # via bleach, django-bower, html5lib, python-dateutil
webencodings==0.5.1 # via html5lib