to_local_var #2

Merged
Bezborodov merged 25 commits from to_local_var into master 2 years ago
  1. 212
      bot_modules/access.py
  2. 37
      bot_modules/access_utils.py
  3. 120
      bot_modules/backup.py
  4. 200
      bot_modules/buttons.py
  5. 396
      bot_modules/comments.py
  6. 152
      bot_modules/groups.py
  7. 16
      bot_modules/groups_utils.py
  8. 401
      bot_modules/languages.py
  9. 431
      bot_modules/messages.py
  10. 15
      bot_modules/mod_agregator.py
  11. 25
      bot_modules/mod_interface.py
  12. 112
      bot_modules/mod_simple_message.py
  13. 386
      bot_modules/mod_table_operate.py
  14. 384
      bot_modules/needs.py
  15. 132
      bot_modules/profile.py
  16. 352
      bot_modules/projects.py
  17. 84
      bot_modules/start.py
  18. 371
      bot_modules/tasks.py
  19. 104
      bot_sys/aiogram_bot.py
  20. 125
      bot_sys/bd_table.py
  21. 30
      bot_sys/bot_bd.py
  22. 83
      bot_sys/bot_messages.py
  23. 38
      bot_sys/interfaces.py
  24. 65
      bot_sys/keyboard.py
  25. 46
      bot_sys/log.py
  26. 218
      bot_sys/user_access.py
  27. 56
      bot_sys/user_messages.py
  28. 122
      main.py
  29. 51
      template/bd_item.py
  30. 78
      template/bd_item_add.py
  31. 31
      template/bd_item_delete.py
  32. 40
      template/bd_item_edit.py
  33. 32
      template/bd_item_select.py
  34. 24
      template/bd_item_view.py
  35. 39
      template/file_message.py
  36. 69
      template/simple_message.py
  37. 59
      template/sql_request.py

212
bot_modules/access.py

@ -3,49 +3,39 @@
# Права пользователей # Права пользователей
from bot_sys import bot_bd, log, config, keyboard, user_access from bot_sys import keyboard, user_access, bot_bd, bd_table
from bot_modules import start, groups from bot_modules import mod_simple_message, access_utils, mod_table_operate
from template import simple_message, sql_request, bd_item_edit, bd_item from template import simple_message, sql_request, bd_item
from aiogram.dispatcher import FSMContext from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import Dispatcher
from aiogram import types
class FSMRequestToBDAccess(StatesGroup): class FSMRequestToBDAccess(StatesGroup):
sqlRequest = State() sqlRequest = State()
class FSMEditAccessItem(StatesGroup): class FSMEditAccessItem(StatesGroup):
item_field = State() item_field = State()
class FSMEditDefaultAccessItem(StatesGroup): class FSMEditDefaultAccessItem(StatesGroup):
item_field = State() item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'access' module_name = 'access'
table_name = 'module_access' table_name = access_utils.table_name
mod_name_field = 'modName' mod_name_field = access_utils.mod_name_field
moduleaccess_field = 'modAccess' moduleaccess_field = access_utils.moduleaccess_field
mod_default_access_field = 'itemDefaultAccess' mod_default_access_field = access_utils.mod_default_access_field
#TODO: Автоматическое создание init_bd_cmds, необходимо table_name, mod_name_field ... объединить в объект
init_bd_cmds = [f"""CREATE TABLE IF NOT EXISTS {table_name}(
{mod_name_field} TEXT,
{moduleaccess_field} TEXT,
{mod_default_access_field} TEXT,
UNIQUE({mod_name_field})
);""",
f"INSERT OR IGNORE INTO {table_name} ({mod_name_field}, {moduleaccess_field}, {mod_default_access_field}) VALUES ('{module_name}', '{user_access.user_access_group_new}=-', '{user_access.user_access_group_new}=-');"
]
table = bd_table.Table(table_name, [
bd_table.TableField(mod_name_field, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.STR),
bd_table.TableField(moduleaccess_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(mod_default_access_field, bd_table.TableFieldDestiny.DEFAULT_ACCESS, bd_table.TableFieldType.STR),
])
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения # Сообщения
access_start_message = ''' start_message = '''
<b> Права пользователей находятся в стадии разработки</b> <b> Права пользователей находятся в стадии разработки</b>
Пока можете воспользоваться хардкорным способом через запросы к БД Пока можете воспользоваться хардкорным способом через запросы к БД
@ -68,11 +58,7 @@ help_message = '''
modAccess - строка modAccess - строка
''' + user_access.user_access_readme ''' + user_access.user_access_readme
access_denied_message = ''' start_button_name = "⛀ Доступ пользователей"
Доступ запрещён!
'''
access_button_name = "⛀ Доступ пользователей"
sql_request_button_name = "⛁ Запрос к БД для редактирования доступа" sql_request_button_name = "⛁ Запрос к БД для редактирования доступа"
help_button_name = "📄 Информация по редактированию доступа" help_button_name = "📄 Информация по редактированию доступа"
@ -92,7 +78,7 @@ moduleaccess_edit_access_message = f'''
Введите новую строку доступа: Введите новую строку доступа:
''' '''
edit_moduleaccess_default_access_button_name = "◈ Изменить доступ по умолчанию к модулю " edit_moduleaccess_default_access_button_name = "◈ Изменить доступ по умолчанию"
moduleaccess_edit_default_access_message = f''' moduleaccess_edit_default_access_message = f'''
Текущий доступ по умолчанию к модулю #{mod_name_field}: Текущий доступ по умолчанию к модулю #{mod_name_field}:
#{mod_default_access_field} #{mod_default_access_field}
@ -101,106 +87,80 @@ moduleaccess_edit_default_access_message = f'''
Введите новую строку доступа: Введите новую строку доступа:
''' '''
moduleaccess_success_edit_message = '''✅ Доступ к модулю успешно отредактирован!'''
button_names = {
mod_simple_message.ButtonNames.START: start_button_name,
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать доступ",
mod_table_operate.ButtonNames.EDIT_ACCESS: edit_moduleaccess_access_button_name,
mod_table_operate.ButtonNames.EDIT_DEFAULT_ACCESS: edit_moduleaccess_default_access_button_name,
}
messages = {
mod_simple_message.Messages.START: start_message,
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие:
''',
mod_table_operate.Messages.SELECT_TO_EDIT: moduleaccess_select_to_edit_message,
mod_table_operate.Messages.EDIT_ACCESS: moduleaccess_edit_access_message,
mod_table_operate.Messages.EDIT_DEFAULT_ACCESS: moduleaccess_edit_default_access_message,
mod_table_operate.Messages.SUCCESS_EDIT: moduleaccess_success_edit_message,
}
fsm = {
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditAccessItem,
mod_table_operate.FSMs.EDIT_DEFAULT_ACCESS: FSMEditDefaultAccessItem,
}
init_access = f'{user_access.user_access_group_new}=-'
class ModuleAccess(mod_table_operate.TableOperateModule):
def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(table, messages, button_names, fsm, None, None, init_access, a_ChildModuleNameList, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
self.m_SqlRequestButtonName = self.CreateButton('sql request', sql_request_button_name)
self.m_RequestStartMessage = self.CreateMessage('equest start', request_start_message)
self.m_HelpButtonName = self.CreateButton('help', help_button_name)
self.m_HelpMessage = self.CreateMessage('help', help_message)
self.m_HelpMessageHandler = simple_message.InfoMessageTemplate(
self.m_Bot,
self.m_HelpMessage,
self.m_GetStartKeyboardButtonsFunc,
None,
self.m_GetAccessFunc
)
moduleaccess_success_edit_message = '''✅ Проект успешно отредактирован!''' def GetButtonNameAndKeyValueAndAccess(self, a_Item):
return \
a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)],\
a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)],\
a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)]
# --------------------------------------------------------- def GetName(self):
# Работа с кнопками return module_name
def GetEditAccessKeyboardButtons(a_Message, a_UserGroups): def GetStartKeyboardButtons(self, a_Message, a_UserGroups):
mod_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups)
cur_buttons = [ cur_buttons = [
keyboard.ButtonWithAccess(sql_request_button_name, user_access.AccessMode.ACCEES_EDIT, GetAccess()), keyboard.ButtonWithAccess(self.m_SqlRequestButtonName, user_access.AccessMode.EDIT, self.GetAccess()),
keyboard.ButtonWithAccess(edit_moduleaccess_access_button_name, user_access.AccessMode.ACCEES_EDIT, GetAccess()), keyboard.ButtonWithAccess(self.m_HelpButtonName , user_access.AccessMode.VIEW, self.GetAccess())
keyboard.ButtonWithAccess(edit_moduleaccess_default_access_button_name, user_access.AccessMode.ACCEES_EDIT, GetAccess()),
keyboard.ButtonWithAccess(help_button_name, user_access.AccessMode.VIEW, GetAccess())
] ]
mods = [start] return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups)
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def RegisterHandlers(self):
# --------------------------------------------------------- super().RegisterHandlers()
# Обработка сообщений sql_request.RequestToBDRegisterHandlers(
self.m_Bot,
def GetButtonNameAndKeyValueAndAccess(a_Item): self.m_SqlRequestButtonName,
# ButtonName KeyValue Access self.m_RequestStartMessage,
return a_Item[0], a_Item[0], a_Item[1] FSMRequestToBDAccess,
self.m_GetStartKeyboardButtonsFunc,
def ShowMessageTemplate(a_StringMessage): user_access.AccessMode.EDIT,
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item): self.m_GetAccessFunc
if (len(a_Item) < 3):
return simple_message.WorkFuncResult(error_find_proj_message)
msg = a_StringMessage.\
replace(f'#{mod_name_field}', a_Item[0]).\
replace(f'#{moduleaccess_field}', a_Item[1]).\
replace(f'#{mod_default_access_field}', a_Item[2])
return simple_message.WorkFuncResult(msg, item_access = a_Item[1])
return ShowMessage
def SimpleMessageTemplate(a_StringMessage):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery):
return simple_message.WorkFuncResult(a_StringMessage)
return ShowMessage
# ---------------------------------------------------------
# Работа с базой данных
def GetModuleAccessList():
return bot_bd.SelectBDTemplate(table_name)()
# ---------------------------------------------------------
# API
def GetAccessForModule(a_ModuleName):
alist = GetModuleAccessList()
for i in alist:
if i[0] == a_ModuleName:
return i[1]
return ''
def GetItemDefaultAccessForModule(a_ModuleName):
alist = GetModuleAccessList()
for i in alist:
if i[0] == a_ModuleName:
return i[2]
return ''
# Инициализация БД
def GetInitBDCommands():
return init_bd_cmds
def GetAccess():
return GetAccessForModule(module_name)
# Доступные кнопки
def GetModuleButtons():
return [keyboard.ButtonWithAccess(access_button_name, user_access.AccessMode.VIEW, GetAccess())]
# Обработка кнопок
def RegisterHandlers(dp : Dispatcher):
defaul_keyboard_func = GetEditAccessKeyboardButtons
dp.register_message_handler(simple_message.InfoMessageTemplate(access_start_message, defaul_keyboard_func, GetAccess), text = access_button_name)
dp.register_message_handler(simple_message.InfoMessageTemplate(help_message, defaul_keyboard_func, GetAccess), text = help_button_name)
sql_request.RequestToBDRegisterHandlers(dp, sql_request_button_name, request_start_message, FSMRequestToBDAccess, defaul_keyboard_func, user_access.AccessMode.ACCEES_EDIT, GetAccess)
edit_keyboard_func = defaul_keyboard_func
def RegisterEdit(a_ButtonName, a_FSM, a_EditMessage, a_FieldName, a_FieldType, a_AccessMode = user_access.AccessMode.ACCEES_EDIT):
bd_item_edit.EditBDItemRegisterHandlers(dp, \
None, \
a_FSM, \
bd_item.GetCheckForTextFunc(a_ButtonName), \
moduleaccess_select_to_edit_message, \
ShowMessageTemplate(a_EditMessage), \
ShowMessageTemplate(moduleaccess_success_edit_message), \
table_name, \
mod_name_field, \
None, \
a_FieldName, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
edit_keyboard_func, \
access_mode = a_AccessMode, \
field_type = a_FieldType\
) )
RegisterEdit(edit_moduleaccess_access_button_name, FSMEditAccessItem, moduleaccess_edit_access_message, moduleaccess_field, bd_item.FieldType.text, user_access.AccessMode.ACCEES_EDIT) self.m_Bot.RegisterMessageHandler(
RegisterEdit(edit_moduleaccess_default_access_button_name, FSMEditDefaultAccessItem, moduleaccess_edit_default_access_message, mod_default_access_field, bd_item.FieldType.text, user_access.AccessMode.EDIT) self.m_HelpMessageHandler,
bd_item.GetCheckForTextFunc(self.m_HelpButtonName)
)

37
bot_modules/access_utils.py

@ -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 ''

120
bot_modules/backup.py

