Telegram-Lunch-Bot/lunch.py
2025-04-10 09:12:36 -04:00

112 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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: # MonFri
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()