From 4a453281ea571468f1bd4d314790243309a19828 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Fri, 15 Jan 2016 17:09:08 +0000 Subject: [PATCH 1/3] Simplified meeting.session_details. Shows all sessions for a meeting on one page instead of having a page per session. Removes the by-date, by-weekday, by-sequence mechanic. - Legacy-Id: 10701 --- ietf/meeting/urls.py | 4 -- ietf/meeting/views.py | 56 +++++---------------- ietf/templates/meeting/session_details.html | 24 ++++----- ietf/templates/meeting/session_list.html | 16 ------ 4 files changed, 24 insertions(+), 76 deletions(-) delete mode 100644 ietf/templates/meeting/session_list.html diff --git a/ietf/meeting/urls.py b/ietf/meeting/urls.py index 28f3bb5f5..8b7ff00f9 100644 --- a/ietf/meeting/urls.py +++ b/ietf/meeting/urls.py @@ -61,10 +61,6 @@ urlpatterns = patterns('', (r'^(?P\d+)/session/(?P\d+)/constraints.json', ajax.session_constraints), (r'^(?P\d+)/session/(?P[A-Za-z0-9_\-\+]+)/$', views.session_details), - (r'^(?P\d+)/session/(?P[A-Za-z0-9_\-\+]+)/(?P\d+)/$', views.session_details), - (r'^(?P\d+)/session/(?P[A-Za-z0-9_\-\+]+)/(?P[a-zA-Z]+)/$', views.session_details), - (r'^(?P\d+)/session/(?P[A-Za-z0-9_\-\+]+)/(?P\d{4}-\d{2}-\d{2}(-\d{4})?)/$', views.session_details), - (r'^(?P\d+)/session/(?P[A-Za-z0-9_\-\+]+)/(?P\d{4}-\d{2}-\d{2}(-\d{4})?)/(?P\d+)/$', views.session_details), (r'^(?P\d+)/constraint/(?P\d+).json', ajax.constraint_json), (r'^(?P\d+).json$', ajax.meeting_json), diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 528402809..d155ff228 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -824,30 +824,13 @@ def meeting_requests(request, num=None): {"meeting": meeting, "sessions":sessions, "groups_not_meeting": groups_not_meeting}) -def session_details(request, num, acronym, date=None, week_day=None, seq=None): +def session_details(request, num, acronym ): meeting = get_meeting(num) sessions = Session.objects.filter(meeting=meeting,group__acronym=acronym,type__in=['session','plenary','other']) if not sessions: sessions = Session.objects.filter(meeting=meeting,short=acronym) - if date: - if len(date)==15: - start = datetime.datetime.strptime(date,"%Y-%m-%d-%H%M") - sessions = sessions.filter(timeslotassignments__schedule=meeting.agenda,timeslotassignments__timeslot__time=start) - else: - start = datetime.datetime.strptime(date,"%Y-%m-%d").date() - end = start+datetime.timedelta(days=1) - sessions = sessions.filter(timeslotassignments__schedule=meeting.agenda,timeslotassignments__timeslot__time__range=(start,end)) - - if week_day: - try: - dow = ['sun','mon','tue','wed','thu','fri','sat'].index(week_day.lower()[:3]) + 1 - except ValueError: - raise Http404 - sessions = sessions.filter(timeslotassignments__schedule=meeting.agenda,timeslotassignments__timeslot__time__week_day=dow) - - def sort_key(session): official_sessions = session.timeslotassignments.filter(schedule=session.meeting.agenda) if official_sessions: @@ -857,34 +840,19 @@ def session_details(request, num, acronym, date=None, week_day=None, seq=None): sessions = sorted(sessions,key=sort_key) - if seq: - iseq = int(seq) - 1 - if not iseq in range(0,len(sessions)): - raise Http404 - else: - sessions= [sessions[iseq]] - if not sessions: raise Http404 - if len(sessions)==1: - session = sessions[0] - scheduled_time = "Not yet scheduled" + for session in sessions: + ss = session.timeslotassignments.filter(schedule=meeting.agenda).order_by('timeslot__time') - if ss: - scheduled_time = ','.join(x.timeslot.time.strftime("%A %b-%d %H%M") for x in ss) + session.time = ', '.join(x.timeslot.time.strftime("%A %b-%d %H%M") for x in ss) if ss else 'Not yet scheduled' + # TODO FIXME Deleted materials shouldn't be in the sessionpresentation_set - filtered_sessionpresentation_set = [p for p in session.sessionpresentation_set.all() if p.document.get_state_slug(p.document.type_id)!='deleted'] - return render(request, "meeting/session_details.html", - { 'session':sessions[0] , - 'meeting' :meeting , - 'acronym' :acronym, - 'time': scheduled_time, - 'filtered_sessionpresentation_set': filtered_sessionpresentation_set - }) - else: - return render(request, "meeting/session_list.html", - { 'sessions':sessions , - 'meeting' :meeting , - 'acronym' :acronym, - }) + session.filtered_sessionpresentation_set = [p for p in session.sessionpresentation_set.all() if p.document.get_state_slug(p.document.type_id)!='deleted'] + + return render(request, "meeting/session_details.html", + { 'sessions':sessions , + 'meeting' :meeting , + 'acronym' :acronym, + }) diff --git a/ietf/templates/meeting/session_details.html b/ietf/templates/meeting/session_details.html index fe86627c6..3952faef6 100644 --- a/ietf/templates/meeting/session_details.html +++ b/ietf/templates/meeting/session_details.html @@ -6,20 +6,20 @@ {% block content %} {% origin %} -