@ -3,33 +3,22 @@
# Бэкапы пользователя # Бэкапы пользователя
from bot_sys import bot_bd, log, config, keyboard, user_access from bot_sys import user_access, keyboard
from bot_modules import start, access, groups from bot_modules import mod_simple_message, profile
from template import file_message, simple_message from template import bd_item, file_message
from aiogram import Bot, types
import sqlite3
from aiogram.dispatcher import Dispatcher
bot = Bot(token=config.GetTelegramBotApiToken(), parse_mode=types.ParseMode.HTML)
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'backup' 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}=-');"
]
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения # Сообщения
start_message = '''
backup_message = '''
<b>Здесь вы можете выполнить специальные операции по сервисному обслуживанию</b> <b>Здесь вы можете выполнить специальные операции по сервисному обслуживанию</b>
''' '''
start_button_name = "📦 Резервные копии и логи"
backup_bd_message = ''' backup_bd_message = '''
<b>📀 Резервная копия базы данных</b> <b>📀 Резервная копия базы данных</b>
🕰 <code>@time</code> 🕰 <code>@time</code>
@ -44,44 +33,69 @@ error_backup_message = '''
<b> Ошибка резервного копирования</b> <b> Ошибка резервного копирования</b>
''' '''
backup_button_name = "📦 Резервные копии и логи"
backup_bd_button_name = "📀 Резервные копия базы" backup_bd_button_name = "📀 Резервные копия базы"
backup_log_button_name = "📃 Логи" backup_log_button_name = "📃 Логи"
# --------------------------------------------------------- button_names = {
# Работа с кнопками mod_simple_message.ButtonNames.START: start_button_name,
}
def GetBackupKeyboardButtons(a_Message, a_UserGroups):
messages = {
mod_simple_message.Messages.START: start_message,
}
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__(messages, button_names, 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().GetFileName(),
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 = [ cur_buttons = [
keyboard.ButtonWithAccess(backup_bd_button_name, user_access.AccessMode.EDIT, GetAccess()), keyboard.ButtonWithAccess(self.m_BackupBDButtonName, user_access.AccessMode.EDIT, self.GetAccess()),
keyboard.ButtonWithAccess(backup_log_button_name, user_access.AccessMode.EDIT, GetAccess()) keyboard.ButtonWithAccess(self.m_BackupLogButtonName , user_access.AccessMode.EDIT, self.GetAccess())
] ]
mods = [start] return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups)
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + 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,
# API bd_item.GetCheckForTextFunc(self.m_BackupLogButtonName)
)
# Инициализация БД
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.InfoMessageTemplate(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)

200
bot_modules/buttons.py

@ -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()

396
bot_modules/comments.py

@ -3,26 +3,27 @@
# Комментарии # Комментарии
from bot_sys import bot_bd, log, keyboard, user_access from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import start, access, groups, projects, tasks, needs from bot_modules import mod_table_operate, mod_simple_message
from template import bd_item_view, simple_message, bd_item_delete, bd_item_edit, bd_item, bd_item_add, bd_item_select
from aiogram import types
from aiogram.dispatcher import FSMContext from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import Dispatcher
import sqlite3
class FSMCreateComment(StatesGroup): class FSMCreateComment(StatesGroup):
bd_item = State() name = State()
desc = State()
photo = State()
class FSMEditCommentPhotoItem(StatesGroup):
item_field = State()
class FSMEditCommentNameItem(StatesGroup):
item_field = State()
class FSMEditCommentDescItem(StatesGroup): class FSMEditCommentDescItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
class FSMEditCommentAccessItem(StatesGroup): class FSMEditCommentAccessItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
@ -30,302 +31,123 @@ module_name = 'comments'
table_name = module_name table_name = module_name
key_name = 'commentID' key_name = 'commentID'
name_field = 'commentName'
desc_field = 'commentDesc' desc_field = 'commentDesc'
photo_field = 'commentPhoto'
access_field = 'commentAccess' access_field = 'commentAccess'
create_datetime_field = 'commentCreateDateTime' create_datetime_field = 'commentCreateDateTime'
parent_id_field = 'needID' parent_id_field = 'needID'
init_bd_cmds = [f'''CREATE TABLE IF NOT EXISTS {table_name}( table = bd_table.Table(table_name, [
{key_name} INTEGER PRIMARY KEY, bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
{desc_field} TEXT, bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
{access_field} TEXT, bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{create_datetime_field} TEXT, bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
{parent_id_field} INTEGER 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),
f"INSERT OR IGNORE INTO module_access (modName, modAccess, itemDefaultAccess) VALUES ('{module_name}', '{user_access.user_access_group_new}=va', '{user_access.user_access_group_new}=va');" bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT),
] ])
select_comments_prefix = '' init_access = f'{user_access.user_access_group_new}=va'
fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateComment,
mod_table_operate.FSMs.EDIT_NAME: FSMEditCommentNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditCommentDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditCommentPhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditCommentAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения # Сообщения и кнопки
comments_button_name = "⚏ Комментарии" button_names = {
base_comment_message = f''' mod_simple_message.ButtonNames.START: "⚏ Комментарии",
<b>{comments_button_name}</b> mod_table_operate.ButtonNames.LIST: "📃 Список комментариев",
mod_table_operate.ButtonNames.ADD: "☑ Добавить комментарий",
''' mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать комментарий",
mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение у комментария",
list_comment_button_name = "📃 Список комментариев" mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название у комментария",
select_comment_message = ''' 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: '''
error_find_proj_message = '''
Ошибка, комментарий не найден Ошибка, комментарий не найден
''' ''',
mod_table_operate.Messages.OPEN: f'''
comment_open_message = f''' <b>Комментарий: #{name_field}</b>
<b>Комментарий</b>
#{desc_field} #{desc_field}
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''' ''',
mod_table_operate.Messages.CREATE_NAME: '''
# Создание комментариев Создание комментария. Шаг 1
add_comment_button_name = "☑ Добавить комментарий" Введите название комментария:
comment_create_desc_message = ''' ''',
Введите свой комментарий: mod_table_operate.Messages.CREATE_DESC: '''
''' Создание комментария. Шаг 2
comment_success_create_message = '''✅ Комментарий успешно добавлен!''' Введите описание комментария:
''',
# Редактирование комментариев. mod_table_operate.Messages.CREATE_PHOTO: '''
Создание комментария. Шаг 3
edit_comment_button_name = "🛠 Редактировать комментарий"
comment_start_edit_message= ''' Загрузите обложку для комментария (Фото):
Она будет отображаться в его описании.
''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Комментарий успешно добавлен!''',
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие: Пожалуйста, выберите действие:
''' ''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
comment_select_to_edit_message = '''
Выберите комментарий, который вы хотите отредактировать. Выберите комментарий, который вы хотите отредактировать.
''' ''',
mod_table_operate.Messages.EDIT_PHOTO: '''
edit_comment_desc_button_name = "𝌴 Изменить комментарий" Загрузите новую обложку для комментария (Фото):
comment_edit_desc_message = f''' Она будет отображаться в его описании.
Текущий комментарий: ''',
mod_table_operate.Messages.EDIT_NAME: f'''
Текущее название комментария:
#{name_field}
Введите новое название комментария:
''',
mod_table_operate.Messages.EDIT_DESC: f'''
Текущее описание комментария:
#{desc_field} #{desc_field}
Введите отредактированный комментарий: Введите новое описание комментария:
''' ''',
mod_table_operate.Messages.EDIT_ACCESS: f'''
edit_comment_access_button_name = "✋ Изменить доступ к комментарию" Текущий доступ к комментарийу:
comment_edit_access_message = f'''
Текущий доступ к комментарию:
#{access_field} #{access_field}
{user_access.user_access_readme} {user_access.user_access_readme}
Введите новую строку доступа: Введите новую строку доступа:
''' ''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Комментарий успешно отредактирован!''',
comment_success_edit_message = '''✅ Комментарий успешно отредактирован!''' mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите комментарий, который вы хотите удалить.
# Удаление комментариев ''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Комментарий успешно удалён!''',
del_comment_button_name = "❌ Удалить комментарий" }
comment_select_to_delete_message = '''
Выберите комментарий, которую вы хотите удалить. class ModuleComments(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)
comment_success_delete_message = '''✅ Комментарий успешно удалён!'''
def GetName(self):
# --------------------------------------------------------- return module_name
# Работа с кнопками
def GetEditCommentKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = GetModuleButtons() + [
keyboard.ButtonWithAccess(edit_comment_desc_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_comment_access_button_name, user_access.AccessMode.ACCEES_EDIT, GetAccess()),
]
mods = [start]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetStartCommentKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = [
keyboard.ButtonWithAccess(list_comment_button_name, user_access.AccessMode.VIEW, GetAccess()),
keyboard.ButtonWithAccess(add_comment_button_name, user_access.AccessMode.ADD, GetAccess()),
keyboard.ButtonWithAccess(del_comment_button_name, user_access.AccessMode.DELETE, GetAccess()),
keyboard.ButtonWithAccess(edit_comment_button_name, user_access.AccessMode.EDIT, GetAccess())
]
mods = [start, projects, tasks, needs]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
# ---------------------------------------------------------
# Обработка сообщений
# стартовое сообщение
async def CommentsOpen(a_Message : types.message, state = None):
return simple_message.WorkFuncResult(base_comment_message)
def GetButtonNameAndKeyValueAndAccess(a_Item):
# commentDesc commentID commentAccess
return a_Item[1], a_Item[0], a_Item[2]
def ShowMessageTemplate(a_StringMessage):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 4):
return simple_message.WorkFuncResult(error_find_proj_message)
msg = a_StringMessage.\
replace(f'#{desc_field}', a_Item[1]).\
replace(f'#{create_datetime_field}', a_Item[3]).\
replace(f'#{access_field}', a_Item[2])
return simple_message.WorkFuncResult(msg, item_access = a_Item[2])
return ShowMessage
def SimpleMessageTemplate(a_StringMessage):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item):
return simple_message.WorkFuncResult(a_StringMessage)
return ShowMessage
# Удаление комментариев
async def CommentPreDelete(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 4):
return simple_message.WorkFuncResult(error_find_proj_message)
access = a_Item[2]
return simple_message.WorkFuncResult('', None, item_access = access)
async def CommentPostDelete(a_CallbackQuery : types.CallbackQuery, a_ItemID):
log.Success(f'Комментарий №{a_ItemID} был удалён пользователем {a_CallbackQuery.from_user.id}.')
#TODO: удалить вложенные
return simple_message.WorkFuncResult(comment_success_delete_message)
# ---------------------------------------------------------
# Работа с базой данных комментариев
def AddBDItemFunc(a_ItemData, a_UserID):
print(a_ItemData)
res, error = bot_bd.SQLRequestToBD(f'INSERT INTO {table_name}({desc_field}, {access_field}, {parent_id_field}, {create_datetime_field}) VALUES(?, ?, ?, {bot_bd.GetBDDateTimeNow()})',
commit = True, return_error = True, param = (a_ItemData[desc_field], access.GetItemDefaultAccessForModule(module_name) + f";{a_UserID}=+", a_ItemData[parent_id_field]))
if error:
log.Error(f'Пользоватлель {a_UserID}. Ошибка добавления записи в таблицу {table_name} ({a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
else:
log.Success(f'Пользоватлель {a_UserID}. Добавлена запись в таблицу {table_name} ({a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
return res, error
# ---------------------------------------------------------
# API
# Инициализация БД
def GetInitBDCommands():
return init_bd_cmds
def GetAccess():
return access.GetAccessForModule(module_name)
# Доступные кнопки
def GetModuleButtons():
return [keyboard.ButtonWithAccess(comments_button_name, user_access.AccessMode.VIEW, GetAccess())]
# Обработка кнопок
def RegisterHandlers(dp : Dispatcher):
defaul_keyboard_func = GetStartCommentKeyboardButtons
def RegisterSelectParent(a_ButtonName, access_mode):
a_PrefixBase = a_ButtonName
a_Prefix = bd_item_select.FirstSelectBDItemRegisterHandlers(dp, \
a_PrefixBase, \
a_ButtonName, \
projects.table_name, \
projects.key_name, \
projects.GetButtonNameAndKeyValueAndAccess, \
projects.select_project_message, \
projects.GetAccess, \
access_mode = access_mode\
)
a_Prefix = bd_item_select.NextSelectBDItemRegisterHandlers(dp, \
a_Prefix, \
tasks.parent_id_field, \
tasks.table_name, \
tasks.key_name, \
tasks.GetButtonNameAndKeyValueAndAccess, \
tasks.select_task_message, \
tasks.GetAccess, \
access_mode = access_mode\
)
a_Prefix = bd_item_select.NextSelectBDItemRegisterHandlers(dp, \
a_Prefix, \
needs.parent_id_field, \
needs.table_name, \
needs.key_name, \
needs.GetButtonNameAndKeyValueAndAccess, \
needs.select_need_message, \
needs.GetAccess, \
access_mode = access_mode\
)
return a_Prefix
# Стартовое сообщение
dp.register_message_handler(simple_message.SimpleMessageTemplate(CommentsOpen, defaul_keyboard_func, GetAccess), text = comments_button_name)
# Список комментариев
a_Prefix = RegisterSelectParent(list_comment_button_name, user_access.AccessMode.VIEW)
bd_item_view.LastSelectAndShowBDItemRegisterHandlers(dp, \
a_Prefix, parent_id_field, \
table_name, key_name, \
ShowMessageTemplate(comment_open_message), \
GetButtonNameAndKeyValueAndAccess, \
select_comment_message, \
GetAccess, \
defaul_keyboard_func, \
access_mode = user_access.AccessMode.VIEW\
)
global select_comments_prefix
select_comments_prefix = a_Prefix
# Удаление комментариев
a_Prefix = RegisterSelectParent(del_comment_button_name, user_access.AccessMode.DELETE)
bd_item_delete.DeleteBDItemRegisterHandlers(dp, \
a_Prefix, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
table_name, \
key_name, \
parent_id_field, \
CommentPreDelete, \
CommentPostDelete, \
GetButtonNameAndKeyValueAndAccess, \
select_comment_message, \
GetAccess, \
defaul_keyboard_func\
)
# Добавление комментариев
a_Prefix = RegisterSelectParent(add_comment_button_name, user_access.AccessMode.ADD)
bd_item_add.AddBDItem1RegisterHandlers(dp, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
FSMCreateComment, \
AddBDItemFunc, \
SimpleMessageTemplate(comment_create_desc_message), \
SimpleMessageTemplate(comment_success_create_message), \
a_Prefix,\
needs.table_name, \
needs.key_name, \
desc_field, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
GetStartCommentKeyboardButtons,\
bd_item.FieldType.text
)
def RegisterEdit(a_ButtonName, a_FSM, a_EditMessage, a_FieldName, a_FieldType, a_AccessMode = user_access.AccessMode.EDIT):
a_Prefix = RegisterSelectParent(a_ButtonName, a_AccessMode)
bd_item_edit.EditBDItemRegisterHandlers(dp, \
a_Prefix, \
a_FSM, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
comment_select_to_edit_message, \
ShowMessageTemplate(a_EditMessage), \
ShowMessageTemplate(comment_success_edit_message), \
table_name, \
key_name, \
parent_id_field, \
a_FieldName, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
edit_keyboard_func, \
access_mode = a_AccessMode, \
field_type = a_FieldType\
)
# Редактирование комментариев
edit_keyboard_func = GetEditCommentKeyboardButtons
dp.register_message_handler(simple_message.InfoMessageTemplate(comment_start_edit_message, edit_keyboard_func, GetAccess, access_mode = user_access.AccessMode.EDIT), text = edit_comment_button_name)
RegisterEdit(edit_comment_desc_button_name, FSMEditCommentDescItem, comment_edit_desc_message, desc_field, bd_item.FieldType.text)
RegisterEdit(edit_comment_access_button_name, FSMEditCommentAccessItem, comment_edit_access_message, access_field, bd_item.FieldType.text)

152
bot_modules/groups.py

@ -3,13 +3,12 @@
# Группы пользователей # Группы пользователей
from bot_sys import bot_bd, log, config, keyboard, user_access from bot_sys import keyboard, user_access, bot_bd
from bot_modules import start, access from bot_modules import mod_simple_message
from template import simple_message, sql_request from template import simple_message, sql_request, bd_item
from aiogram.dispatcher import FSMContext from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import Dispatcher
class FSMRequestToBD(StatesGroup): class FSMRequestToBD(StatesGroup):
sqlRequest = State() sqlRequest = State()
@ -27,34 +26,9 @@ user_id_field = 'user_id'
access_field = 'access' access_field = 'access'
create_datetime_field = 'createDateTime' create_datetime_field = 'createDateTime'
init_bd_cmds = [f"""CREATE TABLE IF NOT EXISTS {table_groups_name}(
{key_table_groups_name} INTEGER PRIMARY KEY NOT NULL,
{name_table_groups_field} TEXT,
{access_field} TEXT,
{create_datetime_field} TEXT,
UNIQUE({key_table_groups_name}),
UNIQUE({name_table_groups_field})
);""",
f"""CREATE TABLE IF NOT EXISTS {table_user_in_groups_name}(
{user_id_field} INTEGER,
{key_table_groups_name} INTEGER,
{access_field} TEXT,
{create_datetime_field} TEXT,
UNIQUE({user_id_field}, {key_table_groups_name})
);""",
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}=-');",
f"INSERT OR IGNORE INTO {table_groups_name} ({name_table_groups_field}, {access_field}, {create_datetime_field}) VALUES ('{user_access.user_access_group_new}', '{user_access.user_access_group_new}=-', {bot_bd.GetBDDateTimeNow()});"
]
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения # Сообщения
group_start_message = '''
<b>Группы пользователей находятся в стадии разработки</b>
Пока можете воспользоваться хардкорным способом через запросы к БД
'''
request_start_message = ''' request_start_message = '''
**Задайте запрос к БД** **Задайте запрос к БД**
@ -73,58 +47,84 @@ help_message = '''
`user_in_groups(user_id, group_id)` - содержит соответсвия ID пользователей и групп `user_in_groups(user_id, group_id)` - содержит соответсвия ID пользователей и групп
''' '''
user_group_button_name = "▦ Группы пользователей"
sql_request_button_name = "⛃ Запрос к БД для редактирования групп" sql_request_button_name = "⛃ Запрос к БД для редактирования групп"
help_button_name = "📄 Информация по группам" help_button_name = "📄 Информация по группам"
# --------------------------------------------------------- button_names = {
# Работа с кнопками mod_simple_message.ButtonNames.START: "▦ Группы пользователей",
}
def GetEditGroupKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = [
keyboard.ButtonWithAccess(sql_request_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(help_button_name, user_access.AccessMode.VIEW, GetAccess())
]
mods = [start]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
# ---------------------------------------------------------
# Обработка сообщений
# --------------------------------------------------------- messages = {
# Работа с базой данных групп mod_simple_message.Messages.START: '''
<b>Группы пользователей находятся в стадии разработки</b>
def GetGroupIDForUser(a_UserID):
return bot_bd.SQLRequestToBD('SELECT group_id FROM user_in_groups WHERE user_id = ?', param = [a_UserID])
def GetGroupNamesForUser(a_UserID):
return bot_bd.SQLRequestToBD('SELECT groupName FROM user_groups WHERE group_id=(SELECT group_id FROM user_in_groups WHERE user_id = ?)', param = [a_UserID])
# ---------------------------------------------------------
# API
def GetUserGroupData(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 GetInitBDCommands():
return init_bd_cmds
def GetAccess(): Пока можете воспользоваться хардкорным способом через запросы к БД
return access.GetAccessForModule(module_name) ''',
}
init_access = f'{user_access.user_access_group_new}=-'
class ModuleGroups(mod_simple_message.SimpleMessageModule):
def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
self.m_SqlRequestButtonName = self.CreateButton('sql request', sql_request_button_name)
self.m_RequestStartMessage = self.CreateMessage('equest start', request_start_message)
self.m_HelpButtonName = self.CreateButton('help', help_button_name)
self.m_HelpMessage = self.CreateMessage('help', help_message)
self.m_HelpMessageHandler = simple_message.InfoMessageTemplate(
self.m_Bot,
self.m_HelpMessage,
self.m_GetStartKeyboardButtonsFunc,
None,
self.m_GetAccessFunc
)
def GetInitBDCommands(self):
return super(). GetInitBDCommands() + [
f"""CREATE TABLE IF NOT EXISTS {table_groups_name}(
{key_table_groups_name} INTEGER PRIMARY KEY NOT NULL,
{name_table_groups_field} TEXT,
{access_field} TEXT,
{create_datetime_field} TEXT,
UNIQUE({key_table_groups_name}),
UNIQUE({name_table_groups_field})
);""",
f"""CREATE TABLE IF NOT EXISTS {table_user_in_groups_name}(
{user_id_field} INTEGER,
{key_table_groups_name} INTEGER,
{access_field} TEXT,
{create_datetime_field} TEXT,
UNIQUE({user_id_field}, {key_table_groups_name})
);""",
f"INSERT OR IGNORE INTO {table_groups_name} ({name_table_groups_field}, {access_field}, {create_datetime_field}) VALUES ('{user_access.user_access_group_new}', '{user_access.user_access_group_new}=-', {bot_bd.GetBDDateTimeNow()});"
]
# Доступные кнопки def GetName(self):
def GetModuleButtons(): return module_name
return [keyboard.ButtonWithAccess(user_group_button_name, user_access.AccessMode.VIEW, GetAccess())]
# Обработка кнопок def GetStartKeyboardButtons(self, a_Message, a_UserGroups):
def RegisterHandlers(dp : Dispatcher): mod_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups)
dp.register_message_handler(simple_message.InfoMessageTemplate(group_start_message, GetEditGroupKeyboardButtons, GetAccess), text = user_group_button_name) cur_buttons = [
dp.register_message_handler(simple_message.InfoMessageTemplate(help_message, GetEditGroupKeyboardButtons, GetAccess), text = help_button_name) keyboard.ButtonWithAccess(self.m_SqlRequestButtonName, user_access.AccessMode.EDIT, self.GetAccess()),
keyboard.ButtonWithAccess(self.m_HelpButtonName , user_access.AccessMode.VIEW, self.GetAccess())
]
return mod_buttons + keyboard.MakeButtons(cur_buttons, a_UserGroups)
def RegisterHandlers(self):
super().RegisterHandlers()
sql_request.RequestToBDRegisterHandlers(
self.m_Bot,
self.m_SqlRequestButtonName,
self.m_RequestStartMessage,
FSMRequestToBD,
self.m_GetStartKeyboardButtonsFunc,
user_access.AccessMode.EDIT,
self.m_GetAccessFunc
)
self.m_Bot.RegisterMessageHandler(
self.m_HelpMessageHandler,
bd_item.GetCheckForTextFunc(self.m_HelpButtonName)
)
sql_request.RequestToBDRegisterHandlers(dp, sql_request_button_name, request_start_message, FSMRequestToBD, GetEditGroupKeyboardButtons, user_access.AccessMode.EDIT, GetAccess)

16
bot_modules/groups_utils.py

@ -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)

401
bot_modules/languages.py

@ -3,16 +3,12 @@
# Языки # Языки
from bot_sys import bot_bd, log, keyboard, user_access, user_messages from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import start, access, groups, messages from bot_modules import mod_table_operate, mod_simple_message, access_utils
from template import bd_item_view, simple_message, bd_item_delete, bd_item_edit, bd_item, bd_item_add from template import bd_item
from aiogram import types
from aiogram.dispatcher import FSMContext from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import Dispatcher
import sqlite3
class FSMCreateLanguage(StatesGroup): class FSMCreateLanguage(StatesGroup):
name = State() name = State()
@ -25,7 +21,7 @@ class FSMEditLanguagePhotoItem(StatesGroup):
class FSMEditLanguageNameItem(StatesGroup): class FSMEditLanguageNameItem(StatesGroup):
item_field = State() item_field = State()
class FSMEditLanguageDeskItem(StatesGroup): class FSMEditLanguageDescItem(StatesGroup):
item_field = State() item_field = State()
class FSMEditLanguageAccessItem(StatesGroup): class FSMEditLanguageAccessItem(StatesGroup):
@ -42,336 +38,157 @@ photo_field = 'languagePhoto'
access_field = 'languageAccess' access_field = 'languageAccess'
create_datetime_field = 'languageCreateDateTime' create_datetime_field = 'languageCreateDateTime'
init_bd_cmds = [f'''CREATE TABLE IF NOT EXISTS {table_name}( table_name_field = bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR)
{key_name} INTEGER PRIMARY KEY,
{name_field} TEXT, table = bd_table.Table(table_name, [
{desc_field} TEXT, bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
{photo_field} TEXT, table_name_field,
{access_field} TEXT, bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{create_datetime_field} TEXT, bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
UNIQUE({key_name}), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
UNIQUE({name_field}) bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
)''', ],
f"INSERT OR IGNORE INTO module_access (modName, modAccess, itemDefaultAccess) VALUES ('{module_name}', '{user_access.user_access_group_all}=-', '{user_access.user_access_group_all}=-');" [
[table_name_field],
] ]
)
# --------------------------------------------------------- init_access = f'{user_access.user_access_group_all}=-'
# Сообщения
languages_button_name = "⚑ Языки"
base_language_message = f'''
<b>{languages_button_name}</b>
''' fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateLanguage,
mod_table_operate.FSMs.EDIT_NAME: FSMEditLanguageNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditLanguageDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditLanguagePhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditLanguageAccessItem,
}
list_language_button_name = "📃 Список языков" # ---------------------------------------------------------
select_language_message = ''' # Сообщения и кнопки
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: '''
error_find_proj_message = '''
Ошибка, язык не найден Ошибка, язык не найден
''' ''',
mod_table_operate.Messages.OPEN: f'''
language_open_message = f'''
<b>Язык: #{name_field}</b> <b>Язык: #{name_field}</b>
#{desc_field} #{desc_field}
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''' ''',
mod_table_operate.Messages.CREATE_NAME: '''
# Создание языка
add_language_button_name = "✅ Добавить язык"
language_create_name_message = '''
Создание языка. Шаг 1 Создание языка. Шаг 1
Введите название языка: Введите название языка:
''' ''',
mod_table_operate.Messages.CREATE_DESC: '''
language_create_desc_message = '''
Создание языка. Шаг 2 Создание языка. Шаг 2
Введите описание языка: Введите описание языка:
''' ''',
mod_table_operate.Messages.CREATE_PHOTO: '''
language_create_photo_message = '''
Создание языка. Шаг 3 Создание языка. Шаг 3
Загрузите обложку для языка (Фото): Загрузите обложку для языка (Фото):
Она будет отображаться в его описании. Она будет отображаться в его описании.
''' ''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Язык успешно добавлен!''',
language_success_create_message = '''✅ Язык успешно добавлен!''' mod_table_operate.Messages.START_EDIT: '''
# Редактирование языка.
edit_language_button_name = "🛠 Редактировать язык"
language_start_edit_message= '''
Пожалуйста, выберите действие: Пожалуйста, выберите действие:
''' ''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
language_select_to_edit_message = '''
Выберите язык, который вы хотите отредактировать. Выберите язык, который вы хотите отредактировать.
''' ''',
mod_table_operate.Messages.EDIT_PHOTO: '''
edit_language_photo_button_name = "☐ Изменить изображение в языке"
language_edit_photo_message = '''
Загрузите новую обложку для языка (Фото): Загрузите новую обложку для языка (Фото):
Она будет отображаться в его описании. Она будет отображаться в его описании.
''' ''',
mod_table_operate.Messages.EDIT_NAME: f'''
edit_language_name_button_name = "≂ Изменить название в языке"
language_edit_name_message = f'''
Текущее название языка: Текущее название языка:
#{name_field} #{name_field}
Введите новое название языка: Введите новое название языка:
''' ''',
mod_table_operate.Messages.EDIT_DESC: f'''
edit_language_desc_button_name = "𝌴 Изменить описание в языке"
language_edit_desc_message = f'''
Текущее описание языка: Текущее описание языка:
#{desc_field} #{desc_field}
Введите новое описание языка: Введите новое описание языка:
''' ''',
mod_table_operate.Messages.EDIT_ACCESS: f'''
edit_language_access_button_name = "✋ Изменить доступ к языку"
language_edit_access_message = f'''
Текущий доступ к языку: Текущий доступ к языку:
#{access_field} #{access_field}
{user_access.user_access_readme} {user_access.user_access_readme}
Введите новую строку доступа: Введите новую строку доступа:
''' ''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Язык успешно отредактирован!''',
language_success_edit_message = '''✅ Язык успешно отредактирован!''' mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите язык, который вы хотите удалить.
# Удаление языка Все задачи и потребности в этом языке так же будут удалены!
''',
del_language_button_name = "❌ Удалить язык" mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Язык успешно удалён!''',
language_select_to_delete_message = ''' }
Выберите язык, которое вы хотите удалить.
''' class ModuleLanguages(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):
language_success_delete_message = '''✅ Язык успешно удален!''' 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)
self.m_LanguageIDs = {}
# ---------------------------------------------------------
# Работа с кнопками def GetName(self):
return module_name
def GetEditLanguageKeyboardButtons(a_Language, a_UserGroups):
cur_buttons = GetModuleButtons() + [ def GetLangID(self, a_Lang):
keyboard.ButtonWithAccess(edit_language_photo_button_name, user_access.AccessMode.EDIT, GetAccess()), return self.m_LanguageIDs.get(a_Lang, None)
keyboard.ButtonWithAccess(edit_language_name_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_language_desc_button_name, user_access.AccessMode.EDIT, GetAccess()), def GetLangName(self, a_LangID):
keyboard.ButtonWithAccess(edit_language_access_button_name, user_access.AccessMode.ACCEES_EDIT, GetAccess()), for lang_name, lang_id in self.m_LanguageIDs:
]
mods = [start]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetStartLanguageKeyboardButtons(a_Language, a_UserGroups):
cur_buttons = [
keyboard.ButtonWithAccess(list_language_button_name, user_access.AccessMode.VIEW, GetAccess()),
keyboard.ButtonWithAccess(add_language_button_name, user_access.AccessMode.ADD, GetAccess()),
keyboard.ButtonWithAccess(del_language_button_name, user_access.AccessMode.DELETE, GetAccess()),
keyboard.ButtonWithAccess(edit_language_button_name, user_access.AccessMode.EDIT, GetAccess())
]
mods = [start, messages]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetViewItemInlineKeyboardTemplate(a_ItemID):
def GetViewItemInlineKeyboard(a_Message, a_UserGroups):
cur_buttons = [
keyboard.InlineButton(messages.list_message_button_name, messages.select_messages_prefix, a_ItemID, GetAccess(), user_access.AccessMode.VIEW),
]
return keyboard.MakeInlineKeyboard(cur_buttons, a_UserGroups)
return GetViewItemInlineKeyboard
# ---------------------------------------------------------
# Обработка языков
# стартовое язык
async def LanguagesOpen(a_Language : types.message, state = None):
return simple_message.WorkFuncResult(base_language_message)
def GetButtonNameAndKeyValueAndAccess(a_Item):
# languageName languageID languageAccess
return a_Item[1], a_Item[0], a_Item[4]
def ShowMessageTemplate(a_StringLanguage, keyboard_template_func = None):
async def ShowLanguage(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 6):
return simple_message.WorkFuncResult(error_find_proj_message)
msg = a_StringLanguage.\
replace(f'#{name_field}', a_Item[1]).\
replace(f'#{desc_field}', a_Item[2]).\
replace(f'#{create_datetime_field}', a_Item[5]).\
replace(f'#{access_field}', a_Item[4])
keyboard_func = None
if keyboard_template_func:
keyboard_func = keyboard_template_func(a_Item[0])
return simple_message.WorkFuncResult(msg, photo_id = a_Item[3], item_access = a_Item[4], keyboard_func = keyboard_func)
return ShowLanguage
def SimpleMessageTemplate(a_StringLanguage):
async def ShowLanguage(a_CallbackQuery : types.CallbackQuery, a_Item):
return simple_message.WorkFuncResult(a_StringLanguage)
return ShowLanguage
# Удаление языка
async def LanguagePreDelete(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 6):
return simple_message.WorkFuncResult(error_find_proj_message)
access = a_Item[4]
return simple_message.WorkFuncResult('', None, item_access = access)
async def LanguagePostDelete(a_CallbackQuery : types.CallbackQuery, a_ItemID):
log.Success(f'Язык №{a_ItemID} был удалён пользователем {a_CallbackQuery.from_user.id}.')
#TODO: удалить вложенные
FlushLanguages()
return simple_message.WorkFuncResult(language_success_delete_message)
# ---------------------------------------------------------
# Работа с базой данных языков
def AddBDItemFunc(a_ItemData, a_UserID):
res, error = bot_bd.SQLRequestToBD(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], access.GetItemDefaultAccessForModule(module_name) + f";{a_UserID}=+"))
if error:
log.Error(f'Пользоватлель {a_UserID}. Ошибка добавления записи в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
else:
log.Success(f'Пользоватлель {a_UserID}. Добавлена запись в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
FlushLanguages()
return res, error
# ---------------------------------------------------------
# API
def AddOrIgnoreLang(a_Lang : str):
res, error = bot_bd.SQLRequestToBD(f'INSERT OR IGNORE INTO {table_name}({photo_field}, {name_field}, {desc_field}, {access_field}, {create_datetime_field}) VALUES(?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()})',
commit = True, return_error = True, param = (0, a_Lang, '', access.GetItemDefaultAccessForModule(module_name)))
g_languages = {}
def GetLangID(a_Lang):
global g_languages
return g_languages.get(a_Lang, None)
def GetLangName(a_LangID):
global g_languages
for lang_name, lang_id in g_languages:
if a_LangID == lang_id: if a_LangID == lang_id:
return lang_name return lang_name
return user_messages.default_language return self.m_BotMessages.m_DefaultLanguage
def FlushLanguages(): def FlushLanguages(self):
global g_languages msg = self.m_BotMessages.GetMessages()
msg = user_messages.GetMessages()
for lang, msg_dict in msg.items(): for lang, msg_dict in msg.items():
AddOrIgnoreLang(lang) self.AddOrIgnoreLang(lang)
langs = bd_item.GetAllItemsTemplate(table_name)() langs = bd_item.GetAllItemsTemplate(self.m_Bot, table_name)()
if langs: if langs:
for l in langs: for l in langs:
g_languages[l[1]] = str(l[0]) self.m_LanguageIDs[l[1]] = str(l[0])
print('FlushLanguages', g_languages) print('FlushLanguages', self.m_LanguageIDs)
# Инициализация БД
def GetInitBDCommands():
return init_bd_cmds
def GetAccess():
return access.GetAccessForModule(module_name)
# Доступные кнопки
def GetModuleButtons():
return [
keyboard.ButtonWithAccess(languages_button_name, user_access.AccessMode.VIEW, GetAccess()),
]
# Обработка кнопок
def RegisterHandlers(dp : Dispatcher):
defaul_keyboard_func = GetStartLanguageKeyboardButtons
# Список языков
dp.register_message_handler(simple_message.SimpleMessageTemplate(LanguagesOpen, defaul_keyboard_func, GetAccess), text = languages_button_name)
bd_item_view.FirstSelectAndShowBDItemRegisterHandlers(dp, \
list_language_button_name, \
table_name, \
key_name, \
ShowMessageTemplate(language_open_message, GetViewItemInlineKeyboardTemplate), \
GetButtonNameAndKeyValueAndAccess, \
select_language_message, \
GetAccess, \
defaul_keyboard_func\
)
# Удаление языка def AddOrIgnoreLang(self, a_Lang : str):
bd_item_delete.DeleteBDItemRegisterHandlers(dp, \ table_name = self.m_Table.GetName()
None, \ name_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.NAME)
bd_item.GetCheckForTextFunc(del_language_button_name), \ photo_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PHOTO)
table_name, \ desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC)
key_name, \ access_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.ACCESS)
None, \ create_datetime_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.CREATE_DATE)
LanguagePreDelete, \
LanguagePostDelete, \
GetButtonNameAndKeyValueAndAccess, \
select_language_message, \
GetAccess, \
defaul_keyboard_func\
)
# Добавление языка res, error = self.m_Bot.SQLRequest(f'INSERT OR IGNORE INTO {table_name}({photo_field}, {name_field}, {desc_field}, {access_field}, {create_datetime_field}) VALUES(?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()})',
bd_item_add.AddBDItem3RegisterHandlers(dp, \ commit = True, return_error = True, param = (0, a_Lang, '', access_utils.GetItemDefaultAccessForModule(self.m_Bot, module_name)))
bd_item.GetCheckForTextFunc(add_language_button_name), \
FSMCreateLanguage,\
FSMCreateLanguage.name,\
FSMCreateLanguage.desc, \
FSMCreateLanguage.photo,\
AddBDItemFunc, \
SimpleMessageTemplate(language_create_name_message), \
SimpleMessageTemplate(language_create_desc_message), \
SimpleMessageTemplate(language_create_photo_message), \
SimpleMessageTemplate(language_success_create_message), \
None,\
None, \
None, \
name_field, \
desc_field, \
photo_field, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
GetStartLanguageKeyboardButtons\
)
# Редактирование языка def OnChange(self):
edit_keyboard_func = GetEditLanguageKeyboardButtons self.FlushLanguages()
def RegisterEdit(a_ButtonName, a_FSM, a_EditLanguage, a_FieldName, a_FieldType, a_AccessMode = user_access.AccessMode.EDIT):
bd_item_edit.EditBDItemRegisterHandlers(dp, \
None, \
a_FSM, \
bd_item.GetCheckForTextFunc(a_ButtonName), \
language_select_to_edit_message, \
ShowMessageTemplate(a_EditLanguage), \
ShowMessageTemplate(language_success_edit_message), \
table_name, \
key_name, \
None, \
a_FieldName, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
edit_keyboard_func, \
access_mode = a_AccessMode, \
field_type = a_FieldType\
)
dp.register_message_handler(simple_message.InfoMessageTemplate(language_start_edit_message, edit_keyboard_func, GetAccess, access_mode = user_access.AccessMode.EDIT), text = edit_language_button_name)
RegisterEdit(edit_language_photo_button_name, FSMEditLanguagePhotoItem, language_edit_photo_message, photo_field, bd_item.FieldType.photo)
RegisterEdit(edit_language_name_button_name, FSMEditLanguageNameItem, language_edit_name_message, name_field, bd_item.FieldType.text)
RegisterEdit(edit_language_desc_button_name, FSMEditLanguageDeskItem, language_edit_desc_message, desc_field, bd_item.FieldType.text)
RegisterEdit(edit_language_access_button_name, FSMEditLanguageAccessItem, language_edit_access_message, access_field, bd_item.FieldType.text)

431
bot_modules/messages.py

