2021-12-09 16:53:44 +01:00
|
|
|
"""Ensemble des classes d'utilité publique :-)"""
|
|
|
|
|
|
|
|
from django.db import models
|
|
|
|
from datetime import datetime, date, time, timedelta
|
|
|
|
from django.utils import timezone
|
|
|
|
|
|
|
|
import markdown
|
|
|
|
|
|
|
|
|
|
|
|
def get_number_of_weeks_between(start, stop):
|
|
|
|
"""
|
2021-12-19 09:30:51 +01:00
|
|
|
Renvoie le nombre de semaines entre deux dates.
|
|
|
|
Par extension, cela permet de connaitre le nombre d'occurence d'un
|
|
|
|
évènement (entraînement, par exemple) hebdromadaire entre deux dates
|
|
|
|
et ainsi pouvoir plannifier.
|
|
|
|
|
|
|
|
:param start: date de début de la période
|
|
|
|
:type start: datetime.date
|
|
|
|
:param stop: date de fin de la période
|
|
|
|
:type stop: datetime.date
|
|
|
|
:return: Le nombre de semaines entre les deux dates.
|
|
|
|
|
|
|
|
Remarks:
|
|
|
|
Proposition d'utiliser isocalendar() sur une date.
|
|
|
|
L'indice 1 de la valeur de retour donne la semaine correspondant.
|
|
|
|
|
|
|
|
Eg.
|
|
|
|
>>> from datetime import date
|
|
|
|
>>> d = date(2020, 9, 27)
|
|
|
|
>>> d.isocalendar()
|
|
|
|
(2020, 39, 7)
|
|
|
|
|
|
|
|
-> Est-ce qu'il ne suffirait pas de faire la différence ?
|
|
|
|
"""
|
2021-12-09 16:53:44 +01:00
|
|
|
|
|
|
|
tmp = stop - start
|
|
|
|
number_of_days = abs(tmp.days)
|
|
|
|
number_of_week = int((number_of_days + 1) / 7)
|
|
|
|
|
|
|
|
if ((number_of_days + 1) % 7) > 0:
|
|
|
|
number_of_week += 1
|
|
|
|
|
|
|
|
if tmp.days < 0:
|
|
|
|
number_of_week *= -1
|
|
|
|
|
|
|
|
return number_of_week
|
|
|
|
|
|
|
|
|
|
|
|
class TemporizableQuerySet(models.QuerySet):
|
|
|
|
"""
|
2021-12-19 09:30:51 +01:00
|
|
|
Classe permettant de spécifier le `QuerySet` de la classe `Temporizable`.
|
|
|
|
"""
|
2021-12-09 16:53:44 +01:00
|
|
|
|
|
|
|
def next(self, limit):
|
|
|
|
"""
|
2021-12-19 09:30:51 +01:00
|
|
|
Renvoie la liste des prochains "temporizable" (par rapport à la date du jour).
|
2021-12-09 16:53:44 +01:00
|
|
|
|
2021-12-19 09:30:51 +01:00
|
|
|
:param limit: nombre d'éléments désirés.
|
|
|
|
:type limit: int
|
|
|
|
:return: une liste de `limit` éléments temporizables.
|
|
|
|
"""
|
|
|
|
return self.filter(datebegin__gte=timezone.now()).order_by("datebegin")[0:limit]
|
2021-12-09 16:53:44 +01:00
|
|
|
|
|
|
|
def last(self, limit):
|
|
|
|
"""
|
2021-12-19 09:30:51 +01:00
|
|
|
Renvoie la liste des derniers "temporizable" (par rapport à la date du jour).
|
2021-12-09 16:53:44 +01:00
|
|
|
|
2021-12-19 09:30:51 +01:00
|
|
|
:param limit: nombre d'éléments désirés.
|
|
|
|
:type limit: int
|
|
|
|
:return: une liste de `limit` éléments temporizables
|
|
|
|
"""
|
|
|
|
return self.filter(dateend__lte=timezone.now()).order_by("-dateend")[0:limit]
|
2021-12-09 16:53:44 +01:00
|
|
|
|
|
|
|
# def get(self, date_string):
|
|
|
|
# """
|
|
|
|
# """
|
|
|
|
# try:
|
|
|
|
# selected_object = self.get(datebegin__lte=date_string, dateend__gte=date_string)
|
|
|
|
# except self.DoesNotExist:
|
|
|
|
# return None
|
|
|
|
# except self.MultipleObjectsReturned:
|
|
|
|
# return None
|
|
|
|
|
|
|
|
# return selected_object
|
|
|
|
|
|
|
|
|
|
|
|
class Temporizable(models.Model):
|
|
|
|
"""
|
|
|
|
Classe abstraite définissant une période comprise entre deux dates.
|
2021-12-19 09:30:51 +01:00
|
|
|
"""
|
2021-12-09 16:53:44 +01:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
abstract = True
|
|
|
|
|
2022-01-03 08:02:02 +01:00
|
|
|
datebegin = models.DateTimeField(verbose_name="Début", default=timezone.now)
|
2022-01-02 16:42:32 +01:00
|
|
|
dateend = models.DateTimeField(blank=True, null=True, verbose_name="Fin")
|
2021-12-09 16:53:44 +01:00
|
|
|
|
|
|
|
objects = models.Manager.from_queryset(TemporizableQuerySet)()
|
|
|
|
|
|
|
|
def get_total_occurence(self):
|
|
|
|
"""
|
2021-12-19 09:30:51 +01:00
|
|
|
Renvoie le nombre de semaines entre les deux dates d'une instance de la
|
|
|
|
classe `Temporizable`.
|
2021-12-09 16:53:44 +01:00
|
|
|
|
2021-12-19 09:30:51 +01:00
|
|
|
:return: nombre de semaines.
|
|
|
|
"""
|
2021-12-09 16:53:44 +01:00
|
|
|
return get_number_of_weeks_between(self.datebegin.date(), self.dateend.date())
|
|
|
|
|
|
|
|
def get_number_of_occurence_to_event(self, the_date):
|
|
|
|
"""
|
2021-12-19 09:30:51 +01:00
|
|
|
Renvoie le nombre semaines entre une date choisie et le début
|
|
|
|
(datebegin) d'une instance de la classe `Temporizable`.
|
2021-12-09 16:53:44 +01:00
|
|
|
|
2021-12-19 09:30:51 +01:00
|
|
|
:param the_date: date par rapport à laquelle le calcul sera fait.
|
|
|
|
:type the_date: datetime.date
|
|
|
|
:return: nombre de semaines.
|
|
|
|
"""
|
2021-12-09 16:53:44 +01:00
|
|
|
return get_number_of_weeks_between(the_date, self.datebegin.date())
|
|
|
|
|
|
|
|
def get_number_of_occurence_inbetween(self, the_date, rest=True):
|
|
|
|
"""
|
2021-12-19 09:30:51 +01:00
|
|
|
Renvoie le nombre semaines entre une date choisie et une instance de la
|
|
|
|
classe `Temporizable`. Le calcul peut se faire soit entre la date
|
|
|
|
choisie et le date de fin d'une occurence de la classe, soit entre la
|
|
|
|
date de début d'une occurence de la classe et la date choisie.
|
|
|
|
|
|
|
|
:param the_date: date par rapport à laquelle le calcul sera fait.
|
|
|
|
:type the_date: datetime.date
|
|
|
|
:param rest: paramètre définissant s'il faut calculer le reste des
|
|
|
|
occurences à venir (depuis `the_date` jusqu'à la date de fin) ou
|
|
|
|
les occurences déjà passées (depuis la date de début jusqu'à
|
|
|
|
`the_date`)
|
|
|
|
:type rest: booléen
|
|
|
|
:return: nombre de semaines.
|
|
|
|
"""
|
2021-12-09 16:53:44 +01:00
|
|
|
if rest:
|
|
|
|
return get_number_of_weeks_between(the_date, self.dateend.date())
|
|
|
|
else:
|
|
|
|
return get_number_of_weeks_between(self.datebegin.date(), the_date)
|
|
|
|
|
|
|
|
|
|
|
|
class Markdownizable(models.Model):
|
|
|
|
"""
|
|
|
|
Classe abstraite ajoutant un champ `informations`, convertible de .md -> .html.
|
|
|
|
"""
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
abstract = True
|
|
|
|
|
|
|
|
informations = models.TextField(
|
|
|
|
null=True,
|
|
|
|
blank=True,
|
2021-12-19 09:30:51 +01:00
|
|
|
verbose_name="Comments",
|
|
|
|
help_text="Only MarkDown is authorized",
|
2021-12-09 16:53:44 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
def to_markdown(self):
|
|
|
|
"""Convertit le champ `informations` en (Github-flavored) Markdown."""
|
|
|
|
|
|
|
|
return markdown.markdown(self.informations)
|