Remy Moll b5551eb596
All checks were successful
continuous-integration/drone/push Build is passing
tentatively add list command
2023-04-21 15:09:37 +02:00

191 lines
8.0 KiB
Python

import os
from pathlib import Path
from telegram.ext import ConversationHandler, CommandHandler, MessageHandler, filters, CallbackQueryHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from .models import ListModel, set_db
MEDIA_DIR = Path(os.getenv("MEDIA_DIR"))
DB_DIR = MEDIA_DIR / "lists_db"
DB_DIR.mkdir(parents=True, exist_ok=True)
NAME, NEW, ACTION, ITEMADD, ITEMREMOVE = range(5)
class ListHandler:
"""Create and edit lists"""
def __init__(self, entry_string, models):
self.models = models
self.handler = ConversationHandler(
entry_points=[CommandHandler(entry_string, self.entry_point)],
states={
NAME: [
CallbackQueryHandler(self.choose_list, pattern="^list-"),
CallbackQueryHandler(self.new_list, pattern="^new$"),
],
NEW : [MessageHandler(filters.TEXT, callback=self.new_listname)],
ACTION: [
CallbackQueryHandler(self.list_add, pattern="^add$"),
CallbackQueryHandler(self.list_remove, pattern="^remove$"),
CallbackQueryHandler(self.list_clear, pattern="^clear$"),
CallbackQueryHandler(self.list_delete, pattern="^delete$"),
CallbackQueryHandler(self.list_print, pattern="^print$"),
CallbackQueryHandler(self.list_menu, pattern="^overview$"),
],
ITEMADD : [MessageHandler(filters.TEXT, callback=self.list_add_item)],
ITEMREMOVE : [CallbackQueryHandler(self.list_remove_index)]
},
fallbacks=[CommandHandler('list', self.entry_point)],
)
async def entry_point(self, update, context) -> None:
set_db(DB_DIR / f"{update.message.chat_id}.db")
lists = ListModel.select()
keyboard = [[InlineKeyboardButton(k.name, callback_data=f"list-{k.name}")] for k in lists] + \
[[InlineKeyboardButton("New list", callback_data="new")]]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text(text="Here are the existing lists. You can also create a new one:", reply_markup=reply_markup)
return NAME
async def choose_list(self, update, context) -> None:
query = update.callback_query
data = query.data
name = data.replace("list-","")
await query.answer()
self.current_name = name
keyboard = [
[InlineKeyboardButton("Add item", callback_data="add")],
[InlineKeyboardButton("Remove item", callback_data="remove")],
[InlineKeyboardButton("Clear list", callback_data="clear")],
[InlineKeyboardButton("Print list", callback_data="print")],
[InlineKeyboardButton("Delete list", callback_data="delete")],
]
reply_markup = InlineKeyboardMarkup(keyboard)
await query.edit_message_text("Very well. For " + name + " the following actions are available:", reply_markup=reply_markup)
return ACTION
async def list_menu(self, update, context) -> None:
query = update.callback_query
await query.answer()
keyboard = [
[InlineKeyboardButton("Add item", callback_data="add")],
[InlineKeyboardButton("Remove item", callback_data="remove")],
[InlineKeyboardButton("Clear list", callback_data="clear")],
[InlineKeyboardButton("Print list", callback_data="print")],
[InlineKeyboardButton("Delete list", callback_data="delete")],
]
reply_markup = InlineKeyboardMarkup(keyboard)
await query.edit_message_text("Very well. For " + self.current_name + " the following actions are available:", reply_markup=reply_markup)
return ACTION
async def new_list(self, update, context) -> None:
query = update.callback_query
await query.answer()
await query.edit_message_text("What's the name of the new list?")
return NEW
async def new_listname(self, update, context) -> None:
name = update.message.text
try:
ListModel.create(name = name)
keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("To the menu!", callback_data="overview")]]
reply_markup = InlineKeyboardMarkup(keyboard)
self.current_name = name
await update.message.reply_text("Thanks. List " + name + " was successfully created.", reply_markup=reply_markup)
return ACTION
except Exception as e:
await update.message.reply_text("Oh no! Encountered exception: {}".format(e))
return ConversationHandler.END
async def list_add(self, update, context) -> None:
query = update.callback_query
await query.answer()
await query.edit_message_text("What would you like to add?")
return ITEMADD
async def list_remove(self, update, context) -> None:
query = update.callback_query
await query.answer()
sl = ListModel.get(name = self.current_name)
keyboard = [[InlineKeyboardButton(k, callback_data=i)] for i,k in enumerate(sl)]
reply_markup = InlineKeyboardMarkup(keyboard)
await query.edit_message_text("Which item would you like to remove?", reply_markup = reply_markup)
return ITEMREMOVE
async def list_clear(self, update, context) -> None:
query = update.callback_query
await query.answer()
ListModel.get(name = self.current_name).content_list = []
keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
reply_markup = InlineKeyboardMarkup(keyboard)
await query.edit_message_text("List " + self.current_name + " cleared", reply_markup=reply_markup)
return ACTION
async def list_delete(self, update, context) -> None:
query = update.callback_query
await query.answer()
ListModel.get(name = self.current_name).delete_instance()
await query.edit_message_text("List " + self.current_name + " deleted")
return ConversationHandler.END
async def list_print(self, update, context) -> None:
query = update.callback_query
await query.answer()
it = ListModel.get(name = self.current_name).content_list
if it:
content = "\n* ".join(it)
else:
content = "List empty"
keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
reply_markup = InlineKeyboardMarkup(keyboard)
await query.edit_message_text("Content of " + self.current_name + ":\n" + content, reply_markup=reply_markup)
return ACTION
async def list_add_item(self, update, context) -> None:
item = update.message.text
ListModel.get(name = self.current_name).content_list = ListModel.get(name = self.current_name).content_list + [item]
# TODO test me!
keyboard = [[InlineKeyboardButton("Add some more", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text("Added " + item, reply_markup=reply_markup)
return ACTION
async def list_remove_index(self, update, context) -> None:
query = update.callback_query
ind = int(query.data)
await query.answer()
list_object = ListModel.get(name = self.current_name)
old = list_object.content_list
name = old.pop(ind)
self.db_utils.list_update(self.current_name, replace=old)
keyboard = [[InlineKeyboardButton("Remove another", callback_data="remove"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
reply_markup = InlineKeyboardMarkup(keyboard)
await query.edit_message_text("Removed " + name, reply_markup=reply_markup)
return ACTION