@ -3,16 +3,12 @@
# Сообщения # Сообщения
from bot_sys import bot_bd, log, keyboard, user_access, user_messages from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_messages
from bot_modules import start, access, groups, languages from bot_modules import mod_table_operate, mod_simple_message, access_utils
from template import bd_item_view, simple_message, bd_item_delete, bd_item_edit, bd_item, bd_item_add, bd_item_select from template import bd_item
from aiogram import types
from aiogram.dispatcher import FSMContext from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import Dispatcher
import sqlite3
class FSMCreateMessage(StatesGroup): class FSMCreateMessage(StatesGroup):
name = State() name = State()
@ -47,355 +43,158 @@ access_field = 'messageAccess'
create_datetime_field = 'messageCreateDateTime' create_datetime_field = 'messageCreateDateTime'
parent_id_field = 'languageID' parent_id_field = 'languageID'
init_bd_cmds = [f'''CREATE TABLE IF NOT EXISTS {table_name}( table_name_field = bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR)
{key_name} INTEGER PRIMARY KEY, table_parent_id_field = bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT)
{name_field} TEXT,
{desc_field} TEXT, table = bd_table.Table(table_name, [
{photo_field} TEXT, bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
{access_field} TEXT, table_name_field,
{create_datetime_field} TEXT, bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{parent_id_field} INTEGER, bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
UNIQUE({key_name}), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
UNIQUE({name_field}, {parent_id_field}) bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
)''', table_parent_id_field,
f"INSERT OR IGNORE INTO module_access (modName, modAccess, itemDefaultAccess) VALUES ('{module_name}', '{user_access.user_access_group_all}=-', '{user_access.user_access_group_all}=-');" ],
[
[table_name_field, table_parent_id_field],
] ]
)
select_messages_prefix = '' init_access = f'{user_access.user_access_group_all}=-'
# ---------------------------------------------------------
# Сообщения
messages_button_name = "✉ Сообщения"
base_message_message = '''
<b> Сообщения</b>
''' fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateMessage,
mod_table_operate.FSMs.EDIT_NAME: FSMEditMessageNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditMessageDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditMessagePhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditMessageAccessItem,
}
list_message_button_name = "📃 Список сообщений" # ---------------------------------------------------------
select_message_message = ''' # Сообщения и кнопки
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: '''
error_find_proj_message = ''' Ошибка, сообщение не найден
Ошибка, сообщенийа не найдена ''',
''' mod_table_operate.Messages.OPEN: f'''
message_open_message = f'''
<b>Сообщение: #{name_field}</b> <b>Сообщение: #{name_field}</b>
#{desc_field} #{desc_field}
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''' ''',
mod_table_operate.Messages.CREATE_NAME: '''
# Создание сообщения
add_message_button_name = "☑ Добавить сообщение"
message_create_name_message = '''
Создание сообщения. Шаг 1 Создание сообщения. Шаг 1
Введите название сообщения: Введите название сообщения:
''' ''',
mod_table_operate.Messages.CREATE_DESC: '''
message_create_desc_message = '''
Создание сообщения. Шаг 2 Создание сообщения. Шаг 2
Введите описание сообщения: Введите описание сообщения:
''' ''',
mod_table_operate.Messages.CREATE_PHOTO: '''
message_create_photo_message = '''
Создание сообщения. Шаг 3 Создание сообщения. Шаг 3
Загрузите обложку для сообщения (Фото): Загрузите обложку для сообщения (Фото):
Она будет отображаться в её описании. Она будет отображаться в его описании.
''' ''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Сообщение успешно добавлено!''',
message_success_create_message = '''✅ Сообщение успешно добавлено!''' mod_table_operate.Messages.START_EDIT: '''
# Редактирование сообщения.
edit_message_button_name = "🛠 Редактировать сообщение"
message_start_edit_message= '''
Пожалуйста, выберите действие: Пожалуйста, выберите действие:
''' ''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
message_select_to_edit_message = ''' Выберите сообщение, который вы хотите отредактировать.
Выберите сообщение, которую вы хотите отредактировать. ''',
''' mod_table_operate.Messages.EDIT_PHOTO: '''
edit_message_photo_button_name = "☐ Изменить изображение у сообщения"
message_edit_photo_message = '''
Загрузите новую обложку для сообщения (Фото): Загрузите новую обложку для сообщения (Фото):
Она будет отображаться в её описании. Она будет отображаться в его описании.
''' ''',
mod_table_operate.Messages.EDIT_NAME: f'''
edit_message_name_button_name = "≂ Изменить название у сообщения"
message_edit_name_message = f'''
Текущее название сообщения: Текущее название сообщения:
#{name_field} #{name_field}
Введите новое название сообщения: Введите новое название сообщения:
''' ''',
mod_table_operate.Messages.EDIT_DESC: f'''
edit_message_desc_button_name = "𝌴 Изменить описание у сообщения"
message_edit_desc_message = f'''
Текущее описание сообщения: Текущее описание сообщения:
#{desc_field} #{desc_field}
Введите новое описание сообщения: Введите новое описание сообщения:
''' ''',
mod_table_operate.Messages.EDIT_ACCESS: f'''
edit_message_access_button_name = "✋ Изменить доступ к сообщению" Текущий доступ к сообщениеу:
message_edit_access_message = f'''
Текущий доступ к сообщению:
#{access_field} #{access_field}
{user_access.user_access_readme} {user_access.user_access_readme}
Введите новую строку доступа: Введите новую строку доступа:
''' ''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Сообщение успешно отредактировано!''',
message_success_edit_message = '''✅ Сообщение успешно отредактировано!''' mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите сообщение, который вы хотите удалить.
# Удаление сообщения ''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Сообщение успешно удалено!''',
del_message_button_name = "❌ Удалить сообщение" }
message_select_to_delete_message = '''
Выберите сообщение, которую вы хотите удалить. class ModuleMessages(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)
message_success_delete_message = '''✅ Сообщение успешно удалено!'''
def GetName(self):
# --------------------------------------------------------- return module_name
# Работа с кнопками
def AddOrIgnoreMessage(self, a_Message):
def GetEditMessageKeyboardButtons(a_Message, a_UserGroups): table_name = self.m_Table.GetName()
cur_buttons = GetModuleButtons() + [ name_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.NAME)
keyboard.ButtonWithAccess(edit_message_photo_button_name, user_access.AccessMode.EDIT, GetAccess()), photo_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PHOTO)
keyboard.ButtonWithAccess(edit_message_name_button_name, user_access.AccessMode.EDIT, GetAccess()), desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC)
keyboard.ButtonWithAccess(edit_message_desc_button_name, user_access.AccessMode.EDIT, GetAccess()), access_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.ACCESS)
keyboard.ButtonWithAccess(edit_message_access_button_name, user_access.AccessMode.ACCEES_EDIT, GetAccess()), create_datetime_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.CREATE_DATE)
] parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
mods = [start]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups) 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()})',
def GetStartMessageKeyboardButtons(a_Message, a_UserGroups): 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))
cur_buttons = [
keyboard.ButtonWithAccess(list_message_button_name, user_access.AccessMode.VIEW, GetAccess()), def FlushMessages(self):
keyboard.ButtonWithAccess(add_message_button_name, user_access.AccessMode.ADD, GetAccess()), msg = self.m_BotMessages.GetMessages()
keyboard.ButtonWithAccess(del_message_button_name, user_access.AccessMode.DELETE, GetAccess()),
keyboard.ButtonWithAccess(edit_message_button_name, user_access.AccessMode.EDIT, GetAccess())
]
mods = [start, languages]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetViewItemInlineKeyboardTemplate(a_ItemID):
def GetViewItemInlineKeyboard(a_Message, a_UserGroups):
cur_buttons = [
#keyboard.InlineButton(needs.list_need_button_name, needs.select_needs_prefix, a_ItemID, GetAccess(), user_access.AccessMode.VIEW),
]
return keyboard.MakeInlineKeyboard(cur_buttons, a_UserGroups)
return GetViewItemInlineKeyboard
# ---------------------------------------------------------
# Обработка сообщений
# стартовое сообщение
async def MessagesOpen(a_Message : types.message, state = None):
return simple_message.WorkFuncResult(base_message_message)
def GetButtonNameAndKeyValueAndAccess(a_Item):
# messageName messageID messageAccess
return a_Item[1], a_Item[0], a_Item[4]
def ShowMessageTemplate(a_StringMessage, keyboard_template_func = None):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 6):
return simple_message.WorkFuncResult(error_find_proj_message)
if message_success_edit_message == a_StringMessage:
FlushMessages()
# TODO FlushMessages происходит рано. Нужно после изменений
msg = a_StringMessage.\
replace(f'#{name_field}', a_Item[1]).\
replace(f'#{desc_field}', a_Item[2]).\
replace(f'#{create_datetime_field}', a_Item[5]).\
replace(f'#{access_field}', a_Item[4])
keyboard_func = None
if keyboard_template_func:
keyboard_func = keyboard_template_func(a_Item[0])
return simple_message.WorkFuncResult(msg, photo_id = a_Item[3], item_access = a_Item[4], keyboard_func = keyboard_func)
return ShowMessage
def SimpleMessageTemplate(a_StringMessage):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item):
return simple_message.WorkFuncResult(a_StringMessage)
return ShowMessage
# Удаление сообщения
async def MessagePreDelete(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 6):
return simple_message.WorkFuncResult(error_find_proj_message)
access = a_Item[4]
return simple_message.WorkFuncResult('', None, item_access = access)
async def MessagePostDelete(a_CallbackQuery : types.CallbackQuery, a_ItemID):
log.Success(f'Сообщение №{a_ItemID} была удалена пользователем {a_CallbackQuery.from_user.id}.')
#TODO: удалить вложенные
FlushMessages()
return simple_message.WorkFuncResult(message_success_delete_message)
# ---------------------------------------------------------
# Работа с базой данных сообщений
def AddBDItemFunc(a_ItemData, a_UserID):
res, error = bot_bd.SQLRequestToBD(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], access.GetItemDefaultAccessForModule(module_name) + f";{a_UserID}=+", a_ItemData[parent_id_field]))
if error:
log.Error(f'Пользоватлель {a_UserID}. Ошибка добавления записи в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
else:
log.Success(f'Пользоватлель {a_UserID}. Добавлена запись в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
FlushMessages()
return res, error
# ---------------------------------------------------------
# API
def AddOrIgnoreMessage(a_Message : user_messages.Message):
return bot_bd.SQLRequestToBD(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.GetItemDefaultAccessForModule(module_name), languages.GetLangID(a_Message.m_Language)))
def FlushMessages():
msg = user_messages.GetMessages()
for lang, msg_dict in msg.items(): for lang, msg_dict in msg.items():
for msg_name, message in msg_dict.items(): for msg_name, message in msg_dict.items():
AddOrIgnoreMessage(message) self.AddOrIgnoreMessage(message)
msgs_bd = bd_item.GetAllItemsTemplate(table_name)() table_name = self.m_Table.GetName()
msgs_bd = bd_item.GetAllItemsTemplate(self.m_Bot, table_name)()
if msgs_bd: if msgs_bd:
for m in msgs_bd: for m in msgs_bd:
name = m[1] name = m[1]
desc = m[2]
photo_id = m[3]
lang_id = m[6] lang_id = m[6]
lang_name = languages.GetLangName(lang_id) lang_name = self.GetModule(self.m_ParentModName).GetLangName(lang_id)
new_msg = user_messages.Message(name, m[2], lang_name, m[3], log.GetTimeNow()) self.m_BotMessages.CreateMessage(name, desc, self.m_Log.GetTimeNow(), a_MessagePhotoID = photo_id, a_MessageLang = lang_name)
if not msg.get(lang_name, None):
msg[lang_name] = {}
msg[lang_name][name] = new_msg
user_messages.UpdateSignal(log.GetTimeNow())
# Инициализация БД
def GetInitBDCommands():
return init_bd_cmds
def GetAccess():
return access.GetAccessForModule(module_name)
# Доступные кнопки
def GetModuleButtons():
return [keyboard.ButtonWithAccess(messages_button_name, user_access.AccessMode.VIEW, GetAccess())]
# Обработка кнопок
def RegisterHandlers(dp : Dispatcher):
defaul_keyboard_func = GetStartMessageKeyboardButtons
def RegisterSelectParent(a_ButtonName, access_mode):
a_PrefixBase = a_ButtonName
return bd_item_select.FirstSelectBDItemRegisterHandlers(dp, \
a_PrefixBase, \
a_ButtonName, \
languages.table_name, \
languages.key_name, \
languages.GetButtonNameAndKeyValueAndAccess, \
languages.select_language_message, \
languages.GetAccess, access_mode = access_mode\
)
# Стартовое сообщение
dp.register_message_handler(simple_message.SimpleMessageTemplate(MessagesOpen, defaul_keyboard_func, GetAccess), text = messages_button_name)
# Список сообщений
a_Prefix = RegisterSelectParent(list_message_button_name, user_access.AccessMode.VIEW)
bd_item_view.LastSelectAndShowBDItemRegisterHandlers(dp, \
a_Prefix, parent_id_field, \
table_name, key_name, \
ShowMessageTemplate(message_open_message), \
GetButtonNameAndKeyValueAndAccess, \
select_message_message, \
GetAccess, \
defaul_keyboard_func, \
access_mode = user_access.AccessMode.VIEW\
)
global select_messages_prefix
select_messages_prefix = a_Prefix
# Удаление сообщения
a_Prefix = RegisterSelectParent(del_message_button_name, user_access.AccessMode.DELETE)
bd_item_delete.DeleteBDItemRegisterHandlers(dp, \
a_Prefix, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
table_name, \
key_name, \
parent_id_field, \
MessagePreDelete, \
MessagePostDelete, \
GetButtonNameAndKeyValueAndAccess, \
select_message_message, \
GetAccess, \
defaul_keyboard_func\
)
# Добавление сообщения
a_Prefix = RegisterSelectParent(add_message_button_name, user_access.AccessMode.ADD)
bd_item_add.AddBDItem3RegisterHandlers(dp, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
FSMCreateMessage, \
FSMCreateMessage.name,\
FSMCreateMessage.desc, \
FSMCreateMessage.photo,\
AddBDItemFunc, \
SimpleMessageTemplate(message_create_name_message), \
SimpleMessageTemplate(message_create_desc_message), \
SimpleMessageTemplate(message_create_photo_message), \
SimpleMessageTemplate(message_success_create_message), \
a_Prefix,\
languages.table_name, \
languages.key_name, \
name_field, \
desc_field, \
photo_field, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
GetStartMessageKeyboardButtons\
)
def RegisterEdit(a_ButtonName, a_FSM, a_EditMessage, a_FieldName, a_FieldType, a_AccessMode = user_access.AccessMode.EDIT):
a_Prefix = RegisterSelectParent(a_ButtonName, a_AccessMode)
bd_item_edit.EditBDItemRegisterHandlers(dp, \
a_Prefix, \
a_FSM, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
message_select_to_edit_message, \
ShowMessageTemplate(a_EditMessage), \
ShowMessageTemplate(message_success_edit_message), \
table_name, \
key_name, \
parent_id_field, \
a_FieldName, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
edit_keyboard_func, \
access_mode = a_AccessMode, \
field_type = a_FieldType\
)
# Редактирование сообщения self.m_BotMessages.UpdateSignal(self.m_Log.GetTimeNow())
edit_keyboard_func = GetEditMessageKeyboardButtons
dp.register_message_handler(simple_message.InfoMessageTemplate(message_start_edit_message, edit_keyboard_func, GetAccess, access_mode = user_access.AccessMode.EDIT), text = edit_message_button_name)
RegisterEdit(edit_message_photo_button_name, FSMEditMessagePhotoItem, message_edit_photo_message, photo_field, bd_item.FieldType.photo) def OnChange(self):
RegisterEdit(edit_message_name_button_name, FSMEditMessageNameItem, message_edit_name_message, name_field, bd_item.FieldType.text) self.FlushMessages()
RegisterEdit(edit_message_desc_button_name, FSMEditMessageDescItem, message_edit_desc_message, desc_field, bd_item.FieldType.text)
RegisterEdit(edit_message_access_button_name, FSMEditMessageAccessItem, message_edit_access_message, access_field, bd_item.FieldType.text)

15
bot_modules/mod_agregator.py

@ -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()

25
bot_modules/mod_interface.py

@ -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

112
bot_modules/mod_simple_message.py

@ -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))
)

386
bot_modules/mod_table_operate.py

@ -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

384
bot_modules/needs.py

@ -3,16 +3,11 @@
# Потребности # Потребности
from bot_sys import bot_bd, log, keyboard, user_access from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import start, access, groups, projects, tasks, comments from bot_modules import mod_table_operate, mod_simple_message
from template import bd_item_view, simple_message, bd_item_delete, bd_item_edit, bd_item, bd_item_add, bd_item_select
from aiogram import types
from aiogram.dispatcher import FSMContext from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import Dispatcher
import sqlite3
class FSMCreateNeed(StatesGroup): class FSMCreateNeed(StatesGroup):
name = State() name = State()
@ -20,19 +15,15 @@ class FSMCreateNeed(StatesGroup):
photo = State() photo = State()
class FSMEditNeedPhotoItem(StatesGroup): class FSMEditNeedPhotoItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
class FSMEditNeedNameItem(StatesGroup): class FSMEditNeedNameItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
class FSMEditNeedDescItem(StatesGroup): class FSMEditNeedDescItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
class FSMEditNeedAccessItem(StatesGroup): class FSMEditNeedAccessItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
@ -47,340 +38,117 @@ access_field = 'needAccess'
create_datetime_field = 'needCreateDateTime' create_datetime_field = 'needCreateDateTime'
parent_id_field = 'taskID' parent_id_field = 'taskID'
init_bd_cmds = [f'''CREATE TABLE IF NOT EXISTS {table_name}( table = bd_table.Table(table_name, [
{key_name} INTEGER PRIMARY KEY, bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
{name_field} TEXT, bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
{desc_field} TEXT, bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{photo_field} TEXT, bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
{access_field} TEXT, bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
{create_datetime_field} TEXT, bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
{parent_id_field} INTEGER bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT),
)''', ])
f"INSERT OR IGNORE INTO module_access (modName, modAccess, itemDefaultAccess) VALUES ('{module_name}', '{user_access.user_access_group_new}=va', '{user_access.user_access_group_new}=va');"
] init_access = f'{user_access.user_access_group_new}=va'
select_needs_prefix = '' fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateNeed,
mod_table_operate.FSMs.EDIT_NAME: FSMEditNeedNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditNeedDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditNeedPhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditNeedAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения # Сообщения и кнопки
needs_button_name = "👉 Потребности" button_names = {
base_need_message = f''' mod_simple_message.ButtonNames.START: "👉 Потребности",
<b>{needs_button_name}</b> mod_table_operate.ButtonNames.LIST: "📃 Список потребностей",
mod_table_operate.ButtonNames.ADD: "☑ Добавить потребность",
''' mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать потребность",
mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение у потребности",
list_need_button_name = "📃 Список потребностей" mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название у потребности",
select_need_message = ''' 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: '''
error_find_proj_message = '''
Ошибка, потребность не найдена Ошибка, потребность не найдена
''' ''',
mod_table_operate.Messages.OPEN: f'''
need_open_message = f'''
<b>Потребность: #{name_field}</b> <b>Потребность: #{name_field}</b>
#{desc_field} #{desc_field}
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''' ''',
mod_table_operate.Messages.CREATE_NAME: '''
# Создание потребностей
add_need_button_name = "☑ Добавить потребность"
need_create_name_message = '''
Создание потребности. Шаг 1 Создание потребности. Шаг 1
Введите название потребности: Введите название потребности:
''' ''',
mod_table_operate.Messages.CREATE_DESC: '''
need_create_desc_message = '''
Создание потребности. Шаг 2 Создание потребности. Шаг 2
Введите описание потребности: Введите описание потребности:
''' ''',
mod_table_operate.Messages.CREATE_PHOTO: '''
need_create_photo_message = '''
Создание потребности. Шаг 3 Создание потребности. Шаг 3
Загрузите обложку для потребности (Фото): Загрузите обложку для потребности (Фото):
Она будет отображаться в её описании. Она будет отображаться в её описании.
''' ''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Потребность успешно добавлена!''',
need_success_create_message = '''✅ Потребность успешно добавлена!''' mod_table_operate.Messages.START_EDIT: '''
# Редактирование потребностей.
edit_need_button_name = "🛠 Редактировать потребность"
need_start_edit_message= '''
Пожалуйста, выберите действие: Пожалуйста, выберите действие:
''' ''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
need_select_to_edit_message = '''
Выберите потребность, которую вы хотите отредактировать. Выберите потребность, которую вы хотите отредактировать.
''' ''',
mod_table_operate.Messages.EDIT_PHOTO: '''
edit_need_photo_button_name = "☐ Изменить изображение у потребности"
need_edit_photo_message = '''
Загрузите новую обложку для потребности (Фото): Загрузите новую обложку для потребности (Фото):
Она будет отображаться в её описании. Она будет отображаться в её описании.
''' ''',
mod_table_operate.Messages.EDIT_NAME: f'''
edit_need_name_button_name = "≂ Изменить название у потребности"
need_edit_name_message = f'''
Текущее название потребности: Текущее название потребности:
#{name_field} #{name_field}
Введите новое название потребности: Введите новое название потребности:
''' ''',
mod_table_operate.Messages.EDIT_DESC: f'''
edit_need_desc_button_name = "𝌴 Изменить описание у потребности"
need_edit_desc_message = f'''
Текущее описание потребности: Текущее описание потребности:
#{desc_field} #{desc_field}
Введите новое описание потребности: Введите новое описание потребности:
''' ''',
mod_table_operate.Messages.EDIT_ACCESS: f'''
edit_need_access_button_name = "✋ Изменить доступ к потребности"
need_edit_access_message = f'''
Текущий доступ к потребности: Текущий доступ к потребности:
#{access_field} #{access_field}
{user_access.user_access_readme} {user_access.user_access_readme}
Введите новую строку доступа: Введите новую строку доступа:
''' ''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Потребность успешно отредактирован!''',
need_success_edit_message = '''✅ Потребность успешно отредактирована!''' mod_table_operate.Messages.SELECT_TO_DELETE: '''
# Удаление потребностей
del_need_button_name = "❌ Удалить потребность"
need_select_to_delete_message = '''
Выберите потребность, которую вы хотите удалить. Выберите потребность, которую вы хотите удалить.
Все сообщения в этой потребности так же будут удалены! Все комментарии в этой потребности так же будут удалены!
''' ''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Потребность успешно удалёна!''',
need_success_delete_message = '''✅ Потребность успешно удалена!''' }
# ---------------------------------------------------------
# Работа с кнопками
def GetEditNeedKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = GetModuleButtons() + [
keyboard.ButtonWithAccess(edit_need_photo_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_need_name_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_need_desc_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_need_access_button_name, user_access.AccessMode.ACCEES_EDIT, GetAccess()),
]
mods = [start]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetStartNeedKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = [
keyboard.ButtonWithAccess(list_need_button_name, user_access.AccessMode.VIEW, GetAccess()),
keyboard.ButtonWithAccess(add_need_button_name, user_access.AccessMode.ADD, GetAccess()),
keyboard.ButtonWithAccess(del_need_button_name, user_access.AccessMode.DELETE, GetAccess()),
keyboard.ButtonWithAccess(edit_need_button_name, user_access.AccessMode.EDIT, GetAccess())
]
mods = [start, projects, tasks, comments]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetViewItemInlineKeyboardTemplate(a_ItemID):
def GetViewItemInlineKeyboard(a_Message, a_UserGroups):
cur_buttons = [
keyboard.InlineButton(comments.list_comment_button_name, comments.select_comments_prefix, a_ItemID, GetAccess(), user_access.AccessMode.VIEW),
]
return keyboard.MakeInlineKeyboard(cur_buttons, a_UserGroups)
return GetViewItemInlineKeyboard
# ---------------------------------------------------------
# Обработка сообщений
# стартовое сообщение
async def NeedsOpen(a_Message : types.message, state = None):
return simple_message.WorkFuncResult(base_need_message)
def GetButtonNameAndKeyValueAndAccess(a_Item):
# needName needID needAccess
return a_Item[1], a_Item[0], a_Item[4]
def ShowMessageTemplate(a_StringMessage, keyboard_template_func = None):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 6):
return simple_message.WorkFuncResult(error_find_proj_message)
msg = a_StringMessage.\
replace(f'#{name_field}', a_Item[1]).\
replace(f'#{desc_field}', a_Item[2]).\
replace(f'#{create_datetime_field}', a_Item[5]).\
replace(f'#{access_field}', a_Item[4])
keyboard_func = None
if keyboard_template_func:
keyboard_func = keyboard_template_func(a_Item[0])
return simple_message.WorkFuncResult(msg, photo_id = a_Item[3], item_access = a_Item[4], keyboard_func = keyboard_func)
return ShowMessage
def SimpleMessageTemplate(a_StringMessage):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item):
return simple_message.WorkFuncResult(a_StringMessage)
return ShowMessage
# Удаление потребностей
async def NeedPreDelete(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 6):
return simple_message.WorkFuncResult(error_find_proj_message)
access = a_Item[4]
return simple_message.WorkFuncResult('', None, item_access = access)
async def NeedPostDelete(a_CallbackQuery : types.CallbackQuery, a_ItemID):
log.Success(f'Потребность №{a_ItemID} была удалена пользователем {a_CallbackQuery.from_user.id}.')
#TODO: удалить вложенные
return simple_message.WorkFuncResult(need_success_delete_message)
# ---------------------------------------------------------
# Работа с базой данных потребностей
def AddBDItemFunc(a_ItemData, a_UserID):
print(a_ItemData)
res, error = bot_bd.SQLRequestToBD(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], access.GetItemDefaultAccessForModule(module_name) + f";{a_UserID}=+", a_ItemData[parent_id_field]))
if error:
log.Error(f'Пользоватлель {a_UserID}. Ошибка добавления записи в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
else:
log.Success(f'Пользоватлель {a_UserID}. Добавлена запись в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
return res, error
# ---------------------------------------------------------
# API
# Инициализация БД
def GetInitBDCommands():
return init_bd_cmds
def GetAccess():
return access.GetAccessForModule(module_name)
# Доступные кнопки
def GetModuleButtons():
return [keyboard.ButtonWithAccess(needs_button_name, user_access.AccessMode.VIEW, GetAccess())]
# Обработка кнопок
def RegisterHandlers(dp : Dispatcher):
defaul_keyboard_func = GetStartNeedKeyboardButtons
def RegisterSelectParent(a_ButtonName, access_mode):
a_PrefixBase = a_ButtonName
a_Prefix = bd_item_select.FirstSelectBDItemRegisterHandlers(dp, \
a_PrefixBase, \
a_ButtonName, \
projects.table_name, \
projects.key_name, \
projects.GetButtonNameAndKeyValueAndAccess, \
projects.select_project_message, \
projects.GetAccess, \
access_mode = access_mode\
)
a_Prefix = bd_item_select.NextSelectBDItemRegisterHandlers(dp, \
a_Prefix, \
tasks.parent_id_field, \
tasks.table_name, \
tasks.key_name, \
tasks.GetButtonNameAndKeyValueAndAccess, \
tasks.select_task_message, \
tasks.GetAccess, \
access_mode = access_mode\
)
return a_Prefix
# Стартовое сообщение
dp.register_message_handler(simple_message.SimpleMessageTemplate(NeedsOpen, defaul_keyboard_func, GetAccess), text = needs_button_name)
# Список потребностей
a_Prefix = RegisterSelectParent(list_need_button_name, user_access.AccessMode.VIEW)
bd_item_view.LastSelectAndShowBDItemRegisterHandlers(dp, \
a_Prefix, parent_id_field, \
table_name, key_name, \
ShowMessageTemplate(need_open_message, GetViewItemInlineKeyboardTemplate), \
GetButtonNameAndKeyValueAndAccess, \
select_need_message, \
GetAccess, \
defaul_keyboard_func, \
access_mode = user_access.AccessMode.VIEW\
)
global select_needs_prefix
select_needs_prefix = a_Prefix
# Удаление потребностей
a_Prefix = RegisterSelectParent(del_need_button_name, user_access.AccessMode.DELETE)
bd_item_delete.DeleteBDItemRegisterHandlers(dp, \
a_Prefix, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
table_name, \
key_name, \
parent_id_field, \
NeedPreDelete, \
NeedPostDelete, \
GetButtonNameAndKeyValueAndAccess, \
select_need_message, \
GetAccess, \
defaul_keyboard_func\
)
# Добавление потребностей
a_Prefix = RegisterSelectParent(add_need_button_name, user_access.AccessMode.ADD)
bd_item_add.AddBDItem3RegisterHandlers(dp, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
FSMCreateNeed, \
FSMCreateNeed.name,\
FSMCreateNeed.desc, \
FSMCreateNeed.photo,\
AddBDItemFunc, \
SimpleMessageTemplate(need_create_name_message), \
SimpleMessageTemplate(need_create_desc_message), \
SimpleMessageTemplate(need_create_photo_message), \
SimpleMessageTemplate(need_success_create_message), \
a_Prefix,\
tasks.table_name, \
tasks.key_name, \
name_field, \
desc_field, \
photo_field, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
GetStartNeedKeyboardButtons\
)
def RegisterEdit(a_ButtonName, a_FSM, a_EditMessage, a_FieldName, a_FieldType, a_AccessMode = user_access.AccessMode.EDIT):
a_Prefix = RegisterSelectParent(a_ButtonName, a_AccessMode)
bd_item_edit.EditBDItemRegisterHandlers(dp, \
a_Prefix, \
a_FSM, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
need_select_to_edit_message, \
ShowMessageTemplate(a_EditMessage), \
ShowMessageTemplate(need_success_edit_message), \
table_name, \
key_name, \
parent_id_field, \
a_FieldName, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
edit_keyboard_func, \
access_mode = a_AccessMode, \
field_type = a_FieldType\
)
# Редактирование потребностей class ModuleNeeds(mod_table_operate.TableOperateModule):
edit_keyboard_func = GetEditNeedKeyboardButtons def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
dp.register_message_handler(simple_message.InfoMessageTemplate(need_start_edit_message, edit_keyboard_func, GetAccess, access_mode = user_access.AccessMode.EDIT), text = edit_need_button_name) 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)
RegisterEdit(edit_need_photo_button_name, FSMEditNeedPhotoItem, need_edit_photo_message, photo_field, bd_item.FieldType.photo) def GetName(self):
RegisterEdit(edit_need_name_button_name, FSMEditNeedNameItem, need_edit_name_message, name_field, bd_item.FieldType.text) return module_name
RegisterEdit(edit_need_desc_button_name, FSMEditNeedDescItem, need_edit_desc_message, desc_field, bd_item.FieldType.text)
RegisterEdit(edit_need_access_button_name, FSMEditNeedAccessItem, need_edit_access_message, access_field, bd_item.FieldType.text)

132
bot_modules/profile.py

@ -3,12 +3,9 @@
# Профиль пользователя # Профиль пользователя
from bot_sys import bot_bd, log, config, keyboard, user_access, user_messages from bot_sys import user_access, bot_bd, bd_table
from bot_modules import start, access, groups from bot_modules import mod_simple_message, groups, access, access_utils, groups_utils
from template import simple_message from template import bd_item, simple_message
from aiogram import types
from aiogram.dispatcher import Dispatcher
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
@ -24,30 +21,23 @@ language_code_field = 'userLanguageCode'
access_field = 'userAccess' access_field = 'userAccess'
create_datetime_field = 'createDateTime' create_datetime_field = 'createDateTime'
init_bd_cmds = [f"""CREATE TABLE IF NOT EXISTS {table_name}( table = bd_table.Table(table_name, [
{key_name} INTEGER, bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
{name_field} TEXT, bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
{name1_field} TEXT, bd_table.TableField(name1_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{name2_field} TEXT, bd_table.TableField(name2_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{is_bot_field} TEXT, bd_table.TableField(is_bot_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{language_code_field} TEXT, bd_table.TableField(language_code_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{access_field} TEXT, bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
{create_datetime_field} TEXT, bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
UNIQUE({key_name}) ])
);""",
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}=+');" button_names = {
] mod_simple_message.ButtonNames.START: "📰 Профиль",
}
def MSG(a_MessageName, a_MessageDesc):
def UpdateMSG(a_Message : user_messages.Message): messages = {
print(a_Message.m_MessageName, a_Message.m_MessageDesc) mod_simple_message.Messages.START: f'''
globals()[a_Message.m_MessageName] = a_Message
user_messages.MSG(a_MessageName, a_MessageDesc, UpdateMSG, log.GetTimeNow())
# ---------------------------------------------------------
# Сообщения
MSG('profile_message', f'''
<b>📰 Профиль:</b> <b>📰 Профиль:</b>
<b>ID:</b> #{key_name} <b>ID:</b> #{key_name}
@ -56,73 +46,53 @@ MSG('profile_message', f'''
<b>Имя2:</b> #{name2_field} <b>Имя2:</b> #{name2_field}
<b>Код языка:</b> #{language_code_field} <b>Код языка:</b> #{language_code_field}
<b>Дата добавления:</b> #{create_datetime_field} <b>Дата добавления:</b> #{create_datetime_field}
''') ''',
}
user_profile_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):
super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
def GetStartKeyboardButtons(a_Message, a_UserGroups): def GetInitBDCommands(self):
mods = [start] return super(). GetInitBDCommands() + [
return keyboard.MakeKeyboardForMods(mods, a_UserGroups) table.GetInitTableRequest(),
]
# --------------------------------------------------------- def GetName(self):
# Обработка сообщений return module_name
async def ProfileOpen(a_Message, state = None): # Основной обработчик главного сообщения
user_info = GetUserInfo(a_Message.from_user.id) async def StartMessageHandler(self, a_Message, state = None):
msg = profile_message user_info = GetUserInfo(self.m_Bot, a_Message.from_user.id)
lang = str(a_Message.from_user.language_code)
if not user_info is None: if not user_info is None:
msg = str(msg).\ msg = self.GetMessage(mod_simple_message.Messages.START)
replace(f'#{key_name}', str(user_info[0])).\ msg = msg.GetMessageForLang(lang).StaticCopy()
replace(f'#{name_field}', str(user_info[1])).\ msg.UpdateDesc(table.ReplaceAllFieldTags(msg.GetDesc(), user_info))
replace(f'#{name1_field}', str(user_info[2])).\ return simple_message.WorkFuncResult(msg, item_access = str(user_info[table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)]))
replace(f'#{name2_field}', str(user_info[3])).\ return await super().StartMessageHandler(a_Message, state)
replace(f'#{is_bot_field}', str(user_info[4])).\
replace(f'#{language_code_field}', str(user_info[5])).\
replace(f'#{access_field}', str(user_info[6])).\
replace(f'#{create_datetime_field}', str(user_info[7]))
return simple_message.WorkFuncResult(msg, item_access = str(user_info[6]))
return simple_message.WorkFuncResult(msg)
# ---------------------------------------------------------
# Работа с базой данных пользователей # Работа с базой данных пользователей
# Добавление пользователя, если он уже есть, то игнорируем # Добавление пользователя, если он уже есть, то игнорируем
def AddUser(a_UserID, a_UserName, a_UserName1, a_UserName2, a_UserIsBot, a_LanguageCode): def AddUser(a_Bot, a_UserID, a_UserName, a_UserName1, a_UserName2, a_UserIsBot, a_LanguageCode):
bot_bd.SQLRequestToBD(f"INSERT OR IGNORE INTO users ({key_name}, {name_field}, {name1_field}, {name2_field}, {is_bot_field}, {language_code_field}, {access_field}, {create_datetime_field}) VALUES (?, ?, ?, ?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()});", a_Bot.SQLRequest(f"INSERT OR IGNORE INTO users ({key_name}, {name_field}, {name1_field}, {name2_field}, {is_bot_field}, {language_code_field}, {access_field}, {create_datetime_field}) VALUES (?, ?, ?, ?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()});",
commit=True, param = (a_UserID, a_UserName, a_UserName1, a_UserName2, a_UserIsBot, a_LanguageCode, access.GetItemDefaultAccessForModule(module_name))) commit=True, param = (a_UserID, a_UserName, a_UserName1, a_UserName2, a_UserIsBot, a_LanguageCode, access_utils.GetItemDefaultAccessForModule(a_Bot, module_name)))
user_groups = groups.GetUserGroupData(a_UserID) user_groups = groups_utils.GetUserGroupData(a_Bot, a_UserID)
# Если пользователь не состоит ни в одной группе, то добавляем его в группу user_access.user_access_group_new # Если пользователь не состоит ни в одной группе, то добавляем его в группу user_access.user_access_group_new
if len(user_groups.group_names_list) == 0: if len(user_groups.group_names_list) == 0:
new_group_id = bot_bd.SQLRequestToBD(f'SELECT {groups.key_table_groups_name} FROM {groups.table_groups_name} WHERE {groups.name_table_groups_field} = ?', new_group_id = a_Bot.SQLRequest(f'SELECT {groups.key_table_groups_name} FROM {groups.table_groups_name} WHERE {groups.name_table_groups_field} = ?',
param = [user_access.user_access_group_new]) param = [user_access.user_access_group_new])
if new_group_id and new_group_id[0]: if new_group_id and new_group_id[0]:
bot_bd.SQLRequestToBD(f"INSERT OR IGNORE INTO {groups.table_user_in_groups_name} ({groups.user_id_field}, {groups.key_table_groups_name}, {groups.access_field}, {groups.create_datetime_field}) VALUES (?, ?, ?, {bot_bd.GetBDDateTimeNow()});", a_Bot.SQLRequest(f"INSERT OR IGNORE INTO {groups.table_user_in_groups_name} ({groups.user_id_field}, {groups.key_table_groups_name}, {groups.access_field}, {groups.create_datetime_field}) VALUES (?, ?, ?, {bot_bd.GetBDDateTimeNow()});",
commit=True, param = (a_UserID, new_group_id[0][0], access.GetItemDefaultAccessForModule(module_name))) commit=True, param = (a_UserID, new_group_id[0][0], access_utils.GetItemDefaultAccessForModule(a_Bot, module_name)))
def GetUserInfo(a_UserID): def GetUserInfo(a_Bot, a_UserID):
user_info = bot_bd.SQLRequestToBD('SELECT * FROM users WHERE user_id = ?', param = [a_UserID]) user_info = a_Bot.SQLRequest('SELECT * FROM users WHERE user_id = ?', param = [a_UserID])
if len(user_info) != 0: if len(user_info) != 0:
return user_info[0] return user_info[0]
return None return None
# ---------------------------------------------------------
# API
# Инициализация БД
def GetInitBDCommands():
return init_bd_cmds
def GetAccess():
return access.GetAccessForModule(module_name)
# Доступные кнопки
def GetModuleButtons():
return [keyboard.ButtonWithAccess(user_profile_button_name, user_access.AccessMode.VIEW, GetAccess())]
# Обработка кнопок
def RegisterHandlers(dp : Dispatcher):
dp.register_message_handler(simple_message.SimpleMessageTemplate(ProfileOpen, GetStartKeyboardButtons, GetAccess), text = user_profile_button_name)

352
bot_modules/projects.py

@ -3,16 +3,11 @@
# Проекты # Проекты
from bot_sys import bot_bd, log, keyboard, user_access, user_messages from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import start, access, groups, tasks, needs, comments from bot_modules import mod_table_operate, mod_simple_message
from template import bd_item_view, simple_message, bd_item_delete, bd_item_edit, bd_item, bd_item_add
from aiogram import types
from aiogram.dispatcher import FSMContext from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import Dispatcher
import sqlite3
class FSMCreateProject(StatesGroup): class FSMCreateProject(StatesGroup):
name = State() name = State()
@ -25,7 +20,7 @@ class FSMEditProjectPhotoItem(StatesGroup):
class FSMEditProjectNameItem(StatesGroup): class FSMEditProjectNameItem(StatesGroup):
item_field = State() item_field = State()
class FSMEditProjectDeskItem(StatesGroup): class FSMEditProjectDescItem(StatesGroup):
item_field = State() item_field = State()
class FSMEditProjectAccessItem(StatesGroup): class FSMEditProjectAccessItem(StatesGroup):
@ -42,314 +37,123 @@ photo_field = 'projectPhoto'
access_field = 'projectAccess' access_field = 'projectAccess'
create_datetime_field = 'projectCreateDateTime' create_datetime_field = 'projectCreateDateTime'
init_bd_cmds = [f'''CREATE TABLE IF NOT EXISTS {table_name}( table = bd_table.Table(table_name, [
{key_name} INTEGER PRIMARY KEY, bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
{name_field} TEXT, bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
{desc_field} TEXT, bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{photo_field} TEXT, bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
{access_field} TEXT, bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
{create_datetime_field} TEXT bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
)''', ])
f"INSERT OR IGNORE INTO module_access (modName, modAccess, itemDefaultAccess) VALUES ('{module_name}', '{user_access.user_access_group_new}=va', '{user_access.user_access_group_new}=va');"
] init_access = f'{user_access.user_access_group_new}=va'
def MSG(a_MessageName, a_MessageDesc): fsm = {
def UpdateMSG(a_Message : user_messages.Message): mod_table_operate.FSMs.CREATE: FSMCreateProject,
print(a_Message.m_MessageName, a_Message.m_MessageDesc) mod_table_operate.FSMs.EDIT_NAME: FSMEditProjectNameItem,
globals()[a_Message.m_MessageName] = a_Message mod_table_operate.FSMs.EDIT_DESC: FSMEditProjectDescItem,
user_messages.MSG(a_MessageName, a_MessageDesc, UpdateMSG, log.GetTimeNow()) mod_table_operate.FSMs.EDIT_PHOTO: FSMEditProjectPhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditProjectAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения # Сообщения и кнопки
projects_button_name = "🟥 Проекты" button_names = {
MSG('base_project_message',''' mod_simple_message.ButtonNames.START: "🟥 Проекты",
<b>🟥 Проекты</b> mod_table_operate.ButtonNames.LIST: "📃 Список проектов",
mod_table_operate.ButtonNames.ADD: "✅ Добавить проект",
''') mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать проект",
mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение в проекте",
list_project_button_name = "📃 Список проектов" mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название в проекте",
MSG('select_project_message',''' 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: '''
MSG('error_find_proj_message','''
Ошибка, проект не найден Ошибка, проект не найден
''') ''',
mod_table_operate.Messages.OPEN: f'''
MSG('project_open_message',f'''
<b>Проект: #{name_field}</b> <b>Проект: #{name_field}</b>
#{desc_field} #{desc_field}
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''') ''',
mod_table_operate.Messages.CREATE_NAME: '''
# Создание проекта
add_project_button_name = "✅ Добавить проект"
MSG('project_create_name_message','''
Создание проекта. Шаг 1 Создание проекта. Шаг 1
Введите название проекта: Введите название проекта:
''') ''',
mod_table_operate.Messages.CREATE_DESC: '''
MSG('project_create_desc_message','''
Создание проекта. Шаг 2 Создание проекта. Шаг 2
Введите описание проекта: Введите описание проекта:
''') ''',
mod_table_operate.Messages.CREATE_PHOTO: '''
MSG('project_create_photo_message','''
Создание проекта. Шаг 3 Создание проекта. Шаг 3
Загрузите обложку для проекта (Фото): Загрузите обложку для проекта (Фото):
Она будет отображаться в его описании. Она будет отображаться в его описании.
''') ''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Проект успешно добавлен!''',
MSG('project_success_create_message','''✅ Проект успешно добавлен!''') mod_table_operate.Messages.START_EDIT: '''
# Редактирование проекта.
edit_project_button_name = "🛠 Редактировать проект"
MSG('project_start_edit_message', '''
Пожалуйста, выберите действие: Пожалуйста, выберите действие:
''') ''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
MSG('project_select_to_edit_message','''
Выберите проект, который вы хотите отредактировать. Выберите проект, который вы хотите отредактировать.
''') ''',
mod_table_operate.Messages.EDIT_PHOTO: '''
edit_project_photo_button_name = "☐ Изменить изображение в проекте"
MSG('project_edit_photo_message','''
Загрузите новую обложку для проекта (Фото): Загрузите новую обложку для проекта (Фото):
Она будет отображаться в его описании. Она будет отображаться в его описании.
''') ''',
mod_table_operate.Messages.EDIT_NAME: f'''
edit_project_name_button_name = "≂ Изменить название в проекте"
MSG('project_edit_name_message',f'''
Текущее название проекта: Текущее название проекта:
#{name_field} #{name_field}
Введите новое название проекта: Введите новое название проекта:
''') ''',
mod_table_operate.Messages.EDIT_DESC: f'''
edit_project_desc_button_name = "𝌴 Изменить описание в проекте"
MSG('project_edit_desc_message',f'''
Текущее описание проекта: Текущее описание проекта:
#{desc_field} #{desc_field}
Введите новое описание проекта: Введите новое описание проекта:
''') ''',
mod_table_operate.Messages.EDIT_ACCESS: f'''
edit_project_access_button_name = "✋ Изменить доступ к проекту"
MSG('project_edit_access_message',f'''
Текущий доступ к проекту: Текущий доступ к проекту:
#{access_field} #{access_field}
{user_access.user_access_readme} {user_access.user_access_readme}
Введите новую строку доступа: Введите новую строку доступа:
''') ''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Проект успешно отредактирован!''',
MSG('project_success_edit_message','''✅ Проект успешно отредактирован!''') mod_table_operate.Messages.SELECT_TO_DELETE: '''
# Удаление проекта
del_project_button_name = "❌ Удалить проект"
MSG('project_select_to_delete_message','''
Выберите проект, который вы хотите удалить. Выберите проект, который вы хотите удалить.
Все задачи и потребности в этом проекте так же будут удалены! Все задачи и потребности в этом проекте так же будут удалены!
''') ''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Проект успешно удалён!''',
MSG('project_success_delete_message','''✅ Проект успешно удалён!''') }
# ---------------------------------------------------------
# Работа с кнопками
def GetEditProjectKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = GetModuleButtons() + [
keyboard.ButtonWithAccess(edit_project_photo_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_project_name_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_project_desc_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_project_access_button_name, user_access.AccessMode.ACCEES_EDIT, GetAccess()),
]
mods = [start]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetStartProjectKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = [
keyboard.ButtonWithAccess(list_project_button_name, user_access.AccessMode.VIEW, GetAccess()),
keyboard.ButtonWithAccess(add_project_button_name, user_access.AccessMode.ADD, GetAccess()),
keyboard.ButtonWithAccess(del_project_button_name, user_access.AccessMode.DELETE, GetAccess()),
keyboard.ButtonWithAccess(edit_project_button_name, user_access.AccessMode.EDIT, GetAccess())
]
mods = [start, tasks, needs, comments]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetViewItemInlineKeyboardTemplate(a_ItemID):
def GetViewItemInlineKeyboard(a_Message, a_UserGroups):
cur_buttons = [
keyboard.InlineButton(tasks.list_task_button_name, tasks.select_tasks_prefix, a_ItemID, GetAccess(), user_access.AccessMode.VIEW),
]
return keyboard.MakeInlineKeyboard(cur_buttons, a_UserGroups)
return GetViewItemInlineKeyboard
# ---------------------------------------------------------
# Обработка сообщений
# стартовое сообщение class ModuleProjects(mod_table_operate.TableOperateModule):
async def ProjectsOpen(a_Message : types.message, state = None): def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
return simple_message.WorkFuncResult(base_project_message) 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 GetButtonNameAndKeyValueAndAccess(a_Item): def GetName(self):
# projectName projectID projectAccess return module_name
return a_Item[1], a_Item[0], a_Item[4]
def ShowMessageTemplate(a_StringMessage, keyboard_template_func = None): def GetModuleButtons(self):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item): return super().GetModuleButtons() + [
if (len(a_Item) < 6): keyboard.ButtonWithAccess(self.GetButton(mod_table_operate.ButtonNames.LIST), user_access.AccessMode.VIEW, self.GetAccess()),
return simple_message.WorkFuncResult(error_find_proj_message)
msg = str(a_StringMessage).\
replace(f'#{name_field}', a_Item[1]).\
replace(f'#{desc_field}', a_Item[2]).\
replace(f'#{create_datetime_field}', a_Item[5]).\
replace(f'#{access_field}', a_Item[4])
keyboard_func = None
if keyboard_template_func:
keyboard_func = keyboard_template_func(a_Item[0])
return simple_message.WorkFuncResult(msg, photo_id = a_Item[3], item_access = a_Item[4], keyboard_func = keyboard_func)
return ShowMessage
def SimpleMessageTemplate(a_StringMessage):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item):
return simple_message.WorkFuncResult(a_StringMessage)
return ShowMessage
# Удаление проекта
async def ProjectPreDelete(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 6):
return simple_message.WorkFuncResult(error_find_proj_message)
access = a_Item[4]
return simple_message.WorkFuncResult('', None, item_access = access)
async def ProjectPostDelete(a_CallbackQuery : types.CallbackQuery, a_ItemID):
log.Success(f'Проект №{a_ItemID} был удалён пользователем {a_CallbackQuery.from_user.id}.')
#TODO: удалить вложенные
return simple_message.WorkFuncResult(project_success_delete_message)
# ---------------------------------------------------------
# Работа с базой данных проектов
def AddBDItemFunc(a_ItemData, a_UserID):
res, error = bot_bd.SQLRequestToBD(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], access.GetItemDefaultAccessForModule(module_name) + f";{a_UserID}=+"))
if error:
log.Error(f'Пользоватлель {a_UserID}. Ошибка добавления записи в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
else:
log.Success(f'Пользоватлель {a_UserID}. Добавлена запись в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
return res, error
# ---------------------------------------------------------
# API
# Инициализация БД
def GetInitBDCommands():
return init_bd_cmds
def GetAccess():
return access.GetAccessForModule(module_name)
# Доступные кнопки
def GetModuleButtons():
return [
keyboard.ButtonWithAccess(projects_button_name, user_access.AccessMode.VIEW, GetAccess()),
keyboard.ButtonWithAccess(list_project_button_name, user_access.AccessMode.VIEW, GetAccess()),
] ]
# Обработка кнопок
def RegisterHandlers(dp : Dispatcher):
defaul_keyboard_func = GetStartProjectKeyboardButtons
# Список проектов
dp.register_message_handler(simple_message.SimpleMessageTemplate(ProjectsOpen, defaul_keyboard_func, GetAccess), text = projects_button_name)
bd_item_view.FirstSelectAndShowBDItemRegisterHandlers(dp, \
list_project_button_name, \
table_name, \
key_name, \
ShowMessageTemplate(project_open_message, GetViewItemInlineKeyboardTemplate), \
GetButtonNameAndKeyValueAndAccess, \
select_project_message, \
GetAccess, \
defaul_keyboard_func\
)
# Удаление проекта
bd_item_delete.DeleteBDItemRegisterHandlers(dp, \
None, \
bd_item.GetCheckForTextFunc(del_project_button_name), \
table_name, \
key_name, \
None, \
ProjectPreDelete, \
ProjectPostDelete, \
GetButtonNameAndKeyValueAndAccess, \
select_project_message, \
GetAccess, \
defaul_keyboard_func\
)
# Добавление проекта
bd_item_add.AddBDItem3RegisterHandlers(dp, \
bd_item.GetCheckForTextFunc(add_project_button_name), \
FSMCreateProject,\
FSMCreateProject.name,\
FSMCreateProject.desc, \
FSMCreateProject.photo,\
AddBDItemFunc, \
SimpleMessageTemplate(project_create_name_message), \
SimpleMessageTemplate(project_create_desc_message), \
SimpleMessageTemplate(project_create_photo_message), \
SimpleMessageTemplate(project_success_create_message), \
None,\
None, \
None, \
name_field, \
desc_field, \
photo_field, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
GetStartProjectKeyboardButtons\
)
# Редактирование проекта
edit_keyboard_func = GetEditProjectKeyboardButtons
def RegisterEdit(a_ButtonName, a_FSM, a_EditMessage, a_FieldName, a_FieldType, a_AccessMode = user_access.AccessMode.EDIT):
bd_item_edit.EditBDItemRegisterHandlers(dp, \
None, \
a_FSM, \
bd_item.GetCheckForTextFunc(a_ButtonName), \
project_select_to_edit_message, \
ShowMessageTemplate(a_EditMessage), \
ShowMessageTemplate(project_success_edit_message), \
table_name, \
key_name, \
None, \
a_FieldName, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
edit_keyboard_func, \
access_mode = a_AccessMode, \
field_type = a_FieldType\
)
dp.register_message_handler(simple_message.InfoMessageTemplate(project_start_edit_message, edit_keyboard_func, GetAccess, access_mode = user_access.AccessMode.EDIT), text = edit_project_button_name)
RegisterEdit(edit_project_photo_button_name, FSMEditProjectPhotoItem, project_edit_photo_message, photo_field, bd_item.FieldType.photo)
RegisterEdit(edit_project_name_button_name, FSMEditProjectNameItem, project_edit_name_message, name_field, bd_item.FieldType.text)
RegisterEdit(edit_project_desc_button_name, FSMEditProjectDeskItem, project_edit_desc_message, desc_field, bd_item.FieldType.text)
RegisterEdit(edit_project_access_button_name, FSMEditProjectAccessItem, project_edit_access_message, access_field, bd_item.FieldType.text)

84
bot_modules/start.py

@ -3,76 +3,50 @@
# Стартовое меню # Стартовое меню
from bot_sys import log, config, keyboard, user_access, user_messages from bot_sys import user_access
from bot_modules import profile, projects, groups, access, backup, languages from bot_modules import mod_simple_message, profile
from template import simple_message from template import bd_item
from aiogram.dispatcher import Dispatcher
def MSG(a_MessageName, a_MessageDesc):
def UpdateMSG(a_Message : user_messages.Message):
print(a_Message.m_MessageName, a_Message.m_MessageDesc)
globals()[a_Message.m_MessageName] = a_Message
user_messages.MSG(a_MessageName, a_MessageDesc, UpdateMSG, log.GetTimeNow())
# ---------------------------------------------------------
# БД
module_name = 'start' module_name = 'start'
init_bd_cmds = [ button_names = {
f"INSERT OR IGNORE INTO module_access (modName, modAccess, itemDefaultAccess) VALUES ('{module_name}', '{user_access.user_access_group_all}=+', '{user_access.user_access_group_all}=+');" mod_simple_message.ButtonNames.START: "☰ Главное меню",
] }
# ---------------------------------------------------------
# Сообщения
MSG('start_message', ''' messages = {
mod_simple_message.Messages.START: f'''
<b>Добро пожаловать!</b> <b>Добро пожаловать!</b>
Выберите возможные действия на кнопках ниже ''' Выберите возможные действия на кнопках ниже ''',
) }
start_menu_button_name = "☰ Главное меню"
# --------------------------------------------------------- init_access = f'{user_access.user_access_group_all}=+'
# Работа с кнопками
def GetStartKeyboardButtons(a_Message, a_UserGroups): class ModuleStart(mod_simple_message.SimpleMessageModule):
mods = [profile, projects, groups, access, backup, languages] def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
return keyboard.MakeKeyboardForMods(mods, a_UserGroups) super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
# --------------------------------------------------------- def GetName(self):
# Обработка сообщений return module_name
# Первичное привестивие # Основной обработчик главного сообщения
async def StartMenu(a_Message, state = None): async def StartMessageHandler(self, a_Message, state = None):
user_id = str(a_Message.from_user.id) user_id = str(a_Message.from_user.id)
user_name = str(a_Message.from_user.username) user_name = str(a_Message.from_user.username)
first_name = str(a_Message.from_user.first_name) first_name = str(a_Message.from_user.first_name)
last_name = str(a_Message.from_user.last_name) last_name = str(a_Message.from_user.last_name)
is_bot = str(a_Message.from_user.is_bot) is_bot = str(a_Message.from_user.is_bot)
language_code = str(a_Message.from_user.language_code) 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(self.m_Bot, user_id, user_name, first_name, last_name, is_bot, language_code)
log.Info(f'Пользователь {user_id} {user_name} авторизовался в боте. Полные данные {a_Message.from_user}.') self.m_Log.Info(f'Пользователь {user_id} {user_name} авторизовался в боте. Полные данные {a_Message.from_user}.')
return simple_message.WorkFuncResult(start_message) return await super().StartMessageHandler(a_Message, state)
# --------------------------------------------------------- def RegisterHandlers(self):
# API super().RegisterHandlers()
self.m_Bot.RegisterMessageHandler(
# Инициализация БД self.m_StartMessageHandler,
def GetInitBDCommands(): None,
return init_bd_cmds commands = ['start']
)
def GetAccess():
return access.GetAccessForModule(module_name)
# Имена доступных кнопок
def GetModuleButtons():
return [keyboard.ButtonWithAccess(start_menu_button_name, user_access.AccessMode.VIEW, GetAccess())]
# Обработка кнопок
def RegisterHandlers(dp : Dispatcher):
dp.register_message_handler(simple_message.SimpleMessageTemplate(StartMenu, GetStartKeyboardButtons, GetAccess), commands = ['start'])
dp.register_message_handler(simple_message.SimpleMessageTemplate(StartMenu, GetStartKeyboardButtons, GetAccess), text = start_menu_button_name)

