From c8aa1d3cf49768c7daf3849c7084187e6c51104b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?=
 <benjamin.haettasch@fachschaft.informatik.tu-darmstadt.de>
Date: Sat, 30 Jan 2021 15:01:48 +0100
Subject: [PATCH] Implement simple AK to slide export

Create template for slides
Add view
Link view from status page
Update translations
---
 AKModel/admin.py                            |   3 +-
 AKModel/locale/de_DE/LC_MESSAGES/django.po  | 151 +++++++++++---------
 AKModel/templates/AKModel/export/slides.tex |  72 ++++++++++
 AKModel/templates/admin/AKModel/status.html |   2 +
 AKModel/views.py                            |  20 +++
 5 files changed, 180 insertions(+), 68 deletions(-)
 create mode 100644 AKModel/templates/AKModel/export/slides.tex

diff --git a/AKModel/admin.py b/AKModel/admin.py
index 48c1f878..a032d938 100644
--- a/AKModel/admin.py
+++ b/AKModel/admin.py
@@ -16,7 +16,7 @@ from AKModel.availability.forms import AvailabilitiesFormMixin
 from AKModel.availability.models import Availability
 from AKModel.models import Event, AKOwner, AKCategory, AKTrack, AKTag, AKRequirement, AK, AKSlot, Room, AKOrgaMessage, \
     ConstraintViolation
-from AKModel.views import EventStatusView, AKCSVExportView, AKWikiExportView, AKMessageDeleteView
+from AKModel.views import EventStatusView, AKCSVExportView, AKWikiExportView, AKMessageDeleteView, export_slides
 
 
 @admin.register(Event)
@@ -33,6 +33,7 @@ class EventAdmin(admin.ModelAdmin):
             path('<slug:slug>/status/', self.admin_site.admin_view(EventStatusView.as_view()), name="event_status"),
             path('<slug:event_slug>/ak-csv-export/', self.admin_site.admin_view(AKCSVExportView.as_view()), name="ak_csv_export"),
             path('<slug:event_slug>/ak-wiki-export/', self.admin_site.admin_view(AKWikiExportView.as_view()), name="ak_wiki_export"),
+            path('<slug:event_slug>/ak-slide-export/', export_slides, name="ak_slide_export"),
             path('<slug:slug>/delete-orga-messages/', self.admin_site.admin_view(AKMessageDeleteView.as_view()),
                  name="ak_delete_orga_messages"),
         ]
diff --git a/AKModel/locale/de_DE/LC_MESSAGES/django.po b/AKModel/locale/de_DE/LC_MESSAGES/django.po
index ebcaa384..a2276999 100644
--- a/AKModel/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKModel/locale/de_DE/LC_MESSAGES/django.po
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-11-03 20:41+0000\n"
+"POT-Creation-Date: 2021-01-30 13:57+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -11,28 +11,32 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: AKModel/admin.py:41 AKModel/admin.py:42
+#: AKModel/admin.py:44 AKModel/admin.py:45
 #: AKModel/templates/admin/AKModel/status.html:7
 #: AKModel/templates/admin/ak_index.html:15
 msgid "Status"
 msgstr "Status"
 
-#: AKModel/admin.py:120
+#: AKModel/admin.py:123
 msgid "Wish"
 msgstr "AK-Wunsch"
 
-#: AKModel/admin.py:126
+#: AKModel/admin.py:129
 msgid "Is wish"
 msgstr "Ist ein Wunsch"
 
-#: AKModel/admin.py:127
+#: AKModel/admin.py:130
 msgid "Is not a wish"
 msgstr "Ist kein Wunsch"
 
-#: AKModel/admin.py:154
+#: AKModel/admin.py:157
 msgid "Export to wiki syntax"
 msgstr "In Wiki-Syntax exportieren"
 
+#: AKModel/admin.py:253
+msgid "AK Details"
+msgstr "AK-Details"
+
 #: AKModel/availability/forms.py:20 AKModel/availability/models.py:239
 msgid "Availability"
 msgstr "Verfügbarkeit"
@@ -60,13 +64,13 @@ msgstr "Bitte Verfügbarkeiten eintragen!"
 #: AKModel/availability/models.py:38 AKModel/models.py:47 AKModel/models.py:76
 #: AKModel/models.py:128 AKModel/models.py:147 AKModel/models.py:179
 #: AKModel/models.py:233 AKModel/models.py:292 AKModel/models.py:324
-#: AKModel/models.py:410
+#: AKModel/models.py:431
 msgid "Event"
 msgstr "Event"
 
 #: AKModel/availability/models.py:39 AKModel/models.py:77 AKModel/models.py:129
 #: AKModel/models.py:148 AKModel/models.py:180 AKModel/models.py:234
