Fix the agena problem where breaks would not have the right name. Also refactor and simplify the agenda code and templates.

- Legacy-Id: 1346
This commit is contained in:
Henrik Levkowetz 2009-03-02 20:46:06 +00:00
parent a7677a8322
commit 103d5972dd
5 changed files with 165 additions and 196 deletions

View file

@ -4,8 +4,10 @@ from django.conf.urls.defaults import patterns
from ietf.meeting import views
urlpatterns = patterns('',
(r'^(?P<meeting_num>\d+)/agenda.(?P<html_or_txt>\S+)$', views.show_html_agenda),
(r'^(?P<meeting_num>\d+)/materials.html$', views.show_html_materials),
(r'^agenda/$', views.html_agenda),
(r'^(?P<num>\d+)/agenda.html$', views.html_agenda),
(r'^(?P<num>\d+)/agenda.txt$', views.text_agenda),
(r'^$', views.current_materials),
)

View file

@ -5,9 +5,11 @@
from django.shortcuts import render_to_response as render, get_object_or_404
from ietf.proceedings.models import Meeting, MeetingTime, WgMeetingSession, NonSession, MeetingVenue, IESGHistory, Proceeding, Switches
from django.views.generic.list_detail import object_list
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect, Http404
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect, Http404, HttpResponse
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.db.models import Q
from django.template import RequestContext
from django.template.loader import render_to_string
import datetime
def show_html_materials(request, meeting_num=None):
@ -39,45 +41,47 @@ def current_materials(request):
meeting = Meeting.objects.order_by('-meeting_num')[0]
return HttpResponseRedirect( reverse(show_html_materials, args=[meeting.meeting_num]) )
def show_html_agenda(request, meeting_num=None, html_or_txt=None):
queryset_list=MeetingTime.objects.filter(meeting=meeting_num,day_id__gt='0').order_by("day_id","time_desc")
queryset_list_pre_session=MeetingTime.objects.filter(meeting=meeting_num,day_id__lte='0').order_by("day_id","time_desc")
meeting_info=get_object_or_404(Meeting, meeting_num=meeting_num)
nonsession_info=NonSession.objects.filter(meeting=meeting_num,day_id__gte='0').order_by("day_id")
meetingvenue_info=get_object_or_404(MeetingVenue, meeting_num=meeting_num)
last_update_info=get_object_or_404(Switches,id=1)
def get_plenary_agenda(meeting_num, id):
try:
plenaryt_agenda_file = "/a/www/ietf/proceedings/%s" % WgMeetingSession.objects.get(meeting=meeting_num,group_acronym_id=-2).agenda_file()
plenary_agenda_file = "/a/www/ietf/proceedings/%s" % WgMeetingSession.objects.get(meeting=meeting_num,group_acronym_id=id).agenda_file()
try:
f = open(plenaryt_agenda_file)
plenaryt_agenda = f.read()
f = open(plenary_agenda_file)
plenary_agenda = f.read()
f.close()
return plenary_agenda
except IOError:
plenaryt_agenda = "THE AGENDA HAS NOT BEEN UPLOADED YET"
return "THE AGENDA HAS NOT BEEN UPLOADED YET"
except WgMeetingSession.DoesNotExist:
plenaryt_agenda = "The Technical Plenary has not been scheduled"
if html_or_txt == "html":
template_file="meeting/agenda.html"
elif html_or_txt == "txt":
template_file="meeting/agenda.txt"
else:
raise Http404
try:
plenaryw_agenda_file = "/a/www/ietf/proceedings/%s" % WgMeetingSession.objects.get(meeting=meeting_num,group_acronym_id=-1).agenda_file()
try:
f = open(plenaryw_agenda_file)
plenaryw_agenda = f.read()
f.close()
except IOError:
plenaryw_agenda = "THE AGENDA HAS NOT BEEN UPLOADED YET"
except WgMeetingSession.DoesNotExist:
plenaryw_agenda = "THE IETF Operations and Administration Plenary has not been secheduled"
# Due to a bug in Django@0.96 we can't use foreign key lookup in
# order_by(), see http://code.djangoproject.com/ticket/2076. Changeset
# [133] is broken because it requires a patched Django to run. Work
# around this instead. Later: FIXME (revert to the straightforward code
# when this bug has been fixed in the Django release we're running.)
queryset_list_ads = list(IESGHistory.objects.filter(meeting=meeting_num))
queryset_list_ads.sort(key=(lambda item: item.area.area_acronym.acronym))
return object_list(request,queryset=queryset_list, template_name=template_file,allow_empty=True, extra_context={'queryset_list_pre_session':queryset_list_pre_session, 'meeting_info':meeting_info, 'meeting_num':meeting_num, 'nonsession_info':nonsession_info, 'meetingvenue_info':meetingvenue_info, 'plenaryw_agenda':plenaryw_agenda, 'plenaryt_agenda':plenaryt_agenda, 'qs_ads':queryset_list_ads,'last_update_info':last_update_info})
return "The Plenary has not been scheduled"
def html_agenda(request, num=None):
if not num:
num = list(Meeting.objects.all())[-1].meeting_num
timeslots = MeetingTime.objects.filter(meeting=num).order_by("day_id", "time_desc")
update = get_object_or_404(Switches,id=1)
meeting=get_object_or_404(Meeting, meeting_num=num)
venue = get_object_or_404(MeetingVenue, meeting_num=num)
ads = list(IESGHistory.objects.filter(meeting=num))
if not ads:
ads = list(IESGHistory.objects.filter(meeting=str(int(num)-1)))
ads.sort(key=(lambda item: item.area.area_acronym.acronym))
plenaryw_agenda = get_plenary_agenda(num, -1)
plenaryt_agenda = get_plenary_agenda(num, -2)
return render("meeting/agenda.html",
{"timeslots":timeslots, "update":update, "meeting":meeting, "venue":venue, "ads":ads,
"ops_plenary_agenda":plenaryw_agenda, "tech_plenary_agenda":plenaryt_agenda, },
RequestContext(request))
def text_agenda(request, num):
timeslots = MeetingTime.objects.filter(meeting=num).order_by("day_id", "time_desc")
update = get_object_or_404(Switches,id=1)
meeting=get_object_or_404(Meeting, meeting_num=num)
venue = get_object_or_404(MeetingVenue, meeting_num=num)
ads = list(IESGHistory.objects.filter(meeting=num))
if not ads:
ads = list(IESGHistory.objects.filter(meeting=str(int(num)-1)))
ads.sort(key=(lambda item: item.area.area_acronym.acronym))
return HttpResponse(render_to_string("meeting/agenda.txt",
{"timeslots":timeslots, "update":update, "meeting":meeting, "venue":venue, "ads":ads},
RequestContext(request)), mimetype="text/plain")

