From 1b20eb62e729f2ca3e27f1b5f278e5517acde970 Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Tue, 3 Aug 2021 20:22:04 +0200
Subject: [PATCH] Add model for live documents

---
 .../resint/migrations/0006_livedocument.py    | 30 +++++++++++++
 aleksis/apps/resint/models.py                 | 45 +++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 aleksis/apps/resint/migrations/0006_livedocument.py

diff --git a/aleksis/apps/resint/migrations/0006_livedocument.py b/aleksis/apps/resint/migrations/0006_livedocument.py
new file mode 100644
index 0000000..44a186a
--- /dev/null
+++ b/aleksis/apps/resint/migrations/0006_livedocument.py
@@ -0,0 +1,30 @@
+# Generated by Django 3.2.5 on 2021-08-03 18:02
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('resint', '0005_fix_permissions'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='LiveDocument',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('slug', models.SlugField(help_text='This will be used for the name of the current PDF file.', verbose_name='Slug')),
+                ('name', models.CharField(max_length=255, verbose_name='Name')),
+                ('last_update', models.DateTimeField(blank=True, null=True, verbose_name='Date and time of the last update')),
+                ('current_file', models.FileField(blank=True, null=True, upload_to='chronos/plan_pdfs/', verbose_name='Current file')),
+                ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_resint.livedocument_set+', to='contenttypes.contenttype')),
+            ],
+            options={
+                'verbose_name': 'Live document',
+                'verbose_name_plural': 'Live documents',
+            },
+        ),
+    ]
diff --git a/aleksis/apps/resint/models.py b/aleksis/apps/resint/models.py
index 4b0c97a..1b47450 100644
--- a/aleksis/apps/resint/models.py
+++ b/aleksis/apps/resint/models.py
@@ -1,6 +1,7 @@
 from datetime import datetime
 from typing import Optional
 
+from django.core.files import File
 from django.core.validators import FileExtensionValidator, MaxValueValidator, MinValueValidator
 from django.db import models
 from django.utils import timezone
@@ -8,6 +9,7 @@ from django.utils.translation import gettext_lazy as _
 
 from calendarweek import CalendarWeek
 from calendarweek.django import i18n_day_name_choices_lazy
+from polymorphic.models import PolymorphicModel
 
 from aleksis.core.mixins import ExtensibleModel
 
@@ -141,3 +143,46 @@ class Poster(ExtensibleModel):
         cw = CalendarWeek(week=self.week, year=self.year)
         day = cw[self.group.publishing_day]
         return timezone.datetime.combine(day, self.group.publishing_time)
+
+
+class LiveDocument(PolymorphicModel):
+    """Model for periodically/automatically updated PDF files."""
+
+    slug = models.SlugField(
+        verbose_name=_("Slug"),
+        help_text=_("This will be used for the name of the current PDF file."),
+    )
+    name = models.CharField(max_length=255, verbose_name=_("Name"))
+
+    last_update = models.DateTimeField(
+        blank=True, null=True, verbose_name=_("Date and time of the last update"), editable=False
+    )
+    current_file = models.FileField(
+        upload_to="live_documents/",
+        null=True,
+        blank=True,
+        verbose_name=_("Current file"),
+        editable=False,
+    )
+
+    def update(self, file: Optional[File] = None):
+        """Set a new PDF file as current file."""
+        if file:
+            self.current_file.save("current.pdf", file)
+            self.last_update = timezone.now()
+            self.save()
+
+    def get_current_file(self) -> Optional[File]:
+        """Get current PDF file."""
+        if not self.current_file:
+            self.update()
+        return self.current_file.file if self.current_file else None
+
+    @property
+    def filename(self) -> str:
+        """Get the filename without path of the PDF file."""
+        return f"{self.slug}.pdf"
+
+    class Meta:
+        verbose_name = _("Live document")
+        verbose_name_plural = _("Live documents")
-- 
GitLab