diff --git a/ietf/meeting/migrations/0029_reconstruct_bluesheet_docs_95through96.py b/ietf/meeting/migrations/0029_reconstruct_bluesheet_docs_95through96.py new file mode 100644 index 000000000..5e3b662a3 --- /dev/null +++ b/ietf/meeting/migrations/0029_reconstruct_bluesheet_docs_95through96.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import os + +from django.db import migrations +from django.conf import settings + + +def official_time(session): + return session.timeslotassignments.filter(schedule=session.meeting.agenda).first() + +def forward(apps, schema_editor): + Document = apps.get_model('doc','Document') + State = apps.get_model('doc','State') + Group = apps.get_model('group','Group') + Meeting = apps.get_model('meeting', 'Meeting') + + active = State.objects.get(type_id='bluesheets',slug='active') + + for num in [95, 96]: + mtg = Meeting.objects.get(number=num) + bs_path = '%s/bluesheets/'% os.path.join(settings.AGENDA_PATH,mtg.number) + bs_files = os.listdir(bs_path) + bs_acronyms = set([x[14:-7] for x in bs_files]) + group_acronyms = set([x.group.acronym for x in mtg.session_set.all() if official_time(x) and x.group.type_id in ['wg','rg','ag'] and not x.agenda_note.lower().startswith('cancel')]) + + if bs_acronyms-group_acronyms: + print "Warning IETF%s : groups that have bluesheets but did not appear to meet: %s"%(num,list(bs_acronyms-group_acronyms)) + if group_acronyms-bs_acronyms: + print "Warning IETF%s : groups that appeared to meet but have no bluesheets: %s"%(num,list(group_acronyms-bs_acronyms)) + + for acronym in group_acronyms & bs_acronyms: + group = Group.objects.get(acronym=acronym) + bs = sorted([x for x in bs_files if '-%s-'%acronym in x]) + bs_count = len(bs) + sess = sorted([ x for x in mtg.session_set.filter(group__acronym=acronym) if not x.agenda_note.lower().startswith('cancel')], + key = lambda x: official_time(x).timeslot.time) + sess_count = len(sess) + if bs_count != sess_count: + print "Warning IETF%s: %s : different number of bluesheets (%d) than sessions (%d)"%(num,acronym,bs_count,sess_count) + numdocs = min(bs_count,sess_count) + for n in range(numdocs): + doc = Document.objects.create( + name=bs[n][:-4], + type_id='bluesheets', + title='Bluesheets IETF%d : %s : %s ' % (num,acronym,official_time(sess[n]).timeslot.time.strftime('%a %H:%M')), + group=group, + rev='00', + external_url=bs[n], + ) + doc.states.add(active) + sess[n].sessionpresentation_set.create(document=doc,rev='00') + +def reverse(apps, schema_editor): + Document = apps.get_model('doc','Document') + Document.objects.filter(type_id='bluesheets',sessionpresentation__session__meeting__number_in=[95,96]).exclude(group__acronym='openpgp').delete() + +class Migration(migrations.Migration): + + dependencies = [ + ('meeting', '0028_add_audio_stream_data'), + ('doc', '0012_auto_20160207_0537'), + ('group','0008_auto_20160505_0523'), + ] + + operations = [ + migrations.RunPython(forward,reverse) + ] diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index 91371c8f9..a7fdcdc0a 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -1010,6 +1010,9 @@ class Session(models.Model): def recordings(self): return list(self.get_material("recording", only_one=False)) + def bluesheets(self): + return list(self.get_material("bluesheets", only_one=False)) + def slides(self): if not hasattr(self, "_slides_cache"): self._slides_cache = list(self.get_material("slides", only_one=False)) @@ -1018,9 +1021,28 @@ class Session(models.Model): def drafts(self): return list(self.materials.filter(type='draft')) + def all_meeting_sessions_for_group(self): + sessions = [s for s in self.meeting.session_set.filter(group=self.group,type=self.type) if s.official_timeslotassignment()] + return sorted(sessions, key = lambda x: x.official_timeslotassignment().timeslot.time) + + def all_meeting_recordings(self): + recordings = [] + sessions = self.all_meeting_sessions_for_group() + for session in sessions: + recordings.extend(session.recordings()) + return recordings + + def all_meeting_bluesheets(self): + bluesheets = [] + sessions = self.all_meeting_sessions_for_group() + for session in sessions: + bluesheets.extend(session.bluesheets()) + return bluesheets + def all_meeting_drafts(self): drafts = [] - for session in self.meeting.session_set.filter(group=self.group): + sessions = self.all_meeting_sessions_for_group() + for session in sessions: drafts.extend(session.drafts()) return drafts diff --git a/ietf/meeting/templatetags/proceedings_filters.py b/ietf/meeting/templatetags/proceedings_filters.py new file mode 100644 index 000000000..4f6bac5f0 --- /dev/null +++ b/ietf/meeting/templatetags/proceedings_filters.py @@ -0,0 +1,14 @@ +from django import template + +register = template.Library() + +@register.filter +def hack_recording_title(recording,add_timestamp=False): + + if recording.title.startswith('Audio recording for') or recording.title.startswith('Video recording for'): + hacked_title = recording.title[:15] + if add_timestamp: + hacked_title += ' '+recording.sessionpresentation_set.first().session.official_timeslotassignment().timeslot.time.strftime("%a %H:%M") + return hacked_title + else: + return recording.title diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index dd14598f7..10087f2a2 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -1525,6 +1525,10 @@ def floor_plan(request, num=None, floor=None, ): def proceedings(request, num=None): meeting = get_meeting(num) + + if meeting.number <= 64 or not meeting.agenda.assignments.exists(): + return HttpResponseRedirect( 'https://www.ietf.org/proceedings/%s' % num ) + begin_date = meeting.get_submission_start_date() cut_off_date = meeting.get_submission_cut_off_date() cor_cut_off_date = meeting.get_submission_correction_date() diff --git a/ietf/templates/meeting/group_proceedings.html b/ietf/templates/meeting/group_proceedings.html new file mode 100644 index 000000000..386a2be1d --- /dev/null +++ b/ietf/templates/meeting/group_proceedings.html @@ -0,0 +1,82 @@ +{# Copyright The IETF Trust 2015, All Rights Reserved #}{% load origin %}{% origin %} +{% load ietf_filters %} +{% load proceedings_filters %} + + + {% comment %} + + + + {% endcomment %} + {% if session.name %} +
{{ session.name }}
+ {% else %} +
{{session.group.acronym}}
+ {% if session.group.state.slug == "bof" %} + {{ session.group.state.slug|upper }} + {% endif %} + {% endif %} + + + {% if session.status_id == 'canceled' %} + Session cancelled + {% else %} + + {% if session.agenda %} + Agenda
+ {% else %} + {% if show_agenda == "True" %} + No agenda
+ {% endif %} + {% endif %} + {% if session.minutes %} + Minutes
+ {% else %} + {% if show_agenda == "True" %} + No minutes
+ {% endif %} + {% endif %} + {% if session.all_meeting_bluesheets %} + {% if session.all_meeting_bluesheets|length == 1 %} + Bluesheets
+ {% else %} + {% for bs in session.all_meeting_bluesheets %} + Bluesheets {{bs.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i"}}
+ {% endfor %} + {% endif %} + {% endif %} + + + + {% if session.all_meeting_sessions_for_group|length == 1 %} + {% for rec in session.all_meeting_recordings %} + {{rec|hack_recording_title:False}}
+ {% endfor %} + {% else %} + {% for rec in session.all_meeting_recordings %} + {{rec|hack_recording_title:True}}
+ {% endfor %} + {% endif %} + + + {% with session.slides as slides %} + {% for slide in slides %} + {{ slide.title|clean_whitespace }} +
+ {% empty %} + No slides + {% endfor %} + {% endwith %} + + + {% with session.all_meeting_drafts as drafts %} + {% for draft in drafts %} + {{ draft.canonical_name }}
+ {% empty %} + No drafts + {% endfor %} + {% endwith %} + + {% endif %} + + diff --git a/ietf/templates/meeting/proceedings.html b/ietf/templates/meeting/proceedings.html index 4eff2d783..3676741f5 100644 --- a/ietf/templates/meeting/proceedings.html +++ b/ietf/templates/meeting/proceedings.html @@ -22,6 +22,11 @@

This page is under construction

+ {% if meeting_num|add:0 <= 96 %} +

+ These are not the official proceedings for IETF{{meeting_num}}. This page shows what would be generated by the new automatic proceedings generator for that meeting. The official proceedings are located at https://www.ietf.org/proceedings/{{meeting_num}} +

+ {% endif %} {# cache for 15 minutes, as long as there's no proceedings activity. takes 4-8 seconds to generate. #} {% load cache %} @@ -35,16 +40,16 @@ Group - Agenda - Minutes - Slides + Artifacts + Recordings + Slides Drafts {% for session in plenaries %} - {% include "meeting/group_materials.html" %} + {% include "meeting/group_proceedings.html" %} {% endfor %} @@ -58,9 +63,9 @@ Group - Agenda - Minutes - Slides + Artifacts + Recordings + Slides Drafts @@ -68,7 +73,7 @@ {% for session in sessions.list|dictsort:"group.acronym" %} {% ifchanged session.group.acronym %} - {% include "meeting/group_materials.html" %} + {% include "meeting/group_proceedings.html" %} {% endifchanged %} {% endfor %} @@ -83,9 +88,9 @@ Group - Agenda - Minutes - Slides + Artifacts + Recordings + Slides Drafts @@ -93,7 +98,7 @@ {% for session in training %} {% ifchanged %} - {% include "meeting/group_materials.html" %} + {% include "meeting/group_proceedings.html" %} {% endifchanged %} {% endfor %} @@ -108,9 +113,9 @@ Group - Agenda - Minutes - Slides + Artifacts + Recordings + Slides Drafts @@ -118,7 +123,7 @@ {% for session in iab %} {% ifchanged %} - {% include "meeting/group_materials.html" %} + {% include "meeting/group_proceedings.html" %} {% endifchanged %} {% endfor %} @@ -132,9 +137,9 @@ Group - Agenda - Minutes - Slides + Artifacts + Recordings + Slides Drafts @@ -142,7 +147,7 @@ {% for session in irtf|dictsort:"group.acronym" %} {% ifchanged %} - {% include "meeting/group_materials.html" %} + {% include "meeting/group_proceedings.html" %} {% endifchanged %} {% endfor %}