View file

@ -108,6 +108,8 @@ class Meeting(models.Model):
return "IETF %d" % (self.meeting_num)
def get_meeting_date (self,offset):
return self.start_date + datetime.timedelta(days=offset)
def num(self):
return self.meeting_num
class Meta:
db_table = 'meetings'
class Admin:
@ -130,6 +132,8 @@ class NonSessionRef(models.Model):
return self.name
class Meta:
db_table = 'non_session_ref'
class Admin:
pass
class NonSession(models.Model):
non_session_id = models.AutoField(primary_key=True)
@ -225,37 +229,29 @@ class MeetingTime(models.Model):
else:
s.room_id = 0
return sessions
def sessions_by_area(self):
return [ {"area":session.area()+session.acronym(), "info":session} for session in self.sessions() ]
def meeting_date(self):
return self.meeting.get_meeting_date(self.day_id)
def registration(self):
reg = NonSession.objects.get(meeting=self.meeting, day_id=self.day_id, non_session_ref=1)
reg.name = reg.non_session_ref.name
return reg
def reg_info(self):
reg_info = NonSession.objects.get(meeting=self.meeting, day_id=self.day_id, non_session_ref=1)
reg_info = self.registration()
if reg_info.time_desc:
return "%s %s" % (reg_info.time_desc, reg_info.non_session_ref)
return "%s %s" % (reg_info.time_desc, reg_info.name)
else:
return ""
def morning_br_info(self):
br_info = NonSession.objects.get(models.Q(day_id=self.day_id) | models.Q(day_id__isnull=True), meeting=self.meeting, non_session_ref=2)
return "%s %s" % (br_info.time_desc, br_info.non_session_ref)
def lunch_br_info(self):
return NonSession.objects.get(meeting=self.meeting, non_session_ref=3).time_desc
def an_br1_info(self):
an_br1_info = NonSession.objects.exclude(time_desc="").get(meeting=self.meeting, day_id=self.day_id, non_session_ref=4)
if an_br1_info:
if self.day_id == 1 or self.day_id == 2:
return "%s Afternoon Beverage Break I" % (an_br1_info.time_desc)
else:
return "%s %s" % (an_br1_info.time_desc, an_br1_info.non_session_ref)
else:
return ""
def an_br2_info(self):
an_br2_info = NonSession.objects.exclude(time_desc="").get(meeting=self.meeting, day_id=self.day_id, non_session_ref=5)
if an_br2_info:
return "%s %s" % (an_br2_info.time_desc, an_br2_info.non_session_ref)
else:
return ""
def fbreak_info(self):
fbreak_info = NonSession.objects.get(meeting=self.meeting, day_id=5, non_session_ref=6)
return "%s %s" % (fbreak_info.time_desc, fbreak_info.non_session_ref)
def break_info(self):
breaks = NonSession.objects.filter(meeting=self.meeting).exclude(non_session_ref=1).filter(models.Q(day_id=self.day_id) | models.Q(day_id__isnull=True)).order_by('time_desc')
for brk in breaks:
if brk.time_desc[-4:] == self.time_desc[:4]:
brk.name = brk.non_session_ref.name
return brk
return None
def is_plenary(self):
return self.session_name_id in [9, 10]
class Meta:
db_table = 'meeting_times'
class Admin:

