146 lines
4.5 KiB
Python
146 lines
4.5 KiB
Python
import datetime
|
||
|
||
from django.db import models
|
||
from django.db.models import BooleanField, CharField, DateField, IntegerField, Q
|
||
from markdownx.models import MarkdownxField
|
||
from solo.models import SingletonModel
|
||
|
||
|
||
class SiteConfiguration(SingletonModel):
|
||
homepageText = MarkdownxField("Texte de la page d'accueil (Markdown)")
|
||
writearticleText = MarkdownxField("Texte de la page « écrire » (Markdown)")
|
||
email = CharField(
|
||
"Adresse de contact du BOcal", max_length=128, help_text="Attention au spam…"
|
||
)
|
||
specialPublisDescr = MarkdownxField(
|
||
"Texte de la page des " "publications spéciales (Markdown)"
|
||
)
|
||
|
||
def __str__(self):
|
||
return "Configuration du site"
|
||
|
||
class Meta: # pyright: ignore
|
||
verbose_name = "Configuration du site"
|
||
|
||
|
||
class Publication(models.Model):
|
||
num = CharField("Numéro du BOcal", max_length=128)
|
||
url = CharField("Adresse sur le site", max_length=512)
|
||
# ^ This is not a URLField because we need internal URLS, eg `/static/blah`
|
||
|
||
date = DateField("Publication")
|
||
unknown_date = BooleanField(
|
||
"Date inconnue",
|
||
help_text=(
|
||
"La date de publication du BOcal "
|
||
"est inconnue parce qu'il est "
|
||
"trop vieux. La date indiquée ne "
|
||
"servira qu'à le ranger dans une "
|
||
"année et à ordonner les BOcals."
|
||
),
|
||
default=False,
|
||
)
|
||
is_special = BooleanField(
|
||
"Numéro spécial", help_text="Numéro du BOcal non-numéroté", default=False
|
||
)
|
||
in_year_view_anyway = BooleanField(
|
||
"Aussi dans l'année",
|
||
help_text=(
|
||
"Si le numéro est spécial, l'afficher quand même dans la "
|
||
"page de l'année correspondante."
|
||
),
|
||
default=False,
|
||
)
|
||
descr = CharField("Description (optionnelle)", max_length=512, blank=True)
|
||
custom_name = CharField(
|
||
"Nom customisé",
|
||
help_text="Vide pour laisser le numéro seulement",
|
||
max_length=128,
|
||
blank=True,
|
||
)
|
||
|
||
class NoPublicationYear(Exception):
|
||
def __str__(self):
|
||
return "No matching publication year."
|
||
|
||
@property
|
||
def numericPublicationYear(self):
|
||
startYear = self.date.year
|
||
if self.date.month < 8:
|
||
return startYear - 1
|
||
return startYear
|
||
|
||
def publicationYear(self):
|
||
"""Fetch corresponding publication year
|
||
Raise `NoPublicationYear` if there is no such entry"""
|
||
startYear = self.numericPublicationYear
|
||
try:
|
||
return PublicationYear.objects.get(startYear=startYear)
|
||
except PublicationYear.DoesNotExist:
|
||
raise self.NoPublicationYear
|
||
|
||
def createPubYear(self):
|
||
"""Creates the corresponding publication year if needed."""
|
||
if (
|
||
PublicationYear.objects.filter(
|
||
startYear=self.numericPublicationYear
|
||
).count()
|
||
) == 0:
|
||
pubYear = PublicationYear(startYear=self.numericPublicationYear, descr="")
|
||
pubYear.save()
|
||
return True
|
||
return False
|
||
|
||
def __str__(self):
|
||
if self.custom_name:
|
||
return self.custom_name
|
||
elif self.is_special:
|
||
return self.num
|
||
return "BOcal n°{}".format(self.num)
|
||
|
||
@staticmethod
|
||
def latest():
|
||
return Publication.objects.order_by("-date")[0]
|
||
|
||
class Meta:
|
||
ordering = ["date"]
|
||
|
||
|
||
class PublicationYear(models.Model):
|
||
startYear = IntegerField(
|
||
"Année de début", help_text="Année scolaire à partir du 15/08", primary_key=True
|
||
)
|
||
descr = MarkdownxField("Accroche de l'année (Markdown)")
|
||
|
||
def __str__(self):
|
||
return "{}-{}".format(self.startYear, self.startYear + 1)
|
||
|
||
def beg(self):
|
||
"""First day of this publication year (incl.)"""
|
||
return datetime.date(self.startYear, 8, 15)
|
||
|
||
def end(self):
|
||
"""Last day of this publication year (excl.)"""
|
||
return datetime.date(self.startYear + 1, 8, 15)
|
||
|
||
def inYear(self, date):
|
||
return self.beg() <= date < self.end()
|
||
|
||
def publis(self):
|
||
"""List of publications from this year"""
|
||
return Publication.objects.filter(
|
||
Q(is_special=False) | Q(in_year_view_anyway=True),
|
||
date__gte=self.beg(),
|
||
date__lt=self.end(),
|
||
)
|
||
|
||
@property
|
||
def url(self):
|
||
return "/{}/".format(self)
|
||
|
||
@property
|
||
def prettyName(self):
|
||
return "{} – {}".format(self.startYear, self.startYear + 1)
|
||
|
||
class Meta:
|
||
ordering = ["-startYear"]
|