Skip to content

Commit

Permalink
Updated agenda.ics to use new data model. Also, tons more efficient. …
Browse files Browse the repository at this point in the history
…Additionally, the description field now includes links to relevant meeting materials.

 - Legacy-Id: 4226
  • Loading branch information
adamroach committed Mar 24, 2012
1 parent 46099bc commit 740487d
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 76 deletions.
11 changes: 10 additions & 1 deletion ietf/meeting/models.py
Expand Up @@ -44,7 +44,7 @@ def __unicode__(self):
return self.number

def time_zone_offset(self):
return pytz.timezone(self.time_zone).localize(datetime.datetime.combine(self.date, datetime.time(0, 0))).strftime("%z")
return pytz.timezone(self.time_zone).localize(datetime.datetime.combine(self.date, datetime.time(8, 0))).strftime("%z")
def get_meeting_date (self,offset):
return self.date + datetime.timedelta(days=offset)

Expand Down Expand Up @@ -105,6 +105,9 @@ def __unicode__(self):

return u"%s: %s-%s %s, %s" % (self.meeting.number, self.time.strftime("%m-%d %H:%M"), (self.time + self.duration).strftime("%H:%M"), self.name, location)

def end_time(self):
return self.time + self.duration

def get_location(self):
location = self.location
if location:
Expand Down Expand Up @@ -152,6 +155,12 @@ class Session(models.Model):

materials = models.ManyToManyField(Document, blank=True)

def agenda(self):
try:
return self.materials.get(type="agenda",states__type="agenda",states__slug="active")
except Exception, e:
return None

def __unicode__(self):
if self.meeting.type_id == "interim":
return self.meeting.number
Expand Down
88 changes: 56 additions & 32 deletions ietf/meeting/views.py
Expand Up @@ -5,6 +5,7 @@
import os
import re
import tarfile
import pytz

from tempfile import mkstemp

Expand All @@ -24,12 +25,16 @@
from ietf.idrfc.idrfc_wrapper import IdWrapper
from ietf.utils.pipe import pipe

from ietf.proceedings.models import Meeting, MeetingTime, WgMeetingSession, MeetingVenue, IESGHistory, Proceeding, Switches, WgProceedingsActivities, SessionConflict

from ietf.group.models import Group
from ietf.utils.history import find_history_active_at
from ietf.doc.models import Document, State

# Old model -- needs to be removed
from ietf.proceedings.models import Meeting as OldMeeting, MeetingTime, WgMeetingSession, MeetingVenue, IESGHistory, Proceeding, Switches, WgProceedingsActivities, SessionConflict

# New models
from ietf.meeting.models import Meeting, Room, TimeSlot, Constraint, Session
from ietf.group.models import Group


@decorator_from_middleware(GZipMiddleware)
def show_html_materials(request, meeting_num=None):
Expand Down Expand Up @@ -91,7 +96,7 @@ def show_html_materials(request, meeting_num=None):
context_instance=RequestContext(request))

def current_materials(request):
meeting = Meeting.objects.order_by('-meeting_num')[0]
meeting = OldMeeting.objects.order_by('-meeting_num')[0]
return HttpResponseRedirect( reverse(show_html_materials, args=[meeting.meeting_num]) )

def get_plenary_agenda(meeting_num, id):
Expand All @@ -118,10 +123,10 @@ def agenda_info(num=None):
try:
timeslots = MeetingTime.objects.select_related().filter(meeting=n).order_by("day_id", "time_desc")
update = Switches.objects.get(id=1)
meeting= Meeting.objects.get(meeting_num=n)
meeting= OldMeeting.objects.get(meeting_num=n)
venue = MeetingVenue.objects.get(meeting_num=n)
break
except (MeetingTime.DoesNotExist, Switches.DoesNotExist, Meeting.DoesNotExist, MeetingVenue.DoesNotExist):
except (MeetingTime.DoesNotExist, Switches.DoesNotExist, OldMeeting.DoesNotExist, MeetingVenue.DoesNotExist):
continue
else:
raise Http404("No meeting information for meeting %s available" % num)
Expand All @@ -136,10 +141,10 @@ def agenda_info(num=None):
def agenda_infoREDESIGN(num=None):
try:
if num != None:
meeting = Meeting.objects.get(number=num)
meeting = OldMeeting.objects.get(number=num)
else:
meeting = Meeting.objects.all().order_by('-date')[:1].get()
except Meeting.DoesNotExist:
meeting = OldMeeting.objects.all().order_by('-date')[:1].get()
except OldMeeting.DoesNotExist:
raise Http404("No meeting information for meeting %s available" % num)