-#: AKModel/models.py:293 AKModel/models.py:325 AKModel/models.py:411
+#: AKModel/models.py:293 AKModel/models.py:325 AKModel/models.py:432
 msgid "Associated event"
 msgstr "Zugehöriges Event"
 
@@ -79,7 +83,7 @@ msgid "Person whose availability this is"
 msgstr "Person deren Verfügbarkeit hier abgebildet wird"
 
 #: AKModel/availability/models.py:56 AKModel/models.py:296
-#: AKModel/models.py:315 AKModel/models.py:419
+#: AKModel/models.py:315 AKModel/models.py:440
 msgid "Room"
 msgstr "Raum"
 
@@ -88,7 +92,7 @@ msgid "Room whose availability this is"
 msgstr "Raum dessen Verfügbarkeit hier abgebildet wird"
 
 #: AKModel/availability/models.py:65 AKModel/models.py:239
-#: AKModel/models.py:314 AKModel/models.py:366
+#: AKModel/models.py:314 AKModel/models.py:387
 msgid "AK"
 msgstr "AK"
 
@@ -97,7 +101,7 @@ msgid "AK whose availability this is"
 msgstr "Verfügbarkeiten"
 
 #: AKModel/availability/models.py:74 AKModel/models.py:132
-#: AKModel/models.py:425
+#: AKModel/models.py:446
 msgid "AK Category"
 msgstr "AK-Kategorie"
 
@@ -261,7 +265,7 @@ msgstr "Internet Link"
 msgid "Link to Homepage"
 msgstr "Link zu Homepage oder Webseite"
 
-#: AKModel/models.py:80 AKModel/models.py:418
+#: AKModel/models.py:80 AKModel/models.py:439
 msgid "AK Owner"
 msgstr "AK-Leitung"
 
@@ -321,7 +325,7 @@ msgstr "AK-Tags"
 msgid "Name of the Requirement"
 msgstr "Name der Anforderung"
 
-#: AKModel/models.py:183 AKModel/models.py:422
+#: AKModel/models.py:183 AKModel/models.py:443
 msgid "AK Requirement"
 msgstr "AK-Anforderung"
 
@@ -405,7 +409,7 @@ msgstr "AK präsentieren"
 msgid "Present results of this AK"
 msgstr "Die Ergebnisse dieses AKs vorstellen"
 
-#: AKModel/models.py:218 AKModel/templates/admin/AKModel/status.html:83
+#: AKModel/models.py:218 AKModel/templates/admin/AKModel/status.html:85
 msgid "Requirements"
 msgstr "Anforderungen"
 
@@ -458,9 +462,9 @@ msgstr "Interessenszähler"
 msgid "People who have indicated interest online"
 msgstr "Anzahl Personen, die online Interesse bekundet haben"
 
-#: AKModel/models.py:240 AKModel/models.py:413
+#: AKModel/models.py:240 AKModel/models.py:434
 #: AKModel/templates/admin/AKModel/status.html:49
-#: AKModel/templates/admin/AKModel/status.html:56
+#: AKModel/templates/admin/AKModel/status.html:56 AKModel/views.py:194
 msgid "AKs"
 msgstr "AKs"
 
@@ -536,163 +540,168 @@ msgstr "Letzte Aktualisierung"
 msgid "AK Slot"
 msgstr "AK-Slot"
 
-#: AKModel/models.py:331 AKModel/models.py:415
+#: AKModel/models.py:331 AKModel/models.py:436
 msgid "AK Slots"
 msgstr "AK-Slot"
 
-#: AKModel/models.py:345
+#: AKModel/models.py:353 AKModel/models.py:362
 msgid "Not scheduled yet"
 msgstr "Noch nicht geplant"
 
-#: AKModel/models.py:367
+#: AKModel/models.py:388
 #, fuzzy
 #| msgid "Track the AK belongs to"
 msgid "AK this message belongs to"
 msgstr "Track zu dem der AK gehört"
 
-#: AKModel/models.py:368
+#: AKModel/models.py:389
 msgid "Message text"
 msgstr "Nachrichtentext"
 
-#: AKModel/models.py:369
+#: AKModel/models.py:390
 msgid "Message to the organizers. This is not publicly visible."
 msgstr ""
 "Nachricht an die Organisator*innen. Diese ist nicht öffentlich sichtbar."
 
-#: AKModel/models.py:373
+#: AKModel/models.py:394
 msgid "AK Orga Message"
 msgstr "AK-Organachricht"
 
