added settings menu
This commit is contained in:
parent
41d7dd066b
commit
b7bf0e7fa2
167
src/beebot.py
167
src/beebot.py
@ -11,8 +11,8 @@ from typing import Optional
|
||||
import requests
|
||||
import telegram.constants
|
||||
from bs4 import BeautifulSoup
|
||||
from telegram import Update
|
||||
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
|
||||
from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes, CallbackQueryHandler
|
||||
|
||||
log_dir = os.getenv("BEEBOT_LOGS")
|
||||
if not log_dir:
|
||||
@ -35,6 +35,12 @@ logging.basicConfig(
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def flag(code):
|
||||
offset = 127462 - ord('A')
|
||||
code = code.upper()
|
||||
return chr(ord(code[0]) + offset) + chr(ord(code[1]) + offset)
|
||||
|
||||
class BeeBot:
|
||||
MENU_URL = "https://www.epfl.ch/campus/restaurants-shops-hotels/fr/industrie21-epfl-valais-wallis/?date={date}"
|
||||
RESTO_ID = 545
|
||||
@ -43,6 +49,34 @@ class BeeBot:
|
||||
DB_PATH = os.path.join(BASE_DIR, "database.db")
|
||||
TEMPLATE_PATH = os.path.join(BASE_DIR, "menu.typ")
|
||||
IMG_DIR = "/tmp/menu_images"
|
||||
LANGUAGES = {
|
||||
"en": {
|
||||
"emoji": flag("gb"),
|
||||
"name": "English"
|
||||
},
|
||||
"fr": {
|
||||
"emoji": flag("fr"),
|
||||
"name": "Français"
|
||||
},
|
||||
"de": {
|
||||
"emoji": flag("de"),
|
||||
"name": "Deutsch"
|
||||
}
|
||||
}
|
||||
CATEGORIES = {
|
||||
"E": {
|
||||
"name": "Étudiant"
|
||||
},
|
||||
"D": {
|
||||
"name": "Doctorant"
|
||||
},
|
||||
"C": {
|
||||
"name": "Campus"
|
||||
},
|
||||
"V": {
|
||||
"name": "Visiteur"
|
||||
}
|
||||
}
|
||||
|
||||
def __init__(self, token: str):
|
||||
self.tg_token: str = token
|
||||
@ -63,6 +97,8 @@ class BeeBot:
|
||||
app = ApplicationBuilder().token(self.tg_token).build()
|
||||
app.add_handler(CommandHandler("week", self.cmd_week))
|
||||
app.add_handler(CommandHandler("today", self.cmd_today))
|
||||
app.add_handler(CommandHandler("settings", self.cmd_settings))
|
||||
app.add_handler(CallbackQueryHandler(self.cb_handler))
|
||||
|
||||
logger.info("Starting bot")
|
||||
app.run_polling()
|
||||
@ -75,6 +111,74 @@ class BeeBot:
|
||||
logger.debug("Received /today")
|
||||
await self.request_menu(update, context, True)
|
||||
|
||||
async def cmd_settings(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
logger.debug("Received /settings")
|
||||
menu = self.get_settings_menu(update)
|
||||
reply_markup = InlineKeyboardMarkup(menu)
|
||||
await update.effective_chat.send_message(text="Your preferences", reply_markup=reply_markup)
|
||||
|
||||
async def cb_handler(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
query = update.callback_query
|
||||
if query.data == "change_language":
|
||||
await self.cb_change_language(update, context)
|
||||
elif query.data.startswith("set_language"):
|
||||
await self.cb_set_language(update, context)
|
||||
elif query.data == "change_categories":
|
||||
await self.cb_change_categories(update, context)
|
||||
elif query.data.startswith("toggle_category"):
|
||||
await self.cb_toggle_category(update, context)
|
||||
elif query.data == "back_to_settings":
|
||||
menu = self.get_settings_menu(update)
|
||||
reply_markup = InlineKeyboardMarkup(menu)
|
||||
await update.effective_message.edit_text(text="Your preferences", reply_markup=reply_markup)
|
||||
|
||||
async def cb_change_language(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
logger.debug("Clicked 'Change language'")
|
||||
menu = self.get_language_menu(update)
|
||||
reply_markup = InlineKeyboardMarkup(menu)
|
||||
await update.effective_message.edit_text(text="Choose a language", reply_markup=reply_markup)
|
||||
|
||||
async def cb_set_language(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
lang = update.callback_query.data.split(":")[1]
|
||||
logger.debug(f"Clicked 'Set language to {lang}'")
|
||||
cur = self.db_con.cursor()
|
||||
cur.execute(
|
||||
"UPDATE user SET lang=? WHERE telegram_id=?",
|
||||
(lang, update.effective_user.id)
|
||||
)
|
||||
self.db_con.commit()
|
||||
cur.close()
|
||||
menu = self.get_language_menu(update)
|
||||
reply_markup = InlineKeyboardMarkup(menu)
|
||||
await update.effective_message.edit_text(text="Choose a language", reply_markup=reply_markup)
|
||||
|
||||
async def cb_change_categories(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
logger.debug("Clicked 'Change categories'")
|
||||
menu = self.get_categories_menu(update)
|
||||
reply_markup = InlineKeyboardMarkup(menu)
|
||||
await update.effective_message.edit_text(text="Choose the price categories to display", reply_markup=reply_markup)
|
||||
|
||||
async def cb_toggle_category(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
category = update.callback_query.data.split(":")[1]
|
||||
logger.debug(f"Clicked 'Toggle category {category}'")
|
||||
categories: set[str] = self.get_user_pref(update)["categories"]
|
||||
|
||||
if category in categories:
|
||||
categories.remove(category)
|
||||
else:
|
||||
categories.add(category)
|
||||
|
||||
cur = self.db_con.cursor()
|
||||
cur.execute(
|
||||
"UPDATE user SET categories=? WHERE telegram_id=?",
|
||||
(",".join(categories), update.effective_user.id)
|
||||
)
|
||||
self.db_con.commit()
|
||||
cur.close()
|
||||
menu = self.get_categories_menu(update)
|
||||
reply_markup = InlineKeyboardMarkup(menu)
|
||||
await update.effective_message.edit_text(text="Choose the price categories to display", reply_markup=reply_markup)
|
||||
|
||||
async def request_menu(self, update: Update, context: ContextTypes.DEFAULT_TYPE, today_only: bool) -> None:
|
||||
chat_id = update.effective_chat.id
|
||||
await context.bot.send_chat_action(chat_id=chat_id, action=telegram.constants.ChatAction.TYPING)
|
||||
@ -113,6 +217,7 @@ class BeeBot:
|
||||
"id" INTEGER,
|
||||
"telegram_id" INTEGER NOT NULL UNIQUE,
|
||||
"categories" TEXT,
|
||||
"lang" TEXT NOT NULL DEFAULT 'fr',
|
||||
"created_at" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY("id" AUTOINCREMENT)
|
||||
);
|
||||
@ -123,27 +228,29 @@ class BeeBot:
|
||||
def get_user_pref(self, update: Update) -> dict:
|
||||
user_id = update.effective_user.id
|
||||
cur = self.db_con.cursor()
|
||||
res = cur.execute("SELECT categories FROM user WHERE telegram_id=?", (user_id,))
|
||||
res = cur.execute("SELECT categories, lang FROM user WHERE telegram_id=?", (user_id,))
|
||||
user = res.fetchone()
|
||||
cur.close()
|
||||
|
||||
if user is None:
|
||||
self.create_user(user_id)
|
||||
return {
|
||||
"categories": {"E", "D", "C", "V"}
|
||||
"categories": {"E", "D", "C", "V"},
|
||||
"lang": "fr"
|
||||
}
|
||||
|
||||
categories = set(user[0].split(","))
|
||||
return {
|
||||
"categories": categories
|
||||
"categories": categories,
|
||||
"lang": user[1]
|
||||
}
|
||||
|
||||
def create_user(self, telegram_id: int) -> None:
|
||||
logger.debug(f"New user with id {telegram_id}")
|
||||
cur = self.db_con.cursor()
|
||||
cur.execute(
|
||||
"INSERT INTO user (telegram_id, categories) VALUES (?, ?)",
|
||||
(telegram_id, "E,D,C,V")
|
||||
"INSERT INTO user (telegram_id, categories, lang) VALUES (?, ?, ?)",
|
||||
(telegram_id, "E,D,C,V", "fr")
|
||||
)
|
||||
self.db_con.commit()
|
||||
cur.close()
|
||||
@ -270,6 +377,52 @@ class BeeBot:
|
||||
|
||||
return menus
|
||||
|
||||
def get_settings_menu(self, update: Update) -> list[list[InlineKeyboardButton]]:
|
||||
prefs = self.get_user_pref(update)
|
||||
menu = [
|
||||
[
|
||||
InlineKeyboardButton(f"Language: {prefs['lang']}", callback_data="change_language")
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(f"Categories: {' / '.join(prefs['categories'])}", callback_data="change_categories")
|
||||
]
|
||||
]
|
||||
return menu
|
||||
|
||||
def get_language_menu(self, update: Update) -> list[list[InlineKeyboardButton]]:
|
||||
prefs = self.get_user_pref(update)
|
||||
buttons = []
|
||||
for lang, data in self.LANGUAGES.items():
|
||||
extra = " ✅" if prefs["lang"] == lang else ""
|
||||
buttons.append(
|
||||
InlineKeyboardButton(
|
||||
data["emoji"] + extra,
|
||||
callback_data=f"set_language:{lang}"
|
||||
)
|
||||
)
|
||||
menu = [buttons[i:i+2] for i in range(0, len(buttons), 2)]
|
||||
menu.append([
|
||||
InlineKeyboardButton("Back to settings", callback_data="back_to_settings")
|
||||
])
|
||||
return menu
|
||||
|
||||
def get_categories_menu(self, update: Update) -> list[list[InlineKeyboardButton]]:
|
||||
prefs = self.get_user_pref(update)
|
||||
buttons = []
|
||||
for categ, data in self.CATEGORIES.items():
|
||||
extra = " ✅" if categ in prefs["categories"] else " ❌"
|
||||
buttons.append(
|
||||
InlineKeyboardButton(
|
||||
data["name"] + extra,
|
||||
callback_data=f"toggle_category:{categ}"
|
||||
)
|
||||
)
|
||||
menu = [buttons[i:i+2] for i in range(0, len(buttons), 2)]
|
||||
menu.append([
|
||||
InlineKeyboardButton("Back to settings", callback_data="back_to_settings")
|
||||
])
|
||||
return menu
|
||||
|
||||
if __name__ == '__main__':
|
||||
logger.info("Welcome to BeeBot !")
|
||||
bot = BeeBot(os.getenv("TELEGRAM_TOKEN"))
|
||||
|
Loading…
Reference in New Issue
Block a user