37 changed files with 2607 additions and 2655 deletions
@ -0,0 +1,37 @@
|
||||
# -*- coding: utf8 -*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
# Права пользователей |
||||
|
||||
from bot_sys import bot_bd |
||||
|
||||
# --------------------------------------------------------- |
||||
# БД |
||||
table_name = 'module_access' |
||||
mod_name_field = 'modName' |
||||
moduleaccess_field = 'modAccess' |
||||
mod_default_access_field = 'itemDefaultAccess' |
||||
|
||||
access_denied_message = ''' |
||||
❌ Доступ запрещён! |
||||
''' |
||||
|
||||
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 GetModulesAccessList(a_Bot): |
||||
return bot_bd.RequestSelectTemplate(a_Bot, 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 '' |
@ -0,0 +1,200 @@
|
||||
# -*- coding: utf8 -*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
# Сообщения |
||||
|
||||
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_messages |
||||
from bot_modules import mod_table_operate, mod_simple_message, access_utils |
||||
from template import bd_item |
||||
|
||||
from aiogram.dispatcher import FSMContext |
||||
from aiogram.dispatcher.filters.state import State, StatesGroup |
||||
|
||||
class FSMCreateButton(StatesGroup): |
||||
name = State() |
||||
desc = State() |
||||
photo = State() |
||||
|
||||
class FSMEditButtonPhotoItem(StatesGroup): |
||||
item_id = State() |
||||
item_field = State() |
||||
|
||||
class FSMEditButtonNameItem(StatesGroup): |
||||
item_id = State() |
||||
item_field = State() |
||||
|
||||
class FSMEditButtonDescItem(StatesGroup): |
||||
item_id = State() |
||||
item_field = State() |
||||
|
||||
class FSMEditButtonAccessItem(StatesGroup): |
||||
item_id = State() |
||||
item_field = State() |
||||
# --------------------------------------------------------- |
||||
# БД |
||||
module_name = 'buttons' |
||||
|
||||
table_name = module_name |
||||
key_name = 'buttonID' |
||||
name_field = 'buttonName' |
||||
desc_field = 'buttonDesc' |
||||
photo_field = 'buttonPhoto' |
||||
access_field = 'buttonAccess' |
||||
create_datetime_field = 'buttonCreateDateTime' |
||||
parent_id_field = 'languageID' |
||||
|
||||
table_name_field = bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR) |
||||
table_parent_id_field = bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT) |
||||
|
||||
table = bd_table.Table(table_name, [ |
||||
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT), |
||||
table_name_field, |
||||
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR), |
||||
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR), |
||||
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR), |
||||
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR), |
||||
table_parent_id_field, |
||||
], |
||||
[ |
||||
[table_name_field, table_parent_id_field], |
||||
] |
||||
) |
||||
|
||||
init_access = f'{user_access.user_access_group_all}=-' |
||||
|
||||
fsm = { |
||||
mod_table_operate.FSMs.CREATE: FSMCreateButton, |
||||
mod_table_operate.FSMs.EDIT_NAME: FSMEditButtonNameItem, |
||||
mod_table_operate.FSMs.EDIT_DESC: FSMEditButtonDescItem, |
||||
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditButtonPhotoItem, |
||||
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditButtonAccessItem, |
||||
} |
||||
|
||||
# --------------------------------------------------------- |
||||
# Сообщения и кнопки |
||||
|
||||
button_names = { |
||||
mod_simple_message.ButtonNames.START: "❍ Названия кнопок", |
||||
mod_table_operate.ButtonNames.LIST: "📃 Список названий кнопок", |
||||
mod_table_operate.ButtonNames.ADD: "☑ Добавить название кнопки", |
||||
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать названия кнопок", |
||||
mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение у названия кнопок", |
||||
mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название у названия кнопок", |
||||
mod_table_operate.ButtonNames.EDIT_DESC: "𝌴 Изменить описание у названия кнопок", |
||||
mod_table_operate.ButtonNames.EDIT_ACCESS: "✋ Изменить доступ к названию кнопки", |
||||
mod_table_operate.ButtonNames.DEL: "❌ Удалить название кнопки", |
||||
} |
||||
|
||||
messages = { |
||||
mod_simple_message.Messages.START: f''' |
||||
<b>{button_names[mod_simple_message.ButtonNames.START]}</b> |
||||
|
||||
''', |
||||
mod_table_operate.Messages.SELECT: ''' |
||||
Пожалуйста, выберите название кнопки: |
||||
''', |
||||
mod_table_operate.Messages.ERROR_FIND: ''' |
||||
❌ Ошибка, название кнопки не найдено |
||||
''', |
||||
mod_table_operate.Messages.OPEN: f''' |
||||
<b>Название кнопки: #{name_field}</b> |
||||
|
||||
#{desc_field} |
||||
|
||||
Время создания: #{create_datetime_field} |
||||
''', |
||||
mod_table_operate.Messages.CREATE_NAME: ''' |
||||
Создание названия кнопки Шаг №1 |
||||
|
||||
Введите название название кнопки: |
||||
''', |
||||
mod_table_operate.Messages.CREATE_DESC: ''' |
||||
Создание названия кнопки. Шаг №2 |
||||
|
||||
Введите описание название кнопки: |
||||
''', |
||||
mod_table_operate.Messages.CREATE_PHOTO: ''' |
||||
Создание названия кнопки |
||||
Загрузите обложку для названия кнопок (Фото): |
||||
На данный момент не поддерживается! |
||||
Нажмите пропустить |
||||
''', |
||||
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Название кнопки успешно добавлено!''', |
||||
mod_table_operate.Messages.START_EDIT: ''' |
||||
Пожалуйста, выберите действие: |
||||
''', |
||||
mod_table_operate.Messages.SELECT_TO_EDIT: ''' |
||||
Выберите название кнопки, который вы хотите отредактировать. |
||||
''', |
||||
mod_table_operate.Messages.EDIT_PHOTO: ''' |
||||
Загрузите новую обложку для названия кнопок (Фото): |
||||
Она будет отображаться в его описании. |
||||
''', |
||||
mod_table_operate.Messages.EDIT_NAME: f''' |
||||
Текущее название названия кнопок: |
||||
#{name_field} |
||||
|
||||
Введите новое название названия кнопки: |
||||
''', |
||||
mod_table_operate.Messages.EDIT_DESC: f''' |
||||
Текущее описание названия кнопок: |
||||
#{desc_field} |
||||
|
||||
Введите новое описание названия кнопки: |
||||
''', |
||||
mod_table_operate.Messages.EDIT_ACCESS: f''' |
||||
Текущий доступ к названию кнопки: |
||||
#{access_field} |
||||
|
||||
{user_access.user_access_readme} |
||||
|
||||
Введите новую строку доступа: |
||||
''', |
||||
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Название кнопки успешно отредактировано!''', |
||||
mod_table_operate.Messages.SELECT_TO_DELETE: ''' |
||||
Выберите название кнопки, которое вы хотите удалить. |
||||
''', |
||||
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Название кнопки успешно удалено!''', |
||||
} |
||||
|
||||
class ModuleButtons(mod_table_operate.TableOperateModule): |
||||
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log): |
||||
super().__init__(table, messages, button_names, fsm, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log) |
||||
|
||||
def GetName(self): |
||||
return module_name |
||||
|
||||
def AddOrIgnoreMessage(self, a_Message): |
||||
table_name = self.m_Table.GetName() |
||||
name_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.NAME) |
||||
photo_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PHOTO) |
||||
desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC) |
||||
access_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.ACCESS) |
||||
create_datetime_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.CREATE_DATE) |
||||
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) |
||||
|
||||
lang_id = self.GetModule(self.m_ParentModName).GetLangID(a_Message.m_Language) |
||||
return self.m_Bot.SQLRequest(f'INSERT OR IGNORE INTO {table_name}({photo_field}, {name_field}, {desc_field}, {access_field}, {parent_id_field}, {create_datetime_field}) VALUES(?, ?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()})', |
||||
commit = True, return_error = True, param = (a_Message.m_PhotoID, a_Message.m_MessageName, a_Message.m_MessageDesc, access_utils.GetItemDefaultAccessForModule(self.m_Bot, module_name), lang_id)) |
||||
|
||||
def FlushMessages(self): |
||||
msg = self.m_BotButtons.GetMessages() |
||||
for lang, msg_dict in msg.items(): |
||||
for msg_name, message in msg_dict.items(): |
||||
self.AddOrIgnoreMessage(message) |
||||
|
||||
table_name = self.m_Table.GetName() |
||||
msgs_bd = bd_item.GetAllItemsTemplate(self.m_Bot, table_name)() |
||||
if msgs_bd: |
||||
for m in msgs_bd: |
||||
name = m[1] |
||||
desc = m[2] |
||||
photo_id = m[3] |
||||
lang_id = m[6] |
||||
lang_name = self.GetModule(self.m_ParentModName).GetLangName(lang_id) |
||||
self.m_BotButtons.CreateMessage(name, desc, self.m_Log.GetTimeNow(), a_MessagePhotoID = photo_id, a_MessageLang = lang_name) |
||||
|
||||
self.m_BotButtons.UpdateSignal(self.m_Log.GetTimeNow()) |
||||
|
||||
def OnChange(self): |
||||
self.FlushMessages() |
@ -0,0 +1,16 @@
|
||||
# -*- coding: utf8 -*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
# Группы пользователей |
||||
|
||||
from bot_sys import user_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) |
@ -0,0 +1,15 @@
|
||||
# -*- coding: utf8 -*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
class ModuleAgregator: |
||||
def __init__(self): |
||||
self.m_Modules = {} |
||||
|
||||
def GetModule(self, a_ModName): |
||||
return self.m_Modules[a_ModName] |
||||
|
||||
def AddModule(self, a_Module): |
||||
self.m_Modules[a_Module.GetName()] = a_Module |
||||
|
||||
def GetModList(self): |
||||
return self.m_Modules.values() |
@ -0,0 +1,25 @@
|
||||
# -*- coding: utf8 -*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
from abc import ABC, abstractmethod |
||||
|
||||
class IModule(ABC): |
||||
@abstractmethod |
||||
def GetName(self): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
def GetInitBDCommands(self): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
def GetAccess(self): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
def GetModuleButtons(self): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
def RegisterHandlers(self): |
||||
pass |
@ -0,0 +1,112 @@
|
||||
# -*- coding: utf8 -*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
# Простой модуль с одним сообщением |
||||
|
||||
from bot_sys import keyboard, user_access |
||||
from bot_modules import access_utils, mod_interface |
||||
from template import simple_message, bd_item |
||||
|
||||
from enum import Enum |
||||
from enum import auto |
||||
|
||||
class ButtonNames(Enum): |
||||
START = auto() |
||||
|
||||
class Messages(Enum): |
||||
START = auto() |
||||
|
||||
class SimpleMessageModule(mod_interface.IModule): |
||||
def __init__(self, a_Messages, a_Buttons, 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 |
||||
self.m_ModuleAgregator = a_ModuleAgregator |
||||
self.m_BotMessages = a_BotMessages |
||||
self.m_BotButtons = a_BotButtons |
||||
self.m_Log = a_Log |
||||
|
||||
self.m_Buttons = {} |
||||
for name, button_name in a_Buttons.items(): |
||||
self.m_Buttons[name] = self.CreateButton(name, button_name) |
||||
|
||||
self.m_Messages = {} |
||||
for name, message in a_Messages.items(): |
||||
self.m_Messages[name] = self.CreateMessage(name, message) |
||||
|
||||
async def StartMessageHandler(a_Message, state = None): |
||||
return await self.StartMessageHandler(a_Message, state) |
||||
self.m_StartMessageHandlerFunc = StartMessageHandler |
||||
|
||||
def GetAccess(): |
||||
return self.GetAccess() |
||||
self.m_GetAccessFunc = GetAccess |
||||
|
||||
def GetStartKeyboardButtons(a_Message, a_UserGroups): |
||||
return self.GetStartKeyboardButtons(a_Message, a_UserGroups) |
||||
self.m_GetStartKeyboardButtonsFunc = GetStartKeyboardButtons |
||||
|
||||
self.m_StartMessageHandler = simple_message.SimpleMessageTemplate( |
||||
self.m_Bot, |
||||
self.m_StartMessageHandlerFunc, |
||||
self.m_GetStartKeyboardButtonsFunc, |
||||
None, |
||||
self.m_GetAccessFunc |
||||
) |
||||
|
||||
# Основной обработчик главного сообщения |
||||
async def StartMessageHandler(self, a_Message, state = None): |
||||
return simple_message.WorkFuncResult(self.GetMessage(Messages.START)) |
||||
|
||||
def GetButton(self, a_ButtonName): |
||||
return self.m_Buttons.get(a_ButtonName, None) |
||||
|
||||
def GetMessage(self, a_MessageNames): |
||||
return self.m_Messages.get(a_MessageNames, None) |
||||
|
||||
def CreateMessage(self, a_MessageName, a_MessageDesc): |
||||
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): |
||||
assert len(a_ButtonDesc) < 41 # Телеграм не поддерживает больше |
||||
assert a_ButtonDesc[0] != ' ' # Телеграм не поддерживает пробелы в начале |
||||
assert a_ButtonDesc[-1:] != ' ' # Телеграм не поддерживает пробелы в конце |
||||
btn = self.m_BotButtons.CreateMessage(f'{self.GetName()} {a_ButtonName}', a_ButtonDesc, self.m_Log.GetTimeNow()) |
||||
return btn |
||||
|
||||
def GetModule(self, a_ModName): |
||||
return self.m_ModuleAgregator.GetModule(a_ModName) |
||||
|
||||
def GetButtons(self, a_ModNameList): |
||||
buttons = [] |
||||
for n in a_ModNameList: |
||||
m = self.m_ModuleAgregator.GetModule(n) |
||||
b = m.GetModuleButtons() |
||||
if not b is None or len(b) != 0: |
||||
buttons += b |
||||
return buttons |
||||
|
||||
def GetStartKeyboardButtons(self, a_Message, a_UserGroups): |
||||
buttons = self.GetButtons(self.m_ChildModuleNameList) |
||||
return keyboard.MakeButtons(self.m_Bot, buttons, a_UserGroups) |
||||
|
||||
def GetInitBDCommands(self): |
||||
return [ |
||||
access_utils.GetAccessForModuleRequest(self.GetName(), self.m_InitAccess, self.m_InitAccess), |
||||
] |
||||
|
||||
def GetAccess(self): |
||||
return access_utils.GetAccessForModule(self.m_Bot, self.GetName()) |
||||
|
||||
def GetModuleButtons(self): |
||||
return [ |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.START), user_access.AccessMode.VIEW, self.GetAccess()), |
||||
] |
||||
|
||||
def RegisterHandlers(self): |
||||
self.m_Bot.RegisterMessageHandler( |
||||
self.m_StartMessageHandler, |
||||
bd_item.GetCheckForTextFunc(self.GetButton(ButtonNames.START)) |
||||
) |
||||
|
@ -0,0 +1,386 @@
|
||||
# -*- coding: utf8 -*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
# Модуль для редактирования и просмотра таблицы в БД |
||||
|
||||
from bot_sys import keyboard, user_access, bd_table, bot_bd |
||||
from bot_modules import access_utils, mod_simple_message |
||||
from template import simple_message, bd_item, bd_item_select, bd_item_view, bd_item_delete, bd_item_add, bd_item_edit |
||||
|
||||
from enum import Enum |
||||
from enum import auto |
||||
|
||||
class ButtonNames(Enum): |
||||
LIST = auto() |
||||
ADD = auto() |
||||
EDIT = auto() |
||||
EDIT_PHOTO = auto() |
||||
EDIT_NAME = auto() |
||||
EDIT_DESC = auto() |
||||
EDIT_ACCESS = auto() |
||||
EDIT_DEFAULT_ACCESS = auto() |
||||
DEL = auto() |
||||
|
||||
class Messages(Enum): |
||||
SELECT = auto() |
||||
ERROR_FIND = auto() |
||||
OPEN = auto() |
||||
CREATE_NAME = auto() |
||||
CREATE_DESC = auto() |
||||
CREATE_PHOTO = auto() |
||||
SUCCESS_CREATE = auto() |
||||
START_EDIT = auto() |
||||
SELECT_TO_EDIT = auto() |
||||
EDIT_PHOTO = auto() |
||||
EDIT_NAME = auto() |
||||
EDIT_DESC = auto() |
||||
EDIT_ACCESS = auto() |
||||
EDIT_DEFAULT_ACCESS = auto() |
||||
SUCCESS_EDIT = auto() |
||||
SELECT_TO_DELETE = auto() |
||||
SUCCESS_DELETE = auto() |
||||
|
||||
class FSMs(Enum): |
||||
CREATE = auto() |
||||
EDIT_PHOTO = auto() |
||||
EDIT_NAME = auto() |
||||
EDIT_DESC = auto() |
||||
EDIT_ACCESS = auto() |
||||
EDIT_DEFAULT_ACCESS = auto() |
||||
|
||||
class TableOperateModule(mod_simple_message.SimpleMessageModule): |
||||
def __init__(self, a_Table, a_Messages, a_Buttons, a_FSMs, a_ParentModName, a_ChildModName, a_InitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log): |
||||
super().__init__(a_Messages, a_Buttons, a_InitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log) |
||||
self.m_Table = a_Table |
||||
self.m_FSMs = a_FSMs |
||||
self.m_EditModuleNameList = a_EditModuleNameList |
||||
self.m_ChildModName = a_ChildModName |
||||
self.m_ParentModName = a_ParentModName |
||||
self.m_SelectPrefix = '' |
||||
|
||||
def GetEditKeyboardButtons(a_Message, a_UserGroups): |
||||
return self.GetEditKeyboardButtons(a_Message, a_UserGroups) |
||||
self.m_GetEditKeyboardButtonsFunc = GetEditKeyboardButtons |
||||
|
||||
def GetButtonNameAndKeyValueAndAccess(a_Item): |
||||
return self.GetButtonNameAndKeyValueAndAccess(a_Item) |
||||
self.m_GetButtonNameAndKeyValueAndAccessFunc = GetButtonNameAndKeyValueAndAccess |
||||
|
||||
async def PreDelete(a_CallbackQuery, a_Item): |
||||
return await self.PreDelete(a_CallbackQuery, a_Item) |
||||
self.m_PreDeleteFunc = PreDelete |
||||
|
||||
async def PostDelete(a_CallbackQuery, a_ItemID): |
||||
return await self.PostDelete(a_CallbackQuery, a_ItemID) |
||||
self.m_PostDeleteFunc = PostDelete |
||||
|
||||
def AddBDItemFunc(a_ItemData, a_UserID): |
||||
return self.AddBDItemFunc(a_ItemData, a_UserID) |
||||
self.m_AddBDItemFunc = AddBDItemFunc |
||||
|
||||
def GetFSM(self, a_FSMName): |
||||
return self.m_FSMs.get(a_FSMName, None) |
||||
|
||||
def GetInitBDCommands(self): |
||||
return super(). GetInitBDCommands() + [ |
||||
self.m_Table.GetInitTableRequest(), |
||||
] |
||||
|
||||
def GetStartKeyboardButtons(self, a_Message, a_UserGroups): |
||||
mod_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups) |
||||
cur_buttons = [ |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.LIST), user_access.AccessMode.VIEW, self.GetAccess()), |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.ADD), user_access.AccessMode.ADD, self.GetAccess()), |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.DEL), user_access.AccessMode.DELETE, self.GetAccess()), |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT), user_access.AccessMode.EDIT, self.GetAccess()), |
||||
] |
||||
return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups) |
||||
|
||||
def GetEditKeyboardButtons(self, a_Message, a_UserGroups): |
||||
mod_buttons = keyboard.MakeButtons(self.m_Bot, self.GetButtons(self.m_EditModuleNameList), a_UserGroups) |
||||
cur_buttons = [ |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_PHOTO), user_access.AccessMode.VIEW, self.GetAccess()), |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_NAME), user_access.AccessMode.ADD, self.GetAccess()), |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_DESC), user_access.AccessMode.DELETE, self.GetAccess()), |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_ACCESS), user_access.AccessMode.DELETE, self.GetAccess()), |
||||
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_DEFAULT_ACCESS), user_access.AccessMode.EDIT, self.GetAccess()), |
||||
] |
||||
return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups) |
||||
|
||||
def GetViewItemInlineKeyboardTemplate(self, a_ItemID): |
||||
def GetViewItemInlineKeyboard(a_Message, a_UserGroups): |
||||
return self.GetViewItemInlineKeyboard(a_Message, a_UserGroups, a_ItemID) |
||||
return GetViewItemInlineKeyboard |
||||
|
||||
def GetSelectPrefix(self): |
||||
return self.m_SelectPrefix |
||||
|
||||
def GetViewItemInlineKeyboard(self, a_Message, a_UserGroups, a_ItemID): |
||||
if not self.m_ChildModName: |
||||
return None |
||||
child_mod = self.GetModule(self.m_ChildModName) |
||||
cur_buttons = [ |
||||
keyboard.InlineButtonWithAccess(child_mod.GetButton(ButtonNames.LIST), child_mod.GetSelectPrefix(), a_ItemID, self.GetAccess(), user_access.AccessMode.VIEW), |
||||
] |
||||
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups) |
||||
|
||||
def GetButtonNameAndKeyValueAndAccess(self, a_Item): |
||||
return \ |
||||
a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.NAME)],\ |
||||
a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)],\ |
||||
a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)] |
||||
|
||||
def ShowMessageTemplate(self, a_Message, Inline_keyboard_template_func = None): |
||||
async def ShowMessage(a_CallbackQuery, a_Item): |
||||
msg = a_Message.StaticCopy() |
||||
# TODO: добавить поддержку языка в a_MessageName |
||||
Inline_keyboard_func = None |
||||
item_access = None |
||||
if a_Item: |
||||
if len(a_Item) < self.m_Table.GetFieldsCount() - 1: # Для проектов это нужно. Там на 1 меньше поле. TODO разделить отправку сообщений item_access и Inline_keyboard_func |
||||
return simple_message.WorkFuncResult(self.GetMessage(Messages.ERROR_FIND)) |
||||
elif len(a_Item) == self.m_Table.GetFieldsCount(): |
||||
lang = str(a_CallbackQuery.from_user.language_code) |
||||
msg = msg.GetMessageForLang(lang).StaticCopy() |
||||
msg.UpdateDesc(self.m_Table.ReplaceAllFieldTags(msg.GetDesc(), a_Item)) |
||||
photo_field = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PHOTO) |
||||
if photo_field: |
||||
msg.UpdatePhotoID(a_Item[photo_field]) |
||||
item_access = a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)] |
||||
if Inline_keyboard_template_func: |
||||
Inline_keyboard_func = Inline_keyboard_template_func(a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)]) |
||||
|
||||
return simple_message.WorkFuncResult(msg, item_access = item_access, Inline_keyboard_func = Inline_keyboard_func) |
||||
return ShowMessage |
||||
|
||||
# TODO: delete? |
||||
def SimpleMessageTemplate(self, a_MessageName : Messages): |
||||
async def ShowMessage(a_CallbackQuery, a_Item): |
||||
return simple_message.WorkFuncResult(self.GetMessage(a_MessageName)) |
||||
return ShowMessage |
||||
|
||||
async def PreDelete(self, a_CallbackQuery, a_Item): |
||||
if len(a_Item) < self.m_Table.GetFieldsCount(): |
||||
return simple_message.WorkFuncResult(error_find_proj_message) |
||||
access = a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)] |
||||
return simple_message.WorkFuncResult(self.GetMessage(Messages.SUCCESS_DELETE), None, item_access = access) |
||||
|
||||
async def PostDelete(self, a_CallbackQuery, a_ItemID): |
||||
self.m_Log.Success(f'Задача №{a_ItemID} была удалена пользователем {a_CallbackQuery.from_user.id}.') |
||||
#TODO: удалить вложенные |
||||
self.OnChange() |
||||
return simple_message.WorkFuncResult(self.GetMessage(Messages.SUCCESS_DELETE)) |
||||
|
||||
def AddBDItemFunc(self, a_ItemData, a_UserID): |
||||
table_name = self.m_Table.GetName() |
||||
name_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.NAME) |
||||
photo_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PHOTO) |
||||
desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC) |
||||
access_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.ACCESS) |
||||
create_datetime_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.CREATE_DATE) |
||||
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) |
||||
|
||||
res, error = None, None |
||||
def_access = access_utils.GetItemDefaultAccessForModule(self.m_Bot, self.GetName()) |
||||
#TODO сделать список полей, чтобы запрос генерировался автоматически. |
||||
if parent_id_field: |
||||
res, error = self.m_Bot.SQLRequest(f'INSERT INTO {table_name}({photo_field}, {name_field}, {desc_field}, {access_field}, {parent_id_field}, {create_datetime_field}) VALUES(?, ?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()})', |
||||
commit = True, return_error = True, param = (a_ItemData[photo_field], a_ItemData[name_field], a_ItemData[desc_field], def_access + f";{a_UserID}=+", a_ItemData[parent_id_field])) |
||||
else: |
||||
res, error = self.m_Bot.SQLRequest(f'INSERT INTO {table_name}({photo_field}, {name_field}, {desc_field}, {access_field}, {create_datetime_field}) VALUES(?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()})', |
||||
commit = True, return_error = True, param = (a_ItemData[photo_field], a_ItemData[name_field], a_ItemData[desc_field], def_access + f";{a_UserID}=+")) |
||||
|
||||
self.OnChange() |
||||
if error: |
||||
self.m_Log.Error(f'Пользоватлель {a_UserID}. Ошибка добавления записи в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {def_access}).') |
||||
else: |
||||
self.m_Log.Success(f'Пользоватлель {a_UserID}. Добавлена запись в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {def_access}).') |
||||
|
||||
return res, error |
||||
|
||||
def RegisterSelect(self, a_ButtonName, access_mode, only_parent = False): |
||||
a_Prefix = None |
||||
if self.m_ParentModName: |
||||
parent_mod = self.GetModule(self.m_ParentModName) |
||||
a_Prefix = parent_mod.RegisterSelect(a_ButtonName, access_mode, only_parent = False) |
||||
if not only_parent: |
||||
a_Prefix = bd_item_select.NextSelectBDItemRegisterHandlers(self.m_Bot, \ |
||||
a_Prefix, \ |
||||
self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID), \ |
||||
self.m_Table.GetName(), \ |
||||
self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY), \ |
||||
self.m_GetButtonNameAndKeyValueAndAccessFunc, \ |
||||
self.GetMessage(Messages.SELECT), \ |
||||
self.m_GetAccessFunc,\ |
||||
access_mode = access_mode\ |
||||
) |
||||
else: |
||||
if not only_parent: |
||||
a_PrefixBase = a_ButtonName.GetDesc() |
||||
a_Prefix = bd_item_select.FirstSelectBDItemRegisterHandlers(self.m_Bot, \ |
||||
a_PrefixBase, \ |
||||
a_ButtonName, \ |
||||
self.m_Table.GetName(), \ |
||||
self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY), \ |
||||
self.m_GetButtonNameAndKeyValueAndAccessFunc, \ |
||||
self.GetMessage(Messages.SELECT), \ |
||||
self.m_GetAccessFunc,\ |
||||
access_mode = access_mode\ |
||||
) |
||||
return a_Prefix |
||||
|
||||
def RegisterHandlers(self): |
||||
super().RegisterHandlers() |
||||
table_name = self.m_Table.GetName() |
||||
key_name = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY) |
||||
name_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.NAME) |
||||
desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC) |
||||
photo_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PHOTO) |
||||
access_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.ACCESS) |
||||
def_access_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DEFAULT_ACCESS) |
||||
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) |
||||
|
||||
parent_table_name = None |
||||
parent_key_name = None |
||||
if self.m_ParentModName: |
||||
parent_mod = self.GetModule(self.m_ParentModName) |
||||
parent_table_name = parent_mod.m_Table.GetName() |
||||
parent_key_name = parent_mod.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY) |
||||
|
||||
def GetViewItemInlineKeyboardTemplate(a_ItemID): |
||||
return self.GetViewItemInlineKeyboardTemplate(a_ItemID) |
||||
|
||||
GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc |
||||
GetAccess = self.m_GetAccessFunc |
||||
|
||||
defaul_keyboard_func = self.m_GetStartKeyboardButtonsFunc |
||||
|
||||
# Список |
||||
a_ButtonName = self.GetButton(ButtonNames.LIST) |
||||
if a_ButtonName: |
||||
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True) |
||||
if a_Prefix: |
||||
bd_item_view.LastSelectAndShowBDItemRegisterHandlers(self.m_Bot, \ |
||||
a_Prefix,\ |
||||
parent_id_field, \ |
||||
table_name,\ |
||||
key_name, \ |
||||
self.ShowMessageTemplate(self.GetMessage(Messages.OPEN), GetViewItemInlineKeyboardTemplate), \ |
||||
GetButtonNameAndKeyValueAndAccess, \ |
||||
self.GetMessage(Messages.SELECT), \ |
||||
GetAccess, \ |
||||
defaul_keyboard_func, \ |
||||
access_mode = user_access.AccessMode.VIEW\ |
||||
) |
||||
else: |
||||
bd_item_view.FirstSelectAndShowBDItemRegisterHandlers(self.m_Bot, \ |
||||
a_ButtonName, \ |
||||
table_name, \ |
||||
key_name, \ |
||||
self.ShowMessageTemplate(self.GetMessage(Messages.OPEN), GetViewItemInlineKeyboardTemplate), \ |
||||
GetButtonNameAndKeyValueAndAccess, \ |
||||
self.GetMessage(Messages.SELECT), \ |
||||
GetAccess, \ |
||||
defaul_keyboard_func\ |
||||
) |
||||
self.m_SelectPrefix = a_Prefix |
||||
|
||||
# Удаление |
||||
a_ButtonName = self.GetButton(ButtonNames.DEL) |
||||
if a_ButtonName: |
||||
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.DELETE) |
||||
bd_item_delete.DeleteBDItemRegisterHandlers(self.m_Bot, \ |
||||
a_Prefix, \ |
||||
table_name, \ |
||||
key_name, \ |
||||
self.m_PreDeleteFunc, \ |
||||
self.m_PostDeleteFunc, \ |
||||
GetAccess, \ |
||||
defaul_keyboard_func\ |
||||
) |
||||
|
||||
# Добавление |
||||
a_ButtonName = self.GetButton(ButtonNames.ADD) |
||||
if a_ButtonName: |
||||
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.ADD, only_parent = True) |
||||
|
||||
check_func = bd_item.GetCheckForTextFunc(a_ButtonName) |
||||
if a_Prefix: |
||||
check_func = bd_item.GetCheckForPrefixFunc(a_Prefix) |
||||
|
||||
bd_item_add.AddBDItem3RegisterHandlers(self.m_Bot, \ |
||||
check_func, \ |
||||
self.GetFSM(FSMs.CREATE), \ |
||||
self.GetFSM(FSMs.CREATE).name,\ |
||||
self.GetFSM(FSMs.CREATE).desc, \ |
||||
self.GetFSM(FSMs.CREATE).photo,\ |
||||
self.m_AddBDItemFunc, \ |
||||
self.ShowMessageTemplate(self.GetMessage(Messages.CREATE_NAME)), \ |
||||
self.ShowMessageTemplate(self.GetMessage(Messages.CREATE_DESC)), \ |
||||
self.ShowMessageTemplate(self.GetMessage(Messages.CREATE_PHOTO)), \ |
||||
self.ShowMessageTemplate(self.GetMessage(Messages.SUCCESS_CREATE)), \ |
||||
a_Prefix,\ |
||||
parent_table_name, \ |
||||
parent_key_name, \ |
||||
name_field, \ |
||||
desc_field, \ |
||||
photo_field, \ |
||||
GetButtonNameAndKeyValueAndAccess, \ |
||||
GetAccess, \ |
||||
self.m_GetStartKeyboardButtonsFunc\ |
||||
) |
||||
|
||||
# Редактирование |
||||
edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc |
||||
def RegisterEdit(a_ButtonName, a_FSM, a_EditMessage, a_FieldName, a_FieldType, a_AccessMode = user_access.AccessMode.EDIT): |
||||
if not a_ButtonName: |
||||
return |
||||
|
||||
def OnChange(): |
||||
return self.OnChange() |
||||
|
||||
a_Prefix = self.RegisterSelect(a_ButtonName, a_AccessMode, only_parent = True) |
||||
check_func = bd_item.GetCheckForTextFunc(a_ButtonName) |
||||
if a_Prefix: |
||||
check_func = bd_item.GetCheckForPrefixFunc(a_Prefix) |
||||
#print(a_ButtonName, a_Prefix, check_func) |
||||
bd_item_edit.EditBDItemRegisterHandlers(self.m_Bot, \ |
||||
a_Prefix, \ |
||||
a_FSM, \ |
||||
check_func, \ |
||||
self.GetMessage(Messages.SELECT_TO_EDIT), \ |
||||
self.ShowMessageTemplate(a_EditMessage), \ |
||||
self.ShowMessageTemplate(self.GetMessage(Messages.SUCCESS_EDIT)), \ |
||||
table_name, \ |
||||
key_name, \ |
||||
parent_id_field, \ |
||||
a_FieldName, \ |
||||
GetButtonNameAndKeyValueAndAccess, \ |
||||
GetAccess, \ |
||||
edit_keyboard_func, \ |
||||
OnChange,\ |
||||
access_mode = a_AccessMode, \ |
||||
field_type = a_FieldType\ |
||||
) |
||||
|
||||
a_ButtonName = self.GetButton(ButtonNames.EDIT) |
||||
if a_ButtonName: |
||||
self.m_Bot.RegisterMessageHandler(\ |
||||
simple_message.InfoMessageTemplate(\ |
||||
self.m_Bot,\ |
||||
self.GetMessage(Messages.START_EDIT),\ |
||||
edit_keyboard_func,\ |
||||
None,\ |
||||
GetAccess,\ |
||||
access_mode = user_access.AccessMode.EDIT),\ |
||||
bd_item.GetCheckForTextFunc(a_ButtonName)\ |
||||
) |
||||
|
||||
RegisterEdit(self.GetButton(ButtonNames.EDIT_NAME), self.GetFSM(FSMs.EDIT_NAME), self.GetMessage(Messages.EDIT_NAME), name_field, bd_item.FieldType.text) |
||||
RegisterEdit(self.GetButton(ButtonNames.EDIT_DESC), self.GetFSM(FSMs.EDIT_DESC), self.GetMessage(Messages.EDIT_DESC), desc_field, bd_item.FieldType.text) |
||||
RegisterEdit(self.GetButton(ButtonNames.EDIT_PHOTO), self.GetFSM(FSMs.EDIT_PHOTO), self.GetMessage(Messages.EDIT_PHOTO), photo_field, bd_item.FieldType.photo) |
||||
RegisterEdit(self.GetButton(ButtonNames.EDIT_ACCESS), self.GetFSM(FSMs.EDIT_ACCESS), self.GetMessage(Messages.EDIT_ACCESS), access_field, bd_item.FieldType.text) |
||||
RegisterEdit(self.GetButton(ButtonNames.EDIT_DEFAULT_ACCESS), self.GetFSM(FSMs.EDIT_DEFAULT_ACCESS), self.GetMessage(Messages.EDIT_DEFAULT_ACCESS), def_access_field, bd_item.FieldType.text) |
||||
|
||||
def OnChange(self): |
||||
pass |
@ -0,0 +1,104 @@
|
||||
#-*-coding utf-8-*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
from bot_sys import interfaces, bot_bd, keyboard, user_access |
||||
|
||||
from aiogram import types |
||||
from aiogram import Bot |
||||
from aiogram.dispatcher import Dispatcher |
||||
from aiogram.contrib.fsm_storage.memory import MemoryStorage |
||||
from aiogram.utils import executor |
||||
|
||||
class AiogramBot(interfaces.IBot): |
||||
def __init__(self, a_TelegramBotApiToken, a_BDFileName, a_RootIDs, a_Log): |
||||
self.m_TelegramBotApiToken = a_TelegramBotApiToken |
||||
self.m_BDFileName = a_BDFileName |
||||
self.m_RootIDs = a_RootIDs |
||||
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 = self.m_Storage) |
||||
|
||||
def GetRootIDs(self): |
||||
return self.m_RootIDs |
||||
|
||||
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_Log, self.m_BDFileName, a_Request, commit = commit, return_error = return_error, param = param) |
||||
|
||||
async def SendMessage(self, a_UserID, a_Message, a_PhotoIDs, a_KeyboardButtons, a_InlineKeyboardButtons, parse_mode = None): |
||||
if not parse_mode: |
||||
parse_mode = types.ParseMode.HTML |
||||
inline_keyboards = None |
||||
if a_InlineKeyboardButtons: |
||||
inline_keyboards = keyboard.MakeAiogramInlineKeyboards(a_InlineKeyboardButtons) |
||||
base_keyboards = None |
||||
if a_KeyboardButtons: |
||||
base_keyboards = [keyboard.MakeAiogramKeyboard(a_KeyboardButtons)] |
||||
if inline_keyboards: |
||||
base_keyboards = inline_keyboards |
||||
if a_PhotoIDs and a_PhotoIDs != 0 and a_PhotoIDs != '0': |
||||
if base_keyboards: |
||||
for k in base_keyboards: |
||||
await self.m_TBot.send_photo( |
||||
a_UserID, |
||||
a_PhotoIDs, |
||||
a_Message, |
||||
reply_markup = k |
||||
) |
||||
else: |
||||
await self.m_TBot.send_photo( |
||||
a_UserID, |
||||
a_PhotoIDs, |
||||
a_Message |
||||
) |
||||
else: |
||||
#print('SendMessage', a_UserID, a_Message, a_PhotoIDs, a_InlineKeyboardButtons, a_KeyboardButtons, base_keyboard) |
||||
if base_keyboards: |
||||
for k in base_keyboards: |
||||
await self.m_TBot.send_message( |
||||
a_UserID, |
||||
a_Message, |
||||
reply_markup = k, |
||||
parse_mode = parse_mode |
||||
) |
||||
else: |
||||
await self.m_TBot.send_message( |
||||
a_UserID, |
||||
a_Message, |
||||
parse_mode = parse_mode |
||||
) |
||||
|
||||
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=None, 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=None, commands=None, regexp=None, content_types=None, state=None): |
||||
if a_CheckFunc: |
||||
self.m_Dispatcher.register_callback_query_handler(a_CallbackHandler, a_CheckFunc, commands=commands, regexp=regexp, content_types=content_types, state=state) |
||||
else: |
||||
self.m_Dispatcher.register_callback_query_handler(a_CallbackHandler, commands=commands, regexp=regexp, content_types=content_types, state=state) |
||||
|
||||
def StartPolling(self): |
||||
executor.start_polling(self.m_Dispatcher) |
||||
|
@ -0,0 +1,125 @@
|
||||
#-*-coding utf-8-*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
from enum import Enum |
||||
from enum import auto |
||||
|
||||
# Тип поля в таблице |
||||
class TableFieldType(Enum): |
||||
INT = 'INTEGER' |
||||
STR = 'TEXT' |
||||
|
||||
# Предназначение поля в таблице |
||||
class TableFieldDestiny(Enum): |
||||
KEY = auto() |
||||
NAME = auto() |
||||
DESC = auto() |
||||
PHOTO = auto() |
||||
ACCESS = auto() |
||||
DEFAULT_ACCESS = auto() |
||||
CREATE_DATE = auto() |
||||
PARENT_ID = auto() |
||||
OTHER = auto() |
||||
|
||||
class TableField: |
||||
def __init__(self, a_Name, a_Destiny : TableFieldDestiny, a_Type : TableFieldType): |
||||
self.m_Name = a_Name |
||||
self.m_Destiny = a_Destiny |
||||
self.m_Type = a_Type |
||||
|
||||
class Table: |
||||
def __init__(self, a_TableName, a_Fields : [TableField], a_UniqueFields = None): |
||||
self.m_TableName = a_TableName |
||||
self.m_Fields = a_Fields |
||||
self.m_UniqueFields = a_UniqueFields |
||||
|
||||
def GetName(self): |
||||
return self.m_TableName |
||||
|
||||
def GetFields(self): |
||||
return self.TableFieldType |
||||
|
||||
def GetFieldsCount(self): |
||||
return len(self.m_Fields) |
||||
|
||||
def GetFieldByDestiny(self, a_Destiny): |
||||
for f in self.m_Fields: |
||||
if f.m_Destiny == a_Destiny: |
||||
return f |
||||
return None |
||||
|
||||
def GetFieldNameByDestiny(self, a_Destiny): |
||||
f = self.GetFieldByDestiny(a_Destiny) |
||||
if f: |
||||
return f.m_Name |
||||
return None |
||||
|
||||
def GetFieldIDByDestiny(self, a_Destiny): |
||||
for i in range(len(self.m_Fields)): |
||||
f = self.m_Fields[i] |
||||
if f.m_Destiny == a_Destiny: |
||||
return i |
||||
return None |
||||
|
||||
def GetInitTableRequest(self): |
||||
request = f'CREATE TABLE IF NOT EXISTS {self.GetName()}(' |
||||
items = [] |
||||
for f in self.m_Fields: |
||||
item = f.m_Name + ' ' + str(f.m_Type.value) |
||||
if f.m_Destiny == TableFieldDestiny.KEY: |
||||
item += ' PRIMARY KEY' |
||||
items += [item] |
||||
if self.m_UniqueFields: |
||||
for u in self.m_UniqueFields: |
||||
fields = [] |
||||
for f in u: |
||||
fields += [f.m_Name] |
||||
items += ['UNIQUE(' + ', '.join(fields) +')'] |
||||
return request + ', '.join(items) + ');' |
||||
|
||||
def ReplaceAllFieldTags(self, a_String, a_BDItem): |
||||
result = a_String |
||||
for i in range(len(self.m_Fields)): |
||||
f = self.m_Fields[i] |
||||
result = result.replace(f'#{f.m_Name}', str(a_BDItem[i])) |
||||
return result |
||||
|
||||
def Test(): |
||||
f1 = TableField('f1', TableFieldDestiny.KEY, TableFieldType.INT) |
||||
f2 = TableField('f2', TableFieldDestiny.NAME, TableFieldType.STR) |
||||
f3 = TableField('f3', TableFieldDestiny.DESC, TableFieldType.STR) |
||||
table = Table('tname', [ |
||||
f1, |
||||
f2, |
||||
f3 |
||||
], |
||||
[[f1], [f2, f3]] |
||||
) |
||||
assert table.GetName() == 'tname' |
||||
assert table.GetFieldByDestiny(TableFieldDestiny.KEY).m_Name == 'f1' |
||||
assert table.GetFieldNameByDestiny(TableFieldDestiny.KEY) == 'f1' |
||||
assert table.GetFieldByDestiny(TableFieldDestiny.KEY).m_Destiny == TableFieldDestiny.KEY |
||||
assert table.GetFieldByDestiny(TableFieldDestiny.KEY).m_Type == TableFieldType.INT |
||||
assert table.GetFieldIDByDestiny(TableFieldDestiny.KEY) == 0 |
||||
assert table.GetFieldByDestiny(TableFieldDestiny.NAME).m_Name == 'f2' |
||||
assert table.GetFieldNameByDestiny(TableFieldDestiny.NAME) == 'f2' |
||||
assert table.GetFieldByDestiny(TableFieldDestiny.NAME).m_Destiny == TableFieldDestiny.NAME |
||||
assert table.GetFieldByDestiny(TableFieldDestiny.NAME).m_Type == TableFieldType.STR |
||||
assert table.GetFieldIDByDestiny(TableFieldDestiny.NAME) == 1 |
||||
assert table.GetFieldByDestiny(TableFieldDestiny.DESC).m_Name == 'f3' |
||||
assert table.GetFieldNameByDestiny(TableFieldDestiny.DESC) == 'f3' |
||||
assert table.GetFieldByDestiny(TableFieldDestiny.DESC).m_Destiny == TableFieldDestiny.DESC |
||||
assert table.GetFieldByDestiny(TableFieldDestiny.DESC).m_Type == TableFieldType.STR |
||||
assert table.GetFieldIDByDestiny(TableFieldDestiny.DESC) == 2 |
||||
|
||||
assert table.GetFieldByDestiny(TableFieldDestiny.PHOTO) == None |
||||
assert table.GetFieldIDByDestiny(TableFieldDestiny.PHOTO) == None |
||||
assert table.GetFieldNameByDestiny(TableFieldDestiny.PHOTO) == None |
||||
|
||||
assert table.GetFieldsCount() == 3 |
||||
|
||||
print(table.GetInitTableRequest()) |
||||
assert table.GetInitTableRequest() == 'CREATE TABLE IF NOT EXISTS tname(f1 INTEGER PRIMARY KEY, f2 TEXT, f3 TEXT, UNIQUE(f1), UNIQUE(f2, f3));' |
||||
|
||||
item = [10, 'i1', 'i2'] |
||||
assert table.ReplaceAllFieldTags('#f1 #f2 #f3', item) == '10 i1 i2' |
@ -0,0 +1,83 @@
|
||||
#-*-coding utf-8-*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
# Работа с сообщениями |
||||
|
||||
class BotMessage: |
||||
def __init__(self, a_BotMessages, a_MessageName : str, a_MessageDesc : str, a_Language : str, a_PhotoID : str, a_DateTime): |
||||
self.m_BotMessages = a_BotMessages |
||||
self.m_MessageName = a_MessageName |
||||
self.m_MessageDesc = a_MessageDesc |
||||
self.m_Language = a_Language |
||||
self.m_PhotoID = a_PhotoID |
||||
self.m_DateTime = a_DateTime |
||||
|
||||
def StaticCopy(self): |
||||
return BotMessage(None, self.m_MessageName, self.m_MessageDesc, self.m_Language, self.m_PhotoID, self.m_DateTime) |
||||
|
||||
def GetName(self): |
||||
return self.m_MessageName |
||||
|
||||
def GetDesc(self): |
||||
return self.m_MessageDesc |
||||
|
||||
def UpdateDesc(self, a_Desc): |
||||
self.m_MessageDesc = a_Desc |
||||
|
||||
def GetLanguage(self): |
||||
return self.m_Language |
||||
|
||||
def GetPhotoID(self): |
||||
return self.m_PhotoID |
||||
|
||||
def UpdatePhotoID(self, a_PhotoID): |
||||
self.m_PhotoID = a_PhotoID |
||||
|
||||
def __str__(self): |
||||
msg = self.GetMessageForLang(self.m_Language) |
||||
return msg.GetDesc() |
||||
|
||||
def GetMessageForLang(self, a_Language): |
||||
if not self.m_BotMessages: |
||||
return self |
||||
last_update = self.m_BotMessages.m_LastUpdate |
||||
new_msg = self |
||||
if self.m_DateTime < last_update: |
||||
msg = self.m_BotMessages.GetMessages() |
||||
if not msg.get(a_Language, None): |
||||
a_Language = self.m_Language |
||||
if not msg.get(a_Language, None): |
||||
a_Language = self.m_BotMessages.a_DefaultLanguage |
||||
new_msg = msg[a_Language].get(self.m_MessageName, self) |
||||
if a_Language == self.m_Language: |
||||
self.m_MessageDesc = new_msg.m_MessageDesc |
||||
self.m_Language = new_msg.m_Language |
||||
self.m_PhotoID = new_msg.m_PhotoID |
||||
self.m_DateTime = new_msg.m_DateTime |
||||
return new_msg |
||||
|
||||
def MakeBotMessage(a_MessageDesc): |
||||
return BotMessage(None, '', a_MessageDesc, None, 0, None) |
||||
|
||||
class BotMessages: |
||||
def __init__(self, a_DefaultLanguage): |
||||
self.m_DefaultLanguage = a_DefaultLanguage |
||||
self.m_Messages = {} |
||||
self.m_LastUpdate = None |
||||
|
||||
def GetMessages(self): |
||||
return self.m_Messages |
||||
|
||||
def UpdateSignal(self, a_DateTime): |
||||
self.m_LastUpdate = a_DateTime |
||||
|
||||
def CreateMessage(self, a_MessageName, a_MessageDesc, a_DateTime, a_MessagePhotoID = 0, a_MessageLang = None): |
||||
if not a_MessageLang: |
||||
a_MessageLang = self.m_DefaultLanguage |
||||
cur_msg = BotMessage(self, a_MessageName, a_MessageDesc, a_MessageLang, a_MessagePhotoID, a_DateTime) |
||||
msg = self.GetMessages() |
||||
if not msg.get(a_MessageLang, None): |
||||
msg[a_MessageLang] = {} |
||||
msg[a_MessageLang][a_MessageName] = cur_msg |
||||
return cur_msg |
||||
|
@ -0,0 +1,38 @@
|
||||
#-*-coding utf-8-*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
from abc import ABC, abstractmethod |
||||
|
||||
class IBot(ABC): |
||||
@abstractmethod |
||||
def GetRootIDs(self): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
def GetLog(self): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
def SQLRequest(self, a_Request : str, commit = False, return_error = False, param = None): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
async def SendMessage(self, a_UserID, a_Message, a_PhotoIDs, a_KeyboardButtons, a_InlineKeyboardButtons, parse_mode=None): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
async def SendDocument(self, a_UserID, a_Document, a_Caption, a_KeyboardButtons, a_InlineKeyboardButtons): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
def RegisterMessageHandler(self, a_MessageHandler, a_CheckFunc=None, commands=None, regexp=None, content_types=None, state=None): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
def RegisterCallbackHandler(self, a_CallbackHandler, a_CheckFunc=None, commands=None, regexp=None, content_types=None, state=None): |
||||
pass |
||||
|
||||
@abstractmethod |
||||
def StartPolling(self): |
||||
pass |
||||
|
@ -1,56 +0,0 @@
|
||||
#-*-coding utf-8-*- |
||||
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> |
||||
|
||||
import sqlite3 |
||||
from bot_sys import log |
||||
|
||||
# Работа ссообщениями |
||||
|
||||
default_language = 'ru' |
||||
|
||||
g_messages = None |
||||
def GetMessages(): |
||||
global g_messages |
||||
if not g_messages: |
||||
g_messages = {} |
||||
return g_messages |
||||
|
||||
g_last_update = None |
||||
def UpdateSignal(a_DateTime): |
||||
global g_last_update |
||||
g_last_update = a_DateTime |
||||
# --------------------------------------------------------- |
||||
# Функции работы с собщениями |
||||
|
||||
# --------------------------------------------------------- |
||||
class Message: |
||||
def __init__(self, a_MessageName : str, a_MessageDesc : str, a_Language : str, a_PhotoID : str, a_DateTime): |
||||
self.m_MessageName = a_MessageName |
||||
self.m_MessageDesc = a_MessageDesc |
||||
self.m_Language = a_Language |
||||
self.m_PhotoID = a_PhotoID |
||||
self.m_DateTime = a_DateTime |
||||
|
||||
def __str__(self): |
||||
global g_last_update |
||||
last_update = g_last_update |
||||
if self.m_DateTime < last_update: |
||||
msg = GetMessages() |
||||
if not msg.get(self.m_Language, None): |
||||
msg[self.m_Language] = {} |
||||
new_msg = msg[self.m_Language].get(self.m_MessageName, self) |
||||
self.m_MessageName = new_msg.m_MessageName |
||||
self.m_MessageDesc = new_msg.m_MessageDesc |
||||
self.m_PhotoID = new_msg.m_PhotoID |
||||
self.m_DateTime = last_update |
||||
return f'{self.m_MessageDesc}' |
||||
|
||||
def MSG(a_MessageName, a_MessageDesc, a_UpdateMSG, a_DateTime): |
||||
cur_msg = Message(a_MessageName, a_MessageDesc, default_language, 0, a_DateTime) |
||||
msg = GetMessages() |
||||
if not msg.get(default_language, None): |
||||
msg[default_language] = {} |
||||
if not msg[default_language].get(a_MessageName, None): |
||||
msg[default_language][a_MessageName] = cur_msg |
||||
a_UpdateMSG(cur_msg) |
||||
|
Loading…
Reference in new issue