371
bot_modules/tasks.py

@ -3,16 +3,11 @@
# Задачи # Задачи
from bot_sys import bot_bd, log, keyboard, user_access from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import start, access, groups, projects, needs, comments from bot_modules import mod_table_operate, mod_simple_message
from template import bd_item_view, simple_message, bd_item_delete, bd_item_edit, bd_item, bd_item_add, bd_item_select
from aiogram import types
from aiogram.dispatcher import FSMContext from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import Dispatcher
import sqlite3
class FSMCreateTask(StatesGroup): class FSMCreateTask(StatesGroup):
name = State() name = State()
@ -20,19 +15,15 @@ class FSMCreateTask(StatesGroup):
photo = State() photo = State()
class FSMEditTaskPhotoItem(StatesGroup): class FSMEditTaskPhotoItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
class FSMEditTaskNameItem(StatesGroup): class FSMEditTaskNameItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
class FSMEditTaskDescItem(StatesGroup): class FSMEditTaskDescItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
class FSMEditTaskAccessItem(StatesGroup): class FSMEditTaskAccessItem(StatesGroup):
item_id = State()
item_field = State() item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
@ -47,327 +38,117 @@ access_field = 'taskAccess'
create_datetime_field = 'taskCreateDateTime' create_datetime_field = 'taskCreateDateTime'
parent_id_field = 'projectID' parent_id_field = 'projectID'
init_bd_cmds = [f'''CREATE TABLE IF NOT EXISTS {table_name}( table = bd_table.Table(table_name, [
{key_name} INTEGER PRIMARY KEY, bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
{name_field} TEXT, bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
{desc_field} TEXT, bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
{photo_field} TEXT, bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
{access_field} TEXT, bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
{create_datetime_field} TEXT, bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
{parent_id_field} INTEGER bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT),
)''', ])
f"INSERT OR IGNORE INTO module_access (modName, modAccess, itemDefaultAccess) VALUES ('{module_name}', '{user_access.user_access_group_new}=va', '{user_access.user_access_group_new}=va');"
] init_access = f'{user_access.user_access_group_new}=va'
select_tasks_prefix = '' fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateTask,
mod_table_operate.FSMs.EDIT_NAME: FSMEditTaskNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditTaskDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditTaskPhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditTaskAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения # Сообщения и кнопки
tasks_button_name = "✎ Задачи" button_names = {
base_task_message = ''' mod_simple_message.ButtonNames.START: "✎ Задачи",
<b> Задачи</b> mod_table_operate.ButtonNames.LIST: "📃 Список задач",
mod_table_operate.ButtonNames.ADD: "☑ Добавить задачу",
''' mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать задачу",
mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение у задачи",
list_task_button_name = "📃 Список задач" mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название у задачи",
select_task_message = ''' 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: '''
error_find_proj_message = '''
Ошибка, задача не найдена Ошибка, задача не найдена
''' ''',
mod_table_operate.Messages.OPEN: f'''
task_open_message = f'''
<b>Задача: #{name_field}</b> <b>Задача: #{name_field}</b>
#{desc_field} #{desc_field}
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''' ''',
mod_table_operate.Messages.CREATE_NAME: '''
# Создание задачи
add_task_button_name = "☑ Добавить задачу"
task_create_name_message = '''
Создание задачи. Шаг 1 Создание задачи. Шаг 1
Введите название задачи: Введите название задачи:
''' ''',
mod_table_operate.Messages.CREATE_DESC: '''
task_create_desc_message = '''
Создание задачи. Шаг 2 Создание задачи. Шаг 2
Введите описание задачи: Введите описание задачи:
''' ''',
mod_table_operate.Messages.CREATE_PHOTO: '''
task_create_photo_message = '''
Создание задачи. Шаг 3 Создание задачи. Шаг 3
Загрузите обложку для задачи (Фото): Загрузите обложку для задачи (Фото):
Она будет отображаться в её описании. Она будет отображаться в её описании.
''' ''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Задача успешно добавлена!''',
task_success_create_message = '''✅ Задача успешно добавлена!''' mod_table_operate.Messages.START_EDIT: '''
# Редактирование задачи.
edit_task_button_name = "🛠 Редактировать задачу"
task_start_edit_message= '''
Пожалуйста, выберите действие: Пожалуйста, выберите действие:
''' ''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
task_select_to_edit_message = '''
Выберите задачу, которую вы хотите отредактировать. Выберите задачу, которую вы хотите отредактировать.
''' ''',
mod_table_operate.Messages.EDIT_PHOTO: '''
edit_task_photo_button_name = "☐ Изменить изображение у задачи"
task_edit_photo_message = '''
Загрузите новую обложку для задачи (Фото): Загрузите новую обложку для задачи (Фото):
Она будет отображаться в её описании. Она будет отображаться в её описании.
''' ''',
mod_table_operate.Messages.EDIT_NAME: f'''
edit_task_name_button_name = "≂ Изменить название у задачи"
task_edit_name_message = f'''
Текущее название задачи: Текущее название задачи:
#{name_field} #{name_field}
Введите новое название задачи: Введите новое название задачи:
''' ''',
mod_table_operate.Messages.EDIT_DESC: f'''
edit_task_desc_button_name = "𝌴 Изменить описание у задачи"
task_edit_desc_message = f'''
Текущее описание задачи: Текущее описание задачи:
#{desc_field} #{desc_field}
Введите новое описание задачи: Введите новое описание задачи:
''' ''',
mod_table_operate.Messages.EDIT_ACCESS: f'''
edit_task_access_button_name = "✋ Изменить доступ к задаче"
task_edit_access_message = f'''
Текущий доступ к задаче: Текущий доступ к задаче:
#{access_field} #{access_field}
{user_access.user_access_readme} {user_access.user_access_readme}
Введите новую строку доступа: Введите новую строку доступа:
''' ''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Задача успешно отредактирован!''',
task_success_edit_message = '''✅ Задача успешно отредактирована!''' mod_table_operate.Messages.SELECT_TO_DELETE: '''
# Удаление задачи
del_task_button_name = "❌ Удалить задачу"
task_select_to_delete_message = '''
Выберите задачу, которую вы хотите удалить. Выберите задачу, которую вы хотите удалить.
Все потребности в этой задачае так же будут удалены! Все потребности в этой задаче так же будут удалены!
''' ''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Задача успешно удалёна!''',
task_success_delete_message = '''✅ Задача успешно удалена!''' }
# ---------------------------------------------------------
# Работа с кнопками
def GetEditTaskKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = GetModuleButtons() + [
keyboard.ButtonWithAccess(edit_task_photo_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_task_name_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_task_desc_button_name, user_access.AccessMode.EDIT, GetAccess()),
keyboard.ButtonWithAccess(edit_task_access_button_name, user_access.AccessMode.ACCEES_EDIT, GetAccess()),
]
mods = [start]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetStartTaskKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = [
keyboard.ButtonWithAccess(list_task_button_name, user_access.AccessMode.VIEW, GetAccess()),
keyboard.ButtonWithAccess(add_task_button_name, user_access.AccessMode.ADD, GetAccess()),
keyboard.ButtonWithAccess(del_task_button_name, user_access.AccessMode.DELETE, GetAccess()),
keyboard.ButtonWithAccess(edit_task_button_name, user_access.AccessMode.EDIT, GetAccess())
]
mods = [start, projects, needs, comments]
return keyboard.MakeKeyboard(keyboard.GetButtons(mods) + cur_buttons, a_UserGroups)
def GetViewItemInlineKeyboardTemplate(a_ItemID):
def GetViewItemInlineKeyboard(a_Message, a_UserGroups):
cur_buttons = [
keyboard.InlineButton(needs.list_need_button_name, needs.select_needs_prefix, a_ItemID, GetAccess(), user_access.AccessMode.VIEW),
]
return keyboard.MakeInlineKeyboard(cur_buttons, a_UserGroups)
return GetViewItemInlineKeyboard
# ---------------------------------------------------------
# Обработка сообщений
# стартовое сообщение
async def TasksOpen(a_Message : types.message, state = None):
return simple_message.WorkFuncResult(base_task_message)
def GetButtonNameAndKeyValueAndAccess(a_Item):
# taskName taskID taskAccess
return a_Item[1], a_Item[0], a_Item[4]
def ShowMessageTemplate(a_StringMessage, keyboard_template_func = None):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 6):
return simple_message.WorkFuncResult(error_find_proj_message)
msg = a_StringMessage.\
replace(f'#{name_field}', a_Item[1]).\
replace(f'#{desc_field}', a_Item[2]).\
replace(f'#{create_datetime_field}', a_Item[5]).\
replace(f'#{access_field}', a_Item[4])
keyboard_func = None
if keyboard_template_func:
keyboard_func = keyboard_template_func(a_Item[0])
return simple_message.WorkFuncResult(msg, photo_id = a_Item[3], item_access = a_Item[4], keyboard_func = keyboard_func)
return ShowMessage
def SimpleMessageTemplate(a_StringMessage):
async def ShowMessage(a_CallbackQuery : types.CallbackQuery, a_Item):
return simple_message.WorkFuncResult(a_StringMessage)
return ShowMessage
# Удаление задачи
async def TaskPreDelete(a_CallbackQuery : types.CallbackQuery, a_Item):
if (len(a_Item) < 6):
return simple_message.WorkFuncResult(error_find_proj_message)
access = a_Item[4]
return simple_message.WorkFuncResult('', None, item_access = access)
async def TaskPostDelete(a_CallbackQuery : types.CallbackQuery, a_ItemID):
log.Success(f'Задача №{a_ItemID} была удалена пользователем {a_CallbackQuery.from_user.id}.')
#TODO: удалить вложенные
return simple_message.WorkFuncResult(task_success_delete_message)
# ---------------------------------------------------------
# Работа с базой данных задач
def AddBDItemFunc(a_ItemData, a_UserID):
res, error = bot_bd.SQLRequestToBD(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], access.GetItemDefaultAccessForModule(module_name) + f";{a_UserID}=+", a_ItemData[parent_id_field]))
if error:
log.Error(f'Пользоватлель {a_UserID}. Ошибка добавления записи в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
else:
log.Success(f'Пользоватлель {a_UserID}. Добавлена запись в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {access.GetItemDefaultAccessForModule(module_name)}).')
return res, error
# ---------------------------------------------------------
# API
# Инициализация БД
def GetInitBDCommands():
return init_bd_cmds
def GetAccess():
return access.GetAccessForModule(module_name)
# Доступные кнопки
def GetModuleButtons():
return [keyboard.ButtonWithAccess(tasks_button_name, user_access.AccessMode.VIEW, GetAccess())]
# Обработка кнопок
def RegisterHandlers(dp : Dispatcher):
defaul_keyboard_func = GetStartTaskKeyboardButtons
def RegisterSelectParent(a_ButtonName, access_mode):
a_PrefixBase = a_ButtonName
return bd_item_select.FirstSelectBDItemRegisterHandlers(dp, \
a_PrefixBase, \
a_ButtonName, \
projects.table_name, \
projects.key_name, \
projects.GetButtonNameAndKeyValueAndAccess, \
projects.select_project_message, \
projects.GetAccess, access_mode = access_mode\
)
# Стартовое сообщение
dp.register_message_handler(simple_message.SimpleMessageTemplate(TasksOpen, defaul_keyboard_func, GetAccess), text = tasks_button_name)
# Список задач
a_Prefix = RegisterSelectParent(list_task_button_name, user_access.AccessMode.VIEW)
bd_item_view.LastSelectAndShowBDItemRegisterHandlers(dp, \
a_Prefix, parent_id_field, \
table_name, key_name, \
ShowMessageTemplate(task_open_message, GetViewItemInlineKeyboardTemplate), \
GetButtonNameAndKeyValueAndAccess, \
select_task_message, \
GetAccess, \
defaul_keyboard_func, \
access_mode = user_access.AccessMode.VIEW\
)
global select_tasks_prefix
select_tasks_prefix = a_Prefix
# Удаление задачи
a_Prefix = RegisterSelectParent(del_task_button_name, user_access.AccessMode.DELETE)
bd_item_delete.DeleteBDItemRegisterHandlers(dp, \
a_Prefix, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
table_name, \
key_name, \
parent_id_field, \
TaskPreDelete, \
TaskPostDelete, \
GetButtonNameAndKeyValueAndAccess, \
select_task_message, \
GetAccess, \
defaul_keyboard_func\
)
# Добавление задачи
a_Prefix = RegisterSelectParent(add_task_button_name, user_access.AccessMode.ADD)
bd_item_add.AddBDItem3RegisterHandlers(dp, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
FSMCreateTask, \
FSMCreateTask.name,\
FSMCreateTask.desc, \
FSMCreateTask.photo,\
AddBDItemFunc, \
SimpleMessageTemplate(task_create_name_message), \
SimpleMessageTemplate(task_create_desc_message), \
SimpleMessageTemplate(task_create_photo_message), \
SimpleMessageTemplate(task_success_create_message), \
a_Prefix,\
projects.table_name, \
projects.key_name, \
name_field, \
desc_field, \
photo_field, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
GetStartTaskKeyboardButtons\
)
def RegisterEdit(a_ButtonName, a_FSM, a_EditMessage, a_FieldName, a_FieldType, a_AccessMode = user_access.AccessMode.EDIT):
a_Prefix = RegisterSelectParent(a_ButtonName, a_AccessMode)
bd_item_edit.EditBDItemRegisterHandlers(dp, \
a_Prefix, \
a_FSM, \
bd_item.GetCheckForPrefixFunc(a_Prefix), \
task_select_to_edit_message, \
ShowMessageTemplate(a_EditMessage), \
ShowMessageTemplate(task_success_edit_message), \
table_name, \
key_name, \
parent_id_field, \
a_FieldName, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
edit_keyboard_func, \
access_mode = a_AccessMode, \
field_type = a_FieldType\
)
# Редактирование задачи class ModuleTasks(mod_table_operate.TableOperateModule):
edit_keyboard_func = GetEditTaskKeyboardButtons def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
dp.register_message_handler(simple_message.InfoMessageTemplate(task_start_edit_message, edit_keyboard_func, GetAccess, access_mode = user_access.AccessMode.EDIT), text = edit_task_button_name) 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)
RegisterEdit(edit_task_photo_button_name, FSMEditTaskPhotoItem, task_edit_photo_message, photo_field, bd_item.FieldType.photo) def GetName(self):
RegisterEdit(edit_task_name_button_name, FSMEditTaskNameItem, task_edit_name_message, name_field, bd_item.FieldType.text) return module_name
RegisterEdit(edit_task_desc_button_name, FSMEditTaskDescItem, task_edit_desc_message, desc_field, bd_item.FieldType.text)
RegisterEdit(edit_task_access_button_name, FSMEditTaskAccessItem, task_edit_access_message, access_field, bd_item.FieldType.text)

104
bot_sys/aiogram_bot.py

@ -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)

125
bot_sys/bd_table.py

@ -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'

30
bot_sys/bot_bd.py

@ -6,30 +6,21 @@ from bot_sys import log
# Работа с базой данных # Работа с базой данных
# Имя файла БД
g_bd_file_name = 'bot.db'
def GetBDFileName():
return g_bd_file_name
# ---------------------------------------------------------
# Функции работы с базой
# ---------------------------------------------------------
def GetBDDateTimeNow(): def GetBDDateTimeNow():
return 'datetime(\'now\')' return 'datetime(\'now\')'
def BDExecute(a_Commands): def SelectBDTemplate(a_Bot, a_TableName):
for cmd in a_Commands: def SelectBD():
SQLRequestToBD(cmd, commit = True) return a_Bot.SQLRequest(f'SELECT * FROM {a_TableName}')
return SelectBD
def SelectBDTemplate(a_TableName): def RequestSelectTemplate(a_Bot, a_TableName):
def SelectBD(): def SelectBD():
return SQLRequestToBD(f'SELECT * FROM {a_TableName}') return a_Bot.SQLRequest(f'SELECT * FROM {a_TableName}')
return SelectBD return SelectBD
def SQLRequestToBD(a_Request : str, commit = False, return_error = False, param = None): def SQLRequest(a_Log, a_BDFileName, a_Request : str, commit = False, return_error = False, param = None):
db = sqlite3.connect(GetBDFileName()) db = sqlite3.connect(a_BDFileName)
cursor = db.cursor() cursor = db.cursor()
result = [] result = []
error = None error = None
@ -42,11 +33,12 @@ def SQLRequestToBD(a_Request : str, commit = False, return_error = False, param
if commit: if commit:
db.commit() db.commit()
except sqlite3.Error as e: except sqlite3.Error as e:
log.Error(f'Ошибка при обработке запроса [{a_Request}]:{str(e)}') a_Log.Error(f'Ошибка при обработке запроса [{a_Request}]:{str(e)}')
error = "Ошибка sqlite3:" + str(e) error = "Ошибка sqlite3:" + str(e)
cursor.close() cursor.close()
db.close() db.close()
if not error and commit: log.Success(f'Выполнен запрос [{a_Request}]') if not error and commit:
a_Log.Success(f'Выполнен запрос [{a_Request}]')
if return_error: if return_error:
return result, error return result, error
return result return result

83
bot_sys/bot_messages.py

@ -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

38
bot_sys/interfaces.py

@ -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

65
bot_sys/keyboard.py

@ -4,8 +4,9 @@
# Работа с кнопками и клавиатурой # Работа с кнопками и клавиатурой
from bot_sys import user_access from bot_sys import user_access
from aiogram import types, Bot, Dispatcher
from aiogram.types import ReplyKeyboardRemove, ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton from aiogram.types import ReplyKeyboardRemove, ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
from aiogram import types
class ButtonWithAccess: class ButtonWithAccess:
def __init__(self, a_Label, a_AccessMode : user_access.AccessMode, a_AccessString): def __init__(self, a_Label, a_AccessMode : user_access.AccessMode, a_AccessString):
@ -24,29 +25,39 @@ def GetButtons(a_ModList):
import math import math
def Chunks(a_List, a_ChunkSize): def Chunks(a_List, a_ChunkSize):
chunk_list = []
for i in range(0, len(a_List), a_ChunkSize): 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): def GetButtonInRowCount(a_AllKeyCount):
return min(max(int(math.sqrt(a_AllKeyCount) // 1), 1), 4) return min(max(int(math.sqrt(a_AllKeyCount) // 1), 1), 3)
def MakeKeyboard(a_ButtonList : [ButtonWithAccess], a_UserGroups): # TODO перенести KeyboardButton в MakeAiogramKeyboard
def MakeButtons(a_Bot, a_ButtonList : [ButtonWithAccess], a_UserGroups):
buttons = [] buttons = []
for b in a_ButtonList: for b in a_ButtonList:
if user_access.CheckAccessString(b.access_string, a_UserGroups, b.access_mode): if not b.label:
buttons += [types.KeyboardButton(b.label)] continue
label = str(b.label)
if user_access.CheckAccess(a_Bot.GetRootIDs(), b.access_string, a_UserGroups, b.access_mode):
buttons += [types.KeyboardButton(label)]
step = GetButtonInRowCount(len(buttons)) step = GetButtonInRowCount(len(buttons))
key = types.ReplyKeyboardMarkup(keyboard=Chunks(buttons, step), resize_keyboard = True) return Chunks(buttons, step)
return key
def MakeKeyboardRemove(): def MakeKeyboard(a_ButtonList : [ButtonWithAccess], a_UserGroups):
return types.ReplyKeyboardRemove() return MakeAiogramKeyboard(MakeButtons(a_ButtonList, a_UserGroups))
def MakeKeyboardForMods(a_ModList, a_UserGroups): def MakeKeyboardForMods(a_ModList, a_UserGroups):
buttons = GetButtons(a_ModList) buttons = GetButtons(a_ModList)
return MakeKeyboard(buttons, a_UserGroups) return MakeKeyboard(buttons, a_UserGroups)
class InlineButton: class InlineButton:
def __init__(self, a_Label, a_CallBackData):
self.label = a_Label
self.callback_data = str(a_CallBackData)
class InlineButtonWithAccess:
def __init__(self, a_Label, a_CallBackPrefix, a_CallBackData, a_AccessString, a_AccessMode): def __init__(self, a_Label, a_CallBackPrefix, a_CallBackData, a_AccessString, a_AccessMode):
self.label = a_Label self.label = a_Label
self.callback_prefix = a_CallBackPrefix self.callback_prefix = a_CallBackPrefix
@ -54,12 +65,36 @@ class InlineButton:
self.access_string = a_AccessString self.access_string = a_AccessString
self.access_mode = a_AccessMode self.access_mode = a_AccessMode
def MakeInlineKeyboard(a_ButtonList : [InlineButton], a_UserGroups): def MakeInlineKeyboardButtons(a_Bot, a_ButtonList : [InlineButtonWithAccess], a_UserGroups):
buttons = [] buttons = []
for b in a_ButtonList: for b in a_ButtonList:
if user_access.CheckAccessString(b.access_string, a_UserGroups, b.access_mode): if user_access.CheckAccess(a_Bot.GetRootIDs(), b.access_string, a_UserGroups, b.access_mode):
buttons += [types.InlineKeyboardButton(text = b.label, callback_data = f'{b.callback_prefix}{b.callback_data}')] data = f'{b.callback_prefix}{b.callback_data}'
assert len(data) < 41 # Телеграм больше не поддерживает
buttons += [InlineButton(b.label, data)]
step = GetButtonInRowCount(len(buttons)) step = GetButtonInRowCount(len(buttons))
inline_keyboard = InlineKeyboardMarkup(inline_keyboard=Chunks(buttons, step)) return Chunks(buttons, step)
return inline_keyboard
# -------------------------------
def MakeKeyboardRemove():
return types.ReplyKeyboardRemove()
def MakeAiogramInlineKeyboards(a_ButtonList : [InlineButton]):
buttons = []
for row in a_ButtonList:
r = []
for b in row:
r += [types.InlineKeyboardButton(text = str(b.label), callback_data = b.callback_data)]
buttons += [r]
button_list_chunks = Chunks(buttons, 20)
result = []
for c in button_list_chunks:
result += [InlineKeyboardMarkup(inline_keyboard=c)]
return result
def MakeAiogramKeyboard(a_ButtonList : [[str]]):
return types.ReplyKeyboardMarkup(keyboard=a_ButtonList, resize_keyboard = True)

46
bot_sys/log.py

@ -10,47 +10,51 @@
# Error - Ошибка. # Error - Ошибка.
# Success - Успех. # Success - Успех.
# Файл лога
g_log_file_name = 'log.txt'
from bot_sys import config from bot_sys import config
import colorama import colorama
import datetime import datetime
colorama.init() colorama.init()
def GetTimeNow(): class Log:
def __init__(self, a_FileName):
self.m_FileName = a_FileName
def GetFileName(self):
return self.m_FileName
def GetTimeNow(self):
return datetime.datetime.now() return datetime.datetime.now()
def GetTime(): def GetTime(self):
now = GetTimeNow() now = self.GetTimeNow()
time = now.strftime(f"[%d.%m.%Y, %H:%M]") time = now.strftime(f"[%d.%m.%Y, %H:%M]")
return time return time
def Info(a_LogMessage): def Info(self, a_LogMessage):
time = GetTime() time = self.GetTime()
WriteToFile(f'{time} | {a_LogMessage}') self.WriteToFile(f'{time} | {a_LogMessage}')
print(f"{time} {colorama.Back.BLUE}{colorama.Style.BRIGHT} ИНФО {colorama.Style.RESET_ALL} | {a_LogMessage}") print(f"{time} {colorama.Back.BLUE}{colorama.Style.BRIGHT} ИНФО {colorama.Style.RESET_ALL} | {a_LogMessage}")
def Warn(a_LogMessage): def Warn(self, a_LogMessage):
time = GetTime() time = self.GetTime()
WriteToFile(f'{time} | {a_LogMessage}') self.WriteToFile(f'{time} | {a_LogMessage}')
print(f"{time} {colorama.Back.YELLOW}{colorama.Style.BRIGHT} ВНИМАНИЕ {colorama.Style.RESET_ALL} | {a_LogMessage}") print(f"{time} {colorama.Back.YELLOW}{colorama.Style.BRIGHT} ВНИМАНИЕ {colorama.Style.RESET_ALL} | {a_LogMessage}")
def Error(a_LogMessage): def Error(self, a_LogMessage):
time = GetTime() time = self.GetTime()
WriteToFile(f'{time} | {a_LogMessage}') self.WriteToFile(f'{time} | {a_LogMessage}')
print(f"{time} {colorama.Back.RED}{colorama.Style.BRIGHT} ОШИБКА {colorama.Style.RESET_ALL} | {a_LogMessage}") print(f"{time} {colorama.Back.RED}{colorama.Style.BRIGHT} ОШИБКА {colorama.Style.RESET_ALL} | {a_LogMessage}")
def Success(a_LogMessage): def Success(self, a_LogMessage):
time = GetTime() time = self.GetTime()
WriteToFile(f'{time} | {a_LogMessage}') self.WriteToFile(f'{time} | {a_LogMessage}')
print(f"{time} {colorama.Back.GREEN}{colorama.Style.BRIGHT} УСПЕХ {colorama.Style.RESET_ALL} | {a_LogMessage}") print(f"{time} {colorama.Back.GREEN}{colorama.Style.BRIGHT} УСПЕХ {colorama.Style.RESET_ALL} | {a_LogMessage}")
def WriteToFile(a_LogMessage): def WriteToFile(self, a_LogMessage):
if config.g_log_to_file != True: if not self.m_FileName:
return return
f = open(g_log_file_name, 'a+') f = open(self.m_FileName, 'a+')
f.write(a_LogMessage) f.write(a_LogMessage)
f.write('\n') f.write('\n')
f.close() f.close()

218
bot_sys/user_access.py

@ -54,8 +54,8 @@ def CheckAccessItem(a_AccessItem : str, a_AccessMode : AccessMode):
return False return False
# Возвращает возможность доступа пользователю a_UserGroups в элемент с правами a_AccessValue по режиму доступа a_AccessMode # Возвращает возможность доступа пользователю a_UserGroups в элемент с правами a_AccessValue по режиму доступа a_AccessMode
def CheckAccessString(a_AccessValue : str, a_UserGroups : UserGroups, a_AccessMode : AccessMode): def CheckAccess(a_RootIDs, a_AccessValue : str, a_UserGroups : UserGroups, a_AccessMode : AccessMode):
if a_UserGroups.user_id in config.GetRootIDs(): if a_UserGroups.user_id in a_RootIDs:
return True return True
for i in a_AccessValue.split(';'): for i in a_AccessValue.split(';'):
d = i.split('=') d = i.split('=')
@ -72,99 +72,125 @@ def Test():
assert '1234' in ['123', '1234'] assert '1234' in ['123', '1234']
assert not '1234' in ['123', '12345'] assert not '1234' in ['123', '12345']
# root имеет полный доступ вне зависимости от a_AccessValue и a_UserGroups и a_AccessMode
roots = ['1234']
for am in AccessMode.ADD, AccessMode.DELETE, AccessMode.EDIT, AccessMode.VIEW, AccessMode.ACCEES_EDIT: for am in AccessMode.ADD, AccessMode.DELETE, AccessMode.EDIT, AccessMode.VIEW, AccessMode.ACCEES_EDIT:
assert CheckAccessString('1234=+', UserGroups('1234', []), am) assert CheckAccess(roots, '1234=+', UserGroups('1234', []), am)
assert not CheckAccessString('1234=-', UserGroups('1234', []), am) assert CheckAccess(roots, '1234=-', UserGroups('1234', []), am)
assert CheckAccessString('1234=+;gr1=+', UserGroups('1234', ['gr1']), am) assert CheckAccess(roots, '1234=+;gr1=+', UserGroups('1234', ['gr1']), am)
assert CheckAccessString('1234=-;gr1=+', UserGroups('1234', ['gr1']), am) assert CheckAccess(roots, '1234=-;gr1=+', UserGroups('1234', ['gr1']), am)
assert not CheckAccessString('1234=+', UserGroups('123', []), am) assert CheckAccess(roots, '1234=+', UserGroups('1234', []), am)
assert not CheckAccessString('1234=-', UserGroups('123', []), am) assert CheckAccess(roots, '1234=-', UserGroups('1234', []), am)
assert not CheckAccessString('1234=+;gr1=+', UserGroups('123', ['gr']), am) assert CheckAccess(roots, '1234=+;gr1=+', UserGroups('1234', ['gr']), am)
assert not CheckAccessString('1234=-;gr1=+', UserGroups('123', ['gr']), am) assert CheckAccess(roots, '1234=-;gr1=+', UserGroups('1234', ['gr']), am)
assert not CheckAccessString('1234=+;gr=+', UserGroups('123', ['gr1']), am) assert CheckAccess(roots, '1234=+;gr=+', UserGroups('1234', ['gr1']), am)
assert not CheckAccessString('1234=-;gr=+', UserGroups('123', ['gr1']), am) assert CheckAccess(roots, '1234=-;gr=+', UserGroups('1234', ['gr1']), am)
assert CheckAccessString('123=-;1234=a', UserGroups('1234', []), AccessMode.ADD) assert CheckAccess(roots, '123=+', UserGroups('1234', []), am)
assert CheckAccessString('123=-;1234=d', UserGroups('1234', []), AccessMode.DELETE) assert CheckAccess(roots, '124=-', UserGroups('1234', []), am)
assert CheckAccessString('123=-;1234=e', UserGroups('1234', []), AccessMode.EDIT) assert CheckAccess(roots, '134=+;gr1=+', UserGroups('1234', ['gr1']), am)
assert CheckAccessString('123=-;1234=r', UserGroups('1234', []), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, '134=-;gr1=+', UserGroups('1234', ['gr1']), am)
assert CheckAccessString('123=-;1234=v', UserGroups('1234', []), AccessMode.VIEW) assert CheckAccess(roots, '124=+', UserGroups('1234', []), am)
assert CheckAccessString('123=-;gr1=a', UserGroups('1234', ['gr1']), AccessMode.ADD) assert CheckAccess(roots, '124=-', UserGroups('1234', []), am)
assert CheckAccessString('123=-;gr1=d', UserGroups('1234', ['gr1']), AccessMode.DELETE) assert CheckAccess(roots, '134=+;gr1=+', UserGroups('1234', ['gr']), am)
assert CheckAccessString('123=-;gr1=e', UserGroups('1234', ['gr1']), AccessMode.EDIT) assert CheckAccess(roots, '134=-;gr1=+', UserGroups('1234', ['gr']), am)
assert CheckAccessString('123=-;gr1=r', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, '124=+;gr=+', UserGroups('1234', ['gr1']), am)
assert CheckAccessString('123=-;gr1=v', UserGroups('1234', ['gr1']), AccessMode.VIEW) assert CheckAccess(roots, '124=-;gr=+', UserGroups('1234', ['gr1']), am)
assert CheckAccessString('123=-;1234=daver', UserGroups('1234', []), AccessMode.ADD)
assert CheckAccessString('123=-;1234=dav', UserGroups('1234', []), AccessMode.DELETE) roots = ['12']
assert CheckAccessString('123=-;1234=edv', UserGroups('1234', []), AccessMode.EDIT) for am in AccessMode.ADD, AccessMode.DELETE, AccessMode.EDIT, AccessMode.VIEW, AccessMode.ACCEES_EDIT:
assert CheckAccessString('123=-;1234=rav', UserGroups('1234', []), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, '1234=+', UserGroups('1234', []), am)
assert CheckAccessString('123=-;1234=va', UserGroups('1234', []), AccessMode.VIEW) assert not CheckAccess(roots, '1234=-', UserGroups('1234', []), am)
assert CheckAccessString('123=-;gr1=avr', UserGroups('1234', ['gr1']), AccessMode.ADD) assert CheckAccess(roots, '1234=+;gr1=+', UserGroups('1234', ['gr1']), am)
assert CheckAccessString('123=-;gr1=daver', UserGroups('1234', ['gr1']), AccessMode.DELETE) assert CheckAccess(roots, '1234=-;gr1=+', UserGroups('1234', ['gr1']), am)
assert CheckAccessString('123=-;gr1=eva', UserGroups('1234', ['gr1']), AccessMode.EDIT) assert not CheckAccess(roots, '1234=+', UserGroups('123', []), am)
assert CheckAccessString('123=-;gr1=re', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT) assert not CheckAccess(roots, '1234=-', UserGroups('123', []), am)
assert CheckAccessString('123=-;gr1=vad', UserGroups('1234', ['gr1']), AccessMode.VIEW) assert not CheckAccess(roots, '1234=+;gr1=+', UserGroups('123', ['gr']), am)
assert not CheckAccess(roots, '1234=-;gr1=+', UserGroups('123', ['gr']), am)
assert not CheckAccessString('123=-;1234=d', UserGroups('1234', []), AccessMode.ADD) assert not CheckAccess(roots, '1234=+;gr=+', UserGroups('123', ['gr1']), am)
assert not CheckAccessString('123=-;1234=a', UserGroups('1234', []), AccessMode.DELETE) assert not CheckAccess(roots, '1234=-;gr=+', UserGroups('123', ['gr1']), am)
assert not CheckAccessString('123=-;1234=r', UserGroups('1234', []), AccessMode.EDIT)
assert not CheckAccessString('123=-;1234=v', UserGroups('1234', []), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, '123=-;1234=a', UserGroups('1234', []), AccessMode.ADD)
assert not CheckAccessString('123=-;1234=e', UserGroups('1234', []), AccessMode.VIEW) assert CheckAccess(roots, '123=-;1234=d', UserGroups('1234', []), AccessMode.DELETE)
assert not CheckAccessString('123=-;gr1=d', UserGroups('1234', ['gr']), AccessMode.ADD) assert CheckAccess(roots, '123=-;1234=e', UserGroups('1234', []), AccessMode.EDIT)
assert not CheckAccessString('123=-;gr1=a', UserGroups('1234', ['gr']), AccessMode.DELETE) assert CheckAccess(roots, '123=-;1234=r', UserGroups('1234', []), AccessMode.ACCEES_EDIT)
assert not CheckAccessString('123=-;gr1=v', UserGroups('1234', ['gr']), AccessMode.EDIT) assert CheckAccess(roots, '123=-;1234=v', UserGroups('1234', []), AccessMode.VIEW)
assert not CheckAccessString('123=-;gr1=e', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, '123=-;gr1=a', UserGroups('1234', ['gr1']), AccessMode.ADD)
assert not CheckAccessString('123=-;gr1=r', UserGroups('1234', ['gr']), AccessMode.VIEW) assert CheckAccess(roots, '123=-;gr1=d', UserGroups('1234', ['gr1']), AccessMode.DELETE)
assert not CheckAccessString('123=-;1234=dver', UserGroups('1234', []), AccessMode.ADD) assert CheckAccess(roots, '123=-;gr1=e', UserGroups('1234', ['gr1']), AccessMode.EDIT)
assert not CheckAccessString('123=-;1234=av', UserGroups('1234', []), AccessMode.DELETE) assert CheckAccess(roots, '123=-;gr1=r', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT)
assert not CheckAccessString('123=-;1234=dv', UserGroups('1234', []), AccessMode.EDIT) assert CheckAccess(roots, '123=-;gr1=v', UserGroups('1234', ['gr1']), AccessMode.VIEW)
assert not CheckAccessString('123=-;1234=av', UserGroups('1234', []), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, '123=-;1234=daver', UserGroups('1234', []), AccessMode.ADD)
assert not CheckAccessString('123=-;1234=a', UserGroups('1234', []), AccessMode.VIEW) assert CheckAccess(roots, '123=-;1234=dav', UserGroups('1234', []), AccessMode.DELETE)
assert not CheckAccessString('123=-;gr1=vr', UserGroups('1234', ['gr']), AccessMode.ADD) assert CheckAccess(roots, '123=-;1234=edv', UserGroups('1234', []), AccessMode.EDIT)
assert not CheckAccessString('123=-;gr1=aver', UserGroups('1234', ['gr']), AccessMode.DELETE) assert CheckAccess(roots, '123=-;1234=rav', UserGroups('1234', []), AccessMode.ACCEES_EDIT)
assert not CheckAccessString('123=-;gr1=va', UserGroups('1234', ['gr']), AccessMode.EDIT) assert CheckAccess(roots, '123=-;1234=va', UserGroups('1234', []), AccessMode.VIEW)
assert not CheckAccessString('123=-;gr1=ea', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, '123=-;gr1=avr', UserGroups('1234', ['gr1']), AccessMode.ADD)
assert not CheckAccessString('123=-;gr1=ad', UserGroups('1234', ['gr']), AccessMode.VIEW) assert CheckAccess(roots, '123=-;gr1=daver', UserGroups('1234', ['gr1']), AccessMode.DELETE)
assert CheckAccess(roots, '123=-;gr1=eva', UserGroups('1234', ['gr1']), AccessMode.EDIT)
assert CheckAccessString(f'123=-;{user_access_group_all}=a', UserGroups('1234', []), AccessMode.ADD) assert CheckAccess(roots, '123=-;gr1=re', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT)
assert CheckAccessString(f'123=-;{user_access_group_all}=d', UserGroups('1234', []), AccessMode.DELETE) assert CheckAccess(roots, '123=-;gr1=vad', UserGroups('1234', ['gr1']), AccessMode.VIEW)
assert CheckAccessString(f'123=-;{user_access_group_all}=e', UserGroups('1234', []), AccessMode.EDIT)
assert CheckAccessString(f'123=-;{user_access_group_all}=r', UserGroups('1234', []), AccessMode.ACCEES_EDIT) assert not CheckAccess(roots, '123=-;1234=d', UserGroups('1234', []), AccessMode.ADD)
assert CheckAccessString(f'123=-;{user_access_group_all}=v', UserGroups('1234', []), AccessMode.VIEW) assert not CheckAccess(roots, '123=-;1234=a', UserGroups('1234', []), AccessMode.DELETE)
assert CheckAccessString(f'123=-;{user_access_group_all}=a', UserGroups('1234', ['gr1']), AccessMode.ADD) assert not CheckAccess(roots, '123=-;1234=r', UserGroups('1234', []), AccessMode.EDIT)
assert CheckAccessString(f'123=-;{user_access_group_all}=d', UserGroups('1234', ['gr1']), AccessMode.DELETE) assert not CheckAccess(roots, '123=-;1234=v', UserGroups('1234', []), AccessMode.ACCEES_EDIT)
assert CheckAccessString(f'123=-;{user_access_group_all}=e', UserGroups('1234', ['gr1']), AccessMode.EDIT) assert not CheckAccess(roots, '123=-;1234=e', UserGroups('1234', []), AccessMode.VIEW)
assert CheckAccessString(f'123=-;{user_access_group_all}=r', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT) assert not CheckAccess(roots, '123=-;gr1=d', UserGroups('1234', ['gr']), AccessMode.ADD)
assert CheckAccessString(f'123=-;{user_access_group_all}=v', UserGroups('1234', ['gr1']), AccessMode.VIEW) assert not CheckAccess(roots, '123=-;gr1=a', UserGroups('1234', ['gr']), AccessMode.DELETE)
assert CheckAccessString(f'123=-;{user_access_group_all}=daver', UserGroups('1234', []), AccessMode.ADD) assert not CheckAccess(roots, '123=-;gr1=v', UserGroups('1234', ['gr']), AccessMode.EDIT)
assert CheckAccessString(f'123=-;{user_access_group_all}=dav', UserGroups('1234', []), AccessMode.DELETE) assert not CheckAccess(roots, '123=-;gr1=e', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT)
assert CheckAccessString(f'123=-;{user_access_group_all}=edv', UserGroups('1234', []), AccessMode.EDIT) assert not CheckAccess(roots, '123=-;gr1=r', UserGroups('1234', ['gr']), AccessMode.VIEW)
assert CheckAccessString(f'123=-;{user_access_group_all}=rav', UserGroups('1234', []), AccessMode.ACCEES_EDIT) assert not CheckAccess(roots, '123=-;1234=dver', UserGroups('1234', []), AccessMode.ADD)
assert CheckAccessString(f'123=-;{user_access_group_all}=va', UserGroups('1234', []), AccessMode.VIEW) assert not CheckAccess(roots, '123=-;1234=av', UserGroups('1234', []), AccessMode.DELETE)
assert CheckAccessString(f'123=-;{user_access_group_all}=avr', UserGroups('1234', ['gr1']), AccessMode.ADD) assert not CheckAccess(roots, '123=-;1234=dv', UserGroups('1234', []), AccessMode.EDIT)
assert CheckAccessString(f'123=-;{user_access_group_all}=daver', UserGroups('1234', ['gr1']), AccessMode.DELETE) assert not CheckAccess(roots, '123=-;1234=av', UserGroups('1234', []), AccessMode.ACCEES_EDIT)
assert CheckAccessString(f'123=-;{user_access_group_all}=eva', UserGroups('1234', ['gr1']), AccessMode.EDIT) assert not CheckAccess(roots, '123=-;1234=a', UserGroups('1234', []), AccessMode.VIEW)
assert CheckAccessString(f'123=-;{user_access_group_all}=re', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT) assert not CheckAccess(roots, '123=-;gr1=vr', UserGroups('1234', ['gr']), AccessMode.ADD)
assert CheckAccessString(f'123=-;{user_access_group_all}=vad', UserGroups('1234', ['gr1']), AccessMode.VIEW) assert not CheckAccess(roots, '123=-;gr1=aver', UserGroups('1234', ['gr']), AccessMode.DELETE)
assert not CheckAccess(roots, '123=-;gr1=va', UserGroups('1234', ['gr']), AccessMode.EDIT)
assert not CheckAccessString(f'123=-;{user_access_group_all}=d', UserGroups('1234', []), AccessMode.ADD) assert not CheckAccess(roots, '123=-;gr1=ea', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT)
assert not CheckAccessString(f'123=-;{user_access_group_all}=a', UserGroups('1234', []), AccessMode.DELETE) assert not CheckAccess(roots, '123=-;gr1=ad', UserGroups('1234', ['gr']), AccessMode.VIEW)
assert not CheckAccessString(f'123=-;{user_access_group_all}=r', UserGroups('1234', []), AccessMode.EDIT)
assert not CheckAccessString(f'123=-;{user_access_group_all}=v', UserGroups('1234', []), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, f'123=-;{user_access_group_all}=a', UserGroups('1234', []), AccessMode.ADD)
assert not CheckAccessString(f'123=-;{user_access_group_all}=e', UserGroups('1234', []), AccessMode.VIEW) assert CheckAccess(roots, f'123=-;{user_access_group_all}=d', UserGroups('1234', []), AccessMode.DELETE)
assert not CheckAccessString(f'123=-;gr1=d;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.ADD) assert CheckAccess(roots, f'123=-;{user_access_group_all}=e', UserGroups('1234', []), AccessMode.EDIT)
assert not CheckAccessString(f'123=-;gr1=a;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.DELETE) assert CheckAccess(roots, f'123=-;{user_access_group_all}=r', UserGroups('1234', []), AccessMode.ACCEES_EDIT)
assert not CheckAccessString(f'123=-;gr1=v;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.EDIT) assert CheckAccess(roots, f'123=-;{user_access_group_all}=v', UserGroups('1234', []), AccessMode.VIEW)
assert not CheckAccessString(f'123=-;gr1=e;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, f'123=-;{user_access_group_all}=a', UserGroups('1234', ['gr1']), AccessMode.ADD)
assert not CheckAccessString(f'123=-;gr1=r;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.VIEW) assert CheckAccess(roots, f'123=-;{user_access_group_all}=d', UserGroups('1234', ['gr1']), AccessMode.DELETE)
assert not CheckAccessString(f'123=-;{user_access_group_all}=dver', UserGroups('1234', []), AccessMode.ADD) assert CheckAccess(roots, f'123=-;{user_access_group_all}=e', UserGroups('1234', ['gr1']), AccessMode.EDIT)
assert not CheckAccessString(f'123=-;{user_access_group_all}=av', UserGroups('1234', []), AccessMode.DELETE) assert CheckAccess(roots, f'123=-;{user_access_group_all}=r', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT)
assert not CheckAccessString(f'123=-;{user_access_group_all}=dv', UserGroups('1234', []), AccessMode.EDIT) assert CheckAccess(roots, f'123=-;{user_access_group_all}=v', UserGroups('1234', ['gr1']), AccessMode.VIEW)
assert not CheckAccessString(f'123=-;{user_access_group_all}=av', UserGroups('1234', []), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, f'123=-;{user_access_group_all}=daver', UserGroups('1234', []), AccessMode.ADD)
assert not CheckAccessString(f'123=-;{user_access_group_all}=a', UserGroups('1234', []), AccessMode.VIEW) assert CheckAccess(roots, f'123=-;{user_access_group_all}=dav', UserGroups('1234', []), AccessMode.DELETE)
assert not CheckAccessString(f'123=-;{user_access_group_all}=vr', UserGroups('1234', ['gr']), AccessMode.ADD) assert CheckAccess(roots, f'123=-;{user_access_group_all}=edv', UserGroups('1234', []), AccessMode.EDIT)
assert not CheckAccessString(f'123=-;{user_access_group_all}=aver', UserGroups('1234', ['gr']), AccessMode.DELETE) assert CheckAccess(roots, f'123=-;{user_access_group_all}=rav', UserGroups('1234', []), AccessMode.ACCEES_EDIT)
assert not CheckAccessString(f'123=-;{user_access_group_all}=va', UserGroups('1234', ['gr']), AccessMode.EDIT) assert CheckAccess(roots, f'123=-;{user_access_group_all}=va', UserGroups('1234', []), AccessMode.VIEW)
assert not CheckAccessString(f'123=-;{user_access_group_all}=ea', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT) assert CheckAccess(roots, f'123=-;{user_access_group_all}=avr', UserGroups('1234', ['gr1']), AccessMode.ADD)
assert not CheckAccessString(f'123=-;{user_access_group_all}=ad', UserGroups('1234', ['gr']), AccessMode.VIEW) assert CheckAccess(roots, f'123=-;{user_access_group_all}=daver', UserGroups('1234', ['gr1']), AccessMode.DELETE)
assert CheckAccess(roots, f'123=-;{user_access_group_all}=eva', UserGroups('1234', ['gr1']), AccessMode.EDIT)
assert CheckAccess(roots, f'123=-;{user_access_group_all}=re', UserGroups('1234', ['gr1']), AccessMode.ACCEES_EDIT)
assert CheckAccess(roots, f'123=-;{user_access_group_all}=vad', UserGroups('1234', ['gr1']), AccessMode.VIEW)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=d', UserGroups('1234', []), AccessMode.ADD)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=a', UserGroups('1234', []), AccessMode.DELETE)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=r', UserGroups('1234', []), AccessMode.EDIT)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=v', UserGroups('1234', []), AccessMode.ACCEES_EDIT)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=e', UserGroups('1234', []), AccessMode.VIEW)
assert not CheckAccess(roots, f'123=-;gr1=d;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.ADD)
assert not CheckAccess(roots, f'123=-;gr1=a;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.DELETE)
assert not CheckAccess(roots, f'123=-;gr1=v;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.EDIT)
assert not CheckAccess(roots, f'123=-;gr1=e;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT)
assert not CheckAccess(roots, f'123=-;gr1=r;{user_access_group_all}=-', UserGroups('1234', ['gr']), AccessMode.VIEW)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=dver', UserGroups('1234', []), AccessMode.ADD)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=av', UserGroups('1234', []), AccessMode.DELETE)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=dv', UserGroups('1234', []), AccessMode.EDIT)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=av', UserGroups('1234', []), AccessMode.ACCEES_EDIT)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=a', UserGroups('1234', []), AccessMode.VIEW)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=vr', UserGroups('1234', ['gr']), AccessMode.ADD)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=aver', UserGroups('1234', ['gr']), AccessMode.DELETE)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=va', UserGroups('1234', ['gr']), AccessMode.EDIT)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=ea', UserGroups('1234', ['gr']), AccessMode.ACCEES_EDIT)
assert not CheckAccess(roots, f'123=-;{user_access_group_all}=ad', UserGroups('1234', ['gr']), AccessMode.VIEW)

56
bot_sys/user_messages.py

@ -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)

122
main.py

@ -4,45 +4,117 @@
log_start_message = 'Бот успешно запущен!' log_start_message = 'Бот успешно запущен!'
import os import os
from aiogram import Bot, types
from aiogram.utils import executor from bot_sys import config, log, aiogram_bot, bot_messages, bd_table, user_access
from aiogram.dispatcher import Dispatcher from bot_modules import mod_agregator, start, profile, backup, groups, access, projects, tasks, needs, comments, languages, messages, buttons
from aiogram.contrib.fsm_storage.memory import MemoryStorage
import sqlite3 bd_file_name = 'bot.db'
from bot_sys import config, log, bot_bd, user_access, user_messages
from bot_modules import profile, start, projects, groups, access, backup, tasks, needs, comments, messages, languages log_file_name = 'log.txt'
storage = MemoryStorage() g_Log = log.Log(log_file_name)
bot = Bot(token = config.GetTelegramBotApiToken(), parse_mode = types.ParseMode.HTML) g_Bot = aiogram_bot.AiogramBot(config.GetTelegramBotApiToken(), bd_file_name, config.GetRootIDs(), g_Log)
dp = Dispatcher(bot, storage = storage)
default_language = 'ru'
# Первичная инициализация модулей. Все модули должны быть прописаны в списке modules
modules = [tasks, access, profile, start, projects, groups, backup, needs, comments, messages, languages] g_BotMessages = bot_messages.BotMessages(default_language)
g_BotButtons = bot_messages.BotMessages(default_language)
init_bd_cmd = []
g_ModuleAgregator = mod_agregator.ModuleAgregator()
mod_start_name = start.module_name
mod_tasks_name = tasks.module_name
mod_needs_name = needs.module_name
mod_comments_name = comments.module_name
mod_projects_name = projects.module_name
mod_languages_name = languages.module_name
mod_messages_name = messages.module_name
mod_buttons_name = buttons.module_name
start_mod_list = [mod_start_name]
mod_access = access.ModuleAccess(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_access)
mod_groups = groups.ModuleGroups(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_groups)
mod_profile = profile.ModuleProfile(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_profile)
mod_backup = backup.ModuleBackup(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_backup)
start_mod_name_list = [mod_start_name, mod_tasks_name, mod_needs_name, mod_comments_name]
mod_project = projects.ModuleProjects(None, mod_tasks_name, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_project)
start_mod_name_list = [mod_start_name]#, mod_projects_name, mod_needs_name, mod_comments_name]
mod_tasks = tasks.ModuleTasks(mod_projects_name, mod_needs_name, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_tasks)
start_mod_name_list = [mod_start_name]#, mod_projects_name, mod_tasks_name, mod_comments_name]
mod_needs= needs.ModuleNeeds(mod_tasks_name, mod_comments_name, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_needs)
start_mod_name_list = [mod_start_name]#, mod_projects_name, mod_tasks_name, mod_needs_name]
mod_comments= comments.ModuleComments(mod_needs_name, None, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_comments)
start_mod_name_list = [mod_start_name, mod_messages_name, mod_buttons_name]
mod_languages = languages.ModuleLanguages(None, mod_messages_name, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_languages)
start_mod_name_list = [mod_start_name]
mod_messages = messages.ModuleMessages(mod_languages_name, None, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_messages)
start_mod_name_list = [mod_start_name]
mod_buttons = buttons.ModuleButtons(mod_languages_name, None, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_buttons)
start_mod_name_list = [
mod_profile.GetName(),
mod_backup.GetName(),
mod_groups.GetName(),
mod_access.GetName(),
mod_project.GetName(),
mod_languages.GetName(),
]
mod_start = start.ModuleStart(start_mod_name_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_start)
# Первичная инициализация модулей.
modules = g_ModuleAgregator.GetModList()
init_bd_cmds = []
for m in modules: for m in modules:
c = m.GetInitBDCommands() c = m.GetInitBDCommands()
if not c is None: if not c is None:
init_bd_cmd += c init_bd_cmds += c
# Первичная инициализация базы данных # Первичная инициализация базы данных
bot_bd.BDExecute(init_bd_cmd) for c in init_bd_cmds:
g_Bot.SQLRequest(c, commit = True)
user_messages.UpdateSignal(log.GetTimeNow()) g_BotMessages.UpdateSignal(g_Log.GetTimeNow())
g_BotButtons.UpdateSignal(g_Log.GetTimeNow())
languages.FlushLanguages() mod_languages.FlushLanguages()
messages.FlushMessages() mod_messages.FlushMessages()
mod_buttons.FlushMessages()
for m in modules: for m in modules:
m.RegisterHandlers(dp) m.RegisterHandlers()
# Юнит тесты модулей и файлов # Юнит тесты модулей и файлов
test_mods = [user_access] test_mods = [user_access, bd_table]
for m in test_mods: for m in test_mods:
m.Test() m.Test()
if __name__ == '__main__': if __name__ == '__main__':
# os.system('clear') # os.system('clear')
# os.system('cls') # os.system('cls')
log.Success(log_start_message) g_Log.Success(log_start_message)
executor.start_polling(dp) g_Bot.StartPolling()

51
template/bd_item.py

@ -4,8 +4,8 @@
# Работа с элементом в БД # Работа с элементом в БД
from enum import Enum from enum import Enum
from bot_sys import user_access, bot_bd, keyboard, log from bot_sys import user_access, bot_bd, keyboard, bot_messages
from bot_modules import groups, access from bot_modules import groups_utils, access_utils
from template import simple_message from template import simple_message
from aiogram import types from aiogram import types
@ -20,7 +20,7 @@ canсel_button_name = "🚫 Отменить"
def HashPrefix(a_Str): def HashPrefix(a_Str):
# callback data в сообщении имеет ограниченную длину, поэтому сокращаем префикс # callback data в сообщении имеет ограниченную длину, поэтому сокращаем префикс
#log.Info(f'HashPrefix {md5(a_Str)[0:8]}: - {a_Str}') #a_Bot.GetLog().Info(f'HashPrefix {md5(a_Str)[0:8]}: - {a_Str}')
return f'{md5(a_Str)[0:8]}:' return f'{md5(a_Str)[0:8]}:'
class FieldType(Enum): class FieldType(Enum):
@ -31,7 +31,10 @@ def GetCheckForPrefixFunc(a_Prefix):
return lambda x: x.data.startswith(a_Prefix) return lambda x: x.data.startswith(a_Prefix)
def GetCheckForTextFunc(a_Text): def GetCheckForTextFunc(a_Text):
return lambda x: x.text == a_Text return lambda x: x.text == str(a_Text)
def GetCheckForCommandsFunc(a_Commands):
return lambda x: x.commands == a_Commands
def GetKeyDataFromCallbackMessage(a_Message, a_Prefix): def GetKeyDataFromCallbackMessage(a_Message, a_Prefix):
key_item_id = None key_item_id = None
@ -39,60 +42,60 @@ def GetKeyDataFromCallbackMessage(a_Message, a_Prefix):
key_item_id = str(a_Message.data).replace(a_Prefix, '') key_item_id = str(a_Message.data).replace(a_Prefix, '')
return key_item_id return key_item_id
def GetCancelKeyboardButtonsTemplate(a_AccessFunc, a_AccessMode): def GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, a_AccessMode):
def GetCancelKeyboardButtons(a_Message, a_UserGroups): def GetCancelKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = [ cur_buttons = [
keyboard.ButtonWithAccess(canсel_button_name, a_AccessMode, a_AccessFunc()), keyboard.ButtonWithAccess(canсel_button_name, a_AccessMode, a_AccessFunc()),
] ]
return keyboard.MakeKeyboard(cur_buttons, a_UserGroups) return keyboard.MakeButtons(a_Bot, cur_buttons, a_UserGroups)
return GetCancelKeyboardButtons return GetCancelKeyboardButtons
def GetSkipAndCancelKeyboardButtonsTemplate(a_AccessFunc, a_AccessMode): def GetSkipAndCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, a_AccessMode):
def GetSkipAndCancelKeyboardButtons(a_Message, a_UserGroups): def GetSkipAndCancelKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = [ cur_buttons = [
keyboard.ButtonWithAccess(skip_button_name, a_AccessMode, a_AccessFunc()), keyboard.ButtonWithAccess(skip_button_name, a_AccessMode, a_AccessFunc()),
keyboard.ButtonWithAccess(canсel_button_name, a_AccessMode, a_AccessFunc()), keyboard.ButtonWithAccess(canсel_button_name, a_AccessMode, a_AccessFunc()),
] ]
return keyboard.MakeKeyboard(cur_buttons, a_UserGroups) return keyboard.MakeButtons(a_Bot, cur_buttons, a_UserGroups)
return GetSkipAndCancelKeyboardButtons return GetSkipAndCancelKeyboardButtons
def GetAllItemsTemplate(a_TableName): def GetAllItemsTemplate(a_Bot, a_TableName):
def GetAllItems(): def GetAllItems():
return bot_bd.SelectBDTemplate(a_TableName)() return bot_bd.SelectBDTemplate(a_Bot, a_TableName)()
return GetAllItems return GetAllItems
def GetBDItemsTemplate(a_TableName : str, a_KeyName : str): def GetBDItemsTemplate(a_Bot, a_TableName : str, a_KeyName : str):
def GetBDItem(a_KeyValue): def GetBDItem(a_KeyValue):
return bot_bd.SQLRequestToBD(f'SELECT * FROM {a_TableName} WHERE {a_KeyName} = ?', param = ([a_KeyValue])) return a_Bot.SQLRequest(f'SELECT * FROM {a_TableName} WHERE {a_KeyName} = ?', param = ([a_KeyValue]))
return GetBDItem return GetBDItem
def DeleteBDItemInTableTemplate(a_TableName : str, a_KeyName : str): def DeleteBDItemInTableTemplate(a_Bot, a_TableName : str, a_KeyName : str):
def DeleteBDItem(a_KeyValue): def DeleteBDItem(a_KeyValue):
return bot_bd.SQLRequestToBD(f'DELETE FROM {a_TableName} WHERE {a_KeyName} = ?', commit = True, return_error = True, param = ([a_KeyValue])) return a_Bot.SQLRequest(f'DELETE FROM {a_TableName} WHERE {a_KeyName} = ?', commit = True, return_error = True, param = ([a_KeyValue]))
return DeleteBDItem return DeleteBDItem
def EditBDItemInTableTemplate(a_TableName : str, a_KeyName : str, a_FieldName : str): def EditBDItemInTableTemplate(a_Bot, a_TableName : str, a_KeyName : str, a_FieldName : str):
def EditBDItemInTable(a_KeyValue, a_FieldValue): def EditBDItemInTable(a_KeyValue, a_FieldValue):
return bot_bd.SQLRequestToBD(f'UPDATE {a_TableName} SET {a_FieldName}=? WHERE {a_KeyName} = ?', commit = True, return_error = True, param = ([a_FieldValue, a_KeyValue])) return a_Bot.SQLRequest(f'UPDATE {a_TableName} SET {a_FieldName}=? WHERE {a_KeyName} = ?', commit = True, return_error = True, param = ([a_FieldValue, a_KeyValue]))
return EditBDItemInTable return EditBDItemInTable
def CheckAccessBDItemTemplate(a_TableName, a_KeyName, a_KeyValue, a_WorkFunc, a_AccessMode : user_access.AccessMode): def CheckAccessBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_KeyValue, a_WorkFunc, a_AccessMode : user_access.AccessMode):
async def CheckAccessBDItem(a_CallbackQuery : types.CallbackQuery): async def CheckAccessBDItem(a_CallbackQuery : types.CallbackQuery):
user_id = str(a_CallbackQuery.from_user.id) user_id = str(a_CallbackQuery.from_user.id)
user_groups = groups.GetUserGroupData(user_id) user_groups = groups_utils.GetUserGroupData(a_Bot, user_id)
item_id = a_KeyValue item_id = a_KeyValue
item = GetBDItemsTemplate(a_TableName, a_KeyName)(item_id) item = GetBDItemsTemplate(a_Bot, a_TableName, a_KeyName)(item_id)
if len(item) < 1: if len(item) < 1:
msg = item_not_found.replace('{item_id}', str(item_id)).replace('{a_TableName}', a_TableName) msg = item_not_found.replace('{item_id}', str(item_id)).replace('{a_TableName}', a_TableName)
log.Error(msg) a_Bot.GetLog().Error(msg)
return simple_message.WorkFuncResult(msg), None return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(msg)), None
result_work_func = await a_WorkFunc(a_CallbackQuery, item[0]) result_work_func = await a_WorkFunc(a_CallbackQuery, item[0])
if result_work_func is None or result_work_func.string_message is None: if result_work_func is None or result_work_func.m_BotMessage is None:
return result_work_func, result_work_func return result_work_func, result_work_func
if not result_work_func.item_access is None and not user_access.CheckAccessString(result_work_func.item_access, user_groups, a_AccessMode): if not result_work_func.item_access is None and not user_access.CheckAccess(a_Bot.GetRootIDs(), result_work_func.item_access, user_groups, a_AccessMode):
return simple_message.WorkFuncResult(access.access_denied_message), None return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(access_utils.access_denied_message)), None
return None, result_work_func return None, result_work_func
return CheckAccessBDItem return CheckAccessBDItem

78
template/bd_item_add.py

@ -3,23 +3,18 @@
# Добавление элемента в БД # Добавление элемента в БД
from bot_sys import user_access, bot_bd, log from bot_sys import user_access, bot_bd, bot_messages
from bot_modules import access, groups from bot_modules import access_utils, groups_utils
from template import simple_message, bd_item_select, bd_item from template import simple_message, bd_item_select, bd_item
from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
cancel_message = ''' cancel_message = '''
🚫 Добавление отменено 🚫 Добавление отменено
''' '''
def StartAddBDItemTemplate(a_FSM, a_FSMStart, a_MessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.ADD): def StartAddBDItemTemplate(a_Bot, a_FSM, a_FSMStart, a_MessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.ADD):
async def StartAddBDItem(a_CallbackQuery : types.CallbackQuery, state : FSMContext): async def StartAddBDItem(a_CallbackQuery, state):
user_id = str(a_CallbackQuery.from_user.id) user_id = str(a_CallbackQuery.from_user.id)
user_groups = groups.GetUserGroupData(user_id) user_groups = groups_utils.GetUserGroupData(a_Bot, user_id)
parent_id = bd_item.GetKeyDataFromCallbackMessage(a_CallbackQuery, a_Prefix) parent_id = bd_item.GetKeyDataFromCallbackMessage(a_CallbackQuery, a_Prefix)
res_of_work_func = None res_of_work_func = None
check = None check = None
@ -30,7 +25,7 @@ def StartAddBDItemTemplate(a_FSM, a_FSMStart, a_MessageFunc, a_ParentTableName,
item_data[a_ParentKeyFieldName] = parent_id item_data[a_ParentKeyFieldName] = parent_id
if parent_id: if parent_id:
check, res_of_work_func = await bd_item.CheckAccessBDItemTemplate(a_ParentTableName, a_ParentKeyFieldName, parent_id, a_MessageFunc, access_mode)(a_CallbackQuery) check, res_of_work_func = await bd_item.CheckAccessBDItemTemplate(a_Bot, a_ParentTableName, a_ParentKeyFieldName, parent_id, a_MessageFunc, access_mode)(a_CallbackQuery)
else: else:
res_of_work_func = await a_MessageFunc(a_CallbackQuery, None) res_of_work_func = await a_MessageFunc(a_CallbackQuery, None)
@ -39,36 +34,36 @@ def StartAddBDItemTemplate(a_FSM, a_FSMStart, a_MessageFunc, a_ParentTableName,
check.keyboard_func = a_FinishButtonFunc check.keyboard_func = a_FinishButtonFunc
return check return check
return res_of_work_func return res_of_work_func
return simple_message.SimpleMessageTemplate(StartAddBDItem, a_ButtonFunc, a_AccessFunc, access_mode) return simple_message.SimpleMessageTemplate(a_Bot, StartAddBDItem, a_ButtonFunc, None, a_AccessFunc, access_mode)
def FinishAddBDItemTemplate(a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text): def FinishAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text):
return FinishOrNextAddBDItemTemplate(a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_ButtonFunc, True, access_mode = access_mode, field_type = field_type) return FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_ButtonFunc, True, access_mode = access_mode, field_type = field_type)
def NextAddBDItemTemplate(a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text): def NextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text):
return FinishOrNextAddBDItemTemplate(a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, False, access_mode = access_mode, field_type = field_type) return FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, False, access_mode = access_mode, field_type = field_type)
def FinishOrNextAddBDItemTemplate(a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, a_Finish, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text): def FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, a_Finish, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text):
async def FinishAddBDItem(a_Message : types.CallbackQuery, state : FSMContext): async def FinishAddBDItem(a_Message, state):
state_func = None state_func = None
if a_Finish: if a_Finish:
state_func = state.finish state_func = state.finish
else: else:
state_func = a_FSM.next state_func = a_FSM.next
user_id = str(a_Message.from_user.id) user_id = str(a_Message.from_user.id)
user_groups = groups.GetUserGroupData(user_id) user_groups = groups_utils.GetUserGroupData(a_Bot, user_id)
error = None error = None
res_of_work_func = None res_of_work_func = None
check = None check = None
async with state.proxy() as item_data: async with state.proxy() as item_data:
if a_Message.text == bd_item.canсel_button_name: if a_Message.text == bd_item.canсel_button_name:
await state.finish() await state.finish()
return simple_message.WorkFuncResult(cancel_message, keyboard_func = a_FinishButtonFunc) return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(cancel_message), keyboard_func = a_FinishButtonFunc)
parent_id = None parent_id = None
if a_ParentKeyFieldName: if a_ParentKeyFieldName:
parent_id = item_data[a_ParentKeyFieldName] parent_id = item_data[a_ParentKeyFieldName]
if parent_id: if parent_id:
check, res_of_work_func = await bd_item.CheckAccessBDItemTemplate(a_ParentTableName, a_ParentKeyFieldName, parent_id, a_MessageFunc, access_mode)(a_Message) check, res_of_work_func = await bd_item.CheckAccessBDItemTemplate(a_Bot, a_ParentTableName, a_ParentKeyFieldName, parent_id, a_MessageFunc, access_mode)(a_Message)
else: else:
res_of_work_func = await a_MessageFunc(a_Message, None) res_of_work_func = await a_MessageFunc(a_Message, None)
@ -83,7 +78,7 @@ def FinishOrNextAddBDItemTemplate(a_FSM, a_AddBDItemFunc, a_ParentTableName, a_P
else: else:
if a_Message.photo == None or len(a_Message.photo) == 0: if a_Message.photo == None or len(a_Message.photo) == 0:
await state.finish() await state.finish()
return simple_message.WorkFuncResult(error_photo_type_message, keyboard_func = a_FinishButtonFunc) return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(error_photo_type_message), keyboard_func = a_FinishButtonFunc)
field_value = a_Message.photo[0].file_id field_value = a_Message.photo[0].file_id
else: else:
field_value = a_Message.text field_value = a_Message.text
@ -92,31 +87,32 @@ def FinishOrNextAddBDItemTemplate(a_FSM, a_AddBDItemFunc, a_ParentTableName, a_P
res, error = a_AddBDItemFunc(item_data, user_id) res, error = a_AddBDItemFunc(item_data, user_id)
await state_func() await state_func()
if error: if error:
return simple_message.WorkFuncResult(error) return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(error))
return res_of_work_func return res_of_work_func
return simple_message.SimpleMessageTemplate(FinishAddBDItem, a_ButtonFunc, a_AccessFunc, access_mode) return simple_message.SimpleMessageTemplate(a_Bot, FinishAddBDItem, a_ButtonFunc, None, a_AccessFunc, access_mode)
def AddBDItem3RegisterHandlers(dp, a_StartCheckFunc, a_FSM, a_FSMName, a_FSMDesc, a_FSMPhoto, a_AddBDItemFunc, a_AddNameMessageFunc, a_AddDescMessageFunc, a_AddPhotoMessageFunc, a_FinishMessageFunc, a_ParentPrefix, a_ParentTableName : str, a_ParentKeyFieldName, a_NameField, a_DescField, a_PhotoField, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.ADD): def AddBDItem3RegisterHandlers(a_Bot, a_StartCheckFunc, a_FSM, a_FSMName, a_FSMDesc, a_FSMPhoto, a_AddBDItemFunc, a_AddNameMessageFunc, a_AddDescMessageFunc, a_AddPhotoMessageFunc, a_FinishMessageFunc, a_ParentPrefix, a_ParentTableName : str, a_ParentKeyFieldName, a_NameField, a_DescField, a_PhotoField, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.ADD):
keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(a_AccessFunc, access_mode) keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, access_mode)
keyboard_skip_and_cancel = bd_item.GetSkipAndCancelKeyboardButtonsTemplate(a_AccessFunc, access_mode) keyboard_skip_and_cancel = bd_item.GetSkipAndCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, access_mode)
reg_func = dp.register_message_handler reg_func = a_Bot.RegisterMessageHandler
if a_ParentTableName: if a_ParentTableName:
reg_func = dp.register_callback_query_handler reg_func = a_Bot.RegisterCallbackHandler
reg_func(StartAddBDItemTemplate(a_FSM, a_FSMName, a_AddNameMessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), a_StartCheckFunc) reg_func(StartAddBDItemTemplate(a_Bot, a_FSM, a_FSMName, a_AddNameMessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), a_StartCheckFunc)
dp.register_message_handler(NextAddBDItemTemplate(a_FSM, None, a_ParentTableName, a_ParentKeyFieldName, a_NameField, a_AddDescMessageFunc, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.text), state = a_FSMName) # TODO: Сделать возможность не указывать все поля. пусть a_FSMName и a_NameField например могут быть пустыми. Возможно лучше вообще передавать список полей и их fsm
dp.register_message_handler(NextAddBDItemTemplate(a_FSM, None, a_ParentTableName, a_ParentKeyFieldName, a_DescField, a_AddPhotoMessageFunc, a_AccessFunc, keyboard_skip_and_cancel, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.text), state = a_FSMDesc) a_Bot.RegisterMessageHandler(NextAddBDItemTemplate(a_Bot, a_FSM, None, a_ParentTableName, a_ParentKeyFieldName, a_NameField, a_AddDescMessageFunc, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.text), state = a_FSMName)
dp.register_message_handler(FinishAddBDItemTemplate(a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_PhotoField, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.photo), content_types = ['photo', 'text'], state = a_FSMPhoto) a_Bot.RegisterMessageHandler(NextAddBDItemTemplate(a_Bot, a_FSM, None, a_ParentTableName, a_ParentKeyFieldName, a_DescField, a_AddPhotoMessageFunc, a_AccessFunc, keyboard_skip_and_cancel, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.text), state = a_FSMDesc)
a_Bot.RegisterMessageHandler(FinishAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_PhotoField, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.photo), content_types = ['photo', 'text'], state = a_FSMPhoto)
def AddBDItem1RegisterHandlers(dp, a_StartCheckFunc, a_FSM, a_AddBDItemFunc, a_AddMessageFunc, a_FinishMessageFunc, a_ParentPrefix, a_ParentTableName : str, a_ParentKeyFieldName, a_FieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, a_FieldType, access_mode = user_access.AccessMode.ADD): def AddBDItem1RegisterHandlers(a_Bot, a_StartCheckFunc, a_FSM, a_AddBDItemFunc, a_AddMessageFunc, a_FinishMessageFunc, a_ParentPrefix, a_ParentTableName : str, a_ParentKeyFieldName, a_FieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, a_FieldType, access_mode = user_access.AccessMode.ADD):
keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(a_AccessFunc, access_mode) keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, access_mode)
reg_func = dp.register_message_handler reg_func = a_Bot.RegisterMessageHandler
if a_ParentTableName: if a_ParentTableName:
reg_func = dp.register_callback_query_handler reg_func = a_Bot.RegisterCallbackHandler
reg_func(StartAddBDItemTemplate(a_FSM, a_FSM.bd_item, a_AddMessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), a_StartCheckFunc) reg_func(StartAddBDItemTemplate(a_Bot, a_FSM, a_FSM.bd_item, a_AddMessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), a_StartCheckFunc)
finish_handler = FinishAddBDItemTemplate(a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, access_mode, field_type = a_FieldType) finish_handler = FinishAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, access_mode, field_type = a_FieldType)
if a_FieldType == bd_item.FieldType.photo: if a_FieldType == bd_item.FieldType.photo:
dp.register_message_handler(finish_handler, content_types = ['photo', 'text'], state = a_FSM.bd_item) a_Bot.RegisterMessageHandler(finish_handler, content_types = ['photo', 'text'], state = a_FSM.bd_item)
else: else:
dp.register_message_handler(finish_handler, state = a_FSM.bd_item) a_Bot.RegisterMessageHandler(finish_handler, state = a_FSM.bd_item)

31
template/bd_item_delete.py

@ -4,40 +4,41 @@
# удаление элемента в БД # удаление элемента в БД
from bot_sys import user_access, bot_bd, keyboard from bot_sys import user_access, bot_bd, keyboard
from bot_modules import access, groups from bot_modules import access_utils, groups_utils
from template import simple_message, bd_item_select, bd_item from template import simple_message, bd_item_select, bd_item
from aiogram import types def DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_Prefix, a_AccessFunc, a_ButtonFunc, delete = True, access_mode = user_access.AccessMode.DELETE):
async def DeleteBDItem(a_CallbackQuery, state = None):
def DeleteBDItemTemplate(a_TableName, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_Prefix, a_AccessFunc, a_ButtonFunc, delete = True, access_mode = user_access.AccessMode.DELETE):
async def DeleteBDItem(a_CallbackQuery : types.CallbackQuery, state = None):
user_id = str(a_CallbackQuery.from_user.id) user_id = str(a_CallbackQuery.from_user.id)
user_groups = groups.GetUserGroupData(user_id) user_groups = groups_utils.GetUserGroupData(a_Bot, user_id)
item_id = str(a_CallbackQuery.data).replace(a_Prefix, '') item_id = str(a_CallbackQuery.data).replace(a_Prefix, '')
check, res_of_pre_del = await bd_item.CheckAccessBDItemTemplate(a_TableName, a_KeyName, item_id, a_PreDeleteWorkFunc, access_mode)(a_CallbackQuery) check, res_of_pre_del = await bd_item.CheckAccessBDItemTemplate(a_Bot, a_TableName, a_KeyName, item_id, a_PreDeleteWorkFunc, access_mode)(a_CallbackQuery)
if not check is None: if not check is None:
return check return check
if not delete: if not delete:
return res_of_pre_del return res_of_pre_del
result, error = bd_item.DeleteBDItemInTableTemplate(a_TableName, a_KeyName)(item_id) result, error = bd_item.DeleteBDItemInTableTemplate(a_Bot, a_TableName, a_KeyName)(item_id)
if not error is None: if not error is None:
msg = error msg = error
log.Error(error) a_Bot.GetLog().Error(error)
return simple_message.WorkFuncResult(error) return simple_message.WorkFuncResult(error)
return await a_PostDeleteWorkFunc(a_CallbackQuery, item_id) return await a_PostDeleteWorkFunc(a_CallbackQuery, item_id)
return simple_message.SimpleMessageTemplate(DeleteBDItem, a_ButtonFunc, a_AccessFunc, access_mode) return simple_message.SimpleMessageTemplate(a_Bot, DeleteBDItem, a_ButtonFunc, None, a_AccessFunc, access_mode)
def DeleteBDItemRegisterHandlers(dp, a_PrevPrefix, a_StartCheckFunc, a_TableName : str, a_KeyName, a_ParentIDFieldName,a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.DELETE): def SelectAndDeleteBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_StartCheckFunc, a_TableName : str, a_KeyName, a_ParentIDFieldName,a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.DELETE):
reg_func = dp.register_message_handler reg_func = a_Bot.RegisterMessageHandler
if a_ParentIDFieldName: if a_ParentIDFieldName:
reg_func = dp.register_callback_query_handler reg_func = a_Bot.RegisterCallbackHandler
a_Prefix = bd_item.HashPrefix(f'delete_{a_TableName}_{a_KeyName}:') a_Prefix = bd_item.HashPrefix(f'delete_{a_TableName}_{a_KeyName}:')
sel_handler = bd_item_select.SelectDBItemTemplate(a_TableName, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_Prefix, access_mode) sel_handler = bd_item_select.SelectDBItemTemplate(a_Bot, a_TableName, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_Prefix, access_mode)
reg_func(sel_handler, a_StartCheckFunc) reg_func(sel_handler, a_StartCheckFunc)
dp.register_callback_query_handler(DeleteBDItemTemplate(a_TableName, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_Prefix)) a_Bot.RegisterCallbackHandler(DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_Prefix))
def DeleteBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_TableName : str, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.DELETE):
a_Bot.RegisterCallbackHandler(DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_PrevPrefix, a_AccessFunc, a_ButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_PrevPrefix))

40
template/bd_item_edit.py

@ -3,14 +3,10 @@
# Редактирование элемента в БД # Редактирование элемента в БД
from bot_sys import user_access, bot_bd, log from bot_sys import user_access, bot_bd
from bot_modules import access, groups from bot_modules import access_utils, groups_utils
from template import simple_message, bd_item_select, bd_item, bd_item_add from template import simple_message, bd_item_select, bd_item, bd_item_add
from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
cancel_message = ''' cancel_message = '''
🚫 Редактирование отменено 🚫 Редактирование отменено
''' '''
@ -19,33 +15,35 @@ error_photo_type_message = '''
🚫 Фотографий не найдено 🚫 Фотографий не найдено
''' '''
def StartEditBDItemTemplate(a_FSM, a_MessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.EDIT): def StartEditBDItemTemplate(a_Bot, a_FSM, a_MessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.EDIT):
return bd_item_add.StartAddBDItemTemplate(a_FSM, a_FSM.item_field, a_MessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = access_mode) return bd_item_add.StartAddBDItemTemplate(a_Bot, a_FSM, a_FSM.item_field, a_MessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = access_mode)
def FinishEditBDItemTemplate(a_FSM, a_TableName, a_KeyName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.EDIT, field_type = bd_item.FieldType.text): def FinishEditBDItemTemplate(a_Bot, a_FSM, a_TableName, a_KeyName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_OnChangeFunc, access_mode = user_access.AccessMode.EDIT, field_type = bd_item.FieldType.text):
def EditBDItemFunc(a_ItemData, a_UserID): def EditBDItemFunc(a_ItemData, a_UserID):
item_id = a_ItemData[a_KeyName] item_id = a_ItemData[a_KeyName]
field_value = a_ItemData[a_FieldName] field_value = a_ItemData[a_FieldName]
res, error = bd_item.EditBDItemInTableTemplate(a_TableName, a_KeyName, a_FieldName)(item_id, field_value) res, error = bd_item.EditBDItemInTableTemplate(a_Bot, a_TableName, a_KeyName, a_FieldName)(item_id, field_value)
if error: if error:
log.Error(f'Пользователю {a_UserID} не удалось изменить поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={field_value}. Ошибка: {error}') a_Bot.GetLog().Error(f'Пользователю {a_UserID} не удалось изменить поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={field_value}. Ошибка: {error}')
else: else:
log.Success(f'Пользователь {a_UserID} изменил поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={field_value}.') a_Bot.GetLog().Success(f'Пользователь {a_UserID} изменил поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={field_value}.')
a_OnChangeFunc()
return res, error return res, error
return bd_item_add.FinishAddBDItemTemplate(a_FSM, EditBDItemFunc, a_TableName, a_KeyName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode, field_type = field_type) return bd_item_add.FinishAddBDItemTemplate(a_Bot, a_FSM, EditBDItemFunc, a_TableName, a_KeyName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode, field_type = field_type)
def EditBDItemRegisterHandlers(dp, a_PrevPrefix, a_FSM, a_StartCheckFunc, a_StartMessage, a_EditMessageFunc, a_FinishMessageFunc, a_TableName : str, a_KeyName, a_ParentIDFieldName, a_FieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.EDIT, field_type = bd_item.FieldType.text): def EditBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_FSM, a_StartCheckFunc, a_StartMessage, a_EditMessageFunc, a_FinishMessageFunc, a_TableName : str, a_KeyName, a_ParentIDFieldName, a_FieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, a_OnChangeFunc, access_mode = user_access.AccessMode.EDIT, field_type = bd_item.FieldType.text):
reg_func = dp.register_message_handler reg_func = a_Bot.RegisterMessageHandler
if a_ParentIDFieldName: if a_ParentIDFieldName:
reg_func = dp.register_callback_query_handler reg_func = a_Bot.RegisterCallbackHandler
keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(a_AccessFunc, access_mode) keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, access_mode)
a_Prefix = bd_item.HashPrefix(f'edit_{a_TableName}_{a_KeyName}_{a_FieldName}:') a_Prefix = bd_item.HashPrefix(f'edit_{a_TableName}_{a_KeyName}_{a_FieldName}:')
sel_handler = bd_item_select.SelectDBItemTemplate(a_TableName, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_Prefix, access_mode) sel_handler = bd_item_select.SelectDBItemTemplate(a_Bot, a_TableName, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_Prefix, access_mode)
reg_func(sel_handler, a_StartCheckFunc) reg_func(sel_handler, a_StartCheckFunc)
dp.register_callback_query_handler(StartEditBDItemTemplate(a_FSM, a_EditMessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_Prefix)) a_Bot.RegisterCallbackHandler(StartEditBDItemTemplate(a_Bot, a_FSM, a_EditMessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_Prefix))
if field_type == bd_item.FieldType.photo: if field_type == bd_item.FieldType.photo:
dp.register_message_handler(FinishEditBDItemTemplate(a_FSM, a_TableName, a_KeyName, a_FieldName, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, access_mode, field_type = field_type), content_types = ['photo', 'text'], state = a_FSM.item_field) a_Bot.RegisterMessageHandler(FinishEditBDItemTemplate(a_Bot, a_FSM, a_TableName, a_KeyName, a_FieldName, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, a_OnChangeFunc, access_mode, field_type = field_type), content_types = ['photo', 'text'], state = a_FSM.item_field)
else: else:
dp.register_message_handler(FinishEditBDItemTemplate(a_FSM, a_TableName, a_KeyName, a_FieldName, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, access_mode, field_type = field_type), state = a_FSM.item_field) a_Bot.RegisterMessageHandler(FinishEditBDItemTemplate(a_Bot, a_FSM, a_TableName, a_KeyName, a_FieldName, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, a_OnChangeFunc, access_mode, field_type = field_type), state = a_FSM.item_field)

