[Debconf-video-commits] r389 - in package/branches/pycon09/src/pyconvideo: . pyconvideo

benh at alioth.debian.org benh at alioth.debian.org
Thu Mar 26 04:25:50 UTC 2009


Author: benh
Date: 2009-03-26 04:25:50 +0000 (Thu, 26 Mar 2009)
New Revision: 389

Added:
   package/branches/pycon09/src/pyconvideo/pyconvideo/review_event_recording.html
   package/branches/pycon09/src/pyconvideo/pyconvideo/review_list_events.html
Modified:
   package/branches/pycon09/src/pyconvideo/pyconvideo/videorecording_list.html
   package/branches/pycon09/src/pyconvideo/pyconvideo/videotargetfile_list.html
   package/branches/pycon09/src/pyconvideo/pyconvideo/views.py
   package/branches/pycon09/src/pyconvideo/urls.py
Log:
Implement most of the review interface.


Added: package/branches/pycon09/src/pyconvideo/pyconvideo/review_event_recording.html
===================================================================
--- package/branches/pycon09/src/pyconvideo/pyconvideo/review_event_recording.html	                        (rev 0)
+++ package/branches/pycon09/src/pyconvideo/pyconvideo/review_event_recording.html	2009-03-26 04:25:50 UTC (rev 389)
@@ -0,0 +1,25 @@
+<html>
+
+  <head><title>Review recording</title></head>
+
+  <body>
+    <h1>Review recording</h1>
+
+    <p>
+      Recording:
+      <a href="file://{{ recording.recording_filename|urlencode }}">
+	{{ recording.recording_filename }}
+      </a>
+    </p>
+
+    <p>Event: {{ event.title }}</p>
+
+    <form action="review" method="POST">
+      <input type="hidden" name="event" value="{{ event.event_id }}" />
+      {{ form.as_p }}
+      <input type="submit" name="finish" value="Finish review" /> |
+      <input type="submit" name="continue" value="Continue review" />
+    </form>
+  </body>
+
+</html>

Added: package/branches/pycon09/src/pyconvideo/pyconvideo/review_list_events.html
===================================================================
--- package/branches/pycon09/src/pyconvideo/pyconvideo/review_list_events.html	                        (rev 0)
+++ package/branches/pycon09/src/pyconvideo/pyconvideo/review_list_events.html	2009-03-26 04:25:50 UTC (rev 389)
@@ -0,0 +1,58 @@
+<html>
+
+  <head><title>Link recording with event</title></head>
+
+  <body>
+    <h1>Link recording with event</h1>
+
+    <p>
+      Recording:
+      <a href="file://{{ recording.recording_filename|urlencode }}">
+	{{ recording.recording_filename }}
+      </a>
+    </p>
+
+    <p>
+      Select the event covered by this recording. If the recording
+      covers multiple events, review the video again for each event.
+    </p>
+
+    <form action="review" method="post">
+      If the recording does not cover any events, press
+      <input type="hidden" name="file_status" value="D" />
+      <input type="submit" name="submit" value="Delete" />
+    </form>
+
+    <table>
+      <tr>
+	<th>Title</th>
+	<th>Start time</th>
+	<th>Duration</th>
+	<th>Room</th>
+	<th>Recorded as</th>
+      </tr>
+      {% for event in events %}
+      <tr>
+	<td>{{ event.title }}</td>
+	<td>{{ event.start_time }}</td>
+	<td>{{ event.duration }}</td>
+	<td>{{ event.conference_room }}</td>
+	<td>
+	  {% for other_recording in event.recording_set.all %}
+	  <a href="file://{{ recording.recording_filename|urlencode }}"
+	     class="status-{{ recording.file_status.file_status_code }}">
+	    {{ other_recording.recording_filename }}<br />
+	  </a>
+	  {% endfor %}
+	  <form action="review" method="post">
+	    <input type="hidden" name="event" value="{{ event.event_id }}" />
+	    <input type="submit" name="submit" value="Select" />
+	  </form>
+	</td>
+      </tr>
+      {% endfor %}
+    </table>
+
+  </body>
+
+</html>