View file

@ -1,106 +1,100 @@
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "base.html" %}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% load humanize %}
{% block title %} Meeting Agenda of the {{ meeting_num|ordinal }} IETF Meeting{% endblock %}
{% block body_attributes %}background="http://www.ietf.org/meetings/peachbkg.gif"{% endblock %}
{% block title %} Meeting Agenda of the {{ meeting.num|ordinal }} IETF Meeting{% endblock %}
{% block content %}
<center>
<strong> Agenda of the {{ meeting_num|ordinal }} IETF Meeting </strong> <br/>
<strong>{{ meeting_info.start_date|date:"F j" }}-{% ifnotequal meeting_info.start_date.month meeting_info.end_date.month %}{{ meeting_info.end_date|date:"F " }}{% endifnotequal %}{{ meeting_info.end_date|date:"j, Y" }} </strong><br />
Updated {{ last_update_info.updated|date:"F j, Y P (T)" }}<br />
(<a href="{% url ietf.meeting.views.show_html_agenda meeting_num,"txt" %}">Agenda in text/plain format</a>) <br />
<p style="text-align: center">
Agenda of the {{ meeting.num|ordinal }} IETF Meeting<br />
{{ meeting.start_date|date:"F j" }}-{% ifnotequal meeting.start_date.month meeting.end_date.month %}{{ meeting.end_date|date:"F " }}{% endifnotequal %}{{ meeting.end_date|date:"j, Y" }}<br />
Updated {{ update.updated|date:"Y-m-d H:i:s T" }}<br />
(There's also a <a href="./agenda.txt">plaintext agenda</a> and a <a href="http://tools.ietf.org/agenda/{{meeting.num}}/">tools-style agenda</a> available)<br />
<br />
<i>IETF agendas are subject to change, up to and during the meeting.</i><br />
<br />
</center>
IETF agendas are subject to change, up to and during the meeting.<br />
</p>
<!-- Update to include Saturday Session -->
{% regroup queryset_list_pre_session by day_id as pre_days %}
{% for pre_day in pre_days %}
<b>{{ pre_day.list.0.meeting_date|date:"l"|upper }}, {{ pre_day.list.0.meeting_date|date:"F j, Y" }} </b><br>
{% ifequal pre_day.list.0.day_id 0 %}
{{ nonsession_info.0.time_desc }} {{ nonsession_info.0.non_session_ref }} - {{ meetingvenue_info.reg_area_name }}
<br>
{% endifequal %}
{% for item in pre_day.list %}
{% for session in item.sessions %}
{{ item.time_desc }} {{ session.acronym_name }} - {{ session.sched_room_id1.room_name }}<br>
{% endfor %}
{% endfor %}
<br>
{% endfor %}
<!-- End Update -->
{% regroup object_list by day_id as days %}
{% for day in days %}
<b>{{ day.list.0.meeting_date|date:"l"|upper }}, {{ day.list.0.meeting_date|date:"F j, Y" }} </b><br>
{% if day.list.0.reg_info %}{{ day.list.0.reg_info }} - {{ meetingvenue_info.reg_area_name }} <br>{% endif %}
{% ifequal day.list.0.day_id "5" %}
{{ day.list.0.fbreak_info }} - {{ meetingvenue_info.break_area_name }} <br>
<table id="agenda">
{% for slot in timeslots %}
{% ifchanged %}
<tr>
<td colspan="4">
<hr />
<h4>{{ slot.meeting_date|date:"l"|upper }}, {{ slot.meeting_date|date:"F j, Y" }}</h4>
</td>
</tr>
{% if slot.reg_info %}
<tr>
<td colspan="4">
{{ slot.registration.time_desc }} {{ slot.registration.name }}
{% if venue.reg_area_name %} - <a href="http://tools.ietf.org/agenda/{{meeting.num}}/venue/?room={{ venue.reg_area_name|slugify }}">{{ venue.reg_area_name }}</a>{% endif %}
</td>
</tr>
{% endif %}
{% endifchanged %}
{% if slot.session_name %}
{% if slot.break_info %}
<tr>
<td colspan="4">
<br />
{{ slot.break_info.time_desc }} {{ slot.break_info.name }}
{% if venue.break_area_name %} - <a href="http://tools.ietf.org/agenda/{{meeting.num}}/venue/?room={{ venue.break_area_name|slugify }}">{{ venue.break_area_name }}</a>{% endif %}
</td>
</tr>
{% endif %}
<tr>
<td colspan="4">
<b>{{ slot.time_desc }} {{ slot.session_name }}</b>
{% ifequal slot.sessions.0.acronym "plenaryw" %}
<b>- {{ slot.sessions.0.room_id.room_name }}</b><br>
<pre>{{ ops_plenary_agenda|escape }}</pre>
{% endifequal %}
{% ifequal slot.sessions.0.acronym "plenaryt" %}
<b>- {{ slot.sessions.0.room_id.room_name }}</b><br>
<pre>{{ tech_plenary_agenda|escape }}</pre>
{% endifequal %}
</td>
</tr>
{% if not slot.is_plenary %}
{% for session in slot.sessions_by_area|dictsort:"area" %}
<tr>
<td><a href="http://tools.ietf.org/agenda/{{meeting.num}}/venue/?room={{session.info.room_id.room_name|slugify}}">{{ session.info.room_id.room_name}}</a></td>
{% if session.info.area %}
<td>{{ session.info.area|upper}}</td>
<td>{% if session.info.isWG %}<a href="http://www.ietf.org/html.charters/{{ session.info.acronym|lower }}-charter.html">{{ session.info.acronym|lower }}</a>{% else %}{{ session.info.acronym|lower }}{% endif %}</td>
<td>
{% if session.info.agenda_file %}<a href="http://www3.ietf.org/proceedings/{{ session.info.agenda_file }}">{{ session.info.acronym_name|escape }} {{ session.info.group_type_str }}</a>{% else %}{{ session.info.acronym_name|escape }} {{ session.info.group_type_str }}{% endif %}
{% if session.info.special_agenda_note %}<br/> - {{ session.info.special_agenda_note }}{% endif %}
</td>
{% endif %}
</tr>
{% endfor %}
{% endif %}
{% else %}
{{ day.list.0.morning_br_info }} - {{ meetingvenue_info.break_area_name }} <br>
{% endifequal %}
<br>
{% for item in day.list %}
{% ifequal item.session_name_id 3 %}
{{ day.list.0.lunch_br_info }} Break<br>
{% endifequal %}
{% ifequal item.session_name_id 4 %}
{% if day.list.0.an_br1_info %}
{{ day.list.0.an_br1_info }} - {{ meetingvenue_info.break_area_name }}<br>
{% endif %}
{% endifequal %}
{% ifequal item.session_name_id 5 %}
{% if day.list.0.an_br2_info %}
{{ day.list.0.an_br2_info }} - {{ meetingvenue_info.break_area_name }}<br>
{% endif %}
{% endifequal %}
{% ifequal item.session_name_id 8 %}
{% if day.list.0.an_br2_info %}
{{ day.list.0.an_br2_info }} - {{ meetingvenue_info.break_area_name }}<br>
{% endif %}
{% endifequal %}
{% ifequal item.session_name_id 10 %}
{% if day.list.0.an_br2_info %}
{{ day.list.0.an_br2_info }} - {{ meetingvenue_info.break_area_name }}<br>
{% endif %}
{% endifequal %}
<b>{{ item.time_desc }} {{ item.session_name }} </b>
{% ifequal item.sessions.0.acronym "plenaryw" %}
<b>- {{ item.sessions.0.room_id.room_name }}</b><br>
<pre>{{ plenaryw_agenda|escape }}</pre>
{% else %}
{% ifequal item.sessions.0.acronym "plenaryt" %}
<b>- {{ item.sessions.0.room_id.room_name }}</b><br>
<pre>{{ plenaryt_agenda|escape }}</pre>
{% else %}
<table border="0" cellspacing="0" cellpadding="0" width="800">
{% for session in item.sessions|dictsort:"area" %}
<tr><td width="200">{{ session.room_id.room_name }}</td><td width="50">{{ session.area|upper }}</td><td width="100">{% if session.isWG %}<a href="http://www.ietf.org/html.charters/{{ session.acronym|lower }}-charter.html">{{ session.acronym|lower }}</a>{% else %}{{ session.acronym|lower }}{% endif %}</td><td>{% if session.agenda_file %}<a href="http://www3.ietf.org/proceedings/{{ session.agenda_file }}">{{ session.acronym_name }} {{ session.group_type_str }}</a>{% else %}{{ session.acronym_name }} {{ session.group_type_str }}{% endif %}{% if session.special_agenda_note %} <b>- {{ session.special_agenda_note }}</b>{% endif %}</td></tr>
{% endfor %}
</table>
{% endifequal %}
{% endifequal %}
<br>
{% endfor %}
<br>
{% for session in slot.sessions %}
<tr>
<td colspan="4">
{{ slot.time_desc }} {{ session.acronym_name|escape }} - <a href="http://tools.ietf.org/agenda/{{meeting.num}}/venue/?room={{session.room_id.room_name|slugify}}">{{ session.room_id.room_name}}</a>
</td>
</tr>
{% endfor %}
{% endif %}
{% endfor %}
<hr>
<center><b>AREA DIRECTORS</b></center><br>
<table border="0" width="800">
{% regroup qs_ads by area as ads %}
{% for ad in ads %}
<tr><td colspan="4"><hr /></td></tr>
<tr><td colspan="4" style="text-align: center"><b>AREA DIRECTORS</b></td></tr>
<tr><td colspan="4">
<table>
{% regroup ads by area as grouped %}{% for ad in grouped %}
<tr valign="top">
<td width="65">{{ ad.grouper|upper }}</td>
<td width="140">{{ ad.list.0.area.area_acronym.name }}</td>
<td>{{ ad.grouper|upper }}</td>
<td>{{ ad.list.0.area.area_acronym.name }}</td>
<td>
{% for ad_person in ad.list %}
{% ifequal forloop.counter 2 %} & {% endifequal %}
{% ifequal forloop.counter 2 %} &amp; {% endifequal %}
{{ ad_person.person }}/{{ ad_person.person.affiliation }}
{% endfor %}
</td>
</tr>
{% endfor %}
</table>
</td></tr>
</table>
{% endblock %}

View file

@ -1,49 +1,22 @@
<?xml version="1.0" encoding="iso-8859-1"?>
{% load humanize %}
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"
xml:lang="en-US"><head><title>Agenda of the {{ meeting_num|ordinal }} IETF Meeting</title>
</head><body><p>
<pre>{# From here on out, horizontal and vertical whitespace is significant... #}
{% filter center:72 %}Agenda of the {{ meeting_num|ordinal }} IETF Meeting{% endfilter %}
{% filter center:72 %}{{ meeting_info.start_date|date:"F j" }}-{% ifnotequal meeting_info.start_date.month meeting_info.end_date.month %}{{ meeting_info.end_date|date:"F " }}{% endifnotequal %}{{ meeting_info.end_date|date:"j, Y" }}{% endfilter %}
{% filter center:72 %}Updated {{ last_update_info.updated|date:"F j, Y P (T)" }}{% endfilter %}
{% filter center:72 %}Agenda of the {{ meeting.num|ordinal }} IETF Meeting{% endfilter %}
{% filter center:72 %}{{ meeting.start_date|date:"F j" }}-{% ifnotequal meeting.start_date.month meeting.end_date.month %}{{ meeting.end_date|date:"F " }}{% endifnotequal %}{{ meeting.end_date|date:"j, Y" }}{% endfilter %}
{% filter center:72 %}Updated {{ update.updated|date:"Y-m-d H:i:s T" }}{% endfilter %}
{% filter center:72 %}IETF agendas are subject to change, up to and during the meeting.{% endfilter %}
{% regroup queryset_list_pre_session by day_id as pre_days %}
{% for pre_day in pre_days %}
{{ pre_day.list.0.meeting_date|date:"l"|upper }}, {{ pre_day.list.0.meeting_date|date:"F j, Y" }}
{% ifequal pre_day.list.0.day_id 0 %}
{{ nonsession_info.0.time_desc }} {{ nonsession_info.0.non_session_ref }} - {{ meetingvenue_info.reg_area_name }}
{% endifequal %}
{% for item in pre_day.list %}
{% for session in item.sessions %}
{{ item.time_desc }} {{ session.acronym_name }} - {{ session.sched_room_id1.room_name }}
{% endfor %}
{% endfor %}
{% endfor %}
<!-- End Update -->
{% regroup object_list by day_id as days %}{% for day in days %}
{{ day.list.0.meeting_date|date:"l"|upper }}, {{ day.list.0.meeting_date|date:"F j, Y" }}
{% if day.list.0.reg_info %}{{ day.list.0.reg_info }} - {{ meetingvenue_info.reg_area_name }}
{% endif %}{% ifequal day.list.0.day_id "5" %}{{ day.list.0.fbreak_info }} - {{ meetingvenue_info.break_area_name }}{% else %}{{ day.list.0.morning_br_info }} - {{ meetingvenue_info.break_area_name }}
{% endifequal %}{% for item in day.list %}{% ifequal item.session_name_id 3 %}{{ day.list.0.lunch_br_info }} Break
{% endifequal %}{% ifequal item.session_name_id 4 %}{{ day.list.0.an_br1_info }} - {{ meetingvenue_info.break_area_name }}
{% endifequal %}{% ifequal item.session_name_id 5 %}{{ day.list.0.an_br2_info }} - {{ meetingvenue_info.break_area_name }}
{% endifequal %}{{ item.time_desc }} {{ item.session_name }}{% ifequal item.sessions.0.acronym "plenaryw" %}{{ item.sessions.0.room_id.room_name }}
{{ plenaryw_agenda|escape }}{% else %}{% ifequal item.sessions.0.acronym "plenaryt" %}{{ item.sessions.0.room_id.room_name }}
{{ plenaryt_agenda|escape }}{% else %}{% for session in item.sessions|dictsort:"area" %}
{{ session.room_id.room_name|ljust:16 }} {{ session.area|upper|ljust:4 }} {{ session.acronym|ljust:7 }} {{ session.acronym_name }} {{ session.group_type_str }}{% if session.special_agenda_note %} - {{ session.special_agenda_note }}{% endif %}{% endfor %}
{% endifequal %}{% endifequal %}
{% endfor %}
{% endfor %}
{% for slot in timeslots %}{% ifchanged %}
{{ slot.meeting_date|date:"l"|upper }}, {{ slot.meeting_date|date:"F j, Y" }}{% if slot.reg_info %}
{{ slot.registration.time_desc }} {{ slot.registration.name }}{% if venue.reg_area_name %} - {{ venue.reg_area_name }}{% endif %}{% endif %}
{% endifchanged %}{% if slot.session_name %}{% if slot.break_info %}{{ slot.break_info.time_desc }} {{ slot.break_info.name }}{% if venue.break_area_name %} - {{ venue.break_area_name }}{% endif %}
{% endif %}{{ slot.time_desc }} {{ slot.session_name }}{% for session in slot.sessions_by_area|dictsort:"area" %}
{{ session.info.room_id.room_name|ljust:14 }} {% if session.info.area %}{{ session.info.area|upper|ljust:4 }} {{ session.info.acronym|ljust:9 }} {% endif %}{{ session.info.acronym_name }} {{ session.info.group_type_str }}{% if session.info.special_agenda_note %} - {{ session.info.special_agenda_note }}{% endif %}{% endfor %}
{% else %}{% for session in slot.sessions %}{{ slot.time_desc }} {{ session.acronym_name }} - {{ session.room_id.room_name }}
{% endfor %}{% endif %}{% endfor %}
====================================================================
AREA DIRECTORS
{% regroup qs_ads by area as ads %}{% for ad in ads %}
{{ ad.grouper|upper|ljust:5 }}{{ ad.list.0.area.area_acronym.name|ljust:18 }} {% for ad_person in ad.list %}{% ifequal forloop.counter 2 %} & {% endifequal %}{{ ad_person.person }}/{{ ad_person.person.affiliation }}{% endfor %}{% endfor %}
</pre>
</body>
</html>
{% regroup ads by area as grouped %}{% for ad in grouped %}
{{ ad.grouper|upper|ljust:5 }}{{ ad.list.0.area.area_acronym.name|slice:":18"|ljust:18 }} {% for ad_person in ad.list %}{% ifequal forloop.counter 2 %} & {% endifequal %}{{ ad_person.person }}/{{ ad_person.person.affiliation }}{% endfor %}{% endfor %}