From 8686fd2a4e9e390e02fd0fb2990d5c780d1dd9e9 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Fri, 23 Jan 2015 17:31:04 +0000 Subject: [PATCH 1/5] simple display fix, already in trunk - Legacy-Id: 8902 --- ietf/meeting/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index 1fdd1c238..1f209676b 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -240,7 +240,7 @@ class Room(models.Model): resources = models.ManyToManyField(ResourceAssociation, blank = True) def __unicode__(self): - return "%s size: %u" % (self.name, self.capacity) + return "%s size: %s" % (self.name, self.capacity) def delete_timeslots(self): for ts in self.timeslot_set.all(): From 47901e8555a796a0f89fe8959bebaab2c21e3d85 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Tue, 27 Jan 2015 19:15:25 +0000 Subject: [PATCH 2/5] Checkpoint: by-room view and basic leadership meetings support - Legacy-Id: 8930 --- ietf/meeting/helpers.py | 2 ++ ietf/meeting/models.py | 6 +++++- ietf/meeting/test_data.py | 12 ++++++++++++ ietf/meeting/tests_views.py | 9 ++++++++- ietf/meeting/urls.py | 1 + ietf/meeting/views.py | 15 +++++++++++++++ 6 files changed, 43 insertions(+), 2 deletions(-) diff --git a/ietf/meeting/helpers.py b/ietf/meeting/helpers.py index 12e82b857..5e25d12b0 100644 --- a/ietf/meeting/helpers.py +++ b/ietf/meeting/helpers.py @@ -67,6 +67,8 @@ def build_all_agenda_slices(meeting): date_slices = {} for ts in meeting.timeslot_set.exclude(type__in=['reg','break']).order_by('time','name'): + #for ts in meeting.timeslot_set.exclude(type__in=['reg','break','other']).order_by('time','name'): + #for ts in meeting.timeslot_set.order_by('time','name'): ymd = ts.time.date() if ymd not in date_slices and ts.location != None: diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index 1f209676b..bdde2ebfd 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -322,7 +322,7 @@ class TimeSlot(models.Model): 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): + def get_hidden_location(self): location = self.location if location: location = location.name @@ -330,6 +330,10 @@ class TimeSlot(models.Model): location = self.meeting.reg_area elif self.type_id == "break": location = self.meeting.break_area + return location + + def get_location(self): + location = self.get_hidden_location() if not self.show_location: location = "" return location diff --git a/ietf/meeting/test_data.py b/ietf/meeting/test_data.py index e7a877f76..c4eaa2fc1 100644 --- a/ietf/meeting/test_data.py +++ b/ietf/meeting/test_data.py @@ -20,6 +20,7 @@ def make_meeting_test_data(): pname = RoomResourceName.objects.create(name='projector',slug='proj') projector = ResourceAssociation.objects.create(name=pname,icon="notfound.png",desc="Basic projector") room = Room.objects.create(meeting=meeting, name="Test Room", capacity=123) + breakfast_room = Room.objects.create(meeting=meeting, name="Breakfast Room", capacity=40) room.resources = [projector] # mars WG @@ -41,6 +42,17 @@ def make_meeting_test_data(): scheduled=datetime.datetime.now()) ScheduledSession.objects.create(timeslot=slot, session=ames_session, schedule=schedule) + # IESG breakfast + breakfast_slot = TimeSlot.objects.create(meeting=meeting, type_id="lead", duration=90 * 60, + location=breakfast_room, + time=datetime.datetime.combine(datetime.date.today(),datetime.time(7,0))) + iesg_session = Session.objects.create(meeting=meeting, group=Group.objects.get(acronym="iesg"), + name="IESG Breakfast", + attendees=25, requested_by=system_person, + requested_duration=20, status_id="schedw", + scheduled=datetime.datetime.now()) + ScheduledSession.objects.create(timeslot=breakfast_slot, session=iesg_session, schedule=schedule) + meeting.agenda = schedule meeting.save() diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index 736c18ff4..afe82785e 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -11,7 +11,7 @@ from pyquery import PyQuery from ietf.doc.models import Document from ietf.meeting.models import Session, TimeSlot from ietf.meeting.test_data import make_meeting_test_data -from ietf.utils.test_utils import TestCase +from ietf.utils.test_utils import TestCase, login_testing_unauthorized class MeetingTests(TestCase): def setUp(self): @@ -98,6 +98,13 @@ class MeetingTests(TestCase): self.assertTrue(session.group.acronym in agenda_content) self.assertTrue(slot.location.name in agenda_content) + def test_agenda_by_room(self): + meeting = make_meeting_test_data() + url = urlreverse("ietf.meeting.views.agenda_by_room",kwargs=dict(num=meeting.number)) + login_testing_unauthorized(self,"secretary",url) + r = self.client.get(url,kwargs=dict(num=meeting.number)) + self.assertTrue(all([x in r.content for x in ['mars','IESG Breakfast','Test Room','Breakfast Room']])) + def test_materials(self): meeting = make_meeting_test_data() session = Session.objects.filter(meeting=meeting, group__acronym="mars").first() diff --git a/ietf/meeting/urls.py b/ietf/meeting/urls.py index f8cce53f7..56a35dd58 100644 --- a/ietf/meeting/urls.py +++ b/ietf/meeting/urls.py @@ -35,6 +35,7 @@ urlpatterns = patterns('', (r'^(?P\d+)/agenda(?P.txt)$', views.agenda), (r'^(?P\d+)/agenda.ics$', views.ical_agenda), (r'^(?P\d+)/agenda(?P.csv)$', views.agenda), + (r'^(?P\d+)/agenda/by-room$', views.agenda_by_room), (r'^(?P\d+)/agendas/edit$', views.edit_agendas), (r'^(?P\d+)/timeslots/edit$', views.edit_timeslots), (r'^(?P\d+)/rooms$', ajax.timeslot_roomsurl), diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 4ea3c54cc..79452846c 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -6,6 +6,7 @@ import re import tarfile import urllib from tempfile import mkstemp +from collections import OrderedDict import debug # pyflakes:ignore @@ -376,6 +377,20 @@ def agenda(request, num=None, name=None, base=None, ext=None): return HttpResponse(render_to_string("meeting/"+base+ext, {"schedule":schedule, "updated": updated}, RequestContext(request)), content_type=mimetype[ext]) +#TODO - let the IAB in +@role_required('Area Director','Secretariat') +@ensure_csrf_cookie +def agenda_by_room(request,num=None): + meeting = get_meeting(num) + schedule = get_schedule(meeting) + ss_by_day = OrderedDict() + for day in schedule.scheduledsession_set.dates('timeslot__time','day'): + ss_by_day[day]=[] + for ss in schedule.scheduledsession_set.order_by('timeslot__location','timeslot__time'): + day = ss.timeslot.time.date() + ss_by_day[day].append(ss) + return render(request,"meeting/agenda_by_room.html",{"meeting":meeting,"ss_by_day":ss_by_day}) + def read_agenda_file(num, doc): # XXXX FIXME: the path fragment in the code below should be moved to # settings.py. The *_PATH settings should be generalized to format() From 3f6503722c4cddc31cb4a5f20ac39884438962fe Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Tue, 27 Jan 2015 21:22:45 +0000 Subject: [PATCH 3/5] Get the leadership timeslots to show in the secr pages - Legacy-Id: 8931 --- ietf/secr/meetings/forms.py | 1 + ietf/secr/meetings/views.py | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ietf/secr/meetings/forms.py b/ietf/secr/meetings/forms.py index d3ee39e2e..1954fa93c 100644 --- a/ietf/secr/meetings/forms.py +++ b/ietf/secr/meetings/forms.py @@ -180,6 +180,7 @@ class TimeSlotForm(forms.Form): class NonSessionForm(TimeSlotForm): short = forms.CharField(max_length=32,label='Short Name',help_text='Enter an abbreviated session name (used for material file names)',required=False) type = forms.ModelChoiceField(queryset=TimeSlotTypeName.objects.filter(slug__in=('other','reg','break','plenary')),empty_label=None) + type = forms.ModelChoiceField(queryset=TimeSlotTypeName.objects.filter(used=True).exclude(slug__in=('session',)),empty_label=None) group = forms.ModelChoiceField(queryset=Group.objects.filter(acronym__in=('edu','ietf','iepg','tools','iesg','iab','iaoc')),help_text='Required for Session types: other, plenary',required=False) show_location = forms.BooleanField(required=False) diff --git a/ietf/secr/meetings/views.py b/ietf/secr/meetings/views.py index 1b2e7eed9..371a95bb1 100644 --- a/ietf/secr/meetings/views.py +++ b/ietf/secr/meetings/views.py @@ -95,7 +95,7 @@ def build_nonsession(meeting,schedule): system = Person.objects.get(name='(system)') secretariat = Group.objects.get(acronym='secretariat') - for slot in TimeSlot.objects.filter(meeting=last_meeting,type__in=('break','reg','other','plenary')): + for slot in TimeSlot.objects.filter(meeting=last_meeting,type__in=('break','reg','other','plenary','lead')): new_time = slot.time + delta session = None # create Session object for Tutorials to hold materials @@ -128,7 +128,7 @@ def check_nonsession(meeting,schedule): Ensure non-session timeslots exist and have appropriate ScheduledSession objects for the specified schedule. ''' - slots = TimeSlot.objects.filter(meeting=meeting,type__in=('break','reg','other','plenary')) + slots = TimeSlot.objects.filter(meeting=meeting,type__in=('break','reg','other','plenary','lead')) if not slots: build_nonsession(meeting,schedule) return None @@ -435,7 +435,7 @@ def non_session(request, meeting_id, schedule_name): check_nonsession(meeting,schedule) - slots = TimeSlot.objects.filter(meeting=meeting,type__in=('break','reg','other','plenary')).order_by('-type__name','time') + slots = TimeSlot.objects.filter(meeting=meeting,type__in=('break','reg','other','plenary','lead')).order_by('-type__name','time') if request.method == 'POST': form = NonSessionForm(request.POST) @@ -458,7 +458,7 @@ def non_session(request, meeting_id, schedule_name): duration=duration, show_location=form.cleaned_data['show_location']) - if timeslot.type.slug not in ('other','plenary'): + if timeslot.type.slug not in ('other','plenary','lead'): group = Group.objects.get(acronym='secretariat') # create associated Session object @@ -501,7 +501,7 @@ def non_session_delete(request, meeting_id, schedule_name, slot_id): meeting = get_object_or_404(Meeting, number=meeting_id) # schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name) slot = get_object_or_404(TimeSlot, id=slot_id) - if slot.type_id in ('other','plenary'): + if slot.type_id in ('other','plenary','lead'): scheduledsessions = slot.scheduledsession_set.filter(schedule__meeting=meeting) session_objects = [ x.session for x in scheduledsessions ] for session in session_objects: From 61a0059d066fccbeadc8a03995af59a07f7074e1 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Wed, 4 Feb 2015 20:47:40 +0000 Subject: [PATCH 4/5] checkpoint before trying to fix the static agenda page - Legacy-Id: 8972 --- ietf/meeting/helpers.py | 1 + static/js/agenda/agenda_objects.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ietf/meeting/helpers.py b/ietf/meeting/helpers.py index 5e25d12b0..1d3b2afc0 100644 --- a/ietf/meeting/helpers.py +++ b/ietf/meeting/helpers.py @@ -69,6 +69,7 @@ def build_all_agenda_slices(meeting): for ts in meeting.timeslot_set.exclude(type__in=['reg','break']).order_by('time','name'): #for ts in meeting.timeslot_set.exclude(type__in=['reg','break','other']).order_by('time','name'): #for ts in meeting.timeslot_set.order_by('time','name'): + #for ts in meeting.timeslot_set.filter(type='offagenda').order_by('time','name'): ymd = ts.time.date() if ymd not in date_slices and ts.location != None: diff --git a/static/js/agenda/agenda_objects.js b/static/js/agenda/agenda_objects.js index 1cc85af09..7f2f728b7 100644 --- a/static/js/agenda/agenda_objects.js +++ b/static/js/agenda/agenda_objects.js @@ -1172,6 +1172,10 @@ Session.prototype.event_template = function() { } //console.log("acronym", groupacronym, this.group.acronym, this.visible_title()); + var durationstring=""; + if (this.requested_duration!="0.0") { + durationstring = " ("+this.requested_duration+")" + } // see comment in ietf.ccs, and // http://stackoverflow.com/questions/5148041/does-firefox-support-position-relative-on-table-elements return "
"+ this.visible_title()+ - " ("+this.requested_duration+")" + + "" + durationstring + "" + ""+pinned+"
"+ area_mark +"
"; }; From 9421ea9b93329b686616930eadda42a13a6a5385 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Thu, 5 Feb 2015 21:16:56 +0000 Subject: [PATCH 5/5] Unbroke week-view, but only by compromising on whether to show things like the terminal room - Legacy-Id: 9004 --- ietf/meeting/models.py | 2 +- ietf/meeting/views.py | 6 ++++-- ietf/templates/meeting/agenda.csv | 4 ++-- ietf/templates/meeting/agenda.html | 2 +- ietf/templates/meeting/agenda.txt | 2 +- ietf/templates/meeting/week-view.html | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index bdde2ebfd..1f4cd0756 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -582,7 +582,7 @@ class Schedule(models.Model): .distinct() ) def groups(self): - return Group.objects.filter(type__slug__in=['wg', 'rg', 'ag', 'iab'], session__scheduledsession__schedule=self).distinct().order_by('parent__acronym', 'acronym') + return Group.objects.filter(type__slug__in=['wg', 'rg', 'ag', 'iab'], session__scheduledsession__schedule=self).exclude(session__scheduledsession__timeslot__type__in=['lead','offagenda']).distinct().order_by('parent__acronym', 'acronym') # calculate badness of entire schedule def calc_badness(self): diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 79452846c..1f0967e6a 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -366,6 +366,7 @@ def agenda(request, num=None, name=None, base=None, ext=None): ext = ext if ext else '.html' if 'iPhone' in get_user_agent(request) and ext == ".html": base = 'm_agenda' + # This is misleading - urls.py doesn't send ics through here anymore mimetype = {".html":"text/html", ".txt": "text/plain", ".ics":"text/calendar", ".csv":"text/csv"} meeting = get_meeting(num) schedule = get_schedule(meeting, name) @@ -374,8 +375,9 @@ def agenda(request, num=None, name=None, base=None, ext=None): {'meeting':meeting }, RequestContext(request)), content_type=mimetype[ext]) updated = meeting_updated(meeting) + filtered_assignments = schedule.assignments.exclude(timeslot__type__in=['lead','offagenda']) return HttpResponse(render_to_string("meeting/"+base+ext, - {"schedule":schedule, "updated": updated}, RequestContext(request)), content_type=mimetype[ext]) + {"schedule":schedule, "filtered_assignments":filtered_assignments, "updated": updated}, RequestContext(request)), content_type=mimetype[ext]) #TODO - let the IAB in @role_required('Area Director','Secretariat') @@ -619,7 +621,7 @@ def ical_agenda(request, num=None, name=None, ext=None): elif item[0] == '~': include_types |= set([item[1:]]) - assignments = schedule.assignments.filter( + assignments = schedule.assignments.exclude(timeslot__type__in=['lead','offagenda']).filter( Q(timeslot__type__slug__in = include_types) | Q(session__group__acronym__in = include) | Q(session__group__parent__acronym__in = include) diff --git a/ietf/templates/meeting/agenda.csv b/ietf/templates/meeting/agenda.csv index c1563f6bc..537a97ace 100644 --- a/ietf/templates/meeting/agenda.csv +++ b/ietf/templates/meeting/agenda.csv @@ -1,7 +1,7 @@ {% load humanize %}{% autoescape off %}{% load ietf_filters %}"Date","Start","End","Session","Room","Area","Acronym","Type","Description","Session ID","Agenda","Slides" -{% for item in schedule.assignments.all.distinct %}{% if item.timeslot.type.slug == "break" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","Break","{{ schedule.meeting.break_area}}","","","","{{ item.timeslot.name }}","b{{ item.timeslot.pk }}","","" +{% for item in filtered_assignments.all.distinct %}{% if item.timeslot.type.slug == "break" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","Break","{{ schedule.meeting.break_area}}","","","","{{ item.timeslot.name }}","b{{ item.timeslot.pk }}","","" {% endif %}{% if item.timeslot.type.slug == "reg" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","{{ item.timeslot.type.name }}","{{ schedule.meeting.reg_area }}","","","","{{ item.timeslot.name }}","r{{item.timeslot.pk}}","","" {% endif %}{% if item.timeslot.type.slug == "other" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","None","{{ item.timeslot.location.name }}","","{{ item.session.group.acronym }}","{% if item.session.group.parent %}{{item.session.group.parent.acronym|upper}}{% endif %}","{{ item.session.name }}","{{item.session.pk}}","","" {% endif %}{% if item.timeslot.type.slug == "plenary" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","{{ item.session.name }}","{{ item.timeslot.location.name }}","","{{ item.session.group.acronym }}","","{{ item.session.name }}","{{item.session.pk}}","{% if item.session.agenda %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/agenda/{{ item.session.agenda.external_url }}{% endif %}","{% if item.session.slides %}{% for slide in item.session.slides %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/slides/{{ slide.external_url }}{% if not forloop.last %}|{% endif %}{% endfor %}{% endif %}" {% endif %}{% if item.timeslot.type.slug == "session" and item.session.group %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","{{ item.timeslot.name }}","{{ item.timeslot.location.name }}","{{ item.session.group.parent.acronym|upper }}","{{ item.session.group.acronym }}","{{ item.session.type }}","{{ item.session.group.name }}","{{ item.session.pk}}","{% if item.session.agenda %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/agenda/{{ item.session.agenda.external_url }}{% endif %}","{% if item.session.slides %}{% for slide in item.session.slides %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/slides/{{ slide.external_url }}{% if not forloop.last %}|{% endif %}{% endfor %}{% endif %}" -{% endif %}{% endfor %}{% endautoescape %} \ No newline at end of file +{% endif %}{% endfor %}{% endautoescape %} diff --git a/ietf/templates/meeting/agenda.html b/ietf/templates/meeting/agenda.html index 7d59a8384..1019d72dd 100644 --- a/ietf/templates/meeting/agenda.html +++ b/ietf/templates/meeting/agenda.html @@ -142,7 +142,7 @@ You can customize the agenda below to show only selected working group sessions. {% if schedule.meeting.agenda_note %}

{{ schedule.meeting.agenda_note|safe }}

{% endif %} -{% for item in schedule.assignments.all %} +{% for item in filtered_assignments.all %} {% ifchanged %}
diff --git a/ietf/templates/meeting/agenda.txt b/ietf/templates/meeting/agenda.txt index fabc00145..2601c2de0 100644 --- a/ietf/templates/meeting/agenda.txt +++ b/ietf/templates/meeting/agenda.txt @@ -8,7 +8,7 @@ {% filter center:72 %}Updated {{ 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 %} -{% for item in schedule.assignments.all.distinct %}{% ifchanged %} +{% for item in filtered_assignments.all.distinct %}{% ifchanged %} {{ item.timeslot.time|date:"l"|upper }}, {{ item.timeslot.time|date:"F j, Y" }} diff --git a/ietf/templates/meeting/week-view.html b/ietf/templates/meeting/week-view.html index 28b9f65cd..4d79193f7 100644 --- a/ietf/templates/meeting/week-view.html +++ b/ietf/templates/meeting/week-view.html @@ -9,7 +9,7 @@ var items = new Array(); {% autoescape off %} {% for slot in timeslots %} {% if slot.type.name in render_types %} -items.push({key:"{{slot.pk}}",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}}",{% if slot.session.group.acronym %} wg:"{{slot.session.group.acronym}}",{%endif%}{% else %}{% if slot.type.name == "Break" %}name:"{{slot.name}}", area:"break", wg:"break",{% else %}name:"{{slot.session.group.name}}{%if slot.session.group.state.name = "BOF"%} BOF{%endif%}",wg:"{{slot.session.group.acronym}}",state:"{{slot.session.group.state}}",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:"{{slot.session.agenda.get_absolute_url}}"{% endif %} });{% endif %}{% endfor %} +items.push({key:"{{slot.pk}}",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|escapejs}}",{% if slot.session.group.acronym %} wg:"{{slot.session.group.acronym}}",{%endif%}{% else %}{% if slot.type.name == "Break" %}name:"{{slot.name}}", area:"break", wg:"break",{% else %}name:"{{slot.session.group.name|escapejs}}{%if slot.session.group.state.name = "BOF"%} BOF{%endif%}",wg:"{{slot.session.group.acronym}}",state:"{{slot.session.group.state}}",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:"{{slot.session.agenda.get_absolute_url}}"{% endif %} });{% endif %}{% endfor %} {% endautoescape %} /* Saturday events need to be moved to the day -1 */