32
template/bd_item_select.py

@ -4,19 +4,17 @@
# Просмотр элемента в БД # Просмотр элемента в БД
from bot_sys import user_access, bot_bd, keyboard from bot_sys import user_access, bot_bd, keyboard
from bot_modules import access, groups from bot_modules import access_utils, groups_utils
from template import simple_message, bd_item from template import simple_message, bd_item
from aiogram import types def GetBDItemsListKeyboardButtonsTemplate(a_Bot, a_TableName : str, a_ParentIDFieldName, a_PrevPrefix, a_NextPrefix : str, a_GetButtonNameAndKeyValueAndAccessFunc, access_mode = user_access.AccessMode.VIEW):
def GetBDItemsListKeyboardButtonsTemplate(a_TableName : str, a_ParentIDFieldName, a_PrevPrefix, a_NextPrefix : str, a_GetButtonNameAndKeyValueAndAccessFunc, access_mode = user_access.AccessMode.VIEW):
def GetBDItemsListKeyboardButtons(a_Message, a_UserGroups): def GetBDItemsListKeyboardButtons(a_Message, a_UserGroups):
parent_id = bd_item.GetKeyDataFromCallbackMessage(a_Message, a_PrevPrefix) parent_id = bd_item.GetKeyDataFromCallbackMessage(a_Message, a_PrevPrefix)
items = [] items = []
if a_ParentIDFieldName and parent_id and parent_id != '': if a_ParentIDFieldName and parent_id and parent_id != '':
items = bd_item.GetBDItemsTemplate(a_TableName, a_ParentIDFieldName)(parent_id) items = bd_item.GetBDItemsTemplate(a_Bot, a_TableName, a_ParentIDFieldName)(parent_id)
else: else:
items = bd_item.GetAllItemsTemplate(a_TableName)() items = bd_item.GetAllItemsTemplate(a_Bot, a_TableName)()
items_button_list = [] items_button_list = []
for t in items: for t in items:
@ -24,28 +22,28 @@ def GetBDItemsListKeyboardButtonsTemplate(a_TableName : str, a_ParentIDFieldName
if access is None: if access is None:
access = '' access = ''
if bname: if bname:
b = keyboard.InlineButton(bname, a_NextPrefix, key_value, access, access_mode) b = keyboard.InlineButtonWithAccess(bname, a_NextPrefix, key_value, access, access_mode)
items_button_list += [b] items_button_list += [b]
return keyboard.MakeInlineKeyboard(items_button_list, a_UserGroups) return keyboard.MakeInlineKeyboardButtons(a_Bot, items_button_list, a_UserGroups)
return GetBDItemsListKeyboardButtons return GetBDItemsListKeyboardButtons
def SelectDBItemTemplate(a_TableName : str, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_NextPrefix, access_mode = user_access.AccessMode.VIEW): def SelectDBItemTemplate(a_Bot, a_TableName : str, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_NextPrefix, access_mode = user_access.AccessMode.VIEW):
keyboard_func = GetBDItemsListKeyboardButtonsTemplate(a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_NextPrefix, a_GetButtonNameAndKeyValueAndAccessFunc) inline_keyboard_func = GetBDItemsListKeyboardButtonsTemplate(a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_NextPrefix, a_GetButtonNameAndKeyValueAndAccessFunc)
return simple_message.InfoMessageTemplate(a_StartMessage, keyboard_func, a_AccessFunc, access_mode) return simple_message.InfoMessageTemplate(a_Bot, a_StartMessage, None, inline_keyboard_func, a_AccessFunc, access_mode)
def FirstSelectBDItemRegisterHandlers(dp, a_PrefixBase, a_ButtonName, a_TableName : str, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = user_access.AccessMode.VIEW): def FirstSelectBDItemRegisterHandlers(a_Bot, a_PrefixBase, a_ButtonName, a_TableName : str, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = user_access.AccessMode.VIEW):
a_Prefix = bd_item.HashPrefix(f'first_select_{a_TableName}_{a_KeyName}_in_base_{a_PrefixBase}:') a_Prefix = bd_item.HashPrefix(f'first_select_{a_TableName}_{a_KeyName}_in_base_{a_PrefixBase}:')
sel_handler = SelectDBItemTemplate(a_TableName, None, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, None, a_Prefix, access_mode = access_mode) sel_handler = SelectDBItemTemplate(a_Bot, a_TableName, None, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, None, a_Prefix, access_mode = access_mode)
dp.register_message_handler(sel_handler, text = a_ButtonName) a_Bot.RegisterMessageHandler(sel_handler, bd_item.GetCheckForTextFunc(a_ButtonName))
return a_Prefix return a_Prefix
def NextSelectBDItemRegisterHandlers(dp, a_PrevPrefix, a_ParentIDFieldName, a_TableName : str, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = user_access.AccessMode.VIEW): def NextSelectBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_ParentIDFieldName, a_TableName : str, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = user_access.AccessMode.VIEW):
a_Prefix = bd_item.HashPrefix(f'next_select_{a_TableName}_{a_KeyName}_{a_ParentIDFieldName}_after_prefix_{a_PrevPrefix}:') a_Prefix = bd_item.HashPrefix(f'next_select_{a_TableName}_{a_KeyName}_{a_ParentIDFieldName}_after_prefix_{a_PrevPrefix}:')
sel_handler = SelectDBItemTemplate(a_TableName, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_Prefix, access_mode = access_mode) sel_handler = SelectDBItemTemplate(a_Bot, a_TableName, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_Prefix, access_mode = access_mode)
dp.register_callback_query_handler(sel_handler, bd_item.GetCheckForPrefixFunc(a_PrevPrefix)) a_Bot.RegisterCallbackHandler(sel_handler, bd_item.GetCheckForPrefixFunc(a_PrevPrefix))
return a_Prefix return a_Prefix

