diff --git a/menubot.py b/menubot.py index b218fa0..d46a838 100644 --- a/menubot.py +++ b/menubot.py @@ -1,19 +1,25 @@ import base64 +import os import re +import traceback from dataclasses import dataclass from typing import Dict import json5 import requests +import telegram from bs4 import BeautifulSoup from tabulate import tabulate +from telegram import Update +from telegram.ext import Updater, CallbackContext, Dispatcher, CommandHandler, MessageHandler, \ + Filters def report(msg: str) -> None: print(msg) -def get_dinning_halls() -> dict[str, dict[str, str]]: +def get_dining_halls() -> dict[str, dict[str, str]]: r: str = requests.get('https://fso.ueat.utoronto.ca/FSO/ServiceMenuReport/Today').text m: list[str] = re.findall(r"ASPx\.createControl\(MVCxClientMenu,'mnuUnits','',.*", r) @@ -91,6 +97,90 @@ def filter_menu(menu: dict[str, list[MenuItem]]) -> dict[str, list[MenuItem]]: if __name__ == '__main__': - menu = filter_menu(get_menu('f1343803-84f6-4b4f-bbfd-a374ed6bd00e')[1]) - menu = {m: menu[m] for m in ['Soup', 'Lunch Entree', 'Pan Station']} - print(menu) + tg_token = os.environ['tg-token'] + updater = Updater(token=tg_token, use_context=True) + dispatcher: Dispatcher = updater.dispatcher + + def r(u: Update, msg: str, md=True): + updater.bot.sendMessage(chat_id=u.effective_chat.id, text=msg, + parse_mode='Markdown' if md else None) + + def start(u: Update, c: CallbackContext): + r(u, 'Test') + + def error(u: Update, c: CallbackContext): + traceback.print_exc() + r(u, str(c.error), False) + + def dining_halls(u: Update, c: CallbackContext): + halls = get_dining_halls() + r(u, '*Available Dining Halls:* \n' + '\n'.join(halls.keys()) + '\n\nNext: /menus ') + + def get_hall_with_name(hall: str): + hall = hall.lower() + halls = get_dining_halls() + h = [halls[h] for h in halls if h.lower().startswith(hall)] + if len(h) == 0: + raise AssertionError(f'No dining hall {hall} found.') + return h, h[0] + + def get_menu_with_name(hall: str, menu: str): + menu = menu.lower() + hall, h = get_hall_with_name(hall) + m = [m for m in h if m.lower().startswith(menu)] + if len(m) == 0: + raise AssertionError(f'No menu {menu} found in {hall}.') + return hall, m[0], get_menu(h[m[0]])[1] + + def get_menu_cats(hall: str, menu: str, cats: list[str]): + hall, menu, m = get_menu_with_name(hall, menu) + m = filter_menu(m) + copy_cats = cats.copy() + cats = [c.lower() for c in cats] + cats = [([n for n in m if n.lower().startswith(c)] or [''])[0] for c in cats] + cats = [c for c in cats if c != ''] + if len(cats) == 0: + raise AssertionError(f'No categories in {copy_cats} are valid.') + m = {c: m[c] for c in cats} + return hall, menu, m + + def menus(u: Update, c: CallbackContext): + if len(c.args) != 1: + r(u, 'Usage: /menus ') + return + hall = c.args[0] + hall, h = get_hall_with_name(hall) + r(u, '*Available Menus:* \n' + '\n'.join(h.keys()) + '\n\nNext: /cats ') + + def categories(u: Update, c: CallbackContext): + if len(c.args) < 2: + r(u, 'Usage: /categories ') + return + hall, menu = c.args + hall, menu, m = get_menu_with_name(hall, menu) + r(u, '*Available Menus:* \n' + '\n'.join(m.keys()) + '\n\nNext: /menu ') + + def menu(u: Update, c: CallbackContext): + if len(c.args) < 2: + r(u, 'Usage: /menu ') + return + hall, menu = c.args[:2] + cats = c.args[2:] + hall, menu, m = get_menu_cats(hall, menu, cats) + r(u, f"*Today's Menu for {menu}:* \n" + + '\n'.join(f"\n*{n}:* \n" + '\n'.join( + f"{i + 1}. {m[n][i].name} - ${m[n][i].price}" for i in range(len(m[n]))) + for n in m)) + + dispatcher.add_error_handler(error) + dispatcher.add_handler(CommandHandler('start', start)) + dispatcher.add_handler(CommandHandler('halls', dining_halls)) + dispatcher.add_handler(CommandHandler('menus', menus)) + dispatcher.add_handler(CommandHandler('categories', categories)) + dispatcher.add_handler(CommandHandler('cats', categories)) + dispatcher.add_handler(CommandHandler('menu', menu)) + dispatcher.add_handler(MessageHandler(Filters.update, start)) + updater.start_polling() + # + # menu = filter_menu(get_menu('f1343803-84f6-4b4f-bbfd-a374ed6bd00e')[1]) + # menu = {m: menu[m] for m in ['Soup', 'Lunch Entree', 'Pan Station']}