Lists with more functionality #3
@@ -1,16 +1,13 @@
 | 
				
			|||||||
import os
 | 
					import os
 | 
				
			||||||
from pathlib import Path
 | 
					from pathlib import Path
 | 
				
			||||||
from telegram.ext import ConversationHandler, CommandHandler, MessageHandler, filters, CallbackQueryHandler
 | 
					from telegram.ext import ConversationHandler, CommandHandler, MessageHandler, filters, CallbackQueryHandler, CallbackContext
 | 
				
			||||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
 | 
					from telegram import InlineKeyboardButton, InlineKeyboardMarkup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import ListModel, set_db, db
 | 
					from .models import ListModel, set_db, db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MEDIA_DIR = Path(os.getenv("MEDIA_DIR"))
 | 
					PERSISTENCE_DIR = Path(os.getenv("PERSISTENCE_DIR"))
 | 
				
			||||||
DB_DIR = MEDIA_DIR / "lists_db"
 | 
					 | 
				
			||||||
DB_DIR.mkdir(parents=True, exist_ok=True)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NAME, NEW, ACTION, ITEMADD, ITEMREMOVE, ITEMTOGGLE = range(6)
 | 
				
			||||||
NAME, NEW, ACTION, ITEMADD, ITEMREMOVE = range(5)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..basehandler import BaseHandler
 | 
					from ..basehandler import BaseHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -19,8 +16,20 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
    """Create and edit lists"""
 | 
					    """Create and edit lists"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, entry_string, models):
 | 
					    def __init__(self, entry_string, models):
 | 
				
			||||||
        self.journal_models = models # not needed here
 | 
					        del models # not needed here, but part of the template
 | 
				
			||||||
        self.entry_string = entry_string
 | 
					        self.entry_string = entry_string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        set_db(PERSISTENCE_DIR / "lists.sqlite")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.list_overview_keyboard = [
 | 
				
			||||||
 | 
					            [InlineKeyboardButton("Add item", callback_data="add")],
 | 
				
			||||||
 | 
					            [InlineKeyboardButton("Toggle item", callback_data="toggle")],
 | 
				
			||||||
 | 
					            [InlineKeyboardButton("Remove item", callback_data="remove")],
 | 
				
			||||||
 | 
					            [InlineKeyboardButton("Clear list", callback_data="clear")],
 | 
				
			||||||
 | 
					            [InlineKeyboardButton("Print list", callback_data="print")],
 | 
				
			||||||
 | 
					            [InlineKeyboardButton("Delete list", callback_data="delete")],
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
        self.handler = ConversationHandler(
 | 
					        self.handler = ConversationHandler(
 | 
				
			||||||
            entry_points=[CommandHandler(entry_string, self.entry_point)],
 | 
					            entry_points=[CommandHandler(entry_string, self.entry_point)],
 | 
				
			||||||
            states={
 | 
					            states={
 | 
				
			||||||
@@ -31,6 +40,7 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
                NEW : [MessageHandler(filters.TEXT, callback=self.new_listname)],
 | 
					                NEW : [MessageHandler(filters.TEXT, callback=self.new_listname)],
 | 
				
			||||||
                ACTION: [
 | 
					                ACTION: [
 | 
				
			||||||
                    CallbackQueryHandler(self.list_add, pattern="^add$"),
 | 
					                    CallbackQueryHandler(self.list_add, pattern="^add$"),
 | 
				
			||||||
 | 
					                    CallbackQueryHandler(self.list_toggle, pattern="^toggle$"),
 | 
				
			||||||
                    CallbackQueryHandler(self.list_remove, pattern="^remove$"),
 | 
					                    CallbackQueryHandler(self.list_remove, pattern="^remove$"),
 | 
				
			||||||
                    CallbackQueryHandler(self.list_clear, pattern="^clear$"),
 | 
					                    CallbackQueryHandler(self.list_clear, pattern="^clear$"),
 | 
				
			||||||
                    CallbackQueryHandler(self.list_delete, pattern="^delete$"),
 | 
					                    CallbackQueryHandler(self.list_delete, pattern="^delete$"),
 | 
				
			||||||
@@ -38,6 +48,7 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
                    CallbackQueryHandler(self.list_menu, pattern="^overview$"),
 | 
					                    CallbackQueryHandler(self.list_menu, pattern="^overview$"),
 | 
				
			||||||
                    ],
 | 
					                    ],
 | 
				
			||||||
                ITEMADD : [MessageHandler(filters.TEXT, callback=self.list_add_item)],
 | 
					                ITEMADD : [MessageHandler(filters.TEXT, callback=self.list_add_item)],
 | 
				
			||||||
 | 
					                ITEMTOGGLE: [CallbackQueryHandler(self.list_toggle_index)],
 | 
				
			||||||
                ITEMREMOVE : [CallbackQueryHandler(self.list_remove_index)]
 | 
					                ITEMREMOVE : [CallbackQueryHandler(self.list_remove_index)]
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            fallbacks=[CommandHandler('list', self.entry_point)],
 | 
					            fallbacks=[CommandHandler('list', self.entry_point)],
 | 
				
			||||||
@@ -46,10 +57,9 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async def entry_point(self, update, context) -> None:
 | 
					    async def entry_point(self, update, context) -> None:
 | 
				
			||||||
        await super().entry_point(update, context)
 | 
					        await super().entry_point(update, context)
 | 
				
			||||||
        set_db(DB_DIR / f"chat_{update.message.chat_id}.db")
 | 
					 | 
				
			||||||
        with db:
 | 
					        with db:
 | 
				
			||||||
            lists = ListModel.select()
 | 
					            lists = ListModel.select().where(ListModel.chat_id == update.effective_chat.id)
 | 
				
			||||||
        keyboard = [[InlineKeyboardButton(k.name, callback_data=f"list-{k.name}")] for k in lists] + \
 | 
					        keyboard = [[InlineKeyboardButton(k.name, callback_data=f"list-{k.id}")] for k in lists] + \
 | 
				
			||||||
            [[InlineKeyboardButton("New list", callback_data="new")]]
 | 
					            [[InlineKeyboardButton("New list", callback_data="new")]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
					        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
				
			||||||
@@ -57,23 +67,16 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
        return NAME
 | 
					        return NAME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def choose_list(self, update, context) -> None:
 | 
					    async def choose_list(self, update, context: CallbackContext) -> None:
 | 
				
			||||||
        query = update.callback_query
 | 
					        query = update.callback_query
 | 
				
			||||||
        data = query.data
 | 
					        data = query.data
 | 
				
			||||||
        name = data.replace("list-","")
 | 
					        id = data.replace("list-","")
 | 
				
			||||||
        await query.answer()
 | 
					        await query.answer()
 | 
				
			||||||
        self.current_name = name
 | 
					        context.user_data["current_list"] = ListModel.get(id = id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        keyboard = [
 | 
					        reply_markup = InlineKeyboardMarkup(self.list_overview_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)
 | 
					        await query.edit_message_text(f"Using {context.user_data['current_list'].name}. Available actions:", reply_markup=reply_markup)
 | 
				
			||||||
        return ACTION
 | 
					        return ACTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,16 +84,9 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
        query = update.callback_query
 | 
					        query = update.callback_query
 | 
				
			||||||
        await query.answer()
 | 
					        await query.answer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        keyboard = [
 | 
					        reply_markup = InlineKeyboardMarkup(self.list_overview_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)
 | 
					        await query.edit_message_text(f"Using {context.user_data['current_list'].name}. Available actions:", reply_markup=reply_markup)
 | 
				
			||||||
        return ACTION
 | 
					        return ACTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -105,10 +101,9 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
        name = update.message.text
 | 
					        name = update.message.text
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            with db:
 | 
					            with db:
 | 
				
			||||||
                ListModel.create(name = name)
 | 
					                context.user_data["current_list"] = ListModel.create(name = name, chat_id=update.effective_chat.id)
 | 
				
			||||||
            keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("To the menu!", callback_data="overview")]]
 | 
					            keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("To the menu!", callback_data="overview")]]
 | 
				
			||||||
            reply_markup = InlineKeyboardMarkup(keyboard)
 | 
					            reply_markup = InlineKeyboardMarkup(keyboard)
 | 
				
			||||||
            self.current_name = name
 | 
					 | 
				
			||||||
            await update.message.reply_text("Thanks. List " + name + " was successfully created.", reply_markup=reply_markup)
 | 
					            await update.message.reply_text("Thanks. List " + name + " was successfully created.", reply_markup=reply_markup)
 | 
				
			||||||
            return ACTION
 | 
					            return ACTION
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
@@ -123,13 +118,24 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
        return ITEMADD
 | 
					        return ITEMADD
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    async def list_toggle(self, update, context) -> None:
 | 
				
			||||||
 | 
					        query = update.callback_query
 | 
				
			||||||
 | 
					        await query.answer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        list_object = context.user_data["current_list"]
 | 
				
			||||||
 | 
					        keyboard = [[InlineKeyboardButton(v, callback_data=k)] for k,v in list_object.content.items()]
 | 
				
			||||||
 | 
					        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await query.edit_message_text("Which item would you like to toggle?", reply_markup = reply_markup)
 | 
				
			||||||
 | 
					        return ITEMTOGGLE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def list_remove(self, update, context) -> None:
 | 
					    async def list_remove(self, update, context) -> None:
 | 
				
			||||||
        query = update.callback_query
 | 
					        query = update.callback_query
 | 
				
			||||||
        await query.answer()
 | 
					        await query.answer()
 | 
				
			||||||
        with db:
 | 
					 | 
				
			||||||
            list_object = ListModel.get(name = self.current_name)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        keyboard = [[InlineKeyboardButton(k, callback_data=i)] for i,k in enumerate(list_object.content_list)]
 | 
					        list_object = context.user_data["current_list"]
 | 
				
			||||||
 | 
					        keyboard = [[InlineKeyboardButton(v, callback_data=k)] for k,v in list_object.content.items()]
 | 
				
			||||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
					        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await query.edit_message_text("Which item would you like to remove?", reply_markup = reply_markup)
 | 
					        await query.edit_message_text("Which item would you like to remove?", reply_markup = reply_markup)
 | 
				
			||||||
@@ -139,47 +145,77 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
    async def list_clear(self, update, context) -> None:
 | 
					    async def list_clear(self, update, context) -> None:
 | 
				
			||||||
        query = update.callback_query
 | 
					        query = update.callback_query
 | 
				
			||||||
        await query.answer()
 | 
					        await query.answer()
 | 
				
			||||||
        with db:
 | 
					
 | 
				
			||||||
            ListModel.get(name = self.current_name).content_list = []
 | 
					        list_object = context.user_data["current_list"]
 | 
				
			||||||
 | 
					        list_object.content = {}
 | 
				
			||||||
        keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
					        keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
				
			||||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
					        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
				
			||||||
        await query.edit_message_text("List " + self.current_name + " cleared", reply_markup=reply_markup)
 | 
					        await query.edit_message_text(f"List {list_object.name} cleared", reply_markup=reply_markup)
 | 
				
			||||||
        return ACTION
 | 
					        return ACTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def list_delete(self, update, context) -> None:
 | 
					    async def list_delete(self, update, context) -> None:
 | 
				
			||||||
        query = update.callback_query
 | 
					        query = update.callback_query
 | 
				
			||||||
        await query.answer()
 | 
					        await query.answer()
 | 
				
			||||||
        with db:
 | 
					        list_object = context.user_data["current_list"]
 | 
				
			||||||
            ListModel.get(name = self.current_name).delete_instance()
 | 
					        list_object.delete_instance()
 | 
				
			||||||
        await query.edit_message_text("List " + self.current_name + " deleted")
 | 
					        await query.edit_message_text(f"List {list_object.name} deleted")
 | 
				
			||||||
        return ConversationHandler.END
 | 
					        return ConversationHandler.END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def list_print(self, update, context) -> None:
 | 
					    async def list_print(self, update, context) -> None:
 | 
				
			||||||
        query = update.callback_query
 | 
					        query = update.callback_query
 | 
				
			||||||
        await query.answer()
 | 
					        await query.answer()
 | 
				
			||||||
        with db:
 | 
					        list_object = context.user_data["current_list"]
 | 
				
			||||||
            it = ListModel.get(name = self.current_name).content_list
 | 
					
 | 
				
			||||||
        if it:
 | 
					        content_it = list_object.content.values()
 | 
				
			||||||
            content = "·" + "\n· ".join(it)
 | 
					        done_it = [
 | 
				
			||||||
 | 
					            "· " if e is None \
 | 
				
			||||||
 | 
					            else "✅ " if e \
 | 
				
			||||||
 | 
					            else "❌ " \
 | 
				
			||||||
 | 
					            for e in list_object.done_dict.values()]
 | 
				
			||||||
 | 
					        if content_it:
 | 
				
			||||||
 | 
					            msg_content = "\n".join([f"{d} {c}" for d, c in zip(done_it, content_it)])
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            content = "List empty"
 | 
					            msg_content = "List empty"
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
					        keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
				
			||||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
					        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
				
			||||||
        await query.edit_message_text("Content of " + self.current_name + ":\n" + content, reply_markup=reply_markup)
 | 
					        await query.edit_message_text(f"Content of {list_object.name}:\n{msg_content}", reply_markup=reply_markup)
 | 
				
			||||||
        return ACTION
 | 
					        return ACTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def list_add_item(self, update, context) -> None:
 | 
					    async def list_add_item(self, update, context) -> None:
 | 
				
			||||||
        item = update.message.text
 | 
					        item = update.message.text
 | 
				
			||||||
        with db:
 | 
					        list_object = context.user_data["current_list"]
 | 
				
			||||||
            ListModel.get(name = self.current_name).content_list = ListModel.get(name = self.current_name).content_list + [item]
 | 
					        new = list_object.content
 | 
				
			||||||
 | 
					        new.update({"random_key": item})
 | 
				
			||||||
 | 
					        list_object.content = new
 | 
				
			||||||
        # TODO test me!
 | 
					        # TODO test me!
 | 
				
			||||||
        keyboard = [[InlineKeyboardButton("Add some more", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
					        keyboard = [[InlineKeyboardButton("Add some more", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
				
			||||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
					        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
				
			||||||
        await update.message.reply_text("Added " + item, reply_markup=reply_markup)
 | 
					        await update.message.reply_text(f"Added {item}", reply_markup=reply_markup)
 | 
				
			||||||
 | 
					        return ACTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def list_toggle_index(self, update, context) -> None:
 | 
				
			||||||
 | 
					        query = update.callback_query
 | 
				
			||||||
 | 
					        toggle_key = int(query.data)
 | 
				
			||||||
 | 
					        await query.answer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        list_object = context.user_data["current_list"]
 | 
				
			||||||
 | 
					        old = list_object.done_dict[toggle_key]
 | 
				
			||||||
 | 
					        # if all None or all False (first toggle or all false) then set all dones to False
 | 
				
			||||||
 | 
					        if not any(list_object.done_dict.values()):
 | 
				
			||||||
 | 
					            new_done_dict = dict.fromkeys(list_object.done_dict, False)
 | 
				
			||||||
 | 
					        else: new_done_dict = list_object.done_dict
 | 
				
			||||||
 | 
					        new_done_dict[toggle_key] = not old
 | 
				
			||||||
 | 
					        list_object.done_dict = new_done_dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        keyboard = [[InlineKeyboardButton("Toggle another", callback_data="toggle"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
				
			||||||
 | 
					        reply_markup = InlineKeyboardMarkup(keyboard)      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await query.edit_message_text(f"Toggled {list_object.content[toggle_key]}", reply_markup=reply_markup)
 | 
				
			||||||
        return ACTION
 | 
					        return ACTION
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -188,14 +224,13 @@ class ListHandler(BaseHandler):
 | 
				
			|||||||
        ind = int(query.data)
 | 
					        ind = int(query.data)
 | 
				
			||||||
        await query.answer()
 | 
					        await query.answer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with db:
 | 
					        list_object = context.user_data["current_list"]
 | 
				
			||||||
            list_object = ListModel.get(name = self.current_name)
 | 
					        old = list_object.content
 | 
				
			||||||
            old = list_object.content_list
 | 
					 | 
				
			||||||
        name = old.pop(ind)
 | 
					        name = old.pop(ind)
 | 
				
			||||||
            list_object.content_list = old
 | 
					        list_object.content = old
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        keyboard = [[InlineKeyboardButton("Remove another", callback_data="remove"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
					        keyboard = [[InlineKeyboardButton("Remove another", callback_data="remove"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
				
			||||||
        reply_markup = InlineKeyboardMarkup(keyboard)      
 | 
					        reply_markup = InlineKeyboardMarkup(keyboard)      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await query.edit_message_text("Removed " + name, reply_markup=reply_markup)
 | 
					        await query.edit_message_text(f"Removed {name}", reply_markup=reply_markup)
 | 
				
			||||||
        return ACTION
 | 
					        return ACTION
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,30 +1,52 @@
 | 
				
			|||||||
from peewee import *
 | 
					from peewee import *
 | 
				
			||||||
import json
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
db = DatabaseProxy()
 | 
					db = DatabaseProxy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BaseModel(Model):
 | 
					class BaseModel(Model):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        database = db
 | 
					        database = db
 | 
				
			||||||
        db_table = 'lists'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ListModel(BaseModel):
 | 
					class ListModel(BaseModel):
 | 
				
			||||||
    name = CharField(unique=True)
 | 
					    name = CharField(default="")
 | 
				
			||||||
    content = TextField(default="") # unlimited length, use to serialise list into
 | 
					    chat_id = IntegerField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def content_list(self):
 | 
					    def content(self) -> dict:
 | 
				
			||||||
        return json.loads(self.content or '[]')
 | 
					        return {e.id: e.entry for e in self.entries}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    @content_list.setter
 | 
					    @content.setter
 | 
				
			||||||
    def content_list(self, list_content):
 | 
					    def content(self, new_content: dict):
 | 
				
			||||||
        self.content = json.dumps(list_content)
 | 
					        old_content = self.content
 | 
				
			||||||
        with db:
 | 
					        if len(old_content) < len(new_content):
 | 
				
			||||||
            self.save()
 | 
					            # we assume: only 1 item added (last item)
 | 
				
			||||||
 | 
					            new_item = list(new_content.values())[-1]
 | 
				
			||||||
 | 
					            ListEntryModel.create(list_model=self, entry = new_item)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif len(old_content) > len(new_content):
 | 
				
			||||||
 | 
					            to_delete_ids = set(old_content.keys()) - set(new_content.keys())
 | 
				
			||||||
 | 
					            ListEntryModel.delete().where(ListEntryModel.id.in_(list(to_delete_ids))).execute()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def done_dict(self):
 | 
				
			||||||
 | 
					        return {e.id: e.done for e in self.entries}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    @done_dict.setter
 | 
				
			||||||
 | 
					    def done_dict(self, new_done: dict):
 | 
				
			||||||
 | 
					        old_done_dict = self.done_dict
 | 
				
			||||||
 | 
					        for k,d in new_done.items():
 | 
				
			||||||
 | 
					            if d != old_done_dict[k]:
 | 
				
			||||||
 | 
					                ListEntryModel.update(done = d).where(ListEntryModel.id == k).execute()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ListEntryModel(BaseModel):
 | 
				
			||||||
 | 
					    list_model = ForeignKeyField(ListModel, backref="entries", on_delete="CASCADE")
 | 
				
			||||||
 | 
					    entry = TextField(default="")
 | 
				
			||||||
 | 
					    done = BooleanField(default=None, null=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def set_db(db_path):
 | 
					def set_db(db_path):
 | 
				
			||||||
    db.initialize(SqliteDatabase(db_path))
 | 
					    db.initialize(SqliteDatabase(db_path))
 | 
				
			||||||
    with db:
 | 
					    with db:
 | 
				
			||||||
        db.create_tables([ListModel], safe=True)
 | 
					        db.create_tables([ListModel, ListEntryModel], safe=True)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user