diff --git a/aleksis/apps/resint/migrations/0006_livedocument.py b/aleksis/apps/resint/migrations/0006_livedocument.py index 0065c61addd0ed16f283c461fb98cdf1585ed989..d7f55e31d14cac2ac795f27d8d8df4827d1b9bc3 100644 --- a/aleksis/apps/resint/migrations/0006_livedocument.py +++ b/aleksis/apps/resint/migrations/0006_livedocument.py @@ -1,5 +1,6 @@ -# Generated by Django 3.2.5 on 2021-08-03 18:02 +# Generated by Django 3.2.4 on 2021-08-05 14:20 +import aleksis.core.managers from django.db import migrations, models import django.db.models.deletion @@ -7,6 +8,7 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ + ('sites', '0002_alter_domain_unique'), ('contenttypes', '0002_remove_content_type_name'), ('resint', '0005_fix_permissions'), ] @@ -16,15 +18,20 @@ class Migration(migrations.Migration): name='LiveDocument', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('extended_data', models.JSONField(default=dict, editable=False)), ('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', editable=False)), - ('current_file', models.FileField(blank=True, null=True, upload_to='chronos/plan_pdfs/', verbose_name='Current file', editable=False)), + ('current_file', models.FileField(blank=True, editable=False, null=True, upload_to='live_documents/', verbose_name='Current file')), + ('last_update_triggered_manually', models.BooleanField(default=False, editable=False, verbose_name='Was the last update triggered manually?')), ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_resint.livedocument_set+', to='contenttypes.contenttype')), + ('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.site')), ], options={ 'verbose_name': 'Live document', 'verbose_name_plural': 'Live documents', }, + managers=[ + ('objects', aleksis.core.managers.PolymorphicCurrentSiteManager()), + ], ), ] diff --git a/aleksis/apps/resint/models.py b/aleksis/apps/resint/models.py index 1b47450b0d2f5f38f5552d344f5a3aaabf612466..b0c0d5c070a838f974080b92c4c1c87c3c08f182 100644 --- a/aleksis/apps/resint/models.py +++ b/aleksis/apps/resint/models.py @@ -7,11 +7,12 @@ from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ +import reversion from calendarweek import CalendarWeek from calendarweek.django import i18n_day_name_choices_lazy -from polymorphic.models import PolymorphicModel +from reversion.models import Revision, Version -from aleksis.core.mixins import ExtensibleModel +from aleksis.core.mixins import ExtensibleModel, ExtensiblePolymorphicModel class PosterGroup(ExtensibleModel): @@ -145,8 +146,8 @@ class Poster(ExtensibleModel): return timezone.datetime.combine(day, self.group.publishing_time) -class LiveDocument(PolymorphicModel): - """Model for periodically/automatically updated PDF files.""" +class LiveDocument(ExtensiblePolymorphicModel): + """Model for periodically/automatically updated files.""" slug = models.SlugField( verbose_name=_("Slug"), @@ -154,9 +155,6 @@ class LiveDocument(PolymorphicModel): ) 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, @@ -164,25 +162,51 @@ class LiveDocument(PolymorphicModel): verbose_name=_("Current file"), editable=False, ) + last_update_triggered_manually = models.BooleanField( + default=False, verbose_name=_("Was the last update triggered manually?"), 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() + @property + def last_version(self) -> Optional[Revision]: + """Get django-reversion version of last file update.""" + versions = Version.objects.get_for_object(self).order_by("revision__date_created") + if versions.exists(): + return versions.last() + return None + + @property + def last_update(self) -> Optional[datetime]: + """Get datetime of last file update.""" + last_version = self.last_version + if last_version: + return last_version.revision.date_created + return None def get_current_file(self) -> Optional[File]: - """Get current PDF file.""" + """Get current file.""" if not self.current_file: self.update() - return self.current_file.file if self.current_file else None + return self.current_file @property def filename(self) -> str: """Get the filename without path of the PDF file.""" return f"{self.slug}.pdf" + def save(self, *args, **kwargs): + with reversion.create_revision(): + super().save(*args, **kwargs) + + def update(self, triggered_manually: bool = True): + """Update the file with a new version. + + Has to be implemented by subclasses. + """ + pass + + def __str__(self) -> str: + return self.name + class Meta: verbose_name = _("Live document") verbose_name_plural = _("Live documents") diff --git a/aleksis/apps/resint/views.py b/aleksis/apps/resint/views.py index 28d5ff54b4f0f155349869a42c4e7599c9edafa7..abef233ed69b751e1f236a92aebf5b96658a5a8a 100644 --- a/aleksis/apps/resint/views.py +++ b/aleksis/apps/resint/views.py @@ -232,4 +232,4 @@ class LiveDocumentShowView(PermissionRequiredMixin, SingleObjectMixin, View): file = live_document.get_current_file() if not file: raise Http404 - return FileResponse(live_document.get_current_file(), content_type="application/pdf") + return FileResponse(file.file, content_type="application/pdf")