diff --git a/bot_modules/backup.py b/bot_modules/backup.py index 800025d..552e036 100644 --- a/bot_modules/backup.py +++ b/bot_modules/backup.py @@ -3,33 +3,22 @@ # Бэкапы пользователя -from bot_sys import bot_bd, log, config, keyboard, user_access -from bot_modules import start, access, groups -from template import file_message, simple_message - -from aiogram import Bot, types - -import sqlite3 - -from aiogram.dispatcher import Dispatcher - -bot = Bot(token=config.GetTelegramBotApiToken(), parse_mode=types.ParseMode.HTML) +from bot_sys import user_access, keyboard +from bot_modules import mod_simple_message, profile +from template import bd_item, file_message # --------------------------------------------------------- # БД module_name = 'backup' -init_bd_cmds = [ -f"INSERT OR IGNORE INTO module_access (modName, modAccess, itemDefaultAccess) VALUES ('{module_name}', '{user_access.user_access_group_new}=-', '{user_access.user_access_group_new}=-');" -] - # --------------------------------------------------------- # Сообщения - -backup_message = ''' +start_message = ''' Здесь вы можете выполнить специальные операции по сервисному обслуживанию ''' +start_menu_button_name = "📦 Резервные копии и логи" + backup_bd_message = ''' 📀 Резервная копия базы данных 🕰 @time @@ -44,44 +33,61 @@ error_backup_message = ''' ❌ Ошибка резервного копирования ''' -backup_button_name = "📦 Резервные копии и логи" backup_bd_button_name = "📀 Резервные копия базы" backup_log_button_name = "📃 Логи" -# --------------------------------------------------------- -# Работа с кнопками - -def GetBackupKeyboardButtons(a_Message, a_UserGroups): - cur_buttons = [ - keyboard.ButtonWithAccess(backup_bd_button_name, user_access.AccessMode.EDIT, GetAccess()), - keyboard.ButtonWithAccess(backup_log_button_name, user_access.AccessMode.EDIT, GetAccess()) - ] - mods = [start] - return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups) - -# --------------------------------------------------------- -# Обработка сообщений - -# --------------------------------------------------------- -# Работа с базой данных пользователей - -# --------------------------------------------------------- -# API - -# Инициализация БД -def GetInitBDCommands(): - return init_bd_cmds - -def GetAccess(): - return access.GetAccessForModule(module_name) - -# Доступные кнопки -def GetModuleButtons(): - return [keyboard.ButtonWithAccess(backup_button_name, user_access.AccessMode.VIEW, GetAccess())] - -# Обработка кнопок -def RegisterHandlers(dp : Dispatcher): - dp.register_message_handler(simple_message.InfoMessageTemplateLegacy(backup_message, GetBackupKeyboardButtons, GetAccess), text = backup_button_name) - - dp.register_message_handler(file_message.BackupFileTemplate(bot_bd.GetBDFileName(), backup_bd_message, GetAccess, GetBackupKeyboardButtons, error_backup_message), text = backup_bd_button_name) - dp.register_message_handler(file_message.BackupFileTemplate(log.g_log_file_name, backup_log_message, GetAccess, GetBackupKeyboardButtons, error_backup_message), text = backup_log_button_name) +init_access = f'{user_access.user_access_group_new}=-' + +class ModuleBackup(mod_simple_message.SimpleMessageModule): + def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log): + super().__init__(start_message, start_menu_button_name, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log) + self.m_BackupBDButtonName = self.CreateButton('backup bd', backup_bd_button_name) + self.m_BackupBDMessage = self.CreateMessage('backup bd', backup_bd_message) + + self.m_BackupLogButtonName = self.CreateButton('backup log', backup_log_button_name) + self.m_BackupLogMessage = self.CreateMessage('backup log', backup_log_message) + + self.m_BackupErrorMessage = self.CreateMessage('backup error', error_backup_message) + + self.m_BackupBDMessageHandler = file_message.BackupFileTemplate( + self.m_Bot, + self.m_Bot.m_BDFileName, + self.m_BackupBDMessage, + self.m_GetAccessFunc, + self.m_GetStartKeyboardButtonsFunc, + None, + self.m_BackupErrorMessage, + access_mode = user_access.AccessMode.EDIT + ) + self.m_BackupLogMessageHandler = file_message.BackupFileTemplate( + self.m_Bot, + self.m_Bot.GetLog().g_log_file_name, + self.m_BackupLogMessage, + self.m_GetAccessFunc, + self.m_GetStartKeyboardButtonsFunc, + None, + self.m_BackupErrorMessage, + access_mode = user_access.AccessMode.EDIT + ) + + def GetName(self): + return module_name + + def GetStartKeyboardButtons(self, a_Message, a_UserGroups): + mod_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups) + cur_buttons = [ + keyboard.ButtonWithAccess(self.m_BackupBDButtonName, user_access.AccessMode.EDIT, self.GetAccess()), + keyboard.ButtonWithAccess(self.m_BackupLogButtonName , user_access.AccessMode.EDIT, self.GetAccess()) + ] + return mod_buttons + keyboard.MakeButtons(cur_buttons, a_UserGroups) + + def RegisterHandlers(self): + super().RegisterHandlers() + self.m_Bot.RegisterMessageHandler( + self.m_BackupBDMessageHandler, + bd_item.GetCheckForTextFunc(self.m_BackupBDButtonName) + ) + self.m_Bot.RegisterMessageHandler( + self.m_BackupLogMessageHandler, + bd_item.GetCheckForTextFunc(self.m_BackupLogButtonName) + ) diff --git a/bot_modules/mod_simple_message.py b/bot_modules/mod_simple_message.py index 2e7bd0f..c3e6995 100644 --- a/bot_modules/mod_simple_message.py +++ b/bot_modules/mod_simple_message.py @@ -45,11 +45,11 @@ class SimpleMessageModule(mod_interface.IModule): return simple_message.WorkFuncResult(self.m_StartMessage) def CreateMessage(self, a_MessageName, a_MessageDesc): - msg = self.m_BotMessages.CreateMessage(f'{self.GetName()}_{a_MessageName}', a_MessageDesc, self.m_Log.GetTimeNow()) + msg = self.m_BotMessages.CreateMessage(f'{self.GetName()} {a_MessageName}', a_MessageDesc, self.m_Log.GetTimeNow()) return msg def CreateButton(self, a_ButtonName, a_ButtonDesc): - btn = self.m_BotButtons.CreateMessage(f'{self.GetName()}_{a_ButtonName}', a_ButtonDesc, self.m_Log.GetTimeNow()) + btn = self.m_BotButtons.CreateMessage(f'{self.GetName()} {a_ButtonName}', a_ButtonDesc, self.m_Log.GetTimeNow()) return btn def GetStartKeyboardButtons(self, a_Message, a_UserGroups): diff --git a/bot_modules/profile.py b/bot_modules/profile.py index cbb65f1..842fd4c 100644 --- a/bot_modules/profile.py +++ b/bot_modules/profile.py @@ -34,10 +34,11 @@ start_message = f''' start_menu_button_name = "📰 Профиль" +init_access = f'{user_access.user_access_group_new}=+' + class ModuleProfile(mod_simple_message.SimpleMessageModule): def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log): - a_InitAccess = f'{user_access.user_access_group_new}=+' - super().__init__(start_message, start_menu_button_name, a_InitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log) + super().__init__(start_message, start_menu_button_name, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log) def GetInitBDCommands(self): return super(). GetInitBDCommands() + [ diff --git a/bot_modules/start.py b/bot_modules/start.py index 34f3514..be1ef0a 100644 --- a/bot_modules/start.py +++ b/bot_modules/start.py @@ -12,11 +12,13 @@ start_message = ''' Выберите возможные действия на кнопках ниже ⌨''' +start_menu_button_name = "☰ Главное меню" + +init_access = f'{user_access.user_access_group_all}=+' + class ModuleStart(mod_simple_message.SimpleMessageModule): def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log): - start_menu_button_name = "☰ Главное меню" - a_InitAccess = f'{user_access.user_access_group_all}=+' - super().__init__(start_message, start_menu_button_name, a_InitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log) + super().__init__(start_message, start_menu_button_name, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log) def GetName(self): return 'start' diff --git a/bot_sys/aiogram_bot.py b/bot_sys/aiogram_bot.py index cf18b35..717f75f 100644 --- a/bot_sys/aiogram_bot.py +++ b/bot_sys/aiogram_bot.py @@ -28,7 +28,7 @@ class AiogramBot(interfaces.IBot): def SQLRequest(self, a_Request : str, commit = False, return_error = False, param = None): return bot_bd.SQLRequest(self.m_BDFileName, a_Request, commit = commit, return_error = return_error, param = param) - async def SendMessage(self, a_UserID, a_Message, a_PhotoIDs, a_InlineKeyboardButtons, a_KeyboardButtons): + async def SendMessage(self, a_UserID, a_Message, a_PhotoIDs, a_KeyboardButtons, a_InlineKeyboardButtons): inline_keyboard = None if a_InlineKeyboardButtons: inline_keyboard = keyboard.MakeAiogramInlineKeyboard(a_InlineKeyboardButtons) @@ -52,6 +52,23 @@ class AiogramBot(interfaces.IBot): reply_markup = base_keyboard ) + async def SendDocument(self, a_UserID, a_Document, a_Caption, a_KeyboardButtons, a_InlineKeyboardButtons): + inline_keyboard = None + if a_InlineKeyboardButtons: + inline_keyboard = keyboard.MakeAiogramInlineKeyboard(a_InlineKeyboardButtons) + base_keyboard = None + if a_KeyboardButtons: + base_keyboard = keyboard.MakeAiogramKeyboard(a_KeyboardButtons) + if inline_keyboard: + base_keyboard = inline_keyboard + await self.m_TBot.send_document( + a_UserID, + a_Document, + caption = a_Caption, + reply_markup = base_keyboard + ) + + def RegisterMessageHandler(self, a_MessageHandler, a_CheckFunc, commands=None, regexp=None, content_types=None, state=None): if a_CheckFunc: self.m_Dispatcher.register_message_handler(a_MessageHandler, a_CheckFunc, commands=commands, regexp=regexp, content_types=content_types, state=state) diff --git a/bot_sys/interfaces.py b/bot_sys/interfaces.py index d57fd92..0b279d9 100644 --- a/bot_sys/interfaces.py +++ b/bot_sys/interfaces.py @@ -17,7 +17,11 @@ class IBot(ABC): pass @abstractmethod - async def SendMessage(self, a_UserID, a_Message, a_PhotoIDs, a_InlineKeyboardButtons, a_KeyboardButtons): + async def SendMessage(self, a_UserID, a_Message, a_PhotoIDs, a_KeyboardButtons, a_InlineKeyboardButtons): + pass + + @abstractmethod + async def SendDocument(self, a_UserID, a_Document, a_Caption, a_KeyboardButtons, a_InlineKeyboardButtons): pass @abstractmethod diff --git a/bot_sys/keyboard.py b/bot_sys/keyboard.py index ba3a38e..56871e3 100644 --- a/bot_sys/keyboard.py +++ b/bot_sys/keyboard.py @@ -24,8 +24,10 @@ def GetButtons(a_ModList): import math def Chunks(a_List, a_ChunkSize): + chunk_list = [] for i in range(0, len(a_List), a_ChunkSize): - yield a_List[i: i + a_ChunkSize] + chunk_list += [a_List[i: i + a_ChunkSize]] + return chunk_list def GetButtonInRowCount(a_AllKeyCount): return min(max(int(math.sqrt(a_AllKeyCount) // 1), 1), 4) @@ -33,6 +35,7 @@ def GetButtonInRowCount(a_AllKeyCount): def MakeAiogramKeyboard(a_ButtonList : [[str]]): return types.ReplyKeyboardMarkup(keyboard=a_ButtonList, resize_keyboard = True) +# TODO перенести KeyboardButton в MakeAiogramKeyboard def MakeButtons(a_ButtonList : [ButtonWithAccess], a_UserGroups): buttons = [] for b in a_ButtonList: diff --git a/main.py b/main.py index 0f29a7c..b85eb32 100644 --- a/main.py +++ b/main.py @@ -6,7 +6,7 @@ log_start_message = 'Бот успешно запущен!' import os from bot_sys import config, log, bot_bd, user_access, aiogram_bot, bot_messages -from bot_modules import mod_agregator, start, profile #, projects, groups, access, backup, tasks, needs, comments, messages, , languages +from bot_modules import mod_agregator, start, profile, backup #, projects, groups, access, , tasks, needs, comments, messages, , languages g_Log = log g_Bot = aiogram_bot.AiogramBot(config.GetTelegramBotApiToken(), bot_bd.GetBDFileName(), config.GetRootIDs(), g_Log) @@ -23,7 +23,13 @@ mod_start_name = 'start' mod_profile = profile.ModuleProfile([mod_start_name], g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log) g_ModuleAgregator.AddModule(mod_profile) -start_mod_name_list = [mod_profile.GetName()]#, 'projects', 'groups', 'access', 'backup', 'languages'] +mod_backup = backup.ModuleBackup([mod_start_name], g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log) +g_ModuleAgregator.AddModule(mod_backup) + +start_mod_name_list = [#, 'projects', 'groups', 'access', , 'languages'] + mod_profile.GetName(), + mod_backup.GetName(), + ] mod_start = start.ModuleStart(start_mod_name_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log) g_ModuleAgregator.AddModule(mod_start) diff --git a/template/file_message.py b/template/file_message.py index aa69670..14c4bee 100644 --- a/template/file_message.py +++ b/template/file_message.py @@ -5,31 +5,41 @@ from bot_sys import log, config, user_access from bot_modules import access, groups -from aiogram import Bot, types +from template import simple_message -from aiogram.dispatcher import Dispatcher - -bot = Bot(token=config.GetTelegramBotApiToken(), parse_mode=types.ParseMode.HTML) - -def BackupFileTemplate(a_Path, a_CaptionMessage, a_AccessFunc, a_ButtonFunc, a_ErrorMessage): +def BackupFileTemplate(a_Bot, a_Path, a_CaptionMessage, a_AccessFunc, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_ErrorMessage, access_mode = user_access.AccessMode.EDIT): async def BackupFile(a_Message): user_id = str(a_Message.from_user.id) - user_groups= groups.GetUserGroupData(user_id) - if not user_access.CheckAccessString(a_AccessFunc(), user_groups, user_access.AccessMode.EDIT): - return await a_Message.answer(access.access_denied_message, reply_markup = a_ButtonFunc(a_Message, user_groups)) + user_groups= groups.GetUserGroupData(a_Bot, user_id) + if not user_access.CheckAccessString(a_AccessFunc(), user_groups, access_mode): + return await simple_message.AccessDeniedMessage(a_Bot, a_GetButtonsFunc, user_id, a_Message, user_groups) - document = await GetFile(a_Path) + document = await GetFile(a_Bot, a_Path) if document is None: - return await a_Message.answer(user_id, error_backup_message, reply_markup = a_ButtonFunc(a_Message, user_groups)) - - await bot.send_document(user_id, document, caption = a_CaptionMessage.replace('@time', log.GetTime()), reply_markup = a_ButtonFunc(a_Message, user_groups)) + return a_Bot.SendMessage( + user_id, + a_ErrorMessage, + None, + simple_message.ProxyGetButtonsTemplate(a_GetButtonsFunc)(a_Message, user_groups), + None + ) + msg = a_CaptionMessage.GetDesc() + msg = msg.replace('@time', a_Bot.GetLog().GetTime()) + + await a_Bot.SendDocument( + user_id, + document, + msg, + simple_message.ProxyGetButtonsTemplate(a_GetButtonsFunc)(a_Message, user_groups), + simple_message.ProxyGetButtonsTemplate(a_GetInlineButtonsFunc)(a_Message, user_groups) + ) return BackupFile -async def GetFile(a_Path): +async def GetFile(a_Bot, a_Path): try: document = open(a_Path, 'rb') - log.Success(f'Загружен файл {a_Path}') + a_Bot.GetLog().Success(f'Загружен файл {a_Path}') return document except Exception as e: - log.Error(f'Не удалось загрузить файл {a_Path}. Ошибка {str(e)}') + a_Bot.GetLog().Error(f'Не удалось загрузить файл {a_Path}. Ошибка {str(e)}') return None diff --git a/template/simple_message.py b/template/simple_message.py index f8a68a6..69525e4 100644 --- a/template/simple_message.py +++ b/template/simple_message.py @@ -7,6 +7,23 @@ from bot_sys import user_access from bot_modules import access, groups from aiogram import types +def ProxyGetButtonsTemplate(a_GetButtonsFunc1): + def ReturnNone(a_Message, user_groups): + return None + if a_GetButtonsFunc1: + return a_GetButtonsFunc1 + else: + return ReturnNone + +async def AccessDeniedMessage(a_Bot, a_GetButtonsFunc, a_UserID, a_Message, user_groups): + return a_Bot.SendMessage( + a_UserID, + access.access_denied_message, + None, + ProxyGetButtonsTemplate(a_GetButtonsFunc)(a_Message, user_groups), + None + ) + class WorkFuncResult(): def __init__(self, a_BotMessage, item_access = None): self.m_BotMessage = a_BotMessage @@ -19,29 +36,12 @@ def InfoMessageTemplate(a_Bot, a_HelpMessage, a_GetButtonsFunc, a_GetInlineButto return SimpleMessageTemplate(a_Bot, GetMessage, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_AccessFunc, access_mode = access_mode) def SimpleMessageTemplate(a_Bot, a_WorkFunc, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_AccessFunc, access_mode = user_access.AccessMode.VIEW): - def ProxyGetButtonsTemplate(a_GetButtonsFunc1): - def ReturnNone(a_Message, user_groups): - return None - if a_GetButtonsFunc1: - return a_GetButtonsFunc1 - else: - return ReturnNone - - async def AccessDeniedMessage(a_UserID, a_Message, user_groups): - return a_Bot.SendMessage( - a_UserID, - access.access_denied_message, - None, - None, - ProxyGetButtonsTemplate(a_GetButtonsFunc)(a_Message, user_groups) - ) - async def SimpleMessage(a_Message : types.message, state = None): user_id = str(a_Message.from_user.id) lang = str(a_Message.from_user.language_code) user_groups = groups.GetUserGroupData(a_Bot, user_id) if not user_access.CheckAccess(a_Bot.GetRootIDs(), a_AccessFunc(), user_groups, access_mode): - return await AccessDeniedMessage(user_id, a_Message, user_groups) + return await AccessDeniedMessage(a_Bot, a_GetButtonsFunc, user_id, a_Message, user_groups) res = await a_WorkFunc(a_Message, state = state) if res is None: @@ -52,7 +52,7 @@ def SimpleMessageTemplate(a_Bot, a_WorkFunc, a_GetButtonsFunc, a_GetInlineButton return if not res.item_access is None and not user_access.CheckAccess(a_Bot.GetRootIDs(), res.item_access, user_groups, access_mode): - return await AccessDeniedMessage(user_id, a_Message, user_groups) + return await AccessDeniedMessage(a_Bot, a_GetButtonsFunc, user_id, a_Message, user_groups) msg = msg.GetMessageForLang(lang).StaticCopy() @@ -60,7 +60,7 @@ def SimpleMessageTemplate(a_Bot, a_WorkFunc, a_GetButtonsFunc, a_GetInlineButton user_id, msg.GetDesc(), msg.GetPhotoID(), - ProxyGetButtonsTemplate(a_GetInlineButtonsFunc)(a_Message, user_groups), - ProxyGetButtonsTemplate(a_GetButtonsFunc)(a_Message, user_groups) + ProxyGetButtonsTemplate(a_GetButtonsFunc)(a_Message, user_groups), + ProxyGetButtonsTemplate(a_GetInlineButtonsFunc)(a_Message, user_groups) ) return SimpleMessage