| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- 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"<Slot name={self.name} start={self.start.ctime()} end={self.end.ctime()}>"
- )
- 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)
|