{{ meeting }} : {{ acronym }} : {{ time }}

+

{{ meeting }} : {{ acronym }}

- {% if session.name %} -

{{ session.name }}

- {% endif %} + {% for session in sessions %} +

{{ session.time }}{% if session.name %} : {{ session.name }}{% endif %}

- {% if filtered_sessionpresentation_set %} -

Materials:

+ {% if session.filtered_sessionpresentation_set %} +

Materials:

- - {% endif %} + + {% endif %} + {% endfor %} {% endblock %} diff --git a/ietf/templates/meeting/session_list.html b/ietf/templates/meeting/session_list.html deleted file mode 100644 index 13715f6fb..000000000 --- a/ietf/templates/meeting/session_list.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} - -{% block title %}{{ meeting }} : {{ acronym }}{% endblock %} - -{% block content %} - {% origin %} -

{{ meeting }} : {{ acronym }}

- -
    - {% for session in sessions %} -
  • {{session}}
  • - {% endfor %} -
-{% endblock %} From 1a9401a72fffa28cc3e6246527372e1deea08ee1 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Tue, 19 Jan 2016 22:41:21 +0000 Subject: [PATCH 2/3] preparing to merge forward - Legacy-Id: 10715 --- ietf/group/info.py | 47 +++++++++++++++++++ ietf/group/urls.py | 1 - ietf/group/urls_info_details.py | 1 + ietf/meeting/models.py | 7 ++- ietf/templates/group/meetings-row.html | 27 +++++++++++ ietf/templates/group/meetings.html | 50 +++++++++++++++++++++ ietf/templates/meeting/session_details.html | 11 +++-- 7 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 ietf/templates/group/meetings-row.html create mode 100644 ietf/templates/group/meetings.html diff --git a/ietf/group/info.py b/ietf/group/info.py index 8a9f5c564..69e3a4046 100644 --- a/ietf/group/info.py +++ b/ietf/group/info.py @@ -36,6 +36,7 @@ import os import itertools import re from tempfile import mkstemp +import datetime from collections import OrderedDict from django.shortcuts import render, redirect @@ -333,6 +334,8 @@ def construct_group_menu_context(request, group, selected, group_type, others): entries.append(("About", urlreverse("group_about", kwargs=kwargs))) if group.features.has_materials and get_group_materials(group).exists(): entries.append(("Materials", urlreverse("ietf.group.info.materials", kwargs=kwargs))) + if group.type_id in ('rg','wg'): + entries.append(("Meetings", urlreverse("ietf.group.info.meetings", kwargs=kwargs))) entries.append(("Email expansions", urlreverse("ietf.group.info.email", kwargs=kwargs))) entries.append(("History", urlreverse("ietf.group.info.history", kwargs=kwargs))) if group.features.has_documents: @@ -714,3 +717,47 @@ def email_aliases(request, acronym=None, group_type=None): return render(request,'group/email_aliases.html',{'aliases':aliases,'ietf_domain':settings.IETF_DOMAIN,'group':group}) +def meetings(request, acronym=None, group_type=None): + group = get_group_or_404(acronym,group_type) if acronym else None + + four_years_ago = datetime.datetime.now()-datetime.timedelta(days=4*365) + + sessions = group.session_set.filter(status__in=['sched','schedw','appr','canceled'],meeting__date__gt=four_years_ago) + + def sort_key(session): + if session.meeting.type.slug=='ietf': + official_sessions = session.timeslotassignments.filter(schedule=session.meeting.agenda) + if official_sessions: + return official_sessions.first().timeslot.time + elif session.meeting.date: + return datetime.datetime.combine(session.meeting.date,datetime.datetime.min.time()) + else: + return session.requested + else: + # TODO: use timeslots for interims once they have them + return datetime.datetime.combine(session.meeting.date,datetime.datetime.min.time()) + + for s in sessions: + s.time=sort_key(s) + + sessions = sorted(sessions,key=lambda s:s.time,reverse=True) + + today = datetime.date.today() + future = [] + in_progress = [] + past = [] + for s in sessions: + if s.meeting.date > today: + future.append(s) + elif s.meeting.end_date() >= today: + in_progress.append(s) + else: + past.append(s) + + return render(request,'group/meetings.html', + construct_group_menu_context(request, group, "meetings", group_type, { + 'group':group, + 'future':future, + 'in_progress':in_progress, + 'past':past, + })) diff --git a/ietf/group/urls.py b/ietf/group/urls.py index c438fea80..30ef24225 100644 --- a/ietf/group/urls.py +++ b/ietf/group/urls.py @@ -10,7 +10,6 @@ urlpatterns = patterns('', (r'^chartering/create/(?P(wg|rg))/$', 'ietf.group.edit.edit', {'action': "charter"}, "group_create"), (r'^concluded/$', 'ietf.group.info.concluded_groups'), (r'^email-aliases/$', 'ietf.group.info.email_aliases'), - (r'^(?P[a-zA-Z0-9-._]+)/$', 'ietf.group.info.group_home', None, "group_home"), (r'^(?P[a-zA-Z0-9-._]+)/', include('ietf.group.urls_info_details')), ) diff --git a/ietf/group/urls_info_details.py b/ietf/group/urls_info_details.py index c0a97e9eb..9f0bc74b6 100644 --- a/ietf/group/urls_info_details.py +++ b/ietf/group/urls_info_details.py @@ -9,6 +9,7 @@ urlpatterns = patterns('', (r'^about/$', 'ietf.group.info.group_about', None, 'group_about'), (r'^history/$','ietf.group.info.history'), (r'^email/$', 'ietf.group.info.email'), + (r'^meetings/$', 'ietf.group.info.meetings'), (r'^deps/dot/$', 'ietf.group.info.dependencies_dot'), (r'^deps/pdf/$', 'ietf.group.info.dependencies_pdf'), (r'^init-charter/', 'ietf.group.edit.submit_initial_charter'), diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index 0629d9155..606cda68c 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -95,7 +95,12 @@ class Meeting(models.Model): return self.date + datetime.timedelta(days=offset) def end_date(self): - return self.get_meeting_date(5) + if self.type.slug == 'ietf': + return self.get_meeting_date(5) + else: + # TODO: Once interims have timeslots assigned, + # look for the last ending timeslot instead + return self.date def get_00_cutoff(self): start_date = datetime.datetime(year=self.date.year, month=self.date.month, day=self.date.day, tzinfo=pytz.utc) diff --git a/ietf/templates/group/meetings-row.html b/ietf/templates/group/meetings-row.html new file mode 100644 index 000000000..1365d2790 --- /dev/null +++ b/ietf/templates/group/meetings-row.html @@ -0,0 +1,27 @@ + + + + + + + + + + + + {% for s in sessions %} + + + + + + + {% endfor %} + +
{% ifchanged s.meeting %}{% if s.meeting.type.slug == 'ietf' %}IETF{% endif %}{{s.meeting.number}}{% endifchanged %} + {% if s.status.slug == "sched" %} + {% if s.meeting.type.slug == 'ietf' %}{{s.time|date:"D M d, Y Hi"}}{% else %}{{s.time|date:"D M d, Y"}}{% endif %} + {% else %} + Not yet scheduled ({{s.status.slug}}) + {% endif %} + {% if s.minutes %}Minutes{% endif %}{% if s.agenda %}Agenda{% endif %}{% if s.meeting.type.slug == 'ietf' %}Materials{% endif %}
diff --git a/ietf/templates/group/meetings.html b/ietf/templates/group/meetings.html new file mode 100644 index 000000000..628a5b340 --- /dev/null +++ b/ietf/templates/group/meetings.html @@ -0,0 +1,50 @@ +{% extends "group/group_base.html" %} +{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% load origin %} + +{% block title %}Meetings{% if group %} for {{group.acronym}}{% endif %}{% endblock %} + +{% block group_content %} +{% origin %} +{% if in_progress %} +
+
+ Meetings in progress +
+
+ {% with in_progress as sessions %} + {% include "group/meetings-row.html" %} + {% endwith %} +
+
+{% endif %} + +{% if future %} +
+
+ Future Meetings +
+
+ {% with future as sessions %} + {% include "group/meetings-row.html" %} + {% endwith %} +
+
+{% endif %} + +{% if past %} +
+
+ Past Meetings +
+
+ {% with past as sessions %} + {% include "group/meetings-row.html" %} + {% endwith %} +
+
+{% endif %} + +
This page shows meetings within the last four years. For earlier meetings, please see the proceedings.
+ +{% endblock %} diff --git a/ietf/templates/meeting/session_details.html b/ietf/templates/meeting/session_details.html index 3952faef6..08925df22 100644 --- a/ietf/templates/meeting/session_details.html +++ b/ietf/templates/meeting/session_details.html @@ -14,11 +14,16 @@ {% if session.filtered_sessionpresentation_set %}

