From 0567b3dea257013475fd31afeddeef326078de49 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Fri, 9 Jun 2023 13:41:01 -0400 Subject: [PATCH] fix: /meeting/materials splits out named sessions the same way /meeting/proceedings does (#5715) * fix: /meeting/materials splits out named sessions the same way /meeting/proceedings does * test: Test separation of named sessions in the materials --- ietf/meeting/tests_views.py | 60 ++++++++++ ietf/meeting/views.py | 21 +++- ietf/templates/meeting/group_materials.html | 118 ++++++++------------ ietf/templates/meeting/materials.html | 42 +++---- 4 files changed, 142 insertions(+), 99 deletions(-) diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index 618fbd842..50323a543 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -508,6 +508,66 @@ class MeetingTests(BaseMeetingTestCase): self.do_test_materials(meeting, session) + def test_named_session(self): + """Session with a name should appear separately in the materials""" + meeting = MeetingFactory(type_id='ietf', number='100') + meeting.importantdate_set.create(name_id='revsub',date=date_today() + datetime.timedelta(days=20)) + group = GroupFactory() + plain_session = SessionFactory(meeting=meeting, group=group) + named_session = SessionFactory(meeting=meeting, group=group, name='I Got a Name') + for doc_type_id in ('agenda', 'minutes', 'bluesheets', 'slides', 'draft'): + # Set up sessions materials that will have distinct URLs for each session. + # This depends on settings.MEETING_DOC_HREFS and may need updating if that changes. + SessionPresentationFactory( + session=plain_session, + document__type_id=doc_type_id, + document__uploaded_filename=f'upload-{doc_type_id}-plain', + document__external_url=f'external_url-{doc_type_id}-plain', + ) + SessionPresentationFactory( + session=named_session, + document__type_id=doc_type_id, + document__uploaded_filename=f'upload-{doc_type_id}-named', + document__external_url=f'external_url-{doc_type_id}-named', + ) + + url = urlreverse('ietf.meeting.views.materials', kwargs={'num': meeting.number}) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + + plain_label = q(f'div#{group.acronym}') + self.assertEqual(plain_label.text(), group.acronym) + plain_row = plain_label.closest('tr') + self.assertTrue(plain_row) + + named_label = q(f'div#{slugify(named_session.name)}') + self.assertEqual(named_label.text(), named_session.name) + named_row = named_label.closest('tr') + self.assertTrue(named_row) + + for material in (sp.document for sp in plain_session.sessionpresentation_set.all()): + if material.type_id == 'draft': + expected_url = urlreverse( + 'ietf.doc.views_doc.document_main', + kwargs={'name': material.canonical_name()}, + ) + else: + expected_url = material.get_href(meeting) + self.assertTrue(plain_row.find(f'a[href="{expected_url}"]')) + self.assertFalse(named_row.find(f'a[href="{expected_url}"]')) + + for material in (sp.document for sp in named_session.sessionpresentation_set.all()): + if material.type_id == 'draft': + expected_url = urlreverse( + 'ietf.doc.views_doc.document_main', + kwargs={'name': material.canonical_name()}, + ) + else: + expected_url = material.get_href(meeting) + self.assertFalse(plain_row.find(f'a[href="{expected_url}"]')) + self.assertTrue(named_row.find(f'a[href="{expected_url}"]')) + @override_settings(MEETING_MATERIALS_SERVE_LOCALLY=True) def test_meeting_materials_non_utf8(self): meeting = make_meeting_test_data() diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 873bdad75..eded3c438 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -155,7 +155,7 @@ def materials(request, num=None): ).distinct().select_related('meeting__schedule', 'group__state', 'group__parent')).order_by('group__acronym') plenaries = sessions.filter(name__icontains='plenary') - ietf = sessions.filter(group__parent__type__slug = 'area').exclude(group__acronym='edu') + ietf = sessions.filter(group__parent__type__slug = 'area').exclude(group__acronym='edu').order_by('group__parent__acronym', 'group__acronym') irtf = sessions.filter(group__parent__acronym = 'irtf') training = sessions.filter(group__acronym__in=['edu','iaoc'], type_id__in=['regular', 'other', ]) iab = sessions.filter(group__parent__acronym = 'iab') @@ -179,12 +179,26 @@ def materials(request, num=None): for type_name in ProceedingsMaterialTypeName.objects.all() ] + plenaries, _ = organize_proceedings_sessions(plenaries) + irtf, _ = organize_proceedings_sessions(irtf) + training, _ = organize_proceedings_sessions(training) + iab, _ = organize_proceedings_sessions(iab) + other, _ = organize_proceedings_sessions(other) + + ietf_areas = [] + for area, area_sessions in itertools.groupby( + ietf, + key=lambda s: s.group.parent + ): + meeting_groups, not_meeting_groups = organize_proceedings_sessions(area_sessions) + ietf_areas.append((area, meeting_groups, not_meeting_groups)) + with timezone.override(meeting.tz()): return render(request, "meeting/materials.html", { 'meeting': meeting, 'proceedings_materials': proceedings_materials, 'plenaries': plenaries, - 'ietf': ietf, + 'ietf_areas': ietf_areas, 'training': training, 'irtf': irtf, 'iab': iab, @@ -3671,6 +3685,7 @@ def organize_proceedings_sessions(sessions): if s.current_status != 'notmeet' or s.sessionpresentation_set.exists(): by_name[s.name].append(s) # for notmeet, only include sessions with materials for sess_name, ss in by_name.items(): + session = ss[0] if ss else None def _format_materials(items): """Format session/material for template @@ -3697,6 +3712,7 @@ def organize_proceedings_sessions(sessions): entry = { 'group': group, 'name': sess_name, + 'session': session, 'canceled': all_canceled, 'has_materials': s.sessionpresentation_set.exists(), 'agendas': _format_materials((s, s.agenda()) for s in ss), @@ -3705,6 +3721,7 @@ def organize_proceedings_sessions(sessions): 'recordings': _format_materials((s, s.recordings()) for s in ss), 'slides': _format_materials((s, s.slides()) for s in ss), 'drafts': _format_materials((s, s.drafts()) for s in ss), + 'last_update': session.last_update if hasattr(session, 'last_update') else None } if is_meeting: meeting_groups.append(entry) diff --git a/ietf/templates/meeting/group_materials.html b/ietf/templates/meeting/group_materials.html index 8cdc9fc54..03ebecccc 100644 --- a/ietf/templates/meeting/group_materials.html +++ b/ietf/templates/meeting/group_materials.html @@ -5,120 +5,98 @@ {% load tz %} - {% if session.name %} -
{{ session.name }}
+ {% if entry.name %} +
{{ entry.name }}
{% else %} -
- {{ session.group.acronym }} + - {% if session.group.state.slug == "bof" %} - {{ session.group.state.slug|upper }} + {% if entry.group.state.slug == "bof" %} + {{ entry.group.state.slug|upper }} {% endif %} {% endif %} - {% if session.all_meeting_sessions_cancelled %} + {% if entry.canceled %} Session cancelled {% else %} - {% if session.all_meeting_agendas %} - {% for agenda in session.all_meeting_agendas %} - {% if session.all_meeting_agendas|length == 1 %} - {% if agenda.time > old %} - - {% endif %} - Agenda -
- {% else %} - - Agenda {{ agenda.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i" }} - -
- {% endif %} - {% endfor %} - {% else %} + {% for agenda in entry.agendas %} + {% if entry.agendas|length == 1 and agenda.time > old %} + + {% endif %} + + Agenda {% if agenda.time %}{{agenda.time|date:"D G:i"}}{% endif %} + +
+ {% empty %} {% if show_agenda == "True" %}No agenda{% endif %} - {% endif %} + {% endfor %} - {% if session.all_meeting_minutes %} - {% if session.all_meeting_minutes|length == 1 %} - Minutes -
- {% else %} - {% for minutes in session.all_meeting_minutes %} - - Minutes {{ minutes.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i" }} - -
- {% endfor %} - {% endif %} - {% else %} + {% for minutes in entry.minutes %} + + Minutes {% if minutes.time %}{{minutes.time|date:"D G:i"}}{% endif %} + +
+ {% empty %} {% if show_agenda == "True" %}No minutes{% endif %} - {% endif %} - {% if session.type_id == 'regular' and show_agenda == "True" %} - {% if session.all_meeting_bluesheets %} - {% if session.all_meeting_bluesheets|length == 1 %} - Bluesheets -
- {% else %} - {% for bluesheets in session.all_meeting_bluesheets %} - - Bluesheets -
- {{ bluesheets.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i" }} -
-
- {% endfor %} - {% endif %} - {% else %} + {% endfor %} + {% if entry.session.type_id == 'regular' and show_agenda == "True" %} + {% for bluesheet in entry.bluesheets %} + + Bluesheets + {% if bluesheet.time %} +
{{ bluesheet.time|date:"D G:i" }} + {% endif %} +
+
+ {% empty %} No bluesheets - {% endif %} + {% endfor %} {% endif %} - {% with session.all_meeting_slides as slides %} - {% for slide in slides %} + {% for slide in entry.slides %} {% if slide.time > old %} {% endif %} - {{ slide.title|clean_whitespace }} + {{ slide.material.title|clean_whitespace }}
{% empty %} No slides {% endfor %} - {% endwith %} - {% with session.all_meeting_drafts as drafts %} - {% for draft in drafts %} + {% for draft in entry.drafts %} {% if draft.time > old %} {% endif %} - {{ draft.name }} + + {{ draft.material.canonical_name }} +
{% empty %} No Internet-Drafts {% endfor %} - {% endwith %} - {% if session.last_update %} - {{ session.last_update|utc|date:"Y-m-d" }} + {% if entry.last_update %} + {{ entry.last_update|utc|date:"Y-m-d" }}
- {{ session.last_update|utc|date:"H:i:s" }} UTC + {{ entry.last_update|utc|date:"H:i:s" }} UTC {% endif %} {% if user|has_role:"Secretariat" or user_groups %} - {% if user|has_role:"Secretariat" or session.group in user_groups %} -
{% include "meeting/edit_materials_button.html" %}
+ {% if user|has_role:"Secretariat" or entry.group in user_groups %} +
{% include "meeting/edit_materials_button.html" with session=entry.session only %}
{% endif %} {% endif %} {% endif %} - \ No newline at end of file + diff --git a/ietf/templates/meeting/materials.html b/ietf/templates/meeting/materials.html index bd91d85b4..667ce7235 100644 --- a/ietf/templates/meeting/materials.html +++ b/ietf/templates/meeting/materials.html @@ -52,17 +52,16 @@ - {% for session in plenaries %} + {% for entry in plenaries %} {% include "meeting/group_materials.html" %} {% endfor %} {% endif %} - {% regroup ietf|dictsort:"group.parent.acronym" by group.parent.name as areas %} - {% for sessions in areas %} -

- {{ sessions.list.0.group.parent.acronym|upper }} {{ sessions.grouper }} + {% for area, meeting_groups, not_meeting_groups in ietf_areas %} +

+ {{ area.acronym|upper }} {{ area.name }}

@@ -79,10 +78,8 @@ - {% for session in sessions.list|dictsort:"group.acronym" %} - {% ifchanged session.group.acronym %} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in meeting_groups %} + {% include "meeting/group_materials.html" %} {% endfor %}
@@ -110,11 +107,8 @@ - {% for session in training %} - {% ifchanged %} - {# TODO: Find a better way to represent purposed sessions in both materials and proceedings #} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in training %} + {% include "meeting/group_materials.html" %} {% endfor %} @@ -152,10 +146,8 @@ - {% for session in iab %} - {% ifchanged session.group.acronym %} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in iab %} + {% include "meeting/group_materials.html" %} {% endfor %} @@ -192,10 +184,8 @@ - {% for session in irtf|dictsort:"group.acronym" %} - {% ifchanged session.group.acronym %} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in irtf %} + {% include "meeting/group_materials.html" %} {% endfor %} @@ -231,10 +221,8 @@ - {% for session in other|dictsort:"group.acronym" %} - {% ifchanged session.group.acronym %} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in other %} + {% include "meeting/group_materials.html" %} {% endfor %} @@ -245,4 +233,4 @@ {% block js %} -{% endblock %} \ No newline at end of file +{% endblock %}