Skip to content

Commit

Permalink
feat: Session adding notes and recordings
Browse files Browse the repository at this point in the history
  • Loading branch information
holloway committed Oct 25, 2024
1 parent 0b4b26f commit 6d0bde5
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 1 deletion.
1 change: 1 addition & 0 deletions ietf/meeting/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def get_redirect_url(self, *args, **kwargs):
safe_for_all_meeting_types = [
url(r'^session/(?P<acronym>[-a-z0-9]+)/?$', views.session_details),
url(r'^session/(?P<session_id>\d+)/drafts$', views.add_session_drafts),
url(r'^session/(?P<session_id>\d+)/notes_and_recordings$', views.add_session_notes_and_recordings),
url(r'^session/(?P<session_id>\d+)/attendance$', views.session_attendance),
url(r'^session/(?P<session_id>\d+)/bluesheets$', views.upload_session_bluesheets),
url(r'^session/(?P<session_id>\d+)/minutes$', views.upload_session_minutes),
Expand Down
51 changes: 50 additions & 1 deletion ietf/meeting/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from collections import OrderedDict, Counter, deque, defaultdict, namedtuple
from functools import partialmethod
import jsonschema
from urllib.parse import parse_qs, unquote, urlencode, urlsplit, urlunsplit
from urllib.parse import parse_qs, unquote, urlencode, urlsplit, urlunsplit, urlparse
from tempfile import mkstemp
from wsgiref.handlers import format_date_time

Expand Down Expand Up @@ -2538,6 +2538,55 @@ def add_session_drafts(request, session_id, num):
'form': form,
})

class SessionNotesAndRecordingsForm(forms.Form):
title = forms.CharField(max_length=255)
url = forms.URLField(label="Link to recording (YouTube only)")

def __init__(self, *args, **kwargs):
self.already_linked = kwargs.pop('already_linked')
super(self.__class__, self).__init__(*args, **kwargs)

def clean(self):
url = self.cleaned_data['url']
parsed_url = urlparse(url)
if parsed_url.hostname not in ['www.youtube.com', 'youtube.com', 'youtu.be', 'm.youtube.com', 'youtube-nocookie.com', 'www.youtube-nocookie.com']:
raise forms.ValidationError("Must be a YouTube URL")
problems = set(url).intersection(set(self.already_linked))
if problems:
raise forms.ValidationError("Already linked: %s" % ', '.join([d.name for d in problems]))
return self.cleaned_data

def add_session_notes_and_recordings(request, session_id, num):
# num is redundant, but we're dragging it along an artifact of where we are in the current URL structure
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
raise Http404
if session.is_material_submission_cutoff() and not has_role(request.user, "Secretariat"):
raise Http404

already_linked = [material.external_url for material in session.materials.filter(type="recording").exclude(states__type="recording", states__slug='deleted').order_by('presentations__order')]

session_number = None
sessions = get_sessions(session.meeting.number,session.group.acronym)
if len(sessions) > 1:
session_number = 1 + sessions.index(session)

if request.method == 'POST':
form = SessionNotesAndRecordingsForm(request.POST,already_linked=already_linked)
if form.is_valid():
title = form.cleaned_data['title']
url = form.cleaned_data['url']
create_recording(session, url, title=title, user=request.user.person)
return redirect('ietf.meeting.views.session_details', num=session.meeting.number, acronym=session.group.acronym)
else:
form = SessionNotesAndRecordingsForm(already_linked=already_linked)

return render(request, "meeting/add_session_notes_and_recordings.html",
{ 'session': session,
'session_number': session_number,
'already_linked': session.materials.filter(type="recording").exclude(states__type="recording", states__slug='deleted').order_by('presentations__order'),
'form': form,
})

