import datetime from typing import List, Tuple import ics from uuid import uuid4 import pandas as pd from jinja2 import Environment, FileSystemLoader, select_autoescape PROGRAM_UID = "a1799f64-f93c-48f1-bcf6-0e5619c9410c" BENEVOLE_SEPARATOR = "\n - " ALARM_DELTA = datetime.timedelta(minutes=-30) JINJA_ENV = Environment( loader=FileSystemLoader("templates"), autoescape=select_autoescape() ) def getContactList(benevole_names: List[str], df_contact) -> List[str]: if len(benevole_names) == 0: return [] filtered_contact = df_contact[df_contact["Prénom"].isin(benevole_names)] arr = filtered_contact.apply( lambda item: f"{item['Prénom']} : {item['Tél']}", axis=1 ) if len(arr) != len(benevole_names): print("Missing names from", benevole_names) return [] return arr.to_list() class Slot(object): def __init__( self, name: str, description: str, start: datetime.datetime, end: datetime.datetime, location: str, responsable: str, starting_with_you: List[str] = [], benevole_you_replace: List[str] = [], benevole_following_you: List[str] = [], ): self.name = name self.description = description self.start = start self.end = end self.location = location self.responsable = responsable self.starting_with_you = starting_with_you self.benevole_you_replace = benevole_you_replace self.benevole_following_you = benevole_following_you @property def horaire(self): return self.start.strftime("%Hh%M") + "-" + self.end.strftime("%Hh%M") @property def day(self): return (self.start - datetime.timedelta(hours=5)).date() @property def alarm_time(self): return self.start + ALARM_DELTA def toIEvent(self) -> ics.Event: description = f"{self.description}\n\nResponsable à contacter en cas de problème : {self.responsable}" if len(self.starting_with_you) > 0: description += ( "\n\nLes bénévoles avec qui tu sera : " + BENEVOLE_SEPARATOR.join(["", *self.starting_with_you]) ) if len(self.benevole_you_replace) > 0: description += ( "\n\nLes bénévoles que tu remplaces : " + BENEVOLE_SEPARATOR.join(["", *self.benevole_you_replace]) ) if len(self.benevole_following_you) > 0: description += ( "\n\nLes personnes qui arrivent après toi : " + BENEVOLE_SEPARATOR.join(["", *self.benevole_following_you]) ) alarms = [ics.AudioAlarm(ALARM_DELTA), ics.DisplayAlarm(ALARM_DELTA)] return ics.Event( name=f"[BDLG] {self.name}", begin=self.start, end=self.end, description=description, location=self.location, alarms=alarms, ) def toHTML(self) -> str: return JINJA_ENV.get_template("Creneau.html").render(slot=self) def toReminderText(self) -> str: return ( "Votre prochain créneau bénévole BDLG commence bientôt!\n" + f"Nom de créneau : {self.name}\n" + f"Début : {self.start.strftime('%Hh%M')}" ) def __repr__(self) -> str: return ( f"" ) def getSlots( username: str, df_planning, df_contact: pd.DataFrame, df_creneau: pd.DataFrame ) -> List[Slot]: df = df_planning arr = [] for row, item in df[df.benevole_nom == username].iterrows(): starting_with_you = df.benevole_nom[ (df.nom == item.nom) & (df.start == item.start) & (df.benevole_nom != username) ].to_list() benevole_you_replace = df.benevole_nom[ (df.nom == item.nom) & (df.end == item.start) ].to_list() benevole_following_you = df.benevole_nom[ (df.nom == item.nom) & (df.start == item.end) ].to_list() creneau_detail = df_creneau[ (df_creneau.nom == item.nom) | (df_creneau.nom == item.description_id) ] description = "" responsable = "undefined" location = "undefined" if len(creneau_detail) > 0: creneau = creneau_detail.iloc[0] description = creneau.description responsable = creneau.responsable location = creneau.lieu arr.append( Slot( name=item.nom, description=description, start=item.start, end=item.end, location=location, responsable=responsable, starting_with_you=getContactList(starting_with_you, df_contact), benevole_you_replace=getContactList(benevole_you_replace, df_contact), benevole_following_you=getContactList( benevole_following_you, df_contact ), ) ) return arr def getCalendarObject(slots: List[Slot]) -> ics.Calendar: new_calendar = ics.Calendar(creator=PROGRAM_UID) for slot in slots: new_calendar.events.add(slot.toIEvent()) return new_calendar def getCalendarObjects(slots: List[Slot]) -> List[ics.Calendar]: return [ ics.Calendar(creator=PROGRAM_UID, events=[slot.toIEvent()]) for slot in slots ] def getHTMLcontent(slots: List[Slot], name="", render_as_mail=True) -> str: return JINJA_ENV.get_template("Calendar.html").render( slots=slots, name=name, render_as_mail=render_as_mail ) def getHTMLhome(links: List[Tuple[str, str]]) -> str: return JINJA_ENV.get_template("Home.html").render(links=links)