From b49a4525951f37b1487f7cd2f137f5090c2e307b Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Mon, 22 Jun 2015 19:33:15 +0000 Subject: [PATCH] Merged in [9651] from rjsparks@nostrum.com: Adds a graphical overview of each day by room for the secretariat to assist with scheduling additional meetings. - Legacy-Id: 9674 Note: SVN reference [9651] has been migrated to Git commit 06a0e2b6481fe909f6620ed951353eaf437321ec --- ietf/meeting/tests_views.py | 7 + ietf/meeting/urls.py | 4 + ietf/meeting/views.py | 56 ++- ietf/templates/meeting/room-view.html | 599 ++++++++++++++++++++++++++ 4 files changed, 664 insertions(+), 2 deletions(-) create mode 100644 ietf/templates/meeting/room-view.html diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index 1e48885b3..88d484b71 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -149,6 +149,13 @@ class MeetingTests(TestCase): self.assertFalse(any([x in r.content for x in ['mars','Test Room']])) self.assertTrue(all([x in r.content for x in ['IESG Breakfast','Breakfast Room']])) + def test_agenda_room_view(self): + meeting = make_meeting_test_data() + url = urlreverse("ietf.meeting.views.room_view",kwargs=dict(num=meeting.number)) + login_testing_unauthorized(self,"secretary",url) + r = self.client.get(url) + self.assertTrue(all([x in r.content for x in ['mars','IESG Breakfast','Test Room','Breakfast Room']])) + def test_session_details(self): meeting = make_meeting_test_data() url = urlreverse("ietf.meeting.views.session_details", kwargs=dict(num=meeting.number, acronym="mars")) diff --git a/ietf/meeting/urls.py b/ietf/meeting/urls.py index 351f3ab5b..8fce21cff 100644 --- a/ietf/meeting/urls.py +++ b/ietf/meeting/urls.py @@ -18,7 +18,9 @@ urlpatterns = patterns('', (r'^agenda/agenda.ics$', views.ical_agenda), (r'^agenda.ics$', views.ical_agenda), (r'^agenda/week-view.html$', views.week_view), + (r'^agenda/room-view.html$', views.room_view), (r'^week-view.html$', views.week_view), + (r'^room-view.html$', views.room_view), (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+)/edit$', views.edit_agenda), (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+)/details$', views.edit_agenda_properties), (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+).(?P.html)?/?$', views.agenda), @@ -48,7 +50,9 @@ urlpatterns = patterns('', (r'^(?P\d+)/agendas$', ajax.agenda_infosurl), (r'^(?P\d+)/agendas.json$', ajax.agenda_infosurl), (r'^(?P\d+)/week-view.html$', views.week_view), + (r'^(?P\d+)/room-view.html$', views.room_view), (r'^(?P\d+)/agenda/week-view.html$', views.week_view), + (r'^(?P\d+)/agenda/room-view.html$', views.room_view), (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-]+)-drafts.pdf$', views.session_draft_pdf), (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-]+)-drafts.tgz$', views.session_draft_tarfile), (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-]+)/?$', views.session_agenda), diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 52c8d7562..1190cde85 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -15,11 +15,10 @@ from django.shortcuts import render, render_to_response, redirect from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404 from django.contrib import messages from django.core.urlresolvers import reverse -from django.db.models import Q +from django.db.models import Q, Min, Max from django.template import RequestContext from django.template.loader import render_to_string from django.conf import settings -from django.db.models import Max from django.forms.models import modelform_factory from django.views.decorators.csrf import ensure_csrf_cookie from django.forms import ModelForm @@ -612,6 +611,59 @@ def week_view(request, num=None): return render_to_response(template, {"timeslots":timeslots,"render_types":["Session","Other","Break","Plenary"]}, context_instance=RequestContext(request)) +@role_required('Secretariat') +def room_view(request, num=None): + meeting = get_meeting(num) + + rooms = meeting.room_set.order_by('functional_name','name') + if rooms.count() == 0: + raise Http404 + + scheduledsessions = meeting.agenda.scheduledsession_set.all() + unavailable = meeting.timeslot_set.filter(type__slug='unavail') + if (unavailable.count() + scheduledsessions.count()) == 0 : + raise Http404 + + earliest = None + latest = None + + if scheduledsessions: + earliest = scheduledsessions.aggregate(Min('timeslot__time'))['timeslot__time__min'] + latest = scheduledsessions.aggregate(Max('timeslot__time'))['timeslot__time__max'] + + if unavailable: + earliest_unavailable = unavailable.aggregate(Min('time'))['time__min'] + if not earliest or ( earliest_unavailable and earliest_unavailable < earliest ): + earliest = earliest_unavailable + latest_unavailable = unavailable.aggregate(Max('time'))['time__max'] + if not latest or ( latest_unavailable and latest_unavailable > latest ): + latest = latest_unavailable + + if not (earliest and latest): + raise Http404 + + base_time = earliest + base_day = datetime.datetime(base_time.year,base_time.month,base_time.day) + + day = base_day + days = [] + while day <= latest : + days.append(day) + day += datetime.timedelta(days=1) + + unavailable = list(unavailable) + for t in unavailable: + t.delta_from_beginning = (t.time - base_time).total_seconds() + t.day = (t.time-base_day).days + + scheduledsessions = list(scheduledsessions) + for ss in scheduledsessions: + ss.delta_from_beginning = (ss.timeslot.time - base_time).total_seconds() + ss.day = (ss.timeslot.time-base_day).days + + template = "meeting/room-view.html" + return render(request, template,{"meeting":meeting,"unavailable":unavailable,"scheduledsessions":scheduledsessions,"rooms":rooms,"days":days}) + def ical_agenda(request, num=None, name=None, ext=None): meeting = get_meeting(num) schedule = get_schedule(meeting, name) diff --git a/ietf/templates/meeting/room-view.html b/ietf/templates/meeting/room-view.html new file mode 100644 index 000000000..05e8d12e0 --- /dev/null +++ b/ietf/templates/meeting/room-view.html @@ -0,0 +1,599 @@ +{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% load origin %}{% origin %} + + + {% comment %} This sets box-sizing: border-box {% endcomment %} + + + + + + +
+ +
+ {% for day in days %} +
Error loading calendar for {{day|date:"D M d"}}
+ {% endfor %} +
+
+