-#: AKModel/models.py:374
+#: AKModel/models.py:395
 msgid "AK Orga Messages"
 msgstr "AK-Organachrichten"
 
-#: AKModel/models.py:383
+#: AKModel/models.py:404
 msgid "Constraint Violation"
 msgstr "Constraintverletzung"
 
-#: AKModel/models.py:384
+#: AKModel/models.py:405
 msgid "Constraint Violations"
 msgstr "Constraintverletzungen"
 
-#: AKModel/models.py:388
+#: AKModel/models.py:409
 msgid "Owner has two parallel slots"
 msgstr "Leitung hat zwei Slots parallel"
 
-#: AKModel/models.py:389
+#: AKModel/models.py:410
 msgid "AK Slot was scheduled outside the AK's availabilities"
 msgstr "AK Slot wurde außerhalb der Verfügbarkeit des AKs platziert"
 
-#: AKModel/models.py:390
+#: AKModel/models.py:411
 msgid "Room has two AK slots scheduled at the same time"
 msgstr "Raum hat AK Slots gleichzeitig"
 
-#: AKModel/models.py:391
+#: AKModel/models.py:412
 msgid "Room does not satisfy the requirement of the scheduled AK"
 msgstr "Room erfüllt die Anforderungen des platzierten AKs nicht"
 
-#: AKModel/models.py:392
+#: AKModel/models.py:413
 msgid "AK Slot is scheduled at the same time as an AK listed as a conflict"
-msgstr "AK Slot wurde wurde zur gleichen Zeit wie ein Konflikt des AKs platziert"
+msgstr ""
+"AK Slot wurde wurde zur gleichen Zeit wie ein Konflikt des AKs platziert"
 
-#: AKModel/models.py:393
+#: AKModel/models.py:414
 msgid "AK Slot is scheduled before an AK listed as a prerequisite"
 msgstr "AK Slot wurde vor einem als Voraussetzung gelisteten AK platziert"
 
-#: AKModel/models.py:395
-msgid "AK Slot for AK with intention to submit a resolution is scheduled after "
+#: AKModel/models.py:416
+msgid ""
+"AK Slot for AK with intention to submit a resolution is scheduled after "
 "resolution deadline"
-msgstr "AK Slot eines AKs mit Resoabsicht wurde nach der Resodeadline platziert"
+msgstr ""
+"AK Slot eines AKs mit Resoabsicht wurde nach der Resodeadline platziert"
 
-#: AKModel/models.py:396
+#: AKModel/models.py:417
 msgid "AK Slot in a category is outside that categories availabilities"
 msgstr "AK Slot wurde außerhalb der Verfügbarkeiten seiner Kategorie"
 
-#: AKModel/models.py:397
+#: AKModel/models.py:418
 msgid "Two AK Slots for the same AK scheduled at the same time"
 msgstr "Zwei AK Slots eines AKs wurden zur selben Zeit platziert"
 
-#: AKModel/models.py:398
+#: AKModel/models.py:419
 msgid "AK Slot is scheduled in a room with less space than interest"
-msgstr "AK Slot wurde in einem Raum mit weniger Plätzen als am AK Interessierten platziert"
+msgstr ""
+"AK Slot wurde in einem Raum mit weniger Plätzen als am AK Interessierten "
+"platziert"
 
-#: AKModel/models.py:399
+#: AKModel/models.py:420
 msgid "AK Slot is scheduled outside the event's availabilities"
 msgstr "AK Slot wurde außerhalb der Verfügbarkeit des Events platziert"
 
-#: AKModel/models.py:402
+#: AKModel/models.py:423
 msgid "Warning"
 msgstr "Warnung"
 
-#: AKModel/models.py:403
+#: AKModel/models.py:424
 msgid "Violation"
 msgstr "Verletzung"
 
-#: AKModel/models.py:405
+#: AKModel/models.py:426
 msgid "Type"
 msgstr "Art"
 
-#: AKModel/models.py:406
+#: AKModel/models.py:427
 msgid "Type of violation, i.e. what kind of constraint was violated"
 msgstr "Art der Verletzung, gibt an welche Art Constraint verletzt wurde"
 
-#: AKModel/models.py:407
+#: AKModel/models.py:428
 msgid "Level"
 msgstr "Level"
 
-#: AKModel/models.py:408
+#: AKModel/models.py:429
 msgid "Severity level of the violation"
 msgstr "Schweregrad der Verletzung"
 
-#: AKModel/models.py:414
+#: AKModel/models.py:435
 msgid "AK(s) belonging to this constraint"
 msgstr "AK(s), die zu diesem Constraint gehören"
 