Modified: package/branches/pycon09/src/pyconvideo/pyconvideo/videorecording_list.html
===================================================================
--- package/branches/pycon09/src/pyconvideo/pyconvideo/videorecording_list.html	2009-03-25 14:47:12 UTC (rev 388)
+++ package/branches/pycon09/src/pyconvideo/pyconvideo/videorecording_list.html	2009-03-26 04:25:50 UTC (rev 389)
@@ -31,6 +31,11 @@
 	  {{ event.title }}<br />
 	  {% endfor %}
 	  {% if recording.locked_by %}
+	  {% ifequal recording.locked_by user %}
+	  <form action="{{ recording.id }}/review" method="post">
+	    <input type="submit" name="submit" value="Continue review" />
+	  </form>
+	  {% endifequal %}
 	  {% else %}
 	  <form action="{{ recording.id }}/review" method="post">
 	    <input type="submit" name="submit" value="Review" />

Modified: package/branches/pycon09/src/pyconvideo/pyconvideo/videotargetfile_list.html
===================================================================
--- package/branches/pycon09/src/pyconvideo/pyconvideo/videotargetfile_list.html	2009-03-25 14:47:12 UTC (rev 388)
+++ package/branches/pycon09/src/pyconvideo/pyconvideo/videotargetfile_list.html	2009-03-26 04:25:50 UTC (rev 389)
@@ -21,7 +21,11 @@
 	{% if target %}
 	<td class="status-{{ target.status.status_code }}">
 	  {% if target.locked_by %}
-	  <a href="file:///{{ target.target_filename|urlencode }}">File</a>
+	  {% ifequal target.locked_by user %}
+	  <form action="{{ target.id }}/review" method="post">
+	    <input type="submit" name="submit" value="Continue review" />
+	  </form>
+	  {% endifequal %}
 	  {% else %}
 	  <form action="{{ target.id }}/review" method="post">
 	    <input type="submit" name="submit" value="Review" />

Modified: package/branches/pycon09/src/pyconvideo/pyconvideo/views.py
===================================================================
--- package/branches/pycon09/src/pyconvideo/pyconvideo/views.py	2009-03-25 14:47:12 UTC (rev 388)
+++ package/branches/pycon09/src/pyconvideo/pyconvideo/views.py	2009-03-26 04:25:50 UTC (rev 389)
@@ -1,9 +1,101 @@
-from django.shortcuts import render_to_response
+from django import forms
+from django.contrib.auth.decorators import login_required
+from django.db import transaction
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template import defaultfilters
+import mx.DateTime
 from . import models
 
+ at defaultfilters.stringfilter
+def slugify(value):
+    # Based on django.template.defaultfilters.slugify
+    # but using underscores and mixed case
+    import re, unicodedata
+    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
+    value = unicode(re.sub('[^\w\s_]', '', value).strip())
+    return defaultfilters.mark_safe(re.sub('[_\s]+', '_', value))
+
+def list_recordings(request):
+    return render_to_response(
+        'pyconvideo/videorecording_list.html',
+        {'object_list':
+             models.VideoRecording.objects.all().order_by('recording_time').select_related(),
+         'user': request.user})
+
+class IntervalField(forms.CharField):
+    help_text = 'A valid time (mm:ss or hh:mm:ss)'
+    def clean(self, value):
+        import re
+        if not value:
+            raise forms.ValidationError('Enter a valid time')
+        match = re.match(r'(?:(\d+):)?(\d+):(\d+(?:\.\d+)?)$', value)
+        if match:
+            hours = match.group(1) and int(match.group(1)) or 0
+            minutes = int(match.group(2))
+            seconds = float(match.group(3))
+            if seconds < 60:
+                return mx.DateTime.DateTimeDelta(0, hours, minutes, seconds)
+        raise forms.ValidationError('%s is not a valid time' % value)
+
+class RecordingReviewForm(forms.Form):
+    file_status = forms.ChoiceField(
+        choices=models.VideoFileStatus.objects.values_list('file_status_code',
+                                                           'file_status_desc'),
+        widget=forms.RadioSelect)
+    start_time = IntervalField()
+    end_time = IntervalField()
+    base_name = forms.CharField()
+    comments = forms.CharField(required=False, widget=forms.Textarea)
+
+ at login_required
+ at transaction.commit_on_success
 def review_recording(request, recording_id):
