# -*- coding: utf8 -*- # Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) # Модуль для редактирования и просмотра таблицы в БД from bot_sys import keyboard, user_access, bd_table, bot_bd, bot_subscribes from bot_modules import access_utils, mod_simple_message, groups_utils from template import simple_message, bd_item, bd_item_select, bd_item_view, bd_item_delete, bd_item_add, bd_item_edit from aiogram.dispatcher import FSMContext from aiogram.dispatcher.filters.state import State, StatesGroup from enum import Enum from enum import auto def EditButton(a_BDTableDestiny): return 'edit ' + str(a_BDTableDestiny) def EnumButton(a_EnumItem): return 'enum ' + str(a_EnumItem) def EditMessage(a_BDTableDestiny): return 'edit ' + str(a_BDTableDestiny) def CreateMessage(a_BDTableDestiny): return 'create ' + str(a_BDTableDestiny) def EnumMessageForView(a_EnumItem): return 'enum ' + str(a_EnumItem) def NotificationMessage(a_EnumItem): return 'notification ' + str(a_EnumItem) def SubscribeMessage(a_EnumItem): return 'subscribe ' + str(a_EnumItem) class ButtonNames(Enum): LIST = auto() ADD = auto() EDIT = auto() DEL = auto() class Messages(Enum): SELECT = auto() ERROR_FIND = auto() OPEN = auto() SUCCESS_CREATE = auto() START_EDIT = auto() SELECT_TO_EDIT = auto() SUCCESS_EDIT = auto() SELECT_TO_DELETE = auto() SUCCESS_DELETE = auto() def GetCurItem(a_Bot, a_TableName, a_KeyName, a_KeyValue): items = bd_item.GetBDItemsTemplate(a_Bot, a_TableName, a_KeyName)(a_KeyValue) if len(items) == 1: return items[0] return None create_fsm_create_cmd = ''' class FSMCreate{a_ModName}(StatesGroup): {items} fsm = FSMCreate{a_ModName} ''' def MakeFSMForAdd(a_ModName, a_Fields): cmd = create_fsm_create_cmd.replace("{a_ModName}", a_ModName) items = "" for i in range(len(a_Fields)): items += f"\titem{i} = State()\n" cmd = cmd.replace("{items}", items) _locals = locals() exec(cmd, globals(), _locals) return _locals['fsm'] edit_fsm_cmd = ''' class FSMEdit{a_ModName}_{a_FieldName}_Item(StatesGroup): item_field = State() fsm = FSMEdit{a_ModName}_{a_FieldName}_Item ''' def MakeFSMForEdit(a_ModName, a_FieldName): cmd = edit_fsm_cmd.replace("{a_ModName}", a_ModName).replace("{a_FieldName}", a_FieldName) _locals = locals() exec(cmd, globals(), _locals) return _locals['fsm'] class TableOperateModule(mod_simple_message.SimpleMessageModule): def __init__(self, a_Table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): super().__init__(a_Messages, a_Buttons, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) self.m_Table = a_Table self.m_EditModuleNameList = a_EditModuleNameList self.m_ChildModName = a_ChildModName self.m_ParentModName = a_ParentModName self.m_SelectPrefix = '' self.m_EditPrefix = {} 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, a_None, table_name = self.m_Table.GetName()): return await self.PreDelete(a_CallbackQuery, a_Item, a_None) self.m_PreDeleteFunc = PreDelete async def PostDelete(a_CallbackQuery, a_ItemID): return await self.PostDelete(a_CallbackQuery, a_ItemID) self.m_PostDeleteFunc = PostDelete async def AddBDItemFunc(a_ItemData, a_UserID): return await self.AddBDItemFunc(a_ItemData, a_UserID) self.m_AddBDItemFunc = AddBDItemFunc def GetInitBDCommands(self): return [ self.m_Table.GetInitTableRequest(), ] + super().GetInitBDCommands() def GetStartButtons(self, a_Message, a_UserGroups): return [ [ButtonNames.LIST, user_access.AccessMode.VIEW], [ButtonNames.ADD, user_access.AccessMode.ADD], [ButtonNames.DEL, user_access.AccessMode.DELETE], [ButtonNames.EDIT, user_access.AccessMode.EDIT], ] def GetStartKeyboardButtons(self, a_Message, a_UserGroups): mod_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups) cur_buttons = [] for b in self.GetStartButtons(a_Message, a_UserGroups): bn = b[0] ba = b[1] cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(bn), ba, self.GetAccess())] return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups) def GetAccessForEditKeyboardButtons(self, a_Field): if a_Field.m_Destiny == bd_table.TableFieldDestiny.ACCESS or a_Field.m_Destiny == bd_table.TableFieldDestiny.DEFAULT_ACCESS: return user_access.AccessMode.ACCEES_EDIT return user_access.AccessMode.EDIT def GetEditKeyboardButtons(self, a_Message, a_UserGroups): mod_buttons = keyboard.MakeButtons(self.m_Bot, self.GetButtons(self.m_EditModuleNameList), a_UserGroups) cur_buttons = [] for f in self.m_Table.GetFields(): access = self.GetAccessForEditKeyboardButtons(f) cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(EditButton(f.m_Destiny)), access, 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 GetDelPrefix(self): return self.m_DelPrefix def GetAddPrefix(self): return self.m_AddPrefix def GetShowPrefix(self): return self.m_ShowPrefix 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, child_mod.GetAccess(), user_access.AccessMode.VIEW), ] return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups) def GetButtonNameAndKeyValueAndAccess(self, a_Item): key_name_id = self.GetKeyFieldID() name_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.NAME) access_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS) assert key_name_id != None assert name_field_id != None assert access_field_id != None return \ a_Item[name_field_id],\ a_Item[key_name_id],\ a_Item[access_field_id] def UpdateMessage(self, a_Msg, a_Lang, a_Item, a_EnablePhoto = False): a_Msg.UpdateDesc(self.m_Table.ReplaceAllFieldTags(a_Msg.GetDesc(), a_Item)) photos = [] field_id = 0 for f in self.m_Table.GetFields(): if f.m_Type == bd_table.TableFieldType.ENUM: for s in f.m_Enum: msg = self.GetMessage(EnumMessageForView(s)) if msg: a_Msg.UpdateDesc(a_Msg.GetDesc().replace(str(s), str(msg.GetMessageForLang(a_Lang).StaticCopy()))) elif f.m_Type == bd_table.TableFieldType.PHOTO: photos += [str(a_Item[field_id])] field_id += 1 if a_EnablePhoto: a_Msg.UpdatePhotoID(','.join(photos)) return a_Msg def UpdateMessageByDict(self, a_Msg, a_Lang, a_ItemDict, a_EnablePhoto = False): a_Msg.UpdateDesc(self.m_Table.ReplaceAllFieldTagsByDict(a_Msg.GetDesc(), a_ItemDict)) photos = [] for f in self.m_Table.GetFields(): if f.m_Type == bd_table.TableFieldType.ENUM: for s in f.m_Enum: msg = self.GetMessage(EnumMessageForView(s)) if msg: a_Msg.UpdateDesc(a_Msg.GetDesc().replace(str(s), str(msg.GetMessageForLang(a_Lang).StaticCopy()))) elif f.m_Type == bd_table.TableFieldType.PHOTO: if f.m_Name in a_ItemDict: photos += [str(a_ItemDict[f.m_Name])] if a_EnablePhoto: a_Msg.UpdatePhotoID(','.join(photos)) return a_Msg def GetParentID(self, a_Item, a_ItemDict, a_TableName): parent_id = None parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) if parent_id_field and a_ItemDict and parent_id_field in a_ItemDict: parent_id = str(a_ItemDict[parent_id_field]) parent_id_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID) if not parent_id and parent_id_field_id != None and a_Item and len(a_Item) == self.m_Table.GetFieldsCount() and self.m_Table.GetName() == a_TableName: parent_id = str(a_Item[parent_id_field_id]) if self.m_ParentModName: parent_mod = self.GetModule(self.m_ParentModName) if parent_mod: key_field_id = parent_mod.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY) if not parent_id and key_field_id != None and a_Item and len(a_Item) == parent_mod.m_Table.GetFieldsCount() and parent_mod.m_Table.GetName() == a_TableName: parent_id = str(a_Item[key_field_id]) return parent_id def GetMessageNameWithTableFieldDestinyAndValue(self, a_NameWithoutDestiny, a_Destiny, a_Value): return a_NameWithoutDestiny + '?' + str(a_Destiny) + '=' + str(a_Value) def ShowMessageTemplate(self, a_Message, Inline_keyboard_template_func = None, a_EnablePhoto = False): async def ShowMessage(a_CallbackQuery, a_Item, a_ItemDict, table_name = self.m_Table.GetName()): lang = str(a_CallbackQuery.from_user.language_code) msg = a_Message # Подменяем сообщение, если оно уже есть для PARENT_ID parent_id = self.GetParentID(a_Item, a_ItemDict, table_name) if parent_id: name = self.GetMessageNameWithTableFieldDestinyAndValue(msg.GetName(), bd_table.TableFieldDestiny.PARENT_ID, parent_id) parent_id_msg = a_Message.FindMessageForLang(name, lang) if parent_id_msg: msg = parent_id_msg msg = msg.GetMessageForLang(lang).StaticCopy() # TODO: добавить поддержку языков в a_MessageName Inline_keyboard_func = None item_access = None if a_ItemDict: msg = self.UpdateMessageByDict(msg, lang, a_ItemDict, a_EnablePhoto = a_EnablePhoto) if a_Item and self.m_Table.GetName() == table_name: 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(): msg = self.UpdateMessage(msg, lang, a_Item, a_EnablePhoto = a_EnablePhoto) 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.GetKeyFieldID()]) return simple_message.WorkFuncResult(msg, item_access = item_access, Inline_keyboard_func = Inline_keyboard_func) return ShowMessage async def PreDelete(self, a_CallbackQuery, a_Item, a_None): if len(a_Item) < self.m_Table.GetFieldsCount(): return simple_message.WorkFuncResult(self.GetMessage(Messages.ERROR_FIND)) 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): user_id = a_CallbackQuery.from_user.id self.m_Log.Success(f'Элемент №{a_ItemID} была удалена пользователем {user_id}.') #TODO: удалить вложенные self.OnChange() subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_DEL item_id = -1 await self.SendSubscribe(subscribe_type, item_id, user_id, item_id) subscribe_type = bot_subscribes.SubscribeType.ITEM_DEL item_id = a_ItemID await self.SendSubscribe(subscribe_type, item_id, user_id, item_id) table_name = self.m_Table.GetName() key_name = self.GetKeyFieldName() cur_item = GetCurItem(self.m_Bot, table_name, key_name, a_ItemID) parent_id_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID) if parent_id_field_index and cur_item and cur_item[parent_id_field_index]: subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT item_id = cur_item[parent_id_field_index] await self.SendSubscribe(subscribe_type, item_id, user_id, item_id) return simple_message.WorkFuncResult(self.GetMessage(Messages.SUCCESS_DELETE)) async def AddBDItemFunc(self, a_ItemData, a_UserID): table_name = self.m_Table.GetName() key_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY) 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) def_access = access_utils.GetItemDefaultAccessForModule(self.m_Bot, self.GetName()) fields = [] values = [] param = () for f in self.m_Table.GetFields(): d = f.m_Destiny n = f.m_Name if d == bd_table.TableFieldDestiny.KEY: continue elif d == bd_table.TableFieldDestiny.CREATE_DATE: fields += [n] values += [bot_bd.GetBDDateTimeNow()] elif d == bd_table.TableFieldDestiny.ACCESS: fields += [n] values += ['?'] param += (def_access + f";{a_UserID}=+", ) else: fields += [n] values += ['?'] param += (a_ItemData[n], ) request = f'INSERT INTO {table_name}({",".join(fields)}) VALUES({",".join(values)}) RETURNING {key_field}' #print('request', request, param) res, error = self.m_Bot.SQLRequest(request, commit = True, return_error = True, param = param) self.OnChange() if error: self.m_Log.Error(f'Пользователь {a_UserID}. Ошибка добавления записи в таблицу {request} {param}.') else: self.m_Log.Success(f'Пользователь {a_UserID}. Добавлена запись в таблицу {request} {param}.') table_item_id = -1 if not error and res and len(res) == 1 and len(res[0]) == 1: table_item_id = str(res[0][0]) #print('res_id', res, error, table_item_id) subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_ADD item_id = -1 await self.SendSubscribe(subscribe_type, item_id, a_UserID, table_item_id) if parent_id_field and a_ItemData[parent_id_field]: subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT item_id = a_ItemData[parent_id_field] await self.SendSubscribe(subscribe_type, item_id, a_UserID, table_item_id) return res, error async def SendMessageToUser(self, a_Message, a_UserID, a_GetButtonsFunc = None, a_GetInlineButtonsFunc = None, parse_mode = None): a_Message = a_Message.StaticCopy() a_MessageFromUSer = None user_groups = groups_utils.GetUserGroupData(self.m_Bot, a_UserID) try: #print('SendMessage', self.m_Bot, a_Message, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_UserID, a_MessageFromUSer, user_groups, parse_mode) await simple_message.SendMessage(self.m_Bot, a_Message, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_UserID, a_MessageFromUSer, user_groups, parse_mode=parse_mode) return True except: return False async def SendSubscribe(self, a_Type, a_ItemID, a_OwnerUserID, a_TableItem): table_name = self.m_Table.GetName() key_name = self.GetKeyFieldName() cur_item = GetCurItem(self.m_Bot, table_name, key_name, a_TableItem) for s_user_id in self.m_BotSubscribes.GetUserIDs(self.GetName(), a_Type, a_ItemID = a_ItemID): a_BotMessage = self.GetMessage(SubscribeMessage(a_Type)) if not a_BotMessage: continue if s_user_id == a_OwnerUserID: continue a_UserID = s_user_id a_BotMessage = a_BotMessage.StaticCopy() a_BotMessage.UpdateDesc(a_BotMessage.GetDesc().replace("#item_id", str(a_ItemID))) if cur_item: a_BotMessage.UpdateDesc(self.m_Table.ReplaceAllFieldTags(a_BotMessage.GetDesc(), cur_item)) await self.SendMessageToUser(a_BotMessage, a_UserID) def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName): parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) return bd_item_select.DBItemSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName) 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.SelectRegisterHandlers(self.m_Bot, \ self.SelectSourceTemplate(a_Prefix, a_ButtonName), \ self.m_GetButtonNameAndKeyValueAndAccessFunc, \ self.GetMessage(Messages.SELECT), \ self.m_GetAccessFunc,\ access_mode = access_mode\ ) return a_Prefix def AdditionalKeyboardForEditTemplate(self, a_Field, user_access = user_access.AccessMode.EDIT): if a_Field.m_Type == bd_table.TableFieldType.ENUM: def KeyboardButtons(a_Message, a_UserGroups): cur_buttons = [] for s in a_Field.m_Enum: cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(EnumButton(s)), user_access, self.GetAccess()),] return keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups) return KeyboardButtons return None def PostProccessingForFieldForEditTemplate(self, a_Field): if a_Field.m_Type == bd_table.TableFieldType.ENUM: def PostProccessing(a_Message): for s in a_Field.m_Enum: if a_Message == str(self.GetButton(EnumButton(s))): return str(s) return a_Message return PostProccessing return None async def OnChangeField(self, a_Field, a_ItemID, a_ItemData, a_EditUserID): subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_EDIT item_id = -1 await self.SendSubscribe(subscribe_type, item_id, a_EditUserID, a_ItemID) subscribe_type = bot_subscribes.SubscribeType.ITEM_EDIT item_id = a_ItemID await self.SendSubscribe(subscribe_type, item_id, a_EditUserID, a_ItemID) table_name = self.m_Table.GetName() key_name = self.GetKeyFieldName() cur_item = GetCurItem(self.m_Bot, table_name, key_name, a_ItemID) print(cur_item) parent_id_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID) if parent_id_field_index and cur_item and cur_item[parent_id_field_index]: subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT item_id = cur_item[parent_id_field_index] await self.SendSubscribe(subscribe_type, item_id, a_EditUserID, a_ItemID) def RegisterEdit(self, a_Field, a_AccessMode = user_access.AccessMode.EDIT): a_ButtonName = self.GetButton(EditButton(a_Field.m_Destiny)) a_EditMessage = self.GetMessage(EditMessage(a_Field.m_Destiny)) a_FieldName = a_Field.m_Name a_FieldType = bd_item.FieldType.text if a_Field.m_Type == bd_table.TableFieldType.PHOTO: a_FieldType = bd_item.FieldType.photo if not a_ButtonName or not a_EditMessage: return async def OnChange(a_ItemID, a_ItemData, a_EditUserID): await self.OnChangeField(a_Field, a_ItemID, a_ItemData, a_EditUserID) return self.OnChange() table_name = self.m_Table.GetName() key_name = self.GetKeyFieldName() edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc GetAccess = self.m_GetAccessFunc a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True) a_Prefix = bd_item_edit.EditBDItemRegisterHandlers(self.m_Bot, \ self.SelectSourceTemplate(a_Prefix, a_ButtonName), \ MakeFSMForEdit(self.GetName(), a_FieldName), \ self.GetMessage(Messages.SELECT_TO_EDIT), \ self.ShowMessageTemplate(a_EditMessage), \ self.ShowMessageTemplate(self.GetMessage(Messages.SUCCESS_EDIT)), \ table_name, \ key_name, \ a_FieldName, \ self.PostProccessingForFieldForEditTemplate(a_Field),\ GetButtonNameAndKeyValueAndAccess, \ GetAccess, \ self.AdditionalKeyboardForEditTemplate(a_Field),\ edit_keyboard_func, \ OnChange,\ access_mode = a_AccessMode, \ field_type = a_FieldType\ ) self.m_EditPrefix.update({a_Field.m_Destiny: a_Prefix}) def GetAddFields(self): add_destiny = ( bd_table.TableFieldDestiny.NAME, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldDestiny.SUBSCRIBE_TYPE, bd_table.TableFieldDestiny.ITEM_ID, bd_table.TableFieldDestiny.USER_NAME, bd_table.TableFieldDestiny.USER_FAMILY_NAME, bd_table.TableFieldDestiny.USER_MIDDLE_NAME, bd_table.TableFieldDestiny.USER_BIRTHDAY, bd_table.TableFieldDestiny.USER_ADDRESS, bd_table.TableFieldDestiny.USER_CONTACTS, bd_table.TableFieldDestiny.USER_CONFIRM, ) fields = [] for f in self.m_Table.GetFields(): if f.m_Destiny in add_destiny: fields += [f] return fields def AddBDItemRegisterHandlers(self, a_StartCheckFunc, a_AddBDItemFunc, a_ParentPrefix, a_ParentTableName : str, a_ParentKeyFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.ADD): fields = self.GetAddFields() if len(fields) == 0: return fsm = MakeFSMForAdd(self.GetName(), fields) keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(self.m_Bot, a_AccessFunc, access_mode) keyboard_skip_and_cancel = bd_item.GetSkipAndCancelKeyboardButtonsTemplate(self.m_Bot, a_AccessFunc, access_mode) reg_func = self.m_Bot.RegisterMessageHandler if a_ParentTableName: reg_func = self.m_Bot.RegisterCallbackHandler def GetFieldType(a_Field): if a_Field.m_Type == bd_table.TableFieldType.PHOTO: return bd_item.FieldType.photo return bd_item.FieldType.text def GetContentTypes(a_Field): if a_Field.m_Type == bd_table.TableFieldType.PHOTO: return ['photo', 'text'] return ['text'] def GetKeyboard(a_Field): if a_Field.m_Type == bd_table.TableFieldType.PHOTO: return keyboard_skip_and_cancel return keyboard_cancel f_id = 0 f = fields[f_id] keyboard = bd_item.MixKeyboardFuncTemplate(self.AdditionalKeyboardForEditTemplate(f, user_access.AccessMode.ADD), GetKeyboard(f)) reg_func(bd_item_add.StartAddBDItemTemplate(self.m_Bot, fsm, getattr(fsm, f'item{f_id}'), self.ShowMessageTemplate(self.GetMessage(CreateMessage(f.m_Destiny))), a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard, a_ButtonFunc, access_mode), a_StartCheckFunc) for i in range(len(fields) - 1): f = fields[i] next_f = fields[i + 1] keyboard = bd_item.MixKeyboardFuncTemplate(self.AdditionalKeyboardForEditTemplate(next_f, user_access.AccessMode.ADD), GetKeyboard(next_f)) self.m_Bot.RegisterMessageHandler(bd_item_add.NextAddBDItemTemplate(self.m_Bot, fsm, None, a_ParentTableName, a_ParentKeyFieldName, f.m_Name, self.ShowMessageTemplate(self.GetMessage(CreateMessage(next_f.m_Destiny))), None, a_AccessFunc, keyboard, a_ButtonFunc, access_mode, field_type = GetFieldType(f)), content_types = GetContentTypes(f), state = getattr(fsm, f'item{i}')) f_id = len(fields) - 1 f = fields[f_id] self.m_Bot.RegisterMessageHandler(bd_item_add.FinishAddBDItemTemplate(self.m_Bot, fsm, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, f.m_Name, self.ShowMessageTemplate(self.GetMessage(Messages.SUCCESS_CREATE)), None, a_AccessFunc, a_ButtonFunc, access_mode, field_type = GetFieldType(f)), content_types = GetContentTypes(f), state = getattr(fsm, f'item{f_id}')) def GetKeyFieldDestiny(self): return bd_table.TableFieldDestiny.KEY def GetKeyFieldName(self): return self.m_Table.GetFieldNameByDestiny(self.GetKeyFieldDestiny()) def GetKeyFieldID(self): return self.m_Table.GetFieldIDByDestiny(self.GetKeyFieldDestiny()) def RegisterHandlers(self): super().RegisterHandlers() table_name = self.m_Table.GetName() key_name = self.GetKeyFieldName() 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.GetKeyFieldName() 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) self.m_SelectPrefix = a_Prefix a_Prefix = bd_item_select.SelectRegisterHandlers(self.m_Bot,\ self.SelectSourceTemplate(a_Prefix, a_ButtonName), \ GetButtonNameAndKeyValueAndAccess,\ self.GetMessage(Messages.SELECT),\ GetAccess,\ access_mode = user_access.AccessMode.VIEW\ ) self.m_ShowPrefix = a_Prefix bd_item_view.ShowBDItemRegisterHandlers(self.m_Bot,\ a_Prefix,\ table_name,\ key_name,\ self.ShowMessageTemplate(self.GetMessage(Messages.OPEN), GetViewItemInlineKeyboardTemplate, a_EnablePhoto = True),\ GetAccess,\ defaul_keyboard_func,\ access_mode = user_access.AccessMode.VIEW\ ) # Удаление a_ButtonName = self.GetButton(ButtonNames.DEL) if a_ButtonName: a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW) self.m_DelPrefix = a_Prefix 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.VIEW, only_parent = True) self.m_AddPrefix = a_Prefix check_func = bd_item.GetCheckForTextFunc(a_ButtonName) if a_Prefix: check_func = bd_item.GetCheckForPrefixFunc(a_Prefix) self.AddBDItemRegisterHandlers(\ check_func, \ self.m_AddBDItemFunc, \ a_Prefix,\ parent_table_name, \ parent_key_name, \ GetButtonNameAndKeyValueAndAccess, \ GetAccess, \ self.m_GetStartKeyboardButtonsFunc\ ) # Редактирование edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc 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)\ ) address_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.ADDRESS) status_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.STATUS) for f in self.m_Table.GetFields(): self.RegisterEdit(f) def OnChange(self): pass