import re import json import os from datetime import datetime, timedelta from PyPDF2 import PdfReader import requests # === CONFIG === PDF_FILE = "menu.pdf" BOT_TOKEN = "TOKEN" CHAT_ID = "CHATID" # or use the channel's numeric ID # === HELPERS === def extract_text_from_pdf(path): reader = PdfReader(path) return "\n".join(page.extract_text() for page in reader.pages) def extract_month_year(text): match = re.search(r"Lunch\s+(\w+)\s+(\d{4})", text) if match: return match.group(1), int(match.group(2)) raise ValueError("Could not find month and year in PDF") def month_name_to_number(name): return datetime.strptime(name[:3], "%b").month def find_menu_items(text): # Match number-day + content, even if day markers are inline (e.g., "29) ... 30)") pattern = r"(\d{1,2}\))\s*(.*?)(?=(?:\n?\s*\d{1,2}\))|\Z)" matches = re.findall(pattern, text, re.DOTALL) entries = [] for day_marker, content in matches: day = day_marker.strip(")").strip() cleaned = re.sub(r"\s+", " ", content).strip() entries.append((day, cleaned)) return entries def build_menu_mapping(text, year, month): items = find_menu_items(text) menu_by_date = {} # Get all weekdays in the month current = datetime(year, month, 1) weekdays = [] while current.month == month: if current.weekday() < 5: # Mon–Fri weekdays.append(current) current += timedelta(days=1) # Match each menu item to weekday, assuming school days only for (day_str, content) in items: try: day = int(day_str) date = datetime(year, month, day) if date.weekday() >= 5: continue # Skip weekends date_key = date.strftime("%Y-%m-%d") cleaned = re.sub(r"\s+", " ", content).strip() menu_by_date[date_key] = cleaned except ValueError: continue return menu_by_date def load_or_parse_menu(): # Extract month/year text = extract_text_from_pdf(PDF_FILE) #print(text[:2000]) # show the first 2000 characters #exit() month_name, year = extract_month_year(text) month = month_name_to_number(month_name) # JSON cache json_file = f"menu_{year}_{month:02d}.json" if os.path.exists(json_file): with open(json_file) as f: return json.load(f) # Parse and save menu_data = build_menu_mapping(text, year, month) with open(json_file, "w") as f: json.dump(menu_data, f, indent=2) return menu_data def send_to_telegram(text): url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage" payload = {"chat_id": CHAT_ID, "text": text} response = requests.post(url, data=payload) return response.status_code == 200 def main(): today = datetime.now().strftime("%Y-%m-%d") menu = load_or_parse_menu() if today in menu: lunch = menu[today] if "Early Dismissal" in lunch: message = f"⚠️ Early Dismissal Today ({today}):\n\n{lunch}" elif "No School" in lunch: message = f"❌ No School Today ({today}):\n\n{lunch}" elif "No lunch" in lunch: message = f"⚠️ No Lunch Today ({today}):\n\n{lunch}" else: message = f"📅 Today's Lunch Menu ({today}):\n\n{lunch}" send_to_telegram(message) else: print(f"No menu for {today}. Might be a weekend or no school.") if __name__ == "__main__": main()