import logging from datetime import date from pathlib import Path from django.core.validators import ValidationError from django.db import models from django.db.models.constraints import UniqueConstraint from django.urls import reverse from django.utils import timezone from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ from documents import create_pad, get_pad_html from documents.api import get_pad_link from tasks.models import TaskList logger = logging.getLogger(__name__) class TopicGroup(models.Model): title = models.CharField(verbose_name="Titel", max_length=128) shortterm = models.CharField(max_length=10, unique=True) slug = models.SlugField(max_length=10, unique=True) short_description = models.TextField(null=True, blank=True) order = models.PositiveSmallIntegerField( verbose_name="Reihenfolge", unique=True, null=True, blank=True ) objects = models.Manager() class Meta: verbose_name = "Themenbereich" # "1." because this point should be displayed first in admin view. verbose_name_plural = "Themenbereiche" def __str__(self): return self.title def get_absolute_url(self): return reverse("intern:index") + "#" + self.slug def clean(self, *args, **kwargs): self.slug = slugify(self.shortterm) class Topic(models.Model): title = models.CharField(verbose_name="Titel", max_length=128) shortterm = models.CharField(max_length=10, unique=True) slug = models.SlugField(max_length=10, unique=True) archive = models.BooleanField(verbose_name="Archiv", default=False) description = models.TextField(null=True, blank=True) topic_group = models.ForeignKey( TopicGroup, on_delete=models.CASCADE, verbose_name="Themenbereich" ) task_list = models.ForeignKey( TaskList, on_delete=models.CASCADE, null=True, blank=True ) objects = models.Manager() class Meta: verbose_name = "Thema" verbose_name_plural = "Themen" def __str__(self): return self.title def get_absolute_url(self): return reverse("intern:topic", kwargs={"slug": self.slug}) def clean(self, *args, **kwargs): self.slug = slugify(self.shortterm) class Attachment(models.Model): title = models.CharField(verbose_name="Titel", max_length=128) shortterm = models.CharField(max_length=10) slug = models.SlugField(max_length=10) description = models.TextField(null=True, blank=True) topic = models.ForeignKey(Topic, on_delete=models.CASCADE) objects = models.Manager() class Meta: verbose_name = "Anhang Ordner" verbose_name_plural = "Anhang Ordner" constraints = [ UniqueConstraint(fields=["slug", "topic"], name="unique_intern_slug_topic"), UniqueConstraint( fields=["title", "topic"], name="unique_intern_title_topic" ), ] def __str__(self): return self.topic.title + " / " + self.title def get_absolute_url(self): kwargs = { "topic_slug": self.topic.slug, "slug": self.slug, } return reverse("intern:attachment", kwargs=kwargs) def clean(self, *args, **kwargs): self.slug = slugify(self.shortterm) class Etherpad(models.Model): title = models.CharField(verbose_name="Titel", max_length=128) slug = models.SlugField(null=True, blank=True) etherpad_key = models.CharField(max_length=50, blank=True) date = models.DateField(verbose_name="Datum", default=date.today) attachment = models.ForeignKey(Attachment, on_delete=models.CASCADE) objects = models.Manager() class Meta: verbose_name = "Etherpad" verbose_name_plural = "Etherpads" constraints = [ UniqueConstraint( fields=["title", "date", "attachment"], name="unique_intern_etherpad" ), ] def __str__(self): return self.title def get_absolute_url(self): return get_pad_link(self.__get_pad_name()) def __get_pad_name(self): return ( slugify(self.date) + "-" + self.attachment.topic.slug + "-" + self.attachment.slug + "-" + self.slug ) def clean(self): self.slug = slugify(self.title) if not self.etherpad_key: pad_name = self.__get_pad_name() if len(pad_name) > 50: raise ValidationError( _( "Name zum Erstellen des Etherpads ist zu lange - max. 50 Zeichen. (Länge: %(length)s, Name: %(pad_name)s)" ), params={"length": len(pad_name), "pad_name": pad_name}, ) self.etherpad_key = create_pad(pad_name) if not self.etherpad_key: raise ValidationError( _(f"Etherpad '{pad_name}' konnte nicht erstellt werden."), ) @property def etherpad_html(self): if not self.__get_pad_name(): return None return get_pad_html(self.__get_pad_name()) class FileUpload(models.Model): title = models.CharField(verbose_name="Titel", max_length=128, blank=True) file_field = models.FileField( verbose_name="Dokument", upload_to="uploads/intern/files/" ) date = models.DateField(verbose_name="Datum", default=date.today) attachment = models.ForeignKey(Attachment, on_delete=models.CASCADE) objects = models.Manager() class Meta: verbose_name = "Datei" verbose_name_plural = "Dateien" def __str__(self): return self.title def clean(self): if not self.title: self.title = Path(self.file_field.name).stem