Files
Solo_bot/hooks/hook_buttons.py
T
Capybara-z 16d031d90e fix hooks
2025-08-29 10:35:12 +03:00

81 lines
3.2 KiB
Python

from aiogram.types import InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder
def insert_hook_buttons(builder: InlineKeyboardBuilder, buttons: list) -> InlineKeyboardBuilder:
"""
Вставляет кнопки из хуков в существующий builder.
Поддерживает:
- {"button": InlineKeyboardButton} — добавить в конец
- {"after": callback_data, "button": InlineKeyboardButton} — вставить после заданной кнопки
- {"insert_at": int, "button": InlineKeyboardButton} — вставить по индексу (0 = начало)
- {"remove": str | list[str]} — удалить кнопки с указанным callback_data
- {"remove_prefix": str} — удалить кнопки, у которых callback_data начинается с префикса
"""
markup = builder.as_markup()
new_rows = markup.inline_keyboard.copy()
buttons = buttons or []
flat_buttons = []
for item in buttons:
if isinstance(item, (list, tuple)):
flat_buttons.extend(item)
else:
flat_buttons.append(item)
remove_operations = [b for b in flat_buttons if isinstance(b, dict) and ("remove" in b or "remove_prefix" in b)]
for module in remove_operations:
removes = module.get("remove")
if isinstance(removes, str):
removes = [removes]
removes = set(removes or [])
prefix = module.get("remove_prefix")
filtered_rows = []
for row in new_rows:
filtered_row = []
for btn in row:
cdata = getattr(btn, "callback_data", None)
if cdata and (cdata in removes or (prefix and cdata.startswith(prefix))):
continue
filtered_row.append(btn)
if filtered_row:
filtered_rows.append(filtered_row)
new_rows = filtered_rows
insert_operations = [b for b in flat_buttons if isinstance(b, dict) and "insert_at" in b and "button" in b]
for module in insert_operations:
insert_at = module["insert_at"]
button = module["button"]
if 0 <= insert_at <= len(new_rows):
new_rows.insert(insert_at, [button])
else:
new_rows.append([button])
after_operations = [b for b in flat_buttons if isinstance(b, dict) and "after" in b and "button" in b]
for module in after_operations:
after = module["after"]
button = module["button"]
insert_pos = -1
for i, row in enumerate(new_rows):
if any(getattr(btn, "callback_data", None) == after for btn in row):
insert_pos = i + 1
break
if 0 <= insert_pos <= len(new_rows):
new_rows.insert(insert_pos, [button])
else:
new_rows.append([button])
for module in flat_buttons:
if isinstance(module, dict) and "button" in module and "insert_at" not in module and "after" not in module:
button = module["button"]
new_rows.append([button])
elif module and not isinstance(module, dict):
new_rows.append([module])
return InlineKeyboardBuilder.from_markup(InlineKeyboardMarkup(inline_keyboard=new_rows))