from pathlib import Path 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.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]: text = extract_text(self.menu_pdf_file, page_numbers=[0]) previous_was_title = False curated_text = "" for element in text.splitlines(): line = Line(element) if line.is_glitch(): previous_was_title = True elif line.starts_with_glitch(): curated_text += f"{line.text[2:]}\n" previous_was_title = True elif line.is_part_of_previous_line(): curated_text = curated_text.removesuffix("\n") curated_text += f"{line.text}\n" previous_was_title = False elif line.text == "" and previous_was_title: previous_was_title = False else: 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]} class Line: def __init__(self, text: str): self.text = text def is_glitch(self) -> bool: return len(self.text) == 1 def starts_with_glitch(self) -> bool: return len(self.text) > 1 and self.text[1] == " " def is_part_of_previous_line(self) -> bool: return len(self.text) > 0 and self.text[0].islower() class MenuMessageFormatter: @staticmethod def create_message(menus: Menus, menu_type: str) -> str: 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}") return f""" **Menu de la crèche** (message automatique) Menu {menu_type}: {days[0].upper()}: *Midi*: {menu[days[0]]["midi"]} *Goûter*: {menu[days[0]]["gouter"]} {days[1].upper()}: *Midi*: {menu[days[1]]["midi"]} *Goûter*: {menu[days[1]]["gouter"]} {days[2].upper()}: *Midi*: {menu[days[2]]["midi"]} *Goûter*: {menu[days[2]]["gouter"]} {days[3].upper()}: *Midi*: {menu[days[3]]["midi"]} *Goûter*: {menu[days[3]]["gouter"]} {days[4].upper()}: *Midi*: {menu[days[4]]["midi"]} *Goûter*: {menu[days[4]]["gouter"]} """