-#: AKModel/models.py:416
+#: AKModel/models.py:437
 msgid "AK Slot(s) belonging to this constraint"
 msgstr "AK Slot(s), die zu diesem Constraint gehören"
 
-#: AKModel/models.py:418
+#: AKModel/models.py:439
 msgid "AK Owner belonging to this constraint"
 msgstr "AK Leitung(en), die zu diesem Constraint gehören"
 
-#: AKModel/models.py:420
+#: AKModel/models.py:441
 msgid "Room belonging to this constraint"
 msgstr "Raum, der zu diesem Constraint gehört"
 
-#: AKModel/models.py:423
+#: AKModel/models.py:444
 msgid "AK Requirement belonging to this constraint"
 msgstr "AK Anforderung, die zu diesem Constraint gehört"
 
-#: AKModel/models.py:425
+#: AKModel/models.py:446
 msgid "AK Category belonging to this constraint"
 msgstr "AK Kategorie, di zu diesem Constraint gehört"
 
-#: AKModel/models.py:427
+#: AKModel/models.py:448
 msgid "Comment"
 msgstr "Kommentar"
 
-#: AKModel/models.py:427
+#: AKModel/models.py:448
 msgid "Comment or further details for this violation"
 msgstr "Kommentar oder weitere Details zu dieser Vereletzung"
 
-#: AKModel/models.py:430
+#: AKModel/models.py:451
 msgid "Timestamp"
 msgstr "Timestamp"
 
-#: AKModel/models.py:430
+#: AKModel/models.py:451
 msgid "Time of creation"
 msgstr "Zeitpunkt der ERstellung"
 
-#: AKModel/models.py:431
+#: AKModel/models.py:452
 msgid "Manually Resolved"
 msgstr "Manuell behoben"
 
-#: AKModel/models.py:432
+#: AKModel/models.py:453
 msgid "Mark this violation manually as resolved"
 msgstr "Markiere diese Verletzung manuell als behoben"
 
-#: AKModel/models.py:454
+#: AKModel/models.py:475
 msgid "Details"
 msgstr "Details"
 
@@ -790,19 +799,23 @@ msgstr "AKs als CSV exportieren"
 msgid "Export AKs for Wiki"
 msgstr "AKs im Wiki-Format exportieren"
 
-#: AKModel/templates/admin/AKModel/status.html:85
+#: AKModel/templates/admin/AKModel/status.html:82
+msgid "Export AK Slides"
+msgstr "AK-Folien exportieren"
+
+#: AKModel/templates/admin/AKModel/status.html:87
 msgid "No requirements yet"
 msgstr "Bisher keine Anforderungen"
 
-#: AKModel/templates/admin/AKModel/status.html:98
+#: AKModel/templates/admin/AKModel/status.html:100
 msgid "Add Requirement"
 msgstr "Anforderungen hinzufügen"
 
-#: AKModel/templates/admin/AKModel/status.html:101
+#: AKModel/templates/admin/AKModel/status.html:103
 msgid "Messages"
 msgstr "Nachrichten"
 
-#: AKModel/templates/admin/AKModel/status.html:103
+#: AKModel/templates/admin/AKModel/status.html:105
 msgid "Delete all messages"
 msgstr "Alle Nachrichten löschen"
 
@@ -810,22 +823,26 @@ msgstr "Alle Nachrichten löschen"
 msgid "Active Events"
 msgstr "Aktive Events"
 
-#: AKModel/views.py:130
+#: AKModel/views.py:133
 msgid "Event Status"
 msgstr "Eventstatus"
 
-#: AKModel/views.py:144
+#: AKModel/views.py:147
 msgid "AK CSV Export"
 msgstr "AK-CSV-Export"
 
-#: AKModel/views.py:158
+#: AKModel/views.py:161
 msgid "AK Wiki Export"
 msgstr "AK-Wiki-Export"
 
-#: AKModel/views.py:178
+#: AKModel/views.py:181
 msgid "AK Orga Messages successfully deleted"
 msgstr "AK-Organachrichten erfolgreich gelöscht"
 
+#: AKModel/views.py:195
+msgid "Wishes"
+msgstr "Wünsche"
+
 #~ msgid "Confirm"
 #~ msgstr "Bestätigen"
 