# now go through the timeslots, only keeping those that are
Expand Down Expand Up @@ -413,39 +418,58 @@ def session_draft_pdf(request, num, session):
os.unlink(pdfn)
return HttpResponse(pdf_contents, mimetype="application/pdf")

def get_meeting (num=None):
try:
if num != None:
meeting = OldMeeting.objects.get(number=num)
else:
meeting = OldMeeting.objects.all().order_by('-date')[:1].get()
except OldMeeting.DoesNotExist:
raise Http404("No meeting information for meeting %s available" % num)
return meeting

def week_view(request, num=None):
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
wgs = IETFWG.objects.filter(status=IETFWG.ACTIVE).order_by('group_acronym__acronym')
rgs = IRTF.objects.all().order_by('acronym')
areas = Area.objects.filter(status=Area.ACTIVE).order_by('area_acronym__acronym')
conflicts = SessionConflict.objects.filter(meeting_num=meeting.meeting_num)
meeting = get_meeting(num)
timeslots = TimeSlot.objects.filter(meeting = meeting.number)

template = "meeting/week-view.html"
return render_to_response(template,
{"timeslots":timeslots, "update":update, "meeting":meeting,
"venue":venue, "ads":ads, "plenaryw_agenda":plenaryw_agenda,
"plenaryt_agenda":plenaryt_agenda, "wg_list" : wgs,
"rg_list" : rgs, "area_list" : areas, "conflicts":conflicts},
context_instance=RequestContext(request))
{"timeslots":timeslots,"render_types":["Session","Other","Break","Plenary"]}, context_instance=RequestContext(request))

def ical_agenda(request, num=None):
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
wgs = IETFWG.objects.filter(status=IETFWG.ACTIVE).order_by('group_acronym__acronym')
rgs = IRTF.objects.all().order_by('acronym')
areas = Area.objects.filter(status=Area.ACTIVE).order_by('area_acronym__acronym')
# The timezone situation here remains tragic, but I've burned
# hours trying to figure out how to get the information I need
# in python. I can do this trivially in perl with its Ical module,
# but the icalendar module in python seems staggeringly less
# capable. There might be a path to success here, but I'm not
# completely convinced. So I'm going to spend some time
# working on more urgent matters for now. -Adam

meeting = get_meeting(num)

q = request.META.get('QUERY_STRING','') or ""
filter = q.lower().split(',');
include = set(filter)
now = datetime.datetime.utcnow()

for slot in timeslots:
for session in slot.sessions():
if session.area() == '' or session.area().find('plenary') > 0 or (session.area().lower() in include):
filter.append(session.acronym())
include_types = ["Plenary","Other"]
exclude = []

# Process the special flags.
for item in include:
if item[0] == '-':
exclude.append(item[1:])
if item[0] == '~':
include_types.append(item[1:2].upper()+item[2:])

timeslots = TimeSlot.objects.filter(Q(meeting = meeting.number),
Q(type__name__in = include_types) |
Q(session__group__acronym__in = filter) |
Q(session__group__parent__acronym__in = filter)
).exclude(Q(session__group__isnull = False),
Q(session__group__acronym__in = exclude) |
Q(session__group__parent__acronym__in = exclude))

return HttpResponse(render_to_string("meeting/agendaREDESIGN.ics" if settings.USE_DB_REDESIGN_PROXY_CLASSES else "meeting/agenda.ics",
{"filter":set(filter), "timeslots":timeslots, "update":update, "meeting":meeting, "venue":venue, "ads":ads,
"plenaryw_agenda":plenaryw_agenda, "plenaryt_agenda":plenaryt_agenda,
"now":now},
{"timeslots":timeslots, "meeting":meeting },
RequestContext(request)), mimetype="text/calendar")