24
template/bd_item_view.py

@ -4,21 +4,19 @@
# Просмотр элемента в БД # Просмотр элемента в БД
from bot_sys import user_access, bot_bd, keyboard from bot_sys import user_access, bot_bd, keyboard
from bot_modules import access, groups from bot_modules import access_utils, groups_utils
from template import simple_message, bd_item_select, bd_item_delete, bd_item from template import simple_message, bd_item_select, bd_item_delete, bd_item
from aiogram import types def ShowBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_WorkFunc, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW):
return bd_item_delete.DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_WorkFunc, None, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode = access_mode, delete = False)
def ShowBDItemTemplate(a_TableName, a_KeyName, a_WorkFunc, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW): def ShowBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW):
return bd_item_delete.DeleteBDItemTemplate(a_TableName, a_KeyName, a_WorkFunc, None, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode = access_mode, delete = False) a_Bot.RegisterCallbackHandler(ShowBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_ShowItemWorkFunc, a_PrevPrefix, a_AccessFunc, a_ButtonFunc, access_mode = access_mode), bd_item.GetCheckForPrefixFunc(a_PrevPrefix))
def ShowBDItemRegisterHandlers(dp, a_PrevPrefix, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW): def FirstSelectAndShowBDItemRegisterHandlers(a_Bot, a_ButtonName, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW):
dp.register_callback_query_handler(ShowBDItemTemplate(a_TableName, a_KeyName, a_ShowItemWorkFunc, a_PrevPrefix, a_AccessFunc, a_ButtonFunc, access_mode = access_mode), bd_item.GetCheckForPrefixFunc(a_PrevPrefix)) a_Prefix = bd_item_select.FirstSelectBDItemRegisterHandlers(a_Bot, '', a_ButtonName, a_TableName, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = access_mode)
ShowBDItemRegisterHandlers(a_Bot, a_Prefix, a_TableName, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode)
def FirstSelectAndShowBDItemRegisterHandlers(dp, a_ButtonName, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW): def LastSelectAndShowBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_ParentIDFieldName, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW):
a_Prefix = bd_item_select.FirstSelectBDItemRegisterHandlers(dp, '', a_ButtonName, a_TableName, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = access_mode) a_Prefix = bd_item_select.NextSelectBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_ParentIDFieldName, a_TableName, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = access_mode)
ShowBDItemRegisterHandlers(dp, a_Prefix, a_TableName, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode) ShowBDItemRegisterHandlers(a_Bot, a_Prefix, a_TableName, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode)
def LastSelectAndShowBDItemRegisterHandlers(dp, a_PrevPrefix, a_ParentIDFieldName, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW):
a_Prefix = bd_item_select.NextSelectBDItemRegisterHandlers(dp, a_PrevPrefix, a_ParentIDFieldName, a_TableName, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = access_mode)
ShowBDItemRegisterHandlers(dp, a_Prefix, a_TableName, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode)

