add ICS variant for citymeo

This commit is contained in:
Élie Bouttier 2017-11-19 21:56:15 +01:00
parent 6610f86801
commit 1159552241
2 changed files with 25 additions and 15 deletions

View File

@ -1,7 +1,7 @@
from django.db.models import Q, Prefetch from django.db.models import Q, Prefetch
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.html import escape from django.utils.html import escape
from django.utils.timezone import localtime from django.utils.timezone import localtime, now
from django.core.cache import cache from django.core.cache import cache
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.template.loader import get_template from django.template.loader import get_template
@ -22,10 +22,13 @@ Event = namedtuple('Event', ['talk', 'row', 'rowcount'])
class Program: class Program:
def __init__(self, site, pending=False, cache=True): def __init__(self, site, pending=False, cache=None):
self.site = site self.site = site
self.pending = pending self.pending = pending
self.cache = cache if cache is None:
self.cache = not settings.DEBUG
else:
self.cache = cache
self.initialized = False self.initialized = False
def _lazy_init(self): def _lazy_init(self):
@ -254,7 +257,7 @@ class Program:
return ET.tostring(schedule) return ET.tostring(schedule)
def _as_ics(self): def _as_ics(self, citymeo=False):
if not self.initialized: if not self.initialized:
self._lazy_init() self._lazy_init()
cal = iCalendar() cal = iCalendar()
@ -263,7 +266,13 @@ class Program:
cal.add('x-wr-calname', self.conference.name) cal.add('x-wr-calname', self.conference.name)
cal.add('x-wr-timezone', settings.TIME_ZONE) cal.add('x-wr-timezone', settings.TIME_ZONE)
cal.add('calscale', 'GREGORIAN') cal.add('calscale', 'GREGORIAN')
for talk in self.talks.all(): talks = self.talks
if citymeo and talks.exists():
talks = talks.filter(start_date__gte=now()-timedelta(minutes=5))
if talks.exists():
limit = talks.first().start_date.replace(hour=23, minute=59, second=59)
talks = talks.filter(start_date__lte=limit)
for talk in talks:
event = iEvent() event = iEvent()
event.add('dtstart', talk.start_date) event.add('dtstart', talk.start_date)
if not talk.end_date: if not talk.end_date:
@ -274,21 +283,22 @@ class Program:
if talk.room: if talk.room:
event.add('location', talk.room) event.add('location', talk.room)
event.add('status', 'CONFIRMED' if talk.accepted else 'TENTATIVE') event.add('status', 'CONFIRMED' if talk.accepted else 'TENTATIVE')
event.add('description', talk.description) if not citymeo:
event.add('description', talk.description)
event.add('uid', '%s/%s' % (self.site.domain, talk.id)) event.add('uid', '%s/%s' % (self.site.domain, talk.id))
cal.add_component(event) cal.add_component(event)
return cal.to_ical() return cal.to_ical()
def render(self, output='html'): def render(self, output='html', **kwargs):
if self.cache: if self.cache:
cache_entry = 'ponyconf-%d' % adler32('|'.join(map(str, [self.site.domain, output, self.pending])).encode('utf-8')) cache_entry = 'ponyconf-%d' % adler32('|'.join(map(str, [self.site.domain, output, self.pending] + list(kwargs.values()))).encode('utf-8'))
result = cache.get(cache_entry) result = cache.get(cache_entry)
if not result: if not result:
result = getattr(self, '_as_%s' % output)() result = getattr(self, '_as_%s' % output)(**kwargs)
cache.set(cache_entry, result, 3 * 60 * 60) # 3H cache.set(cache_entry, result, 3 * 60 * 60) # 3H
return mark_safe(result) return mark_safe(result)
else: else:
return mark_safe(getattr(self, '_as_%s' % output)()) return mark_safe(getattr(self, '_as_%s' % output)(**kwargs))
def __str__(self): def __str__(self):
return self.render() return self.render()

View File

@ -1021,7 +1021,7 @@ def create_user(request):
}) })
def schedule(request, program_format, pending, cache, template): def schedule(request, program_format, pending, template, cache=None):
program = Program(site=request.conference.site, pending=pending, cache=cache) program = Program(site=request.conference.site, pending=pending, cache=cache)
if program_format is None: if program_format is None:
return render(request, template, {'program': program.render('html')}) return render(request, template, {'program': program.render('html')})
@ -1029,8 +1029,8 @@ def schedule(request, program_format, pending, cache, template):
return HttpResponse(program.render('html')) return HttpResponse(program.render('html'))
elif program_format == 'xml': elif program_format == 'xml':
return HttpResponse(program.render('xml'), content_type="application/xml") return HttpResponse(program.render('xml'), content_type="application/xml")
elif program_format == 'ics': elif program_format in ['ics', 'citymeo']:
response = HttpResponse(program.render('ics'), content_type='text/calendar') response = HttpResponse(program.render('ics', citymeo=bool(program_format == 'citymeo')), content_type='text/calendar')
response['Content-Disposition'] = 'attachment; filename="planning.ics"' response['Content-Disposition'] = 'attachment; filename="planning.ics"'
return response return response
else: else:
@ -1043,12 +1043,12 @@ def public_schedule(request, program_format):
if request.conference.schedule_redirection_url and program_format is None: if request.conference.schedule_redirection_url and program_format is None:
return redirect(request.conference.schedule_redirection_url) return redirect(request.conference.schedule_redirection_url)
else: else:
return schedule(request, program_format=program_format, pending=False, cache=True, template='cfp/schedule.html') return schedule(request, program_format=program_format, pending=False, template='cfp/schedule.html')
@staff_required @staff_required
def staff_schedule(request, program_format): def staff_schedule(request, program_format):
return schedule(request, program_format=program_format, pending=True, cache=False, template='cfp/staff/schedule.html') return schedule(request, program_format=program_format, pending=True, template='cfp/staff/schedule.html', cache=False)
class Select2View(StaffRequiredMixin, AutoResponseView): class Select2View(StaffRequiredMixin, AutoResponseView):