def csv_agenda(request, num=None):
Expand Down
38 changes: 16 additions & 22 deletions ietf/templates/meeting/agendaREDESIGN.ics
Expand Up @@ -9,27 +9,21 @@ TZOFFSETTO:{{meeting.time_zone_offset}}
TZNAME:{{meeting.time_zone}}
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
{% endif %}{% for slot in timeslots %}{% ifchanged %}{% if slot.session_name and slot.break_info %}BEGIN:VEVENT
UID:ietf-{{meeting.num}}-break-{{slot.time_id}}
SUMMARY:{{slot.break_info.name}}
{% if venue.break_area_name and slot.break_info.show_break_location %}LOCATION:{{venue.break_area_name}}
END:VTIMEZONE{% endif %}{% for slot in timeslots %}
BEGIN:VEVENT
UID:ietf-{{slot.meeting.number}}-{{slot.pk}}
SUMMARY:{% if slot.session.name %}{{slot.session.name}}{% else %}{% if slot.type.name == "Break" %}{{slot.name}}{% else %}{{slot.session.group.acronym|upper}} - {{slot.session.group.name}}{% endif%}{%endif%}
{% if slot.show_location %}LOCATION:{{slot.get_location}}
{% endif %}STATUS:TENTATIVE
CLASS:PUBLIC
DTSTART{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.meeting_date|date:"Ymd" }}T{{slot.break_info.time_desc|slice:":4"}}00
DTEND{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.meeting_date|date:"Ymd" }}T{{slot.break_info.time_desc|slice:"5:9"}}00
DTSTAMP:{{ now|date:"Ymd" }}T{{ now|date:"His" }}Z
END:VEVENT
{% endif %}{% endifchanged %}{% for session in slot.sessions %}{%for f in filter%}{%ifequal f session.acronym%}BEGIN:VEVENT
UID:ietf-{{meeting.num}}-{{session.acronym}}-{{session.pk}}
SUMMARY:{% if session.area %}{% ifnotequal session.area "1plenary" %}{{session.acronym|upper}} - {% endifnotequal %}{% endif %}{{session.acronym_name}}
LOCATION:{{session.room_id.room_name}}
STATUS:TENTATIVE
CLASS:PUBLIC
DTSTART{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.meeting_date|date:"Ymd" }}T{{slot.time_desc|slice:":4"}}00
DTEND{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.meeting_date|date:"Ymd" }}T{{slot.time_desc|slice:"5:9"}}00
DTSTAMP:{{ now|date:"Ymd" }}T{{ now|date:"His" }}Z
{% if session.description %}DESCRIPTION:
{{ session.description|escapejs }}
{% endif %}END:VEVENT
{%endifequal%}{%endfor%}{% endfor %}{% endfor %}END:VCALENDAR{% endautoescape %}
DTSTART{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.time|date:"Ymd" }}T{{slot.time|date:"Hi"}}00
DTEND{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.end_time|date:"Ymd" }}T{{slot.end_time|date:"Hi"}}00
DTSTAMP:{{ slot.modified|date:"Ymd" }}T{{ slot.modified|date:"His" }}Z
{% if slot.session.agenda %}URL:http://www.ietf.org{{slot.session.agenda.get_absolute_url}}
DESCRIPTION:{{slot.name}}\n{% if slot.session.agenda_note %}
Note: {{slot.session.agenda_note}}\n{% endif %}{% for material in slot.session.materials.all %}
\n{{material.type}}{% if material.type.name != "Agenda" %}
({{material.title}}){% endif %}:
http://www.ietf.org{{material.get_absolute_url}}\n{% endfor %}
{% endif %}END:VEVENT{% endfor %}
END:VCALENDAR{% endautoescape %}
49 changes: 28 additions & 21 deletions ietf/templates/meeting/week-view.html
Expand Up @@ -7,10 +7,16 @@
<script type="text/javascript">
var items = new Array();
{% autoescape off %}
{% for slot in timeslots %}{% for session in slot.sessions %}
items.push({day:{{slot.day_id}}, time:"{{slot.time_desc}}", time_id:{{slot.time_id}}, name:"{{session.acronym_name}}", wg:"{{session.acronym}}", area:"{{session.area}}", room:"{{session.room_id.room_name}}", dayname:"{{ slot.meeting_date|date:"l"|upper }}, {{ slot.meeting_date|date:"F j, Y" }}"{% if session.agenda_file %}, agenda:"/meeting/{{ meeting.num }}/agenda/{{ session.acronym }}-agenda/"{% endif %}});{% endfor %}{% endfor %}