39
template/file_message.py

@ -4,32 +4,37 @@
# Сообщения для работы с файлами # Сообщения для работы с файлами
from bot_sys import log, config, user_access from bot_sys import log, config, user_access
from bot_modules import access, groups from bot_modules import groups_utils
from aiogram import Bot, types from template import simple_message
from aiogram.dispatcher import Dispatcher def BackupFileTemplate(a_Bot, a_Path, a_CaptionMessage, a_AccessFunc, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_ErrorMessage, access_mode = user_access.AccessMode.EDIT):
bot = Bot(token=config.GetTelegramBotApiToken(), parse_mode=types.ParseMode.HTML)
def BackupFileTemplate(a_Path, a_CaptionMessage, a_AccessFunc, a_ButtonFunc, a_ErrorMessage):
async def BackupFile(a_Message): async def BackupFile(a_Message):
user_id = str(a_Message.from_user.id) user_id = str(a_Message.from_user.id)
user_groups= groups.GetUserGroupData(user_id) user_groups= groups_utils.GetUserGroupData(a_Bot, user_id)
if not user_access.CheckAccessString(a_AccessFunc(), user_groups, user_access.AccessMode.EDIT): if not user_access.CheckAccess(a_Bot.GetRootIDs(), a_AccessFunc(), user_groups, access_mode):
return await a_Message.answer(access.access_denied_message, reply_markup = a_ButtonFunc(a_Message, user_groups)) 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: if document is None:
return await a_Message.answer(user_id, error_backup_message, reply_markup = a_ButtonFunc(a_Message, user_groups)) return simple_message.SendMessage(a_Bot, a_ErrorMessage, a_GetButtonsFunc, None, user_id, 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)) 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 return BackupFile
async def GetFile(a_Path): async def GetFile(a_Bot, a_Path):
try: try:
document = open(a_Path, 'rb') document = open(a_Path, 'rb')
log.Success(f'Загружен файл {a_Path}') a_Bot.GetLog().Success(f'Загружен файл {a_Path}')
return document return document
except Exception as e: except Exception as e:
log.Error(f'Не удалось загрузить файл {a_Path}. Ошибка {str(e)}') a_Bot.GetLog().Error(f'Не удалось загрузить файл {a_Path}. Ошибка {str(e)}')
return None return None

