diff --git a/config.py b/config.py index 0cf8dc8..caec3f9 100644 --- a/config.py +++ b/config.py @@ -5,7 +5,6 @@ from dotenv import load_dotenv load_dotenv() MENU_CRECHE_PDF_URL = os.environ.get("MENU_CRECHE_PDF_URL") -MENU_TYPES = os.environ.get("MENU_TYPES").split(",") SIGNAL_SENDER = os.environ.get("SIGNAL_SENDER") SIGNAL_RECIPIENTS = os.environ.get("SIGNAL_RECIPIENTS", default=SIGNAL_SENDER).split( "," diff --git a/main.py b/main.py index 716f911..d0c850a 100644 --- a/main.py +++ b/main.py @@ -1,13 +1,11 @@ +import hashlib from pathlib import Path from dotenv import load_dotenv -from jinja2 import Environment, select_autoescape, FileSystemLoader -from pdfminer.pdfdocument import PDFDocument -from pdfminer.pdfparser import PDFParser +from jinja2 import Environment, FileSystemLoader, select_autoescape from config import ( MENU_CRECHE_PDF_URL, - MENU_TYPES, SIGNAL_SENDER, SIGNAL_RECIPIENTS, SIGNAL_API_URL, @@ -23,55 +21,38 @@ load_dotenv() logger = get_logger(__name__) -def read_pdf_metadata(pdf_file: Path): - fp = open(pdf_file, "rb") - parser = PDFParser(fp) - doc = PDFDocument(parser) - return doc.info +templates_path = Path(__file__).parent / "templates" +env = Environment( + loader=FileSystemLoader(templates_path), autoescape=select_autoescape() +) +message_formatter = MenuMessageFormatter(env) + +signal_messager = SignalMessager(SIGNAL_API_URL, SIGNAL_SENDER) def main(): logger.info(f"Téléchargement du menu à l'adresse {MENU_CRECHE_PDF_URL}...") menu_pdf_file = download(MENU_CRECHE_PDF_URL, file_name="menu.pdf") + with open(menu_pdf_file, "rb") as pdf_file: + sha256 = hashlib.file_digest(pdf_file, "sha256").hexdigest() try: menus = Menus(menu_pdf_file) except IndexError as err: logger.error(err) - menus = None - - logger.info("Extraction des métadonnées du PDF") - pdf_metadata = read_pdf_metadata(menu_pdf_file) - creation_date = pdf_metadata[0]["CreationDate"].decode("utf-8").removeprefix("D:") - modification_date = pdf_metadata[0]["ModDate"].decode("utf-8").removeprefix("D:") - logger.debug( - f"Le PDF a été créé le {creation_date} et modifié le {modification_date}" - ) + return result_file = ResultFile(Path.home() / ".cache" / "menu_creche.txt") + if result_file.was_already_sent(sha256, menus): + return + is_update = result_file.is_update(sha256, menus) + message = message_formatter.create_message(menus, is_update) - templates_path = Path(__file__).parent / "templates" - env = Environment( - loader=FileSystemLoader(templates_path), autoescape=select_autoescape() + logger.info( + f"Envoi du message aux numéros {SIGNAL_RECIPIENTS} de la part de " + f"{SIGNAL_SENDER} avec pour contenu:\n\n{message}" ) - message_formatter = MenuMessageFormatter(env) - - for menu_type in MENU_TYPES: - if result_file.was_already_sent(creation_date, modification_date, menu_type): - logger.info(f"Le menu {menu_type} du PDF a déjà été envoyé par le passé.") - continue - - logger.debug(f"Création du message à envoyer pour le menu {menu_type}") - message = message_formatter.create_message(menus, menu_type) - - logger.info( - f"Envoi du message aux numéros {SIGNAL_RECIPIENTS} de la part de {SIGNAL_SENDER}" - ) - logger.debug(f"Le message envoyé a pour contenu :\n\n{message}") - signal_messager = SignalMessager(SIGNAL_API_URL, SIGNAL_SENDER) - signal_messager.send_message(message, menu_pdf_file, SIGNAL_RECIPIENTS) - - result_file.write(creation_date, modification_date, menu_type) + signal_messager.send_message(message, menu_pdf_file, SIGNAL_RECIPIENTS) if __name__ == "__main__": diff --git a/menus.py b/menus.py index aff7236..2c8461d 100644 --- a/menus.py +++ b/menus.py @@ -2,31 +2,17 @@ from pathlib import Path from jinja2 import Environment from pdfminer.high_level import extract_text -from pdfminer.pdfdocument import PDFDocument -from pdfminer.pdfparser import PDFParser class Menus: def __init__(self, menu_pdf_file: Path): self.menu_pdf_file = menu_pdf_file - self.pdf_metadata = self.extract_pdf_metadata() - self._cells = self.extract_cells() - self.month = self.extract_month() - self.days = self.extract_days() + self.month = "" + self.days = [] + self.extract_cells() - self.introduction = self.extract_introduction_menu() - self.diversification = self.extract_diversification_menu() - self.petit_muscle = self.extract_petit_muscle_menu() - self.petit_lion = self.extract_petit_lion_menu() - - def extract_pdf_metadata(self): - fp = open(self.menu_pdf_file, "rb") - parser = PDFParser(fp) - doc = PDFDocument(parser) - return doc.info - - def extract_cells(self) -> list[str]: + def extract_cells(self) -> None: text = extract_text(self.menu_pdf_file, page_numbers=[0]) previous_was_title = False @@ -48,52 +34,9 @@ class Menus: curated_text += f"{line.text}\n" previous_was_title = False - return curated_text.split("\n\n") - - def extract_month(self) -> str: - return self._cells[0] - - def extract_days(self) -> list[str]: - return self._cells[6:11] - - def extract_introduction_menu(self) -> dict[str, dict[str, str]]: - return { - self.days[0]: self.build_menu_of_day(11, 16), - self.days[1]: self.build_menu_of_day(12, 17), - self.days[2]: self.build_menu_of_day(13, 18), - self.days[3]: self.build_menu_of_day(14, 19), - self.days[4]: self.build_menu_of_day(15, 20), - } - - def extract_diversification_menu(self) -> dict[str, dict[str, str]]: - return { - self.days[0]: self.build_menu_of_day(21, 26), - self.days[1]: self.build_menu_of_day(22, 27), - self.days[2]: self.build_menu_of_day(23, 28), - self.days[3]: self.build_menu_of_day(24, 29), - self.days[4]: self.build_menu_of_day(25, 30), - } - - def extract_petit_muscle_menu(self) -> dict[str, dict[str, str]]: - return { - self.days[0]: self.build_menu_of_day(31, 35), - self.days[1]: self.build_menu_of_day(32, 36), - self.days[2]: self.build_menu_of_day(33, 37), - self.days[3]: self.build_menu_of_day(34, 38), - self.days[4]: self.build_menu_of_day(43, 50), - } - - def extract_petit_lion_menu(self): - return { - self.days[0]: self.build_menu_of_day(39, 46), - self.days[1]: self.build_menu_of_day(40, 47), - self.days[2]: self.build_menu_of_day(41, 48), - self.days[3]: self.build_menu_of_day(42, 49), - self.days[4]: self.build_menu_of_day(45, 44), - } - - def build_menu_of_day(self, midi: int, gouter: int) -> dict[str, str]: - return {"midi": self._cells[midi], "gouter": self._cells[gouter]} + cells = curated_text.split("\n\n") + self.month = cells[0] + self.days = cells[6:11] class Line: @@ -114,22 +57,6 @@ class MenuMessageFormatter: def __init__(self, env: Environment): self.env = env - def create_message(self, menus: Menus, menu_type: str) -> str: - if menus is None: - template = self.env.get_template("menu-erreur.txt") - return template.render(menu_type=menu_type) - - days = menus.days - if menu_type.lower() == "introduction": - menu = menus.introduction - elif menu_type.lower() == "diversification": - menu = menus.diversification - elif menu_type.lower() == "petit muscle": - menu = menus.petit_muscle - elif menu_type.lower() == "petit lion": - menu = menus.petit_lion - else: - raise Exception(f"Unknown menu type: {menu_type}") - - template = self.env.get_template("menus.txt") - return template.render(menu=menu, menu_type=menu_type, days=days) + def create_message(self, menus: Menus, is_update: bool) -> str: + template = self.env.get_template("message.txt") + return template.render(menus=menus, is_update=is_update) diff --git a/message.txt b/message.txt new file mode 100644 index 0000000..aa2c11a --- /dev/null +++ b/message.txt @@ -0,0 +1,4 @@ +{% if is_update %} +*Mise-à-jour* +{% endif %} +Menu de la crèche de la semaine du {{ menus.days[0] }} {{ menus.month }} au {{ menus.days[4] }} {{ menus.month }} \ No newline at end of file diff --git a/result_file.py b/result_file.py index c1c629f..c4ca839 100644 --- a/result_file.py +++ b/result_file.py @@ -1,20 +1,33 @@ +import datetime from pathlib import Path +from menus import Menus + class ResultFile: def __init__(self, path: Path): self.path = path - def write(self, creation_date: str, modification_date: str, menu_type: str) -> None: + def write(self, sha256: str, menus: Menus) -> None: if not self.path.exists(): self.path.write_text("") with self.path.open(mode="a") as file: - file.write(f"{creation_date}/{modification_date}/{menu_type}\n") + file.write( + f"{sha256} - {menus.days[0]} - {menus.month} - {datetime.date.today().year}\n" + ) - def was_already_sent( - self, creation_date: str, modification_date: str, menu_type: str - ): + def was_already_sent(self, sha256: str, menus: Menus): if not self.path.exists(): return False content = self.path.read_text() - return f"{creation_date}/{modification_date}/{menu_type}\n" in content + return ( + f"{sha256} - {menus.days[0]} - {menus.month} - {datetime.date.today().year}" + in content + ) + + def is_update(self, sha256: str, menus: Menus): + if not self.path.exists(): + return False + content = self.path.read_text() + date = f"{menus.days[0]} - {menus.month} - {datetime.date.today().year}" + return f"{sha256} - {date}" not in content and date in content diff --git a/templates/menu-erreur.txt b/templates/menu-erreur.txt deleted file mode 100644 index b16e8af..0000000 --- a/templates/menu-erreur.txt +++ /dev/null @@ -1,9 +0,0 @@ -**Menu de la crèche** - -Menu {{ menu_type.upper() }}: -Malheureusement, une erreur a eu lieu lors de la récupération des menus. -Etant donné la complexité de la récupération des menus, on peut envisager que cela est dû à un jour férié. -D'autres hypothèses peuvent toutefois être envisagées -Veuillez contacter le développeur pour plus d'informations... - -Il est bien mon texte ? Il fait très pro, je trouve :D diff --git a/templates/menus.txt b/templates/menus.txt deleted file mode 100644 index 91754e3..0000000 --- a/templates/menus.txt +++ /dev/null @@ -1,8 +0,0 @@ -**Menu de la crèche** - -Menu {{ menu_type.upper() }}: -{% for day in days %} -**{{ day.upper() }}** -**Midi :** {{ menu[day]["midi"] }} -**Goûter :** {{ menu[day]["gouter"] }} -{% endfor %} \ No newline at end of file