Compare commits

...

4 Commits

Author SHA1 Message Date
Luca 57317b51d2 feat: export ratings
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-12-18 01:38:35 +01:00
Luca 3091fb0783 fix: keep dropdown menu expanded 2023-12-18 01:15:50 +01:00
Luca 14df5d5b68 fix: highlighting of active nav elements 2023-12-18 01:11:53 +01:00
Luca a0ccd2ff8e style(isort): use default skip settings 2023-12-18 00:51:41 +01:00
7 changed files with 85 additions and 16 deletions

View File

@ -1 +1 @@
__version__ = "0.8.0" __version__ = "0.9.0"

View File

@ -5,10 +5,10 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: pretalx-musicrate 0.0.1\n" "Project-Id-Version: pretalx-musicrate 0.9.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-12-16 03:23+0100\n" "POT-Creation-Date: 2023-12-18 01:34+0100\n"
"PO-Revision-Date: 2023-12-16 03:24+0100\n" "PO-Revision-Date: 2023-12-18 01:36+0100\n"
"Last-Translator: Luca <Luca@hackerspace-bamberg.de>\n" "Last-Translator: Luca <Luca@hackerspace-bamberg.de>\n"
"Language-Team: Luca <Luca@hackerspace-bamberg.de>\n" "Language-Team: Luca <Luca@hackerspace-bamberg.de>\n"
"Language: de_DE\n" "Language: de_DE\n"
@ -93,6 +93,14 @@ msgstr "Zum Anhörtag"
msgid "pretalx-musicrate settings" msgid "pretalx-musicrate settings"
msgstr "pretalx-musicrate-Einstellungen" msgstr "pretalx-musicrate-Einstellungen"
#: pretalx_musicrate/templates/pretalx_musicrate/settings.html:22
msgid "Save"
msgstr "Speichern"
#: pretalx_musicrate/templates/pretalx_musicrate/settings.html:30
msgid "Export ratings"
msgstr "Bewertungen exportieren"
#: pretalx_musicrate/templates/pretalx_musicrate/submission_base.html:29 #: pretalx_musicrate/templates/pretalx_musicrate/submission_base.html:29
msgid "(not specified)" msgid "(not specified)"
msgstr "(nicht angegeben)" msgstr "(nicht angegeben)"
@ -105,19 +113,19 @@ msgstr "Zurück"
msgid "Next" msgid "Next"
msgstr "Weiter" msgstr "Weiter"
#: pretalx_musicrate/views.py:39 #: pretalx_musicrate/views.py:41
msgid "Invalid token" msgid "Invalid token"
msgstr "Ungültiges Token" msgstr "Ungültiges Token"
#: pretalx_musicrate/views.py:114 #: pretalx_musicrate/views.py:116
msgid "The pretalx-musicrate settings were updated." msgid "The pretalx-musicrate settings were updated."
msgstr "Die pretalx-musicrate-Einstellungen wurden gespeichert." msgstr "Die pretalx-musicrate-Einstellungen wurden gespeichert."
#: pretalx_musicrate/views.py:273 #: pretalx_musicrate/views.py:275
msgid "Saved!" msgid "Saved!"
msgstr "Gespeichert!" msgstr "Gespeichert!"
#: pretalx_musicrate/views.py:375 #: pretalx_musicrate/views.py:377
#, python-format #, python-format
msgid "%(num_ratings)d of %(num_jurors)d has rated this submission" 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" msgid_plural "%(num_ratings)d of %(num_jurors)d have rated this submission"

View File

