feat: endpoint, script and setting for auto-advance
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Luca 2023-12-15 18:14:33 +01:00
parent e070fd1281
commit f04e42cfc1
9 changed files with 83 additions and 4 deletions

View File

@ -26,7 +26,12 @@ class MusicrateSettingsForm(I18nModelForm):
class Meta: class Meta:
model = MusicrateSettings model = MusicrateSettings
fields = ("submission_types", "genre_question", "origin_question") fields = (
"submission_types",
"genre_question",
"origin_question",
"advance_threshold",
)
widgets = { widgets = {
"submission_types": forms.SelectMultiple(attrs={"class": "select2"}), "submission_types": forms.SelectMultiple(attrs={"class": "select2"}),
"genre_question": forms.Select(attrs={"class": "select2"}), "genre_question": forms.Select(attrs={"class": "select2"}),

View File

@ -0,0 +1,21 @@
# Generated by Django 4.2.8 on 2023-12-15 16:32
from decimal import Decimal
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("pretalx_musicrate", "0003_musicratesettings_join_token"),
]
operations = [
migrations.AddField(
model_name="musicratesettings",
name="advance_threshold",
field=models.DecimalField(
decimal_places=2, default=Decimal("0.6"), max_digits=3
),
),
]

View File

@ -1,3 +1,4 @@
from decimal import Decimal
from secrets import token_urlsafe from secrets import token_urlsafe
from django.db import models from django.db import models
@ -40,3 +41,12 @@ class MusicrateSettings(models.Model):
null=True, null=True,
) )
join_token = models.CharField(max_length=43, default=generate_token) join_token = models.CharField(max_length=43, default=generate_token)
advance_threshold = models.DecimalField(
max_digits=3,
decimal_places=2,
default=Decimal("0.6"),
help_text=_(
"The fraction of jurors that has to submit a rating before the presenter view automatically advances to the next submission."
),
verbose_name=_("Advance Threshold"),
)

View File

@ -0,0 +1,16 @@
const mayAdvance = (callback) =>
fetch("may-advance?")
.then(response => response.json())
.then(mayAdvance => {
if (mayAdvance === true) {
callback();
}
});
const timeout = setTimeout(() => {
setInterval(() => {
mayAdvance(() => {
location = document.getElementById("next").href;
});
}, 3000);
}, 3000);
mayAdvance(() => clearTimeout(timeout));

View File

@ -1,4 +1,11 @@
{% extends "pretalx_musicrate/submission_base.html" %} {% extends "pretalx_musicrate/submission_base.html" %}
{% load compress %}
{% load static %}
{% block submission_content %} {% block submission_content %}
{% if next %}
{% compress js %}
<script src="{% static "pretalx_musicrate/may-advance.js" %}"></script>
{% endcompress %}
{% endif %}
{% endblock %} {% endblock %}

View File

@ -12,6 +12,7 @@
{% bootstrap_field form.submission_types layout='event' %} {% bootstrap_field form.submission_types layout='event' %}
{% bootstrap_field form.genre_question layout='event' %} {% bootstrap_field form.genre_question layout='event' %}
{% bootstrap_field form.origin_question layout='event' %} {% bootstrap_field form.origin_question layout='event' %}
{% bootstrap_field form.advance_threshold layout='event' %}
{% include "orga/includes/submit_row.html" %} {% include "orga/includes/submit_row.html" %}
</form> </form>
{% endblock %} {% endblock %}

View File

@ -47,7 +47,7 @@
{{ index }}/{{ count }} {{ index }}/{{ count }}
{% endif %} {% endif %}
{% if next and can_continue %} {% if next and can_continue %}
<a href="{{ next }}">{% translate "Next" %} &gt;</a> <a href="{{ next }}" id="next">{% translate "Next" %} &gt;</a>
{% else %} {% else %}
<a></a> <a></a>
{% endif %} {% endif %}

View File

@ -1,6 +1,12 @@
from django.urls import include, path from django.urls import include, path
from .views import JoinView, MusicrateSettingsView, PresenterView, QRCodeView from .views import (
JoinView,
MayAdvanceView,
MusicrateSettingsView,
PresenterView,
QRCodeView,
)
urlpatterns = [ urlpatterns = [
path( path(
@ -14,6 +20,11 @@ urlpatterns = [
[ [
path("", QRCodeView.as_view(), name="qrcode"), path("", QRCodeView.as_view(), name="qrcode"),
path("present/<code>/", PresenterView.as_view(), name="present"), path("present/<code>/", PresenterView.as_view(), name="present"),
path(
"present/<code>/may-advance",
MayAdvanceView.as_view(),
name="may_advance",
),
path("<slug:token>/", JoinView.as_view(), name="join"), path("<slug:token>/", JoinView.as_view(), name="join"),
] ]
), ),

View File

@ -4,11 +4,12 @@ from operator import itemgetter
from django.contrib import messages from django.contrib import messages
from django.db.models import F, Max, Min, Window from django.db.models import F, Max, Min, Window
from django.db.models.functions import RowNumber from django.db.models.functions import RowNumber
from django.http import JsonResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.urls import reverse from django.urls import reverse
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import FormView, TemplateView from django.views.generic import FormView, TemplateView, View
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from django_context_decorator import context from django_context_decorator import context
from pretalx.common.mixins.views import EventPermissionRequired from pretalx.common.mixins.views import EventPermissionRequired
@ -189,3 +190,10 @@ class PresenterView(EventPermissionRequired, SubmissionMixin, TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
class MayAdvanceView(EventPermissionRequired, View):
permission_required = "orga.view_submissions"
def get(self, request, *args, **kwargs):
return JsonResponse(True, safe=False)