From 8c82fef683a83e56df961b27438a326e9ce7f26b Mon Sep 17 00:00:00 2001
From: Ryan Cross <rcross@amsl.com>
Date: Sat, 31 Oct 2015 09:00:15 +0000
Subject: [PATCH] Add more information to Secretariat session recordings view. 
 Commit ready for merge  - Legacy-Id: 10348

---
 ietf/meeting/models.py                        |  3 ++
 ietf/secr/proceedings/tests.py                | 18 ++++---
 ietf/secr/proceedings/views.py                | 25 ++++++++--
 ietf/secr/static/secr/css/custom.css          |  4 ++
 .../secr/templates/proceedings/recording.html | 50 +++++++++++++------
 5 files changed, 76 insertions(+), 24 deletions(-)

diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py
index cadf19421..0629d9155 100644
--- a/ietf/meeting/models.py
+++ b/ietf/meeting/models.py
@@ -928,6 +928,9 @@ class Session(models.Model):
     def minutes(self):
         return self.get_material("minutes", only_one=True)
 
+    def recordings(self):
+        return list(self.get_material("recording", only_one=False))
+
     def slides(self):
         return list(self.get_material("slides", only_one=False))
 
diff --git a/ietf/secr/proceedings/tests.py b/ietf/secr/proceedings/tests.py
index 640d43188..90438fc89 100644
--- a/ietf/secr/proceedings/tests.py
+++ b/ietf/secr/proceedings/tests.py
@@ -14,6 +14,7 @@ from ietf.meeting.test_data import make_meeting_test_data
 from ietf.utils.test_data import make_test_data
 from ietf.utils.test_utils import TestCase
 
+from ietf.name.models import SessionStatusName
 from ietf.secr.utils.meeting import get_proceedings_path
 
 SECR_USER='secretary'
@@ -27,19 +28,23 @@ class MainTestCase(TestCase):
         response = self.client.get(url)
         self.assertEqual(response.status_code, 200)
 
+
 class RecordingTestCase(TestCase):
     def test_page(self):
-        make_test_data()
-        meeting = Meeting.objects.first()
+        meeting = make_meeting_test_data()
         url = reverse('proceedings_recording', kwargs={'meeting_num':meeting.number})
         self.client.login(username="secretary", password="secretary+password")
         response = self.client.get(url)
         self.assertEqual(response.status_code, 200)
+
     def test_post(self):
-        make_meeting_test_data()
-        meeting = Meeting.objects.first()
+        meeting = make_meeting_test_data()
         group = Group.objects.get(acronym='mars')
-        session = Session.objects.filter(meeting=meeting,group=group,status__in=('sched','schedw')).first()
+        session = Session.objects.filter(meeting=meeting,group=group).first()
+        # explicitly set to scheduled for this test
+        status = SessionStatusName.objects.get(slug='sched')
+        session.status = status
+        session.save()
         url = reverse('proceedings_recording', kwargs={'meeting_num':meeting.number})
         data = dict(group=group.acronym,external_url='http://youtube.com/xyz',session=session.pk)
         self.client.login(username="secretary", password="secretary+password")
@@ -54,7 +59,8 @@ class RecordingTestCase(TestCase):
         response = self.client.post(url,dict(external_url=external_url),follow=True)
         self.assertEqual(response.status_code, 200)
         self.failUnless(external_url in response.content)
-        
+
+
 class BluesheetTestCase(TestCase):
     def setUp(self):
         self.proceedings_dir = os.path.abspath("tmp-proceedings-dir")
diff --git a/ietf/secr/proceedings/views.py b/ietf/secr/proceedings/views.py
index 4ab2ef51f..db1ce6e73 100644
--- a/ietf/secr/proceedings/views.py
+++ b/ietf/secr/proceedings/views.py
@@ -75,6 +75,21 @@ def get_doc_filename(doc):
         # TODO we might want to choose from among multiple files using some logic
         return files[0]
 
+def get_unmatched_recordings(meeting):
+    '''
+    Returns a list of recording filenames that haven't been matched to a session
+    '''
+    unmatched_recordings = []
+    path = os.path.join(settings.MEETING_RECORDINGS_DIR,'ietf{}'.format(meeting.number))
+    try:
+        files = os.listdir(path)
+    except OSError:
+        files = []
+    for file in files:
+        if not Document.objects.filter(external_url__endswith=file).exists():
+            unmatched_recordings.append(file)
+    return unmatched_recordings
+
 def get_extras(meeting):
     '''
     Gather "extras" which are one off groups. ie iab-wcit(86)
@@ -608,10 +623,13 @@ def progress_report(request, meeting_num):
 @role_required('Secretariat')
 def recording(request, meeting_num):
     '''