{% for slot in timeslots %} {% if slot.type.name in render_types %}
items.push({day:{{slot.time|date:"w"}}, time:"{{slot.time|date:"Hi"}}-{{slot.end_time|date:"Hi"}}", duration:{{slot.duration.seconds}}, time_id:"{{slot.time|date:"mdHi"}}", type:"{{slot.type}}", {% if slot.session.name %}name:"{{slot.session.name}}",{% else %}{% if slot.type.name == "Break" %}name:"{{slot.name}}", area:"break", wg:"break",{% else %}name:"{{slot.session.group.name}}",wg:"{{slot.session.group.acronym}}",area:"{{slot.session.group.parent.acronym}}",{% endif %}{% endif %} {% if slot.show_location %}room:"{{slot.get_location}}",{% endif %} dayname:"{{ slot.time|date:"l"|upper }}, {{ slot.time|date:"F j, Y" }}"{% if slot.session.agenda %}, agenda:"http://www.ietf.org{{slot.session.agenda.get_absolute_url}}"{% endif %} });{% endif %}{% endfor %}
{% endautoescape %}

/* Saturday events need to be moved to the day -1 */
for (var i = 0; i < items.length; i++)
{
if (items[i].day == 6) { items[i].day = -1; }
}

var fg = {
'app': "#008",
Expand All @@ -21,7 +27,8 @@
'rtg': "#880",
'sec': "#488",
'tsv': "#484",
'irtf': "#448"
'irtf': "#448",
'break': "#000"
};

var bg = {
Expand All @@ -33,7 +40,8 @@
'rtg': "#ffe",
'sec': "#dff",
'tsv': "#dfd",
'irtf': "#ddf"
'irtf': "#ddf",
'break': "#fff"
};

var day = [
Expand Down Expand Up @@ -87,20 +95,16 @@
{
include[(frag[i]+"").toLowerCase()] = true;
}
include[''] = true;
include['1plenary'] = true;
include['2plenary'] = true;

/* Find our boundaries */
for (i = 0; i < items.length; i++)
{
if (include[(items[i].wg).toLowerCase()]
|| include[(items[i].area).toLowerCase()])
if (!("wg" in items[i]) || (include[(items[i].wg).toLowerCase()]
|| include[(items[i].area).toLowerCase()]))
{
var start_time = parseInt(items[i].time.substr(0,2),10) * 60 +
parseInt(items[i].time.substr(2,2),10);
var end_time = parseInt(items[i].time.substr(5,2),10) * 60 +
parseInt(items[i].time.substr(7,2),10);
var end_time = start_time + (items[i].duration / 60)

if (!day_start || start_time < day_start) { day_start = start_time; }
if (end_time > day_end) { day_end = end_time; }
Expand Down Expand Up @@ -203,13 +207,12 @@

for (i = 0; i < items.length; i++)
{
if (include[(items[i].wg).toLowerCase()]
|| include[(items[i].area).toLowerCase()])
if (!("wg" in items[i])|| (include[(items[i].wg).toLowerCase()]
|| include[(items[i].area).toLowerCase()]))
{
var start_time = parseInt(items[i].time.substr(0,2),10) * 60 +
parseInt(items[i].time.substr(2,2),10);
var end_time = parseInt(items[i].time.substr(5,2),10) * 60 +
parseInt(items[i].time.substr(7,2),10);
var end_time = start_time + (items[i].duration / 60)

var sess_width = day_width / sessions[items[i].time_id];
var sess_height = ((end_time - start_time) * minute_height)
Expand Down Expand Up @@ -269,7 +272,8 @@
div.appendChild(document.createElement("br"));

var label = items[i].name;
if (fg[items[i].area])
if (label.length === 0) { label = "Free Slot"; }
if (items[i].wg && fg[items[i].area])
{
label = label + " (" + items[i].wg + ")";
}
Expand All @@ -278,11 +282,14 @@
bold.style.fontWeight="bold";
div.appendChild(bold);

div.appendChild(document.createElement("br"));
var italics = document.createElement("span");
italics.appendChild(document.createTextNode(items[i].room));
italics.style.fontStyle="oblique";
div.appendChild(italics);
if (items[i].room)
{
div.appendChild(document.createElement("br"));
var italics = document.createElement("span");
italics.appendChild(document.createTextNode(items[i].room));
italics.style.fontStyle="oblique";
div.appendChild(italics);
}

e.appendChild(div);

Expand Down

0 comments on commit 740487d

Please sign in to comment.