def session_attendance(request, session_id, num):
"""Session attendance view
Expand Down
70 changes: 70 additions & 0 deletions ietf/templates/meeting/add_session_notes_and_recordings.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin static django_bootstrap5 %}
{% block title %}Add I-Ds to {{ session.meeting }} : {{ session.group.acronym }}{% endblock %}
{% block pagehead %}{{ form.media.css }}{% endblock %}
{% block content %}
{% origin %}
<h1>
Add Notes and Recordings to {{ session.meeting }}
{% if session_number %}: Session {{ session_number }}{% endif %}
<br>
<small class="text-body-secondary">{{ session.group.acronym }}
{% if session.name %}: {{ session.name }}{% endif %}
</small>
</h1>
{% comment %} TODO: put the session name here or calculate the number at the meeting {% endcomment %}
{% if session.is_material_submission_cutoff %}
<div class="alert alert-warning my-3">
The deadline for submission corrections has passed. This may affect published proceedings.
</div>
{% endif %}
<div class="alert alert-info my-3">
This form will link additional Notes and Recordings to this session with a revision of "Current at time of presentation". For more fine grained control of versions, or to remove Notes and Recordings from a session, adjust the sessions associated with an Internet-Draft from the Internet-Draft's main page.
</div>
<h2 class="mt-5">Notes and Recordings already linked to this session</h2>
<table class="table table-sm table-striped tablesorter">
<thead>
<tr>
<th scope="col" data-sort="num">Revision</th>
<th scope="col" data-sort="document">Document</th>
</tr>
</thead>
{% if already_linked %}
<tbody>
{% for sp in already_linked %}
<tr>
<td>
{% if sp.rev %}
-{{ sp.rev }}
{% else %}
(current)
{% endif %}
</td>
<td><a href="{{ sp.external_url }}">{{ sp.title }}</a></td>
</tr>
{% endfor %}
</tbody>
{% else %}
<tbody>
<tr>
<td colspan="2" class="text-center font-italic">(none)</td>
</tr>
</tbody>
{% endif %}
</table>
<h2 class="mt-5">Add additional Notes and Recordings to this session</h2>
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
<button class="btn btn-{% if session.is_material_submission_cutoff %}warning{% else %}primary{% endif %}"
type="submit">
Save
</button>
<a class="btn btn-secondary float-end"
href="{% url 'ietf.meeting.views.session_details' num=session.meeting.number acronym=session.group.acronym %}">
Back
</a>
</form>
{% endblock %}
{% block js %}{{ form.media.js }}{% endblock %}
68 changes: 68 additions & 0 deletions ietf/templates/meeting/session_details_panel.html
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,76 @@ <h3 class="mt-4">Notes and recordings</h3>
</tr>
{% endif %}
{% endif %}

{% with session.recordings as recordings %}
{% if recordings %}
{# There's no guaranteed order, so this is a bit messy: #}
{# Audio #}
{% for r in recordings %}
{% with href=r.get_href %}
{% if 'audio' in href %}
<tr>
<td>
<a href="{{ href }}">
{{ r.title }}
</a>
</td>
</tr>
{% endif %}
{% endwith %}
{% endfor %}
{# YouTube #}
{% for r in recordings %}
{% with href=r.get_href %}
{% if 'youtu' in href %}
<tr>
<td>
<a href="{{ href }}">
{{ r.title }}
</a>
</td>
</tr>
{% endif %}
{% endwith %}
{% endfor %}
{# Any other recordings #}
{% for r in recordings %}
{% with href=r.get_href %}
{% if not 'audio' in href and not 'youtu' in href %}
<tr>
<td>
<a href="{{ href }}">
{{ r.title }}
</a>
</td>
</tr>
{% endif %}
{% endwith %}
{% endfor %}
{% elif show_empty %}
{# <i class="bi"></i> #}
{% endif %}
{% if session.session_recording_url %}
<tr>
<td>
<a href="{{ session.session_recording_url }}">
Meetecho session recording
</a>
</td>
</tr>
{% endif %}
{% endwith %}

</tbody>
</table>

{% if can_manage_materials %}
<a class="btn btn-primary"
href="{% url 'ietf.meeting.views.add_session_notes_and_recordings' session_id=session.pk num=session.meeting.number %}">
Link additional notes and recordings to session
</a>
{% endif %}

{% endif %}
{% endwith %}{% endwith %}
{% endfor %}

0 comments on commit 6d0bde5

Please sign in to comment.