diff --git a/AKModel/templates/AKModel/export/slides.tex b/AKModel/templates/AKModel/export/slides.tex
new file mode 100644
index 00000000..31f8bdcd
--- /dev/null
+++ b/AKModel/templates/AKModel/export/slides.tex
@@ -0,0 +1,72 @@
+\documentclass{beamer}
+\usetheme{metropolis}
+% \usetheme[numbering=fraction, progressbar=foot]{metropolis} TODO Activate when total number of frames bug is resolved
+
+\usepackage[utf8]{inputenc}
+\usepackage{fontawesome5}
+
+\title{ {{- title -}} }
+\subtitle{ {{- subtitle -}} }
+\date{\today}
+
+\begin{document}
+
+\begin{frame}
+\maketitle
+\end{frame}
+
+
+{%for category in categories %}
+
+    \section{ {{- category.name | latex_escape_utf8 -}} }
+
+    {% for ak in category.ak_set.all() %}
+
+        {% if not ak.wish %}
+
+            %\setbeamertemplate{frame footer}{}
+
+            \begin{frame}[shrink=15]
+                \frametitle{ {{- ak.name | latex_escape_utf8 -}} }
+
+                \vspace{1em}
+
+                \faUser~ {{ ak.owners_list | latex_escape_utf8 }}
+
+                \faClock~ {{ak.durations_list}}
+
+                {% if ak.reso %}
+                    \faScroll
+                {% endif %}
+
+                {{ ak.description | latex_escape_utf8 }}
+
+            \end{frame}
+
+        {% endif %}
+
+    {% endfor %}
+
+{% endfor %}
+
+
+\section{ {{- wish_category_title -}} }
+
+{% for ak in wishes %}
+
+    %\setbeamertemplate{frame footer}{}
+
+    \begin{frame}[shrink=15]
+        \frametitle{ {{- ak.name | latex_escape_utf8 -}} }
+
+        \vspace{1em}
+
+        \faFilter~ {{ ak.category.name | latex_escape_utf8 }}
+
+        {{ ak.description | latex_escape_utf8 }}
+
+    \end{frame}
+
+{% endfor %}
+
+\end{document}
diff --git a/AKModel/templates/admin/AKModel/status.html b/AKModel/templates/admin/AKModel/status.html
index 032181e5..c0073e6c 100644
--- a/AKModel/templates/admin/AKModel/status.html
+++ b/AKModel/templates/admin/AKModel/status.html
@@ -78,6 +78,8 @@
                        href="{% url 'admin:ak_csv_export' event_slug=event.slug %}">{% trans "Export AKs as CSV" %}</a>
                     <a class="btn btn-success"
                        href="{% url 'admin:ak_wiki_export' event_slug=event.slug %}">{% trans "Export AKs for Wiki" %}</a>
+                    <a class="btn btn-success"
+                       href="{% url 'admin:ak_slide_export' event_slug=event.slug %}">{% trans "Export AK Slides" %}</a>
                 {% endif %}
 
                 <h3 class="block-header">{% trans "Requirements" %}</h3>
diff --git a/AKModel/views.py b/AKModel/views.py
index d560e9f6..b73c18a1 100644
--- a/AKModel/views.py
+++ b/AKModel/views.py
@@ -1,4 +1,5 @@
 from django.contrib import admin, messages
+from django.contrib.admin.views.decorators import staff_member_required
 from django.http import HttpResponseRedirect
 from django.shortcuts import get_object_or_404
 from django.urls import reverse_lazy
@@ -6,6 +7,8 @@ from django.utils.translation import gettext_lazy as _
 
 from django.views.generic import TemplateView, DetailView, ListView, DeleteView
 from rest_framework import viewsets, permissions, mixins
+from django_tex.shortcuts import render_to_pdf
+
 
 from AKModel.models import Event, AK, AKSlot, Room, AKTrack, AKCategory, AKOwner, AKOrgaMessage
 from AKModel.serializers import AKSerializer, AKSlotSerializer, RoomSerializer, AKTrackSerializer, AKCategorySerializer, \
@@ -177,3 +180,20 @@ class AKMessageDeleteView(AdminViewMixin, DeleteView):
         self.get_orga_messages_for_event(self.get_object()).delete()
         messages.add_message(self.request, messages.SUCCESS, _("AK Orga Messages successfully deleted"))
         return HttpResponseRedirect(reverse_lazy('admin:event_status', kwargs={'slug': self.get_object().slug}))
+
+
+@staff_member_required
+def export_slides(request, event_slug):
+    template_name = 'AKModel/export/slides.tex'
+
+    event = get_object_or_404(Event, slug=event_slug)
+
+    context = {
+        'title': event.name,
+        'categories': event.akcategory_set.all(),
+        'subtitle': _("AKs"),
+        'wish_category_title': _("Wishes"),
+        "wishes": [ak for ak in event.ak_set.order_by('category') if ak.wish]
+        }
+
+    return render_to_pdf(request, template_name, context, filename='slides.pdf')
-- 
GitLab