From cc4178baba185cd38816b734300148050d17d24c Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 16 Dec 2023 03:11:18 +0100 Subject: [PATCH] feat: collect and show links from submissions --- .../locale/de_DE/LC_MESSAGES/django.po | 10 ++-- .../templates/pretalx_musicrate/present.html | 10 ++++ pretalx_musicrate/templatetags/youtube.py | 12 +++++ pretalx_musicrate/views.py | 49 ++++++++++++++++++- 4 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 pretalx_musicrate/templatetags/youtube.py diff --git a/pretalx_musicrate/locale/de_DE/LC_MESSAGES/django.po b/pretalx_musicrate/locale/de_DE/LC_MESSAGES/django.po index 5f0f511..b70eb58 100644 --- a/pretalx_musicrate/locale/de_DE/LC_MESSAGES/django.po +++ b/pretalx_musicrate/locale/de_DE/LC_MESSAGES/django.po @@ -77,7 +77,7 @@ msgstr "" msgid "Join" msgstr "Mitmachen" -#: pretalx_musicrate/templates/pretalx_musicrate/present.html:15 +#: pretalx_musicrate/templates/pretalx_musicrate/present.html:25 msgid "Show Join QR Code" msgstr "Mitmach-QR-Code anzeigen" @@ -101,19 +101,19 @@ msgstr "Zurück" msgid "Next" msgstr "Weiter" -#: pretalx_musicrate/views.py:32 +#: pretalx_musicrate/views.py:40 msgid "Invalid token" msgstr "Ungültiges Token" -#: pretalx_musicrate/views.py:107 +#: pretalx_musicrate/views.py:115 msgid "The pretalx-musicrate settings were updated." msgstr "Die pretalx-musicrate-Einstellungen wurden gespeichert." -#: pretalx_musicrate/views.py:266 +#: pretalx_musicrate/views.py:274 msgid "Saved!" msgstr "Gespeichert!" -#: pretalx_musicrate/views.py:323 +#: pretalx_musicrate/views.py:372 #, python-format msgid "%(num_ratings)d of %(num_jurors)d has rated this submission" msgid_plural "%(num_ratings)d of %(num_jurors)d have rated this submission" diff --git a/pretalx_musicrate/templates/pretalx_musicrate/present.html b/pretalx_musicrate/templates/pretalx_musicrate/present.html index ba384b8..6685d6c 100644 --- a/pretalx_musicrate/templates/pretalx_musicrate/present.html +++ b/pretalx_musicrate/templates/pretalx_musicrate/present.html @@ -2,6 +2,7 @@ {% load compress %} {% load i18n %} {% load static %} +{% load youtube %} {% block submission_header %} {% if next %} @@ -12,6 +13,15 @@ {% endblock %} {% block submission_content %} + {% for type, link in links %} + {% if type == 'youtube' %} +
+ {% youtube link %} +
+ {% else %} +

{{ link | urlize }}

+ {% endif %} + {% endfor %} {% translate "Show Join QR Code" %}

{% endblock %} diff --git a/pretalx_musicrate/templatetags/youtube.py b/pretalx_musicrate/templatetags/youtube.py new file mode 100644 index 0000000..7f34dcf --- /dev/null +++ b/pretalx_musicrate/templatetags/youtube.py @@ -0,0 +1,12 @@ +from django import template +from django.utils.html import format_html + +register = template.Library() + + +@register.simple_tag +def youtube(v): + return format_html( + '', + v, + ) diff --git a/pretalx_musicrate/views.py b/pretalx_musicrate/views.py index c9f9fea..208f987 100644 --- a/pretalx_musicrate/views.py +++ b/pretalx_musicrate/views.py @@ -1,10 +1,13 @@ +import re from hmac import compare_digest +from urllib.parse import parse_qs, urlparse from django.contrib import messages from django.http import JsonResponse from django.shortcuts import get_object_or_404, redirect from django.urls import reverse from django.utils.functional import cached_property +from django.utils.html import Urlizer from django.utils.translation import gettext_lazy as _, ngettext from django.views.generic import FormView, TemplateView, View from django.views.generic.detail import SingleObjectMixin @@ -14,6 +17,10 @@ from pretalx.common.mixins.views import EventPermissionRequired from .forms import MusicrateSettingsForm, RatingForm from .models import Juror, Rating +youtube_re = re.compile( + r"(?:https?://)?(youtu\.be/|(?:(?:m|www)\.)?youtube\.com/watch\?)", re.IGNORECASE +) + class JoinView(TemplateView): template_name = "pretalx_musicrate/join.html" @@ -286,6 +293,44 @@ class PresenterView(EventPermissionRequired, SubmissionMixin, TemplateView): permission_required = "orga.view_submissions" template_name = "pretalx_musicrate/present.html" + @context + @cached_property + def links(self): + class Extractor: + def __init__(self): + self.urls = [] + + def format(self, href, **kwargs): + self.urls.append(href) + return href + + extractor = Extractor() + urlizer = Urlizer() + urlizer.url_template = extractor + urlizer(self.submission.abstract) + urlizer(self.submission.description) + urlizer(self.submission.notes) + urlizer(self.submission.internal_notes) + links = [] + for url in extractor.urls: + if (m := youtube_re.search(url)) is not None: + links.append( + ( + "youtube", + url.removeprefix("http") + .removeprefix("s") + .removeprefix("://") + .removeprefix("youtu.be/")[:11] + if m[1] == "youtu.be/" + else "".join( + parse_qs(urlparse(url).query).get("v", "dQw4w9WgXcQ") + ), + ) + ) + else: + links.append(("other", url)) + return links + @context @property def can_continue(self): @@ -303,7 +348,9 @@ class PresenterView(EventPermissionRequired, SubmissionMixin, TemplateView): settings.save() except Exception: pass - return super().get(request, *args, **kwargs) + response = super().get(request, *args, **kwargs) + response._csp_update = {"frame-src": "https://www.youtube-nocookie.com"} + return response class MayAdvanceView(EventPermissionRequired, SubmissionMixin, View):