From 08aa545101fe328a9c27e695475a746d7a2cb89c Mon Sep 17 00:00:00 2001 From: Alexei Date: Sun, 23 Apr 2023 21:09:54 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D1=81?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot_modules/projects.py | 154 ++++++++++++++++++++++++++++++++++++++++-------- bot_sys/keyboard.py | 9 ++- 2 files changed, 138 insertions(+), 25 deletions(-) diff --git a/bot_modules/projects.py b/bot_modules/projects.py index ef1d32f..d5a8f7a 100644 --- a/bot_modules/projects.py +++ b/bot_modules/projects.py @@ -6,12 +6,17 @@ from bot_sys import bot_bd, log, config, keyboard from bot_modules import start from aiogram import Bot, types - +from aiogram.dispatcher import FSMContext +from aiogram.dispatcher.filters.state import State, StatesGroup +from aiogram.dispatcher import Dispatcher import sqlite3 -from aiogram.dispatcher import Dispatcher +bot = Bot(token=config.GetTelegramBotApiToken(), parse_mode = types.ParseMode.HTML) -bot = Bot(token=config.GetTelegramBotApiToken(), parse_mode=types.ParseMode.HTML) +class FSMCreateProject(StatesGroup): + prjPhoto = State() + prjName = State() + prjDesc = State() # --------------------------------------------------------- # БД @@ -19,7 +24,6 @@ init_bd_cmd = '''CREATE TABLE IF NOT EXISTS projects( projectPhoto TEXT, projectName TEXT, projectDesc TEXT, - parentID INTEGER, projectID INTEGER PRIMARY KEY )''' @@ -44,28 +48,66 @@ project_open_message = ''' @proj_desk ''' +project_create_message_1 = ''' +Создание проекта. Шаг №1 + +Загрузите обложку для проекта (Фото): +Она будет отображаться в его описании. +''' + +project_create_message_2 = ''' +Создание проекта. Шаг №2 + +Введите название проекта: +''' + +project_create_message_3 = ''' +Создание проекта. Шаг №3 + +Введите описание проекта: +''' + +project_success_create_message = 'Проект успешно добавлен!' +project_success_delete_message = 'Проект успешно удалён!' + +project_cancel_create_message = 'Действие отменено' + + +project_select_to_delete_message = ''' +Выберите проект, который вы хотите удалить. +Все задачи и потребности в этом проекте так же будут удалены! +''' + projects_button_name = "📰 Проекты" add_project_button_name = "📰 Добавить проект" del_project_button_name = "📰 Удалить проект" edit_project_button_name = "📰 Редактировать проект" +projects_canсel_button_name = "📰 Отменить" + # Префиксы -select_project_callback_prefix = 'project:' +select_project_callback_prefix = 'sel_project:' +delete_project_callback_prefix = 'del_project:' + # --------------------------------------------------------- # Работа с кнопками -def GetEditProjectKeyboardButtons(a_UserAccess, a_ParentID): +def GetEditProjectKeyboardButtons(a_UserAccess): proj_buttons = [add_project_button_name, del_project_button_name, edit_project_button_name] mods = [start] return keyboard.MakeKeyboard(keyboard.GetButtons(mods, a_UserAccess) + proj_buttons) -def GetProjectsListKeyboardButtons(a_UserAccess, a_ParentID): - projects = GetProjectList(a_ParentID) +def GetCancelKeyboardButtons(a_UserAccess): +# return keyboard.MakeKeyboardRemove() + return keyboard.MakeKeyboard([projects_canсel_button_name]) + +def GetProjectsListKeyboardButtons(a_UserAccess, a_Prefix): + projects = GetProjectList() projects_button_list = [] for t in projects: - projects_button_list += [keyboard.Button(str(t[1]), t[4])] - return keyboard.MakeInlineKeyboard(projects_button_list, select_project_callback_prefix) + projects_button_list += [keyboard.Button(str(t[1]), t[3])] + return keyboard.MakeInlineKeyboard(projects_button_list, a_Prefix) def GetUserAccess(a_UserID): return None @@ -74,11 +116,10 @@ def GetUserAccess(a_UserID): # Обработка сообщений # Отображение всех проектов без родителя -async def ProjectsOpen(a_Message, **kwargs): - print('test', kwargs) +async def ProjectsOpen(a_Message : types.message): user_access = GetUserAccess(a_Message.from_user.id) - await bot.send_message(a_Message.from_user.id, base_project_message, reply_markup = GetEditProjectKeyboardButtons(user_access, 0)) - await bot.send_message(a_Message.from_user.id, select_project_message, reply_markup = GetProjectsListKeyboardButtons(user_access, 0)) + await bot.send_message(a_Message.from_user.id, base_project_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) + await bot.send_message(a_Message.from_user.id, select_project_message, reply_markup = GetProjectsListKeyboardButtons(user_access, select_project_callback_prefix)) async def ShowProject(a_CallbackQuery : types.CallbackQuery): project_id = str(a_CallbackQuery.data).replace(select_project_callback_prefix, '') @@ -87,20 +128,67 @@ async def ShowProject(a_CallbackQuery : types.CallbackQuery): if len(project) != 1: log.Error(f'Проект не найден {project_id}') msg = Ошибка.replace('@project_id', project_id) - await bot.send_message(a_CallbackQuery.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_access, project_id)) + await bot.send_message(a_CallbackQuery.from_user.id, msg, reply_markup = GetEditProjectKeyboardButtons(user_access)) return p = project[0] msg = project_open_message.replace('@proj_name', p[1]).replace('@proj_desk', p[2]) - await bot.send_photo(a_CallbackQuery.from_user.id, p[0], msg, reply_markup = GetEditProjectKeyboardButtons(user_access, project_id)) + await bot.send_photo(a_CallbackQuery.from_user.id, p[0], msg, reply_markup = GetEditProjectKeyboardButtons(user_access)) + +async def ProjectCreateCancel(a_Message : types.message, state : FSMContext): + user_access = GetUserAccess(a_Message.from_user.id) + await state.finish() + await a_Message.answer(project_cancel_create_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) + +async def ProjectCreate(a_Message : types.message): + user_access = GetUserAccess(a_Message.from_user.id) + await FSMCreateProject.prjPhoto.set() + await a_Message.answer(project_create_message_1, reply_markup = GetCancelKeyboardButtons(user_access)) + +async def ProjectPhotoLoad(a_Message : types.message, state : FSMContext): + user_access = GetUserAccess(a_Message.from_user.id) + async with state.proxy() as prjData: + prjData['photo'] = a_Message.photo[0].file_id + await FSMCreateProject.next() + await a_Message.answer(project_create_message_2, reply_markup = GetCancelKeyboardButtons(user_access)) + +async def ProjectNameLoad(a_Message : types.message, state : FSMContext): + user_access = GetUserAccess(a_Message.from_user.id) + async with state.proxy() as prjData: + prjData['name'] = a_Message.text + await FSMCreateProject.next() + await a_Message.answer(project_create_message_3, reply_markup = GetCancelKeyboardButtons(user_access)) + +async def ProjectDescLoad(a_Message : types.message, state : FSMContext): + user_access = GetUserAccess(a_Message.from_user.id) + async with state.proxy() as prjData: + prjData['desc'] = a_Message.text + prjPhoto = prjData['photo'] + prjName = prjData['name'] + prjDesc = prjData['desc'] + AddProject(prjPhoto, prjName, prjDesc) + log.Success(f'Добавлен проект {prjName} пользователем {a_Message.from_user.id}.') + await state.finish() + await a_Message.answer(project_success_create_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) + +async def ProjectDelete(a_Message : types.message): + user_access = GetUserAccess(a_Message.from_user.id) + await bot.send_message(a_Message.from_user.id, project_select_to_delete_message, reply_markup = GetProjectsListKeyboardButtons(user_access, delete_project_callback_prefix)) + +async def prjDelete(a_CallbackQuery : types.CallbackQuery): + user_access = GetUserAccess(a_CallbackQuery.from_user.id) + projectID = str(a_CallbackQuery.data).replace(delete_project_callback_prefix, '') + DelProject(projectID) + log.Success(f'Проект №{projectID} был удален пользователем {a_CallbackQuery.from_user.id}.') + await bot.send_message(a_CallbackQuery.from_user.id, project_success_delete_message, reply_markup = GetEditProjectKeyboardButtons(user_access)) # --------------------------------------------------------- # Работа с базой данных проектов -def GetProjectList(a_ParentID): +def GetProjectList(): db = sqlite3.connect(bot_bd.GetBDFileName()) cursor = db.cursor() - projects = cursor.execute('SELECT * FROM projects where parentID = ?', ([a_ParentID])).fetchall() + projects = cursor.execute('SELECT * FROM projects').fetchall() cursor.close() db.close() return projects @@ -113,6 +201,24 @@ def GetProject(a_ProjectID): db.close() return project +def AddProject(a_prjPhoto, a_prjName, a_prjDesc): + db = sqlite3.connect(bot_bd.GetBDFileName()) + cursor = db.cursor() + cursor.execute('INSERT INTO projects(projectPhoto, projectName, projectDesc) VALUES(?, ?, ?)', (a_prjPhoto, a_prjName, a_prjDesc)) + db.commit() + cursor.close() + db.close() + return + +def DelProject(a_ProjectID): + db = sqlite3.connect(bot_bd.GetBDFileName()) + cursor = db.cursor() + cursor.execute('DELETE FROM projects WHERE projectID = ?', ([a_ProjectID])) + #cursor.execute('DELETE FROM tasks WHERE projectID = ?', ([a_ProjectID])) + db.commit() + db.close() + return + # --------------------------------------------------------- # API @@ -128,10 +234,12 @@ def GetButtonNames(a_UserAccess): def RegisterHandlers(dp : Dispatcher): dp.register_message_handler(ProjectsOpen, text = projects_button_name) dp.register_callback_query_handler(ShowProject, lambda x: x.data.startswith(select_project_callback_prefix)) -''' dp.register_message_handler(ProjectCreate, text = add_project_button_name) + dp.register_message_handler(ProjectCreateCancel, text = projects_canсel_button_name, state = FSMCreateProject.prjPhoto) + dp.register_message_handler(ProjectCreateCancel, text = projects_canсel_button_name, state = FSMCreateProject.prjName) + dp.register_message_handler(ProjectCreateCancel, text = projects_canсel_button_name, state = FSMCreateProject.prjDesc) + dp.register_message_handler(ProjectPhotoLoad, content_types = ['photo'], state = FSMCreateProject.prjPhoto) + dp.register_message_handler(ProjectNameLoad, state = FSMCreateProject.prjName) + dp.register_message_handler(ProjectDescLoad, state = FSMCreateProject.prjDesc) dp.register_message_handler(ProjectDelete, text = del_project_button_name) - dp.register_callback_query_handler(catDelete, lambda x: x.data.startswith('delcat ')) - dp.register_message_handler(ProjectPhotoLoad, content_types = ['photo'], state = FSMCreateCategory.catPhoto) - dp.register_message_handler(ProjectNameLoad, state = FSMCreateCategory.catName) - dp.register_message_handler(ProjectDescLoad, state = FSMCreateCategory.catDesc)''' + dp.register_callback_query_handler(prjDelete, lambda x: x.data.startswith(delete_project_callback_prefix)) diff --git a/bot_sys/keyboard.py b/bot_sys/keyboard.py index 9f314d2..9d53696 100644 --- a/bot_sys/keyboard.py +++ b/bot_sys/keyboard.py @@ -22,6 +22,9 @@ def MakeKeyboard(a_ButtonList): return key +def MakeKeyboardRemove(): + return types.ReplyKeyboardRemove() + def MakeKeyboardForMods(a_ModList, a_UserAccess): names = GetButtons(a_ModList, a_UserAccess) return MakeKeyboard(names) @@ -34,6 +37,8 @@ class Button: self.callback_data = a_CallBackData def MakeInlineKeyboard(a_ButtonList, a_CallBackPrefix): # class Button - inline_keyboard = InlineKeyboardMarkup(resize_keyboard = True, row_width = 2) + inline_keyboard = InlineKeyboardMarkup() for b in a_ButtonList: - inline_keyboard.insert(types.InlineKeyboardButton(text = b.label, callback_data = f'{a_CallBackPrefix}{b.callback_data}')) + inline_keyboard.insert(types.InlineKeyboardButton(text = b.label, callback_data = f'{a_CallBackPrefix}{b.callback_data}')) + return inline_keyboard +