69
template/simple_message.py

@ -3,53 +3,78 @@
# Простые информационные сообщения # Простые информационные сообщения
from bot_sys import user_access, config from bot_sys import user_access
from bot_modules import access, groups from bot_modules import access_utils, groups_utils
from aiogram import types from aiogram import types
from aiogram import Bot def ProxyGetButtonsTemplate(a_GetButtonsFunc1):
bot = Bot(token=config.GetTelegramBotApiToken(), parse_mode = types.ParseMode.HTML) def ReturnNone(a_Message, user_groups):
return None
if a_GetButtonsFunc1:
return a_GetButtonsFunc1
else:
return ReturnNone
async def SendMessage(a_Bot, a_BotMessage, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_UserID, a_Message, user_groups, parse_mode=None):
return await a_Bot.SendMessage(
a_UserID,
a_BotMessage.GetDesc(),
a_BotMessage.GetPhotoID(),
ProxyGetButtonsTemplate(a_GetButtonsFunc)(a_Message, user_groups),
ProxyGetButtonsTemplate(a_GetInlineButtonsFunc)(a_Message, user_groups),
parse_mode = parse_mode
)
async def AccessDeniedMessage(a_Bot, a_GetButtonsFunc, a_UserID, a_Message, user_groups):
return await SendMessage(a_Bot, bot_messages.MakeBotMessage(access_utils.access_denied_message), a_GetButtonsFunc, None, a_UserID, a_Message, user_groups)
class WorkFuncResult(): class WorkFuncResult():
def __init__(self, a_StringMessage : str, photo_id = None, item_access = None, keyboard_func = None): def __init__(self, a_BotMessage, keyboard_func = None, Inline_keyboard_func = None, item_access = None):
self.string_message = a_StringMessage self.m_BotMessage = a_BotMessage
self.photo_id = photo_id
self.item_access = item_access self.item_access = item_access
self.keyboard_func = keyboard_func self.keyboard_func = keyboard_func
self.Inline_keyboard_func = Inline_keyboard_func
def InfoMessageTemplate(a_Bot, a_HelpMessage, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_AccessFunc, access_mode = user_access.AccessMode.VIEW):
def InfoMessageTemplate(a_HelpMessage, a_GetButtonsFunc, a_AccessFunc, access_mode = user_access.AccessMode.VIEW):
async def GetMessage(a_Message : types.message, state = None): async def GetMessage(a_Message : types.message, state = None):
return WorkFuncResult(a_HelpMessage) return WorkFuncResult(a_HelpMessage)
return SimpleMessageTemplate(GetMessage, a_GetButtonsFunc, a_AccessFunc, access_mode) return SimpleMessageTemplate(a_Bot, GetMessage, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_AccessFunc, access_mode = access_mode)
def SimpleMessageTemplate(a_WorkFunc, a_GetButtonsFunc, a_AccessFunc, access_mode = user_access.AccessMode.VIEW): def SimpleMessageTemplate(a_Bot, a_WorkFunc, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_AccessFunc, access_mode = user_access.AccessMode.VIEW):
async def SimpleMessage(a_Message : types.message, state = None): async def SimpleMessage(a_Message : types.message, state = None):
user_id = str(a_Message.from_user.id) user_id = str(a_Message.from_user.id)
user_groups = groups.GetUserGroupData(user_id) lang = str(a_Message.from_user.language_code)
if not user_access.CheckAccessString(a_AccessFunc(), user_groups, access_mode): user_groups = groups_utils.GetUserGroupData(a_Bot, user_id)
return await bot.send_message(a_Message.from_user.id, access.access_denied_message, reply_markup = a_GetButtonsFunc(a_Message, user_groups)) if not user_access.CheckAccess(a_Bot.GetRootIDs(), a_AccessFunc(), user_groups, access_mode):
return await AccessDeniedMessage(a_Bot, a_GetButtonsFunc, user_id, a_Message, user_groups)
res = await a_WorkFunc(a_Message, state = state) res = await a_WorkFunc(a_Message, state = state)
if res is None: if res is None:
return return
Inline_keyboard_func = a_GetInlineButtonsFunc
if res.Inline_keyboard_func:
Inline_keyboard_func = res.Inline_keyboard_func
keyboard_func = a_GetButtonsFunc keyboard_func = a_GetButtonsFunc
if res.keyboard_func: if res.keyboard_func:
keyboard_func = res.keyboard_func keyboard_func = res.keyboard_func
msg = res.string_message msg = res.m_BotMessage
if msg is None: if msg is None:
return return
photo_id = res.photo_id 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(a_Bot, keyboard_func, user_id, a_Message, user_groups)
if not res.item_access is None and not user_access.CheckAccessString(res.item_access, user_groups, access_mode):
return await bot.send_message(a_Message.from_user.id, access.access_denied_message, reply_markup = keyboard_func(a_Message, user_groups))
if photo_id is None or photo_id == 0 or photo_id == '0': msg = msg.GetMessageForLang(lang).StaticCopy()
return await bot.send_message(a_Message.from_user.id, msg, reply_markup = keyboard_func(a_Message, user_groups))
await bot.send_photo(user_id, photo_id, msg, reply_markup = keyboard_func(a_Message, user_groups)) await a_Bot.SendMessage(
user_id,
msg.GetDesc(),
msg.GetPhotoID(),
ProxyGetButtonsTemplate(keyboard_func)(a_Message, user_groups),
ProxyGetButtonsTemplate(Inline_keyboard_func)(a_Message, user_groups)
)
return SimpleMessage return SimpleMessage

59
template/sql_request.py

@ -3,11 +3,9 @@
# Сообщения для работы с sql запросами # Сообщения для работы с sql запросами
from bot_sys import bot_bd, log, config, user_access, keyboard from bot_sys import user_access, keyboard, bot_messages
from bot_modules import access, groups from bot_modules import groups_utils
from template import bd_item, simple_message
from aiogram import types
from aiogram.dispatcher import FSMContext
canсel_button_name = "🚫 Отменить" canсel_button_name = "🚫 Отменить"
@ -15,46 +13,53 @@ cancel_message = '''
🚫 Запрос к БД отменён 🚫 Запрос к БД отменён
''' '''
def GetCancelKeyboardButtons(a_Message, a_UserGroups, a_AccessFunc, a_AccessMode): def GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, a_AccessMode):
def GetCancelKeyboardButtons(a_Message, a_UserGroups):
print ('canсel_button_name', canсel_button_name)
cur_buttons = [ cur_buttons = [
keyboard.ButtonWithAccess(canсel_button_name, a_AccessMode, a_AccessFunc()) keyboard.ButtonWithAccess(canсel_button_name, a_AccessMode, a_AccessFunc())
] ]
return keyboard.MakeKeyboard(cur_buttons, a_UserGroups) return keyboard.MakeButtons(a_Bot, cur_buttons, a_UserGroups)
return GetCancelKeyboardButtons
def RequestToBDTemplate(a_StartMessage, a_AccessFunc, a_FSM, a_AccessMode): def RequestToBDTemplate(a_Bot, a_StartMessage, a_GetButtonsFunc, a_AccessFunc, a_FSM, a_AccessMode):
async def RequestToBDStart(a_Message : types.message): async def RequestToBDStart(a_Message):
user_id = str(a_Message.from_user.id) user_id = str(a_Message.from_user.id)
user_groups = groups.GetUserGroupData(user_id) user_groups = groups_utils.GetUserGroupData(a_Bot, user_id)
if not user_access.CheckAccessString(a_AccessFunc(), user_groups, a_AccessMode): if not user_access.CheckAccess(a_Bot.GetRootIDs(), a_AccessFunc(), user_groups, a_AccessMode):
return await a_Message.answer(access.access_denied_message, reply_markup = GetCancelKeyboardButtons(a_Message, user_groups, a_AccessFunc, a_AccessMode)) return await simple_message.AccessDeniedMessage(a_Bot, a_GetButtonsFunc, user_id, a_Message, user_groups)
await a_FSM.sqlRequest.set() await a_FSM.sqlRequest.set()
await a_Message.answer(a_StartMessage, reply_markup = GetCancelKeyboardButtons(a_Message, user_groups, a_AccessFunc, a_AccessMode), parse_mode='Markdown') print ('a_FSM.sqlRequest.set()', a_StartMessage)
await simple_message.SendMessage(a_Bot, a_StartMessage, GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, a_AccessMode), None, user_id, a_Message, user_groups, parse_mode='Markdown')
return RequestToBDStart return RequestToBDStart
def RequestToBDFinishTemplate(a_GetButtonsFunc, a_AccessFunc, a_AccessMode): def RequestToBDFinishTemplate(a_Bot, a_GetButtonsFunc, a_AccessFunc, a_AccessMode):
async def RequestToBDFinish(a_Message : types.message, state : FSMContext): async def RequestToBDFinish(a_Message, state):
user_id = str(a_Message.from_user.id) user_id = str(a_Message.from_user.id)
user_groups = groups.GetUserGroupData(user_id) user_groups = groups_utils.GetUserGroupData(a_Bot, user_id)
if not user_access.CheckAccessString(a_AccessFunc(), user_groups, a_AccessMode): if not user_access.CheckAccess(a_Bot.GetRootIDs(), a_AccessFunc(), user_groups, a_AccessMode):
return await a_Message.answer(access.access_denied_message, reply_markup = a_GetButtonsFunc(a_Message, user_groups)) return await simple_message.AccessDeniedMessage(a_Bot, a_GetButtonsFunc, user_id, a_Message, user_groups)
result = '' result = ''
async with state.proxy() as prjData: async with state.proxy() as prjData:
if a_Message.text == canсel_button_name: if a_Message.text == canсel_button_name:
await state.finish() await state.finish()
return await a_Message.answer(cancel_message, reply_markup = a_GetButtonsFunc(a_Message, user_groups)) return await simple_message.SendMessage(a_Bot, bot_messages.MakeBotMessage(cancel_message), a_GetButtonsFunc, None, user_id, a_Message, user_groups)
sql_request = a_Message.text sql_request = a_Message.text
log.Success(f'Сделан запрос [{sql_request}] пользователем {a_Message.from_user.id}.') a_Bot.GetLog().Success(f'Сделан запрос [{sql_request}] пользователем {a_Message.from_user.id}.')
result, error = bot_bd.SQLRequestToBD(sql_request, commit = True, return_error = True) result, error = a_Bot.SQLRequest(sql_request, commit = True, return_error = True)
if not error is None: if not error is None:
log.Error(f'Ошибка при выполнении запроса [{sql_request}] от пользователя {a_Message.from_user.id} ответ следующий [{str(error)}].') a_Bot.GetLog().Error(f'Ошибка при выполнении запроса [{sql_request}] от пользователя {a_Message.from_user.id} ответ следующий [{str(error)}].')
result = str(error) result = str(error)
else: else:
log.Success(f'Результат запроса [{sql_request}] от пользователя {a_Message.from_user.id} следующий [{result}].') a_Bot.GetLog().Success(f'Результат запроса [{sql_request}] от пользователя {a_Message.from_user.id} следующий [{result}].')
await state.finish() await state.finish()
await a_Message.answer(str(result), reply_markup = a_GetButtonsFunc(a_Message, user_groups)) await simple_message.SendMessage(a_Bot, bot_messages.MakeBotMessage(str(result)), a_GetButtonsFunc, None, user_id, a_Message, user_groups)
return RequestToBDFinish return RequestToBDFinish
def RequestToBDRegisterHandlers(dp, a_RequestButtonName, a_RequestStartMessage, a_FSM, a_GetButtonsFunc, a_AccessMode, a_AccessFunc): def RequestToBDRegisterHandlers(a_Bot, a_RequestButtonName, a_RequestStartMessage, a_FSM, a_GetButtonsFunc, a_AccessMode, a_AccessFunc):
dp.register_message_handler(RequestToBDTemplate(a_RequestStartMessage, a_AccessFunc, a_FSM, a_AccessMode), text = a_RequestButtonName) a_Bot.RegisterMessageHandler(RequestToBDTemplate(a_Bot, a_RequestStartMessage, a_GetButtonsFunc, a_AccessFunc, a_FSM, a_AccessMode), bd_item.GetCheckForTextFunc(a_RequestButtonName))
dp.register_message_handler(RequestToBDFinishTemplate(a_GetButtonsFunc, a_AccessFunc, a_AccessMode), state = a_FSM.sqlRequest) a_Bot.RegisterMessageHandler(RequestToBDFinishTemplate(a_Bot, a_GetButtonsFunc, a_AccessFunc, a_AccessMode), None, state = a_FSM.sqlRequest)

Loading…
Cancel
Save