""" Génération d'un calendrier (Classe abstraite à implémenter dans les classes filles) """ import datetime from flask import render_template import app.scodoc.sco_utils as scu from app import g class Jour: """ Représente un jour dans le calendrier Permet d'obtenir les informations sur le jour et générer une représentation html """ def __init__(self, date: datetime.date): self.date = date self.class_list: list[str] = [] if self.is_non_work(): self.class_list.append("non-travail") if self.is_current_week(): self.class_list.append("sem-courante") def get_nom(self, short=True): """ Renvoie le nom du jour "M19" ou "Mer 19" par défaut en version courte """ str_jour: str = scu.DAY_NAMES[self.date.weekday()].capitalize() return ( f"{str_jour[0] if short or self.is_non_work() else str_jour[:3]+' '}" + f"{self.date.day}" ) def is_non_work(self): """ Renvoie True si le jour est un jour non travaillé (en fonction de la préférence du département) """ return self.date.weekday() in scu.NonWorkDays.get_all_non_work_days( dept_id=g.scodoc_dept_id ) def is_current_week(self): """ Renvoie True si le jour est dans la semaine courante """ return self.date.isocalendar()[1] == datetime.date.today().isocalendar()[1] def get_date(self) -> str: """ Renvoie la date du jour au format "dd/mm/yyyy" """ return self.date.strftime(scu.DATE_FMT) def get_html(self): """ Renvoie le code html du jour à surcharger dans les classes filles l'html final ressemblera à :
{{jour.get_nom()}}
{{jour.get_html() | safe}}
""" raise NotImplementedError("Méthode à implémenter dans les classes filles") def get_class(self): """ Renvoie la classe css du jour utilise self.class_list -> fait un join de la liste """ return " ".join(self.class_list) class Calendrier: """ Représente un calendrier Permet d'obtenir les informations sur les jours et générer une représentation html """ def __init__(self, date_debut: datetime.date, date_fin: datetime.date): self.date_debut = date_debut self.date_fin = date_fin self.jours: dict[str, list[Jour]] = {} def _get_dates_between(self) -> list[datetime.date]: """ get_dates_between Renvoie la liste des dates entre date_debut et date_fin Returns: list[datetime.date]: liste des dates entre date_debut et date_fin """ resultat = [] date_actuelle: datetime.date = self.date_debut while date_actuelle <= self.date_fin: if isinstance(date_actuelle, datetime.datetime): resultat.append(date_actuelle.date()) elif isinstance(date_actuelle, datetime.date): resultat.append(date_actuelle) date_actuelle += datetime.timedelta(days=1) return resultat def organize_by_month(self): """ Organise les jours par mois Instancie un objet Jour pour chaque jour met à jour self.jours """ organized = {} for date in self._get_dates_between(): # Récupérer le mois en français month = scu.MONTH_NAMES_ABBREV[date.month - 1] # Ajouter le jour à la liste correspondante au mois if month not in organized: organized[month] = [] jour: Jour = self.instanciate_jour(date) organized[month].append(jour) self.jours = organized def instanciate_jour(self, date: datetime.date) -> Jour: """ Instancie un objet Jour pour chaque jour A surcharger dans les classes filles si besoin """ raise NotImplementedError("Méthode à implémenter dans les classes filles") def get_html(self): """ get_html Renvoie le code html du calendrier """ self.organize_by_month() return render_template("calendrier.j2", calendrier=self.jours)