Materials:

-
    + {% for pres in session.filtered_sessionpresentation_set %} -
  • {{ pres.document.name }}-{{ pres.rev }}
  • + + + {% endfor %} - +
    + {{pres.document.title}} ({{ pres.document.name }}-{{ pres.rev }}) + +
    {% endif %} {% endfor %} From 4261c4f54963ebe1935b7a679a9cf0c133c01b96 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Tue, 19 Jan 2016 22:42:07 +0000 Subject: [PATCH 3/3] still preparing to merge forward - Legacy-Id: 10716 --- .../migrations/0016_schedule_ietf88_and_89.py | 23 +++++++++++++++ .../0017_schedule_approved_interims.py | 28 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 ietf/meeting/migrations/0016_schedule_ietf88_and_89.py create mode 100644 ietf/meeting/migrations/0017_schedule_approved_interims.py diff --git a/ietf/meeting/migrations/0016_schedule_ietf88_and_89.py b/ietf/meeting/migrations/0016_schedule_ietf88_and_89.py new file mode 100644 index 000000000..c0bfd1521 --- /dev/null +++ b/ietf/meeting/migrations/0016_schedule_ietf88_and_89.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + +def forward(apps, schema_editor): + Session = apps.get_model('meeting','Session') + assert(Session.objects.filter(meeting__number__in=['88','89'],group__type__in=['ag','iab','rg','wg'],status_id='sched').count() == 0) + Session.objects.filter(meeting__number__in=['88','89'],group__type__in=['ag','iab','rg','wg'],status_id='schedw').update(status_id='sched') + +def reverse(apps, schema_editor): + Session = apps.get_model('meeting','Session') + Session.objects.filter(meeting__number__in=['88','89'],group__type__in=['ag','iab','rg','wg'],status_id='sched').update(status_id='schedw') + +class Migration(migrations.Migration): + + dependencies = [ + ('meeting', '0015_auto_20151102_1845'), + ] + + operations = [ + migrations.RunPython(forward,reverse), + ] diff --git a/ietf/meeting/migrations/0017_schedule_approved_interims.py b/ietf/meeting/migrations/0017_schedule_approved_interims.py new file mode 100644 index 000000000..5576f85a5 --- /dev/null +++ b/ietf/meeting/migrations/0017_schedule_approved_interims.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations +from collections import Counter +import datetime + +affected = ['interim-2010-drinks-1','interim-2010-core-1','interim-2010-behave-1','interim-2010-siprec-1','interim-2010-cuss-1','interim-2010-iri-1','interim-2010-pcp-1','interim-2010-geopriv-1','interim-2010-soc-1','interim-2010-precis-1','interim-2010-mptcp-1','interim-2010-roll-1','interim-2011-sipclf-1','interim-2011-ipsecme-1','interim-2011-siprec-1','interim-2011-alto-1','interim-2011-xmpp-1','interim-2011-precis-1','interim-2011-nfsv4-1','interim-2011-pcp-1','interim-2011-clue-1','interim-2011-oauth-1','interim-2011-rtcweb-1','interim-2011-drinks-1','interim-2011-atoca-1','interim-2011-cuss-1','interim-2011-softwire-1','interim-2011-ppsp-1','interim-2011-homenet-1','interim-2011-mptcp-1','interim-2012-rtcweb-1','interim-2012-drinks-1','interim-2012-sidr-1','interim-2012-clue-1','interim-2012-krb-wg-1','interim-2012-behave-1','interim-2012-bfcpbis-1','interim-2012-mboned-1'] + +def forward(apps, schema_editor): + Session = apps.get_model('meeting','Session') + assert( Counter(Session.objects.filter(meeting__number__in=affected).values_list('status',flat=True)) == Counter({u'appr':38}) ) + Session.objects.filter(meeting__number__in=affected).update(status_id='sched') + +def reverse(apps, schema_editor): + Session = apps.get_model('meeting','Session') + Session.objects.filter(meeting__number__in=affected).update(status_id='appr') + + +class Migration(migrations.Migration): + + dependencies = [ + ('meeting', '0016_schedule_ietf88_and_89'), + ] + + operations = [ + migrations.RunPython(forward,reverse), + ]