@ -10,7 +10,7 @@ def pretalx_musicrate_qrcode(sender, request, **kwargs):
return [] return []
return [ return [
{ {
"active": request.resolver_match.url_name "active": request.resolver_match.view_name
== "plugins:pretalx_musicrate:qrcode", == "plugins:pretalx_musicrate:qrcode",
"icon": "star", "icon": "star",
"label": _("Collective Rating"), "label": _("Collective Rating"),
@ -29,10 +29,10 @@ def pretalx_musicrate_settings(sender, request, **kwargs):
{ {
"label": "pretalx-musicrate", "label": "pretalx-musicrate",
"url": reverse( "url": reverse(
"plugins:pretalx_musicrate:settings", "plugins:pretalx_musicrate:settings.musicrate",
kwargs={"event": request.event.slug}, kwargs={"event": request.event.slug},
), ),
"active": request.resolver_match.url_name "active": request.resolver_match.view_name
== "plugins:pretalx_musicrate:settings", == "plugins:pretalx_musicrate:settings.musicrate",
} }
] ]

View File

@ -24,4 +24,9 @@
</span> </span>
</div> </div>
</form> </form>
<hr>
<a class="btn btn-success btn-lg btn-block" href="{% url "plugins:pretalx_musicrate:export" event=request.event.slug %}">
<i class="fa fa-download"></i>
{% translate "Export ratings" %}
</a>
{% endblock %} {% endblock %}

View File

@ -1,6 +1,7 @@
from django.urls import include, path from django.urls import include, path
from .views import ( from .views import (
ExportView,
JoinView, JoinView,
MayAdvanceView, MayAdvanceView,
MusicrateSettingsView, MusicrateSettingsView,
@ -12,8 +13,12 @@ from .views import (
urlpatterns = [ urlpatterns = [
path( path(
"orga/event/<slug:event>/settings/p/pretalx_musicrate/", "orga/event/<slug:event>/settings/p/pretalx_musicrate/",
MusicrateSettingsView.as_view(), include(
name="settings", [
path("", MusicrateSettingsView.as_view(), name="settings.musicrate"),
path("export/", ExportView.as_view(), name="export"),
]
),
), ),
path( path(
"<slug:event>/p/pretalx_musicrate/", "<slug:event>/p/pretalx_musicrate/",

View File

@ -1,9 +1,11 @@
import csv
import re import re
from hmac import compare_digest from hmac import compare_digest
from urllib.parse import parse_qs, urlparse from urllib.parse import parse_qs, urlparse
from django.contrib import messages from django.contrib import messages
from django.http import JsonResponse from django.db.models import Case, FilteredRelation, Q, Value, When
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, 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
@ -379,3 +381,53 @@ class MayAdvanceView(EventPermissionRequired, SubmissionMixin, View):
% {"num_jurors": num_jurors, "num_ratings": num_ratings}, % {"num_jurors": num_jurors, "num_ratings": num_ratings},
} }
) )
class ExportView(EventPermissionRequired, View):
permission_required = "orga.view_submissions"
def get(self, request, *args, **kwargs):
response = HttpResponse(
content_type="text/csv",
headers={
"Content-Disposition": f'attachment; filename="{request.event.slug}.csv"'
},
)
writer = csv.writer(response)
genre_question = request.event.pretalx_musicrate_settings.genre_question
origin_question = request.event.pretalx_musicrate_settings.origin_question
jurors = request.event.jurors.order_by("token")
for submission in request.event.submissions.prefetch_related("answers").filter(
submission_type__in=request.event.pretalx_musicrate_settings.submission_types.all()
):
submission_info = [submission.title, submission.submission_type.name]
if genre_question is not None:
submission_info.append(
submission.answers.filter(question=genre_question)
.values_list("answer", flat=True)
.first()
or ""
)
if origin_question is not None:
submission_info.append(
submission.answers.filter(question=origin_question)
.values_list("answer", flat=True)
.first()
or ""
)
writer.writerow(
[
*submission_info,
*jurors.annotate(
filtered_ratings=FilteredRelation(
"ratings", condition=Q(ratings__submission=submission)
),
rating=Case(
When(filtered_ratings__rating=None, then=Value("")),
When(filtered_ratings__rating="", then=Value("E")),
default="filtered_ratings__rating",
),
).values_list("rating", flat=True),
]
)
return response

View File

@ -6,7 +6,6 @@ use_parentheses=True
line_length=88 line_length=88
known_first_party=pretalx_musicrate known_first_party=pretalx_musicrate
known_third_party=pretalx known_third_party=pretalx
skip=setup.py,.venv
combine_as_imports=True combine_as_imports=True
default_section = THIRDPARTY default_section = THIRDPARTY