-    Enter Session recording info.  Creates Document and associates it with Session
+    Enter Session recording info.  Creates Document and associates it with Session.
+    For auditing purposes, lists all scheduled sessions and associated recordings, if
+    any.  Also lists those audio recording files which haven't been matched to a
+    session.
     '''
     meeting = get_object_or_404(Meeting, number=meeting_num)
-    recordings = Document.objects.filter(name__startswith='recording-{}'.format(meeting.number),states__slug='active').order_by('group__acronym')
+    sessions = meeting.session_set.filter(type='session',status='sched').order_by('group__acronym')
     
     if request.method == 'POST':
         form = RecordingForm(request.POST)
@@ -638,7 +656,8 @@ def recording(request, meeting_num):
     return render_to_response('proceedings/recording.html',{
         'meeting':meeting,
         'form':form,
-        'recordings':recordings},
+        'sessions':sessions,
+        'unmatched_recordings': get_unmatched_recordings(meeting)},
         RequestContext(request, {}),
     )
 
diff --git a/ietf/secr/static/secr/css/custom.css b/ietf/secr/static/secr/css/custom.css
index 76b284ae6..5d609f24b 100644
--- a/ietf/secr/static/secr/css/custom.css
+++ b/ietf/secr/static/secr/css/custom.css
@@ -583,6 +583,10 @@ td.hidden {
     display: none;
 }
 
+td.document-name {
+    white-space: nowrap;
+}
+
 /* ==========================================================================
    Role Tool
    ========================================================================== */
diff --git a/ietf/secr/templates/proceedings/recording.html b/ietf/secr/templates/proceedings/recording.html
index 56c39c8e7..3918eee04 100755
--- a/ietf/secr/templates/proceedings/recording.html
+++ b/ietf/secr/templates/proceedings/recording.html
@@ -43,9 +43,9 @@
         </div> <!-- button-group -->
  
        </form>
+     
      <div class="inline-related">
-           <h2>{{ meeting }} - Recordings
-    </h2>
+       <h2>{{ meeting }} - Recordings</h2>
        <table class="center">
          <thead>
            <tr>
@@ -57,27 +57,47 @@
            </tr>
          </thead>
          <tbody>
-         {% for record in recordings %}
+         {% for session in sessions %}
          <tr>
-           <td>{{ record.group.acronym }}</td>
-           <td>{{ record.session_set.first.official_scheduledsession.timeslot.time|date:"m-d H:i" }}</td>
-           <td>{{ record.name }}</td>
-           <td><a href="{{ record.href }}">{{ record.href }}</a></td>
-           <td><a href="{% url "proceedings_recording_edit" meeting_num=meeting.number name=record.name %}">Edit</a></td>
+           <td>{{ session.group.acronym }}</td>
+           <td>{{ session.official_timeslotassignment.timeslot.time|date:"m-d H:i" }}</td>
+           {% if session.recordings %}
+             <td class="document-name" >{{ session.recordings.0.name }}</td>
+             <td><a href="{{ session.recordings.first.href }}">{{ session.recordings.0.href }}</a></td>
+             <td><a href="{% url "proceedings_recording_edit" meeting_num=meeting.number name=session.recordings.0.name %}">Edit</a></td>
+           {% else %}
+             <td></td>
+             <td></td>
+             <td></td>
+           {% endif %}
          </tr>
          {% endfor %}
          </tbody>
        </table>
-     
      </div> <!-- inline-group -->
+     
+     {% if unmatched_recordings %}
+     <div class="inline-related">
+       <h2>Unmatched Recording Files</h2>
+       <table class="center">
+         <thead>
+           <tr>
+             <th>Filename</th>
+           </tr>
+         </thead>
+         <tbody>
+         {% for file in unmatched_recordings %}
+           <tr>
+             <td>{{ file }}</td>
+           </tr>
+         {% endfor %}
+         </tbody>
+       </table>
+     </div> <!-- inline-group -->
+     {% endif %}
+     
 </div> <!-- module -->
 
-{% if docevents %}
-  <br>
-  <div class="module interim-container">
-    {% include "includes/docevents.html" %}
-  </div>
-{% endif %}
 
 {% endblock %}