from django.db import models from django.db.models import Q from django.db.models import DateField, \ CharField, \ BooleanField, \ IntegerField from solo.models import SingletonModel from markdownx.models import MarkdownxField import datetime 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: 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 1/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, 1) def end(self): ''' Last day of this publication year (excl.) ''' return datetime.date(self.startYear + 1, 8, 1) 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']