-    recording_id = int(recording_id)
+    recording = get_object_or_404(models.VideoRecording, pk=recording_id)
 
+    # lock or fail
+    if not recording.locked_by:
+        recording.locked_by = request.user
+        recording.save()
+    elif recording.locked_by == request.user:
+        pass
+    else:
+        return render_to_response('pyconvideo/review_locked.html',
+                                  {'filename': recording.recording_filename,
+                                   'user': recording.locked_by})
+
+    event_id = request.POST.get('event')
+    event = event_id and models.Event.objects.get(event_id=event_id)
+    file_status = request.POST.get('file_status')
+
+    if (event and file_status) or file_status == 'D':
+        # process review
+        form = RecordingReviewForm(request.POST)
+        if form.is_valid():
+            # TODO
+            pass
+    elif event:
+        # show main form
+        defaults = {'file_status': recording.file_status.file_status_code,
+                    'start_time': '00:00:00',
+                    'end_time': recording.recording_duration,
+                    'base_name': slugify(event.title)}
+        return render_to_response('pyconvideo/review_event_recording.html',
+                                  {'recording': recording,
+                                   'event': event,
+                                   'form': RecordingReviewForm(defaults)})
+    else:
+        # list events for association
+        events = models.Event.objects
+        events = events.extra(
+            select={'proximity':
+                        "abs(date_part('epoch', age(event.start_time, %s)))"},
+            select_params=[recording.recording_time],
+            order_by=['proximity'])
+        events = events.all()
+        return render_to_response('pyconvideo/review_list_events.html',
+                                  {'recording': recording,
+                                   'events': events})
+
 def list_targets(request):
     sources = models.VideoEventRecording.objects.all().select_related()
     formats = models.VideoTargetFormat.objects.all()
@@ -18,7 +110,22 @@
                 target = None
             files[-1]['target'].append(target)
     return render_to_response('pyconvideo/videotargetfile_list.html',
-                              {'files': files, 'formats': formats})
+                              {'files': files,
+                               'formats': formats,
+                               'user': request.user})
 
+ at login_required
+ at transaction.commit_on_success
 def review_target(request, target_id):
-    target_id = int(target_id)
+    target = get_object_or_404(models.VideoTargetFile, pk=target_id)
+
+    # lock or fail
+    if not target.locked_by:
+        target.locked_by = request.user
+        target.save()
+    elif target.locked_by == request.user:
+        return render_to_response('pyconvideo/review_locked.html',
+                                  {'filename': target.target_filename,
+                                   'user': target.locked_by})
+    else:
+        return render_to_response('pyconvideo/review_locked.html')

Modified: package/branches/pycon09/src/pyconvideo/urls.py
===================================================================
--- package/branches/pycon09/src/pyconvideo/urls.py	2009-03-25 14:47:12 UTC (rev 388)
+++ package/branches/pycon09/src/pyconvideo/urls.py	2009-03-26 04:25:50 UTC (rev 389)
@@ -25,9 +25,7 @@
     (r'^event/$', object_list,
      {'queryset':
       models.Event.objects.all().order_by('start_time').select_related()}),
-    (r'^recording/$', object_list,
-     {'queryset':
-      models.VideoRecording.objects.all().order_by('recording_time').select_related()}),
+    (r'^recording/$', views.list_recordings),
     (r'^recording/(\d+)/review$', views.review_recording),
     (r'^target/$', views.list_targets),
     (r'^target/(\d+)/review$', views.review_target),




More information about the Debconf-video-commits mailing list