from django.db.models import Q
from django.utils.safestring import mark_safe
from django.utils.html import escape
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
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
Event = namedtuple('Event', ['talk', 'row', 'rowcount'])
class Program:
def __init__(self, site, pending=False, cache=True):
self.site = site
self.pending = pending
self.cache = cache
self.initialized = False
def _lazy_init(self):
self.conference = Conference.objects.get(site=self.site)
self.talks = Talk.objects.\
exclude(category__label__exact='').\
filter(site=self.site, room__isnull=False, start_date__isnull=False).\
filter(Q(duration__gt=0) | Q(category__duration__gt=0))
if self.pending:
self.talks = self.talks.exclude(accepted=False)
else:
self.talks = self.talks.filter(accepted=True)
self.talks = self.talks.order_by('start_date')
self.rooms = Room.objects.filter(talk__in=self.talks.all()).order_by('name').distinct()
self.days = {}
for talk in self.talks.all():
duration = talk.estimated_duration
assert(duration)
dt1 = talk.start_date
d1 = localtime(dt1).date()
if d1 not in self.days.keys():
self.days[d1] = {'timeslots': []}
dt2 = dt1 + timedelta(minutes=duration)
d2 = localtime(dt2).date()
if d2 not in self.days.keys():
self.days[d2] = {'timeslots': []}
if dt1 not in self.days[d1]['timeslots']:
self.days[d1]['timeslots'].append(dt1)
if dt2 not in self.days[d2]['timeslots']:
self.days[d2]['timeslots'].append(dt2)
self.cols = OrderedDict([(room, 1) for room in self.rooms])
for day in self.days.keys():
self.days[day]['timeslots'] = sorted(self.days[day]['timeslots'])
self.days[day]['rows'] = OrderedDict([(timeslot, OrderedDict([(room, []) for room in self.rooms])) for timeslot in self.days[day]['timeslots'][:-1]])
for talk in self.talks.exclude(plenary=True).all():
self._add_talk(talk)
for talk in self.talks.filter(plenary=True).all():
self._add_talk(talk)
self.initialized = True
def _add_talk(self, talk):
room = talk.room
dt1 = talk.start_date
d1 = localtime(dt1).date()
dt2 = talk.start_date + timedelta(minutes=talk.estimated_duration)
d2 = localtime(dt2).date()
assert(d1 == d2) # this is a current limitation
dt1 = self.days[d1]['timeslots'].index(dt1)
dt2 = self.days[d1]['timeslots'].index(dt2)
col = None
for row, timeslot in enumerate(islice(self.days[d1]['timeslots'], dt1, dt2)):
if col is None:
col = 0
while col < len(self.days[d1]['rows'][timeslot][room]) and self.days[d1]['rows'][timeslot][room][col]:
col += 1
self.cols[room] = max(self.cols[room], col+1)
event = Event(talk=talk, row=row, rowcount=dt2-dt1)
while len(self.days[d1]['rows'][timeslot][room]) <= col:
self.days[d1]['rows'][timeslot][room].append(None)
self.days[d1]['rows'][timeslot][room][col] = event
def _html_header(self):
output = '