From 20600710be68c3db4a914a20cac5f713d54e3f18 Mon Sep 17 00:00:00 2001 From: Alexei Date: Sat, 13 May 2023 22:30:39 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D1=82=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= =?UTF-8?q?=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot_modules/access_utils.py | 29 +++++++++++++++++ bot_modules/mod_agregator.py | 8 ++--- bot_modules/mod_interface.py | 10 +++--- bot_modules/mod_simple_message.py | 36 +++++++++++----------- bot_modules/start.py | 23 ++++++++------ bot_sys/aiogram_bot.py | 65 +++++++++++++-------------------------- bot_sys/bot_messages.py | 18 +++++------ bot_sys/interfaces.py | 20 +++--------- bot_sys/user_access.py | 23 ++++++++++---- main.py | 2 +- template/simple_message.py | 6 ++-- 11 files changed, 125 insertions(+), 115 deletions(-) diff --git a/bot_modules/access_utils.py b/bot_modules/access_utils.py index abc3531..07248de 100644 --- a/bot_modules/access_utils.py +++ b/bot_modules/access_utils.py @@ -3,6 +3,8 @@ # Права пользователей. Утилиты +from bot_sys import user_access, bot_bd + table_name = 'module_access' mod_name_field = 'modName' moduleaccess_field = 'modAccess' @@ -10,3 +12,30 @@ mod_default_access_field = 'itemDefaultAccess' def GetAccessForModuleRequest(module_name, access, default_access): return f"INSERT OR IGNORE INTO {table_name} ({mod_name_field}, {moduleaccess_field}, {mod_default_access_field}) VALUES ('{module_name}', '{access}', '{default_access}');" + +def GetUserGroupData(a_Bot, a_UserID): + def GetGroupNamesForUser(a_UserID): + return a_Bot.SQLRequest('SELECT groupName FROM user_groups WHERE group_id=(SELECT group_id FROM user_in_groups WHERE user_id = ?)', param = [a_UserID]) + r = GetGroupNamesForUser(a_UserID) + groups = [] + for i in r: + if len(i) > 0: + groups += [i[0]] + return user_access.UserGroups(a_UserID, groups) + +def GetModulesAccessList(a_Bot): + return bot_bd.RequestSelectTemplate(a_Bot.m_BDFileName, table_name)() + +def GetAccessForModule(a_Bot, a_ModuleName): + alist = GetModulesAccessList(a_Bot) + for i in alist: + if i[0] == a_ModuleName: + return i[1] + return '' + +def GetItemDefaultAccessForModule(a_Bot, a_ModuleName): + alist = GetModulesAccessList(a_Bot) + for i in alist: + if i[0] == a_ModuleName: + return i[2] + return '' diff --git a/bot_modules/mod_agregator.py b/bot_modules/mod_agregator.py index 715609a..f2e3306 100644 --- a/bot_modules/mod_agregator.py +++ b/bot_modules/mod_agregator.py @@ -5,11 +5,11 @@ class ModuleAgregator: def __init__(self): self.m_Modules = {} - def GetModule(a_ModName): + def GetModule(self, a_ModName): return self.m_Modules[a_ModName] - def AddModule(a_Module): + def AddModule(self, a_Module): self.m_Modules[a_Module.GetName()] = a_Module - def GetModList(): - self.m_Modules.items() + def GetModList(self): + return self.m_Modules.values() diff --git a/bot_modules/mod_interface.py b/bot_modules/mod_interface.py index 026deb3..3423c78 100644 --- a/bot_modules/mod_interface.py +++ b/bot_modules/mod_interface.py @@ -5,21 +5,21 @@ from abc import ABC, abstractmethod class IModule(ABC): @abstractmethod - def GetName(): + def GetName(self): pass @abstractmethod - def GetInitBDCommands(): + def GetInitBDCommands(self): pass @abstractmethod - def GetAccess(): + def GetAccess(self): pass @abstractmethod - def GetModuleButtons(): + def GetModuleButtons(self): pass @abstractmethod - def RegisterHandlers(): + def RegisterHandlers(self): pass diff --git a/bot_modules/mod_simple_message.py b/bot_modules/mod_simple_message.py index 88b51c7..f7030bf 100644 --- a/bot_modules/mod_simple_message.py +++ b/bot_modules/mod_simple_message.py @@ -3,12 +3,12 @@ # Простой модуль с одним сообщением -from bot_sys import keyboard, user_access -from bot_modules import access_utils -from template import simple_message +from bot_sys import keyboard, user_access, keyboard +from bot_modules import access_utils, mod_interface +from template import simple_message, bd_item class SimpleMessageModule(mod_interface.IModule): - def __init__(self, a_StartMessage, a_StartButtonName, a_InitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log): + def __init__(self, a_StartMessage, a_StartButtonName, a_InitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log): self.m_ChildModuleNameList = a_ChildModuleNameList self.m_InitAccess = a_InitAccess self.m_Bot = a_Bot @@ -17,11 +17,11 @@ class SimpleMessageModule(mod_interface.IModule): self.m_BotButtons = a_BotButtons self.m_Log = a_Log - self.m_StartButtonName = CreateButton(f'{GetName()}_start', a_StartButtonName) - self.m_StartMessage = CreateMessage(f'{GetName()}_start', a_StartMessage) + self.m_StartButtonName = self.CreateButton(f'{self.GetName()}_start', a_StartButtonName) + self.m_StartMessage = self.CreateMessage(f'{self.GetName()}_start', a_StartMessage) async def StartMessageHandler(a_Message, state = None): - return self.StartMessageHandler(a_Message, state) + return await self.StartMessageHandler(a_Message, state) self.m_StartMessageHandlerFunc = StartMessageHandler def GetAccess(): @@ -41,18 +41,18 @@ class SimpleMessageModule(mod_interface.IModule): ) # Основной обработчик главного сообщения - async def StartMessageHandler(a_Message, state = None): + async def StartMessageHandler(self, a_Message, state = None): return simple_message.WorkFuncResult(self.m_StartMessage) - def CreateMessage(a_MessageName, a_MessageDesc): + def CreateMessage(self, a_MessageName, a_MessageDesc): msg = self.m_BotMessages.CreateMessage(a_MessageName, a_MessageDesc, self.m_Log.GetTimeNow()) return msg - def CreateButton(a_ButtonName, a_ButtonDesc): + def CreateButton(self, a_ButtonName, a_ButtonDesc): btn = self.m_BotButtons.CreateMessage(a_ButtonName, a_ButtonDesc, self.m_Log.GetTimeNow()) return btn - def GetStartKeyboardButtons(a_Message, a_UserGroups): + def GetStartKeyboardButtons(self, a_Message, a_UserGroups): def GetButtons(a_ModNameList): buttons = [] for n in a_ModNameList: @@ -63,22 +63,22 @@ class SimpleMessageModule(mod_interface.IModule): return buttons buttons = GetButtons(self.m_ChildModuleNameList) - return MakeButtons(buttons, a_UserGroups) + return keyboard.MakeButtons(buttons, a_UserGroups) - def GetInitBDCommands(): + def GetInitBDCommands(self): return [ - access_utils.GetAccessForModuleRequest(GetName(), self.m_InitAccess, self.m_InitAccess), + access_utils.GetAccessForModuleRequest(self.GetName(), self.m_InitAccess, self.m_InitAccess), ] - def GetAccess(): - return self.m_Bot.GetAccessForModule(module_name) + def GetAccess(self): + return access_utils.GetAccessForModule(self.m_Bot, self.GetName()) - def GetModuleButtons(): + def GetModuleButtons(self): return [ keyboard.ButtonWithAccess(self.m_StartButtonName, user_access.AccessMode.VIEW, GetAccess()), ] - def RegisterHandlers(): + def RegisterHandlers(self): self.m_Bot.RegisterMessageHandler( self.m_StartMessageHandler, bd_item.GetCheckForTextFunc(self.m_StartButtonName) diff --git a/bot_modules/start.py b/bot_modules/start.py index ef6ced9..fab84aa 100644 --- a/bot_modules/start.py +++ b/bot_modules/start.py @@ -5,37 +5,40 @@ from bot_sys import user_access from bot_modules import mod_simple_message +from template import bd_item -class ModuleStart(mod_simple_message.SimpleMessageModule): - def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log): - msg = ''' +start_message = ''' Добро пожаловать! Выберите возможные действия на кнопках ниже ⌨''' + +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__(self, msg, 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, a_InitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log) - def GetName(): + def GetName(self): return 'start' # Основной обработчик главного сообщения - async def StartMessageHandler(a_Message, state = None): + async def StartMessageHandler(self, a_Message, state = None): user_id = str(a_Message.from_user.id) user_name = str(a_Message.from_user.username) first_name = str(a_Message.from_user.first_name) last_name = str(a_Message.from_user.last_name) is_bot = str(a_Message.from_user.is_bot) language_code = str(a_Message.from_user.language_code) - profile.AddUser(user_id, user_name, first_name, last_name, is_bot, language_code) + #profile.AddUser(user_id, user_name, first_name, last_name, is_bot, language_code) self.m_Log.Info(f'Пользователь {user_id} {user_name} авторизовался в боте. Полные данные {a_Message.from_user}.') - return super().StartMessageHandler(a_Message, state) + return await super().StartMessageHandler(a_Message, state) - def RegisterHandlers(): + def RegisterHandlers(self): super().RegisterHandlers() self.m_Bot.RegisterMessageHandler( self.m_StartMessageHandler, - bd_item.GetCheckForCommandsFunc(['start']) + None, + commands = ['start'] ) diff --git a/bot_sys/aiogram_bot.py b/bot_sys/aiogram_bot.py index 2c49bd3..a2994f8 100644 --- a/bot_sys/aiogram_bot.py +++ b/bot_sys/aiogram_bot.py @@ -1,7 +1,7 @@ #-*-coding utf-8-*- # Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) -from bot_sys import interfaces, bot_bd, keyboard +from bot_sys import interfaces, bot_bd, keyboard, user_access from aiogram import types from aiogram import Bot @@ -17,68 +17,47 @@ class AiogramBot(interfaces.IBot): self.m_Log = a_Log self.m_TBot = Bot(token=self.m_TelegramBotApiToken, parse_mode = types.ParseMode.HTML) self.m_Storage = MemoryStorage() - self.m_Dispatcher = Dispatcher(self.m_TBot, storage = storage) + self.m_Dispatcher = Dispatcher(self.m_TBot, storage = self.m_Storage) - def GetRootIDs(): + def GetRootIDs(self): return self.m_RootIDs - def GetLog(): + def GetLog(self): return self.m_Log 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) - def GetUserGroupData(a_UserID): - def GetGroupNamesForUser(a_UserID): - return SQLRequest('SELECT groupName FROM user_groups WHERE group_id=(SELECT group_id FROM user_in_groups WHERE user_id = ?)', param = [a_UserID]) - r = GetGroupNamesForUser(a_UserID) - groups = [] - for i in r: - if len(i) > 0: - groups += [i[0]] - return user_access.UserGroups(a_UserID, groups) - - def GetModulesAccessList(): - return bot_bd.RequestSelectTemplate(self.m_BDFileName, table_name)() - - def GetAccessForModule(a_ModuleName): - alist = GetModulesAccessList() - for i in alist: - if i[0] == a_ModuleName: - return i[1] - return '' - - def GetItemDefaultAccessForModule(a_ModuleName): - alist = GetModulesAccessList() - for i in alist: - if i[0] == a_ModuleName: - return i[2] - return '' - async def SendMessage(self, a_UserID, a_Message, a_PhotoIDs, a_InlineKeyboardButtons, a_KeyboardButtons): inline_keyboard = keyboard.MakeAiogramInlineKeyboard(a_InlineKeyboardButtons) - keyboard = keyboard.MakeAiogramKeyboard(a_KeyboardButtons) - if not keyboard: - keyboard = inline_keyboard - if a_PhotoIDs and a_PhotoIDs != 0 or a_PhotoIDs != '0': - self.m_TBot.send_photo( + base_keyboard = keyboard.MakeAiogramKeyboard(a_KeyboardButtons) + if a_InlineKeyboardButtons: + base_keyboard = inline_keyboard + if a_PhotoIDs and a_PhotoIDs != 0 and a_PhotoIDs != '0': + await self.m_TBot.send_photo( a_UserID, a_PhotoIDs, a_Message, - reply_markup = keyboard + reply_markup = base_keyboard ) else: - self.m_TBot.send_message( + await self.m_TBot.send_message( a_UserID, a_Message, - reply_markup = keyboard + reply_markup = base_keyboard ) - def RegisterMessageHandler(self, a_MessageHandler, a_CheckFunc): - self.m_Dispatcher.register_message_handler(a_MessageHandler, a_CheckFunc) + 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) + else: + self.m_Dispatcher.register_message_handler(a_MessageHandler, commands=commands, regexp=regexp, content_types=content_types, state=state) - def RegisterCallbackHandler(self, a_CallbackHandler, a_CheckFunc): - self.m_Dispatcher.register_callback_query_handler(a_CallbackHandler, a_CheckFunc) + def RegisterCallbackHandler(self, a_CallbackHandler, a_CheckFunc, commands=None, regexp=None, content_types=None, state=None): + if a_CheckFunc: + self.register_callback_query_handler.register_message_handler(a_CallbackHandler, a_CheckFunc, commands=commands, regexp=regexp, content_types=content_types, state=state) + else: + self.register_callback_query_handler.register_message_handler(a_CallbackHandler, commands=commands, regexp=regexp, content_types=content_types, state=state) def StartPolling(self): executor.start_polling(self.m_Dispatcher) diff --git a/bot_sys/bot_messages.py b/bot_sys/bot_messages.py index c84b528..ef1fb34 100644 --- a/bot_sys/bot_messages.py +++ b/bot_sys/bot_messages.py @@ -12,16 +12,16 @@ class BotMessage: self.m_PhotoID = a_PhotoID self.m_DateTime = a_DateTime - def GetName(): + def GetName(self): return self.m_MessageName - def GetDesc(): + def GetDesc(self): return self.m_MessageDesc - def GetLanguage(): + def GetLanguage(self): return self.m_Language - def GetPhotoID(): + def GetPhotoID(self): return self.m_PhotoID def __str__(self): @@ -51,15 +51,15 @@ class BotMessages: self.m_Messages = {} self.m_LastUpdate = None - def GetMessages(): + def GetMessages(self): return self.m_Messages - def UpdateSignal(a_DateTime): + def UpdateSignal(self, a_DateTime): self.m_LastUpdate = a_DateTime - def CreateMessage(a_MessageName, a_MessageDesc, a_DateTime): - cur_msg = BotMessage(a_MessageName, a_MessageDesc, self.a_DefaultLanguage, 0, a_DateTime) - msg = GetMessages() + def CreateMessage(self, a_MessageName, a_MessageDesc, a_DateTime): + cur_msg = BotMessage(self, a_MessageName, a_MessageDesc, self.a_DefaultLanguage, 0, a_DateTime) + msg = self.GetMessages() if not msg.get(self.a_DefaultLanguage, None): msg[self.a_DefaultLanguage] = {} if not msg[self.a_DefaultLanguage].get(a_MessageName, None): diff --git a/bot_sys/interfaces.py b/bot_sys/interfaces.py index 3638f12..d57fd92 100644 --- a/bot_sys/interfaces.py +++ b/bot_sys/interfaces.py @@ -5,11 +5,11 @@ from abc import ABC, abstractmethod class IBot(ABC): @abstractmethod - def GetRootIDs(): + def GetRootIDs(self): pass @abstractmethod - def GetLog(): + def GetLog(self): pass @abstractmethod @@ -17,27 +17,15 @@ class IBot(ABC): pass @abstractmethod - def GetUserGroupData(a_UserID): - pass - - @abstractmethod - def GetAccessForModule(a_ModuleName): - pass - - @abstractmethod - def GetItemDefaultAccessForModule(a_ModuleName): - pass - - @abstractmethod async def SendMessage(self, a_UserID, a_Message, a_PhotoIDs, a_InlineKeyboardButtons, a_KeyboardButtons): pass @abstractmethod - def RegisterMessageHandler(self, a_MessageHandler, a_CheckFunc): + def RegisterMessageHandler(self, a_MessageHandler, a_CheckFunc, commands=None, regexp=None, content_types=None, state=None): pass @abstractmethod - def RegisterCallbackHandler(self, a_CallbackHandler, a_CheckFunc): + def RegisterCallbackHandler(self, a_CallbackHandler, a_CheckFunc, commands=None, regexp=None, content_types=None, state=None): pass @abstractmethod diff --git a/bot_sys/user_access.py b/bot_sys/user_access.py index 12e3c18..c4fbd67 100644 --- a/bot_sys/user_access.py +++ b/bot_sys/user_access.py @@ -83,12 +83,23 @@ def Test(): assert CheckAccess(roots, '1234=-', UserGroups('1234', []), am) assert CheckAccess(roots, '1234=+;gr1=+', UserGroups('1234', ['gr1']), am) assert CheckAccess(roots, '1234=-;gr1=+', UserGroups('1234', ['gr1']), am) - assert CheckAccess(roots, '1234=+', UserGroups('123', []), am) - assert CheckAccess(roots, '1234=-', UserGroups('123', []), am) - assert CheckAccess(roots, '1234=+;gr1=+', UserGroups('123', ['gr']), am) - assert CheckAccess(roots, '1234=-;gr1=+', UserGroups('123', ['gr']), am) - assert CheckAccess(roots, '1234=+;gr=+', UserGroups('123', ['gr1']), am) - assert CheckAccess(roots, '1234=-;gr=+', UserGroups('123', ['gr1']), am) + assert CheckAccess(roots, '1234=+', UserGroups('1234', []), am) + assert CheckAccess(roots, '1234=-', UserGroups('1234', []), am) + assert CheckAccess(roots, '1234=+;gr1=+', UserGroups('1234', ['gr']), am) + assert CheckAccess(roots, '1234=-;gr1=+', UserGroups('1234', ['gr']), am) + assert CheckAccess(roots, '1234=+;gr=+', UserGroups('1234', ['gr1']), am) + assert CheckAccess(roots, '1234=-;gr=+', UserGroups('1234', ['gr1']), am) + + assert CheckAccess(roots, '123=+', UserGroups('1234', []), am) + assert CheckAccess(roots, '124=-', UserGroups('1234', []), am) + assert CheckAccess(roots, '134=+;gr1=+', UserGroups('1234', ['gr1']), am) + assert CheckAccess(roots, '134=-;gr1=+', UserGroups('1234', ['gr1']), am) + assert CheckAccess(roots, '124=+', UserGroups('1234', []), am) + assert CheckAccess(roots, '124=-', UserGroups('1234', []), am) + assert CheckAccess(roots, '134=+;gr1=+', UserGroups('1234', ['gr']), am) + assert CheckAccess(roots, '134=-;gr1=+', UserGroups('1234', ['gr']), am) + assert CheckAccess(roots, '124=+;gr=+', UserGroups('1234', ['gr1']), am) + assert CheckAccess(roots, '124=-;gr=+', UserGroups('1234', ['gr1']), am) roots = ['12'] for am in AccessMode.ADD, AccessMode.DELETE, AccessMode.EDIT, AccessMode.VIEW, AccessMode.ACCEES_EDIT: diff --git a/main.py b/main.py index dee9567..c93b3f0 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,7 @@ from bot_sys import config, log, bot_bd, user_access, aiogram_bot, bot_messages from bot_modules import mod_agregator, start #, projects, groups, access, backup, tasks, needs, comments, messages, profile, languages g_Log = log -g_Bot = aiogram_bot.AiogramBot(config.GetTelegramBotApiToken(), bot_bd.GetBDFileName(), config.GetRootIDs(), g_Log): +g_Bot = aiogram_bot.AiogramBot(config.GetTelegramBotApiToken(), bot_bd.GetBDFileName(), config.GetRootIDs(), g_Log) default_language = 'ru' diff --git a/template/simple_message.py b/template/simple_message.py index cfe8da3..0a5f4a5 100644 --- a/template/simple_message.py +++ b/template/simple_message.py @@ -4,7 +4,7 @@ # Простые информационные сообщения from bot_sys import user_access -from bot_modules import access +from bot_modules import access, access_utils from aiogram import types class WorkFuncResult(): @@ -20,7 +20,7 @@ def InfoMessageTemplate(a_Bot, a_HelpMessage, a_GetButtonsFunc, a_GetInlineButto def SimpleMessageTemplate(a_Bot, a_WorkFunc, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_AccessFunc, access_mode = user_access.AccessMode.VIEW): def ProxyGetButtonsTemplate(a_GetButtonsFunc): - def ReturnNone(): + def ReturnNone(a_Message, user_groups): return None if a_GetButtonsFunc: return a_GetButtonsFunc @@ -39,7 +39,7 @@ def SimpleMessageTemplate(a_Bot, a_WorkFunc, a_GetButtonsFunc, a_GetInlineButton 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 = a_Bot.GetUserGroupData(user_id) + user_groups = access_utils.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)