bot/bozenka/instances/telegram/utils/keyboards/inline.py

448 lines
19 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import gpt4all
from typing import Any
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from gpt4all import GPT4All
from bozenka.instances.telegram.utils.callbacks_factory import *
from bozenka.instances.telegram.utils.simpler import gpt_categories, generate_gpt4free_models, generate_gpt4free_providers, \
generate_list_of_features
"""
File, contains inline keyboard & menus and their work.
Right now only on Russian language, multi-language planning soon.
"""
# Help related keyboards
def help_keyboard() -> InlineKeyboardMarkup:
"""
Generate keyboard for /help command
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[[
InlineKeyboardButton(text="Администраторы 👮‍♂",
callback_data=HelpCategory(category_name="Admins").pack())],
[InlineKeyboardButton(text="Пользователи 👤",
callback_data=HelpCategory(category_name="Members").pack())],
[InlineKeyboardButton(text="В разработке 👨‍💻",
callback_data=HelpCategory(category_name="Devs").pack())]])
return kb
def help_category_keyboard(category: str) -> InlineKeyboardMarkup:
"""
Generate keyboard for one of categories
:param category:
:return:
"""
kb = InlineKeyboardBuilder()
list_of_features = generate_list_of_features(category)
for setting in list_of_features:
kb.row(InlineKeyboardButton(text=setting.name,
callback_data=HelpFeature(
feature_index=list_of_features.index(setting),
feature_category=category
).pack()))
kb.row(InlineKeyboardButton(text="🔙 Назад к категориям",
callback_data=HelpBack(back_to="category").pack()))
return kb.as_markup()
def help_feature_keyboard(category: str) -> InlineKeyboardMarkup:
"""
Just button for function of /help
:param category:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="🔙 Назад к функциям",
callback_data=HelpBackCategory(back_to_category=category).pack())],
[InlineKeyboardButton(text="🔙 Назад к функциям",
callback_data=HelpBackCategory(back_to_category=category).pack())]
])
return kb
# Setup related keyboards
def setup_keyboard() -> InlineKeyboardMarkup:
"""
Generate keyboard for /setup command
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[[
InlineKeyboardButton(text="Администраторы 👮‍♂",
callback_data=SetupCategory(category_name="Admins").pack())],
[InlineKeyboardButton(text="Пользователи 👤",
callback_data=SetupCategory(category_name="Members").pack())],
[InlineKeyboardButton(text="В разработке 👨‍💻",
callback_data=SetupCategory(category_name="Devs").pack())]])
return kb
def setup_category_keyboard(category: str) -> InlineKeyboardMarkup:
"""
Generate keyboard for one of categories
:param category:
:return:
"""
kb = InlineKeyboardBuilder()
list_of_features = generate_list_of_features(category)
for setting in list_of_features:
kb.row(InlineKeyboardButton(text=setting.name,
callback_data=SetupFeature(
feature_index=list_of_features.index(setting),
feature_category=category
).pack()))
return kb.as_markup()
def setup_feature_keyboard() -> InlineKeyboardMarkup:
pass
def delete_keyboard(admin_id: int) -> InlineKeyboardMarkup:
"""
Basic keyboard for all messages from bot.
By pressing this button, message from bot will get deleted.
:param admin_id:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[[
InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())
]])
return kb
# LLM / GPT related keyboards
# GPT CATEGORIES
def gpt_categories_keyboard(user_id: int) -> InlineKeyboardMarkup:
"""
Create list keyboard list of gpt libraries, available in the bot
:param user_id:
:return: InlineKeyboardMarkup
"""
builder = InlineKeyboardBuilder()
for category in gpt_categories:
builder.row(InlineKeyboardButton(text=category, callback_data=GptCategory(user_id=str(user_id), category=category).pack()))
return builder.as_markup()
# Helper
def items_list_generator(page: int, list_of_items, count_of_items: int) -> list[Any]:
"""
Generate page, made for backend
:param page:
:param list_of_items:
:param count_of_items:
"""
items = []
required_items = [item + page * count_of_items for item in range(count_of_items)]
for item, count in zip(list_of_items, range(0, len(list_of_items))):
if count not in required_items:
continue
items.append(item)
return items
def gpt4free_providers_keyboard(user_id: int, page: int) -> InlineKeyboardMarkup:
"""
Generate page of gpt providers, can be used by user.
:param user_id:
:param page:
:return:
"""
providers = generate_gpt4free_providers()
names = items_list_generator(page, providers, 4)
pages = [len(providers) // 4 - 1 if page - 1 == -1 else page - 1,
0 if page + 1 >= len(providers) // 4 else page + 1]
generated_page = InlineKeyboardMarkup(inline_keyboard=[
# First one provider
[InlineKeyboardButton(text=names[0],
callback_data=Gpt4FreeProvider(user_id=user_id, provider=names[0], page="0").pack())],
# Second one provider
[InlineKeyboardButton(text=names[1],
callback_data=Gpt4FreeProvider(user_id=user_id, provider=names[1], page="0").pack())],
# Third one provider
[InlineKeyboardButton(text=names[2],
callback_data=Gpt4FreeProvider(user_id=user_id, provider=names[2], page="0").pack())],
# Fourh one provider (if exist)
[InlineKeyboardButton(text=names[3],
callback_data=Gpt4FreeProvider(user_id=user_id, provider=names[3],
page="0").pack())] if len(
names) == 4 else [],
# Page right
[InlineKeyboardButton(text=str(len(providers) // 4 if page == 0 else "1"),
callback_data=Gpt4FreeProviderPage(
page=str(len(providers) // 4 - 1 if page == 0 else "0"),
user_id=user_id).pack()),
InlineKeyboardButton(text="⬅️", callback_data=Gpt4FreeProviderPage(page=pages[0], user_id=user_id).pack()),
InlineKeyboardButton(text=str(page + 1), callback_data="gotpages"),
# Page left
InlineKeyboardButton(text="➡️", callback_data=Gpt4FreeProviderPage(page=pages[1], user_id=user_id).pack()),
InlineKeyboardButton(text=str(len(providers) // 4 if page != len(providers) // 4 - 1 else "1"),
callback_data=Gpt4FreeProviderPage(
page=str(len(providers) // 4 - 1 if page != len(providers) // 4 - 1 else "0"),
user_id=user_id).pack())
],
# Under list buttons
[InlineKeyboardButton(text="🔙 Вернуться к категориям",
callback_data=GptBackMenu(user_id=user_id, back_to="category").pack())],
[InlineKeyboardButton(text="Спасибо, не надо ❌",
callback_data=GptStop(user_id=str(user_id)).pack())]])
return generated_page
def gpt4free_models_keyboard(user_id: int, provider, page: int) -> InlineKeyboardMarkup:
"""
Generating list of GPT4Free provider's models, can be used to generate text.
Will be also reworked.
:param user_id:
:param provider:
:param page:
"""
builder = InlineKeyboardBuilder()
models = generate_gpt4free_models()
providers = generate_gpt4free_providers()
if provider in models:
if providers[provider].supports_gpt_4:
models[provider].append("")
names = items_list_generator(page, models[provider], 4)
for name in names:
builder.row(InlineKeyboardButton(text=name.replace('-', ' '), callback_data=Gpt4freeResult(user_id=str(user_id), provider=provider, model=name).pack()))
pages = [len(models[provider]) // 4 - 1 if page - 1 == -1 else page - 1,
0 if page + 1 >= len(models[provider]) // 4 else page + 1]
if len(models[provider]) > 4:
builder.row(
# First page button
InlineKeyboardButton(text=str(len(models[provider]) // 4 if page == 0 else "1"),
callback_data=Gpt4FreeModelPage(
page=str(len(models[provider]) // 4 - 1 if page == 0 else "1"),
user_id=user_id,).pack(),
),
# Page back button
InlineKeyboardButton(text="⬅️",
callback_data=Gpt4FreeModelPage(user_id=str(user_id), page=pages[0], provider=provider).pack()),
# Count of page button
InlineKeyboardButton(text=str(page + 1), callback_data="gotpages"),
# Next page button
InlineKeyboardButton(text="➡️", callback_data=Gpt4FreeModelPage(user_id=str(user_id), page=pages[1], provider=provider).pack()),
# Last page button
InlineKeyboardButton(text=str(len(models[provider]) // 4 if page != 0 else "1"),
callback_data=Gpt4FreeModelPage(
page=str(len(models[provider]) // 4 - 1) if page != 0 else "1",
user_id=user_id,
provider=provider).pack(),))
else:
if providers[provider].supports_gpt_4:
builder.row(InlineKeyboardButton(text="gpt 4",
callback_data=Gpt4freeResult(user_id=str(user_id),
provider=provider,
model="gpt-4").pack()))
if providers[provider].supports_gpt_35_turbo:
builder.row(InlineKeyboardButton(text="gpt 3.5 turbo",
callback_data=Gpt4freeResult
(user_id=str(user_id), provider=provider, model="gpt-3.5-turbo").pack()))
builder.row(InlineKeyboardButton(text="🔙 Вернуться к провайдерам", callback_data=GptBackMenu(user_id=user_id, back_to="providers").pack()))
builder.row(InlineKeyboardButton(text="Спасибо, не надо ❌", callback_data=GptStop(user_id=str(user_id)).pack()))
return builder.as_markup()
# Gpt4All related keyboards
def generate_gpt4all_page(user_id: int) -> InlineKeyboardMarkup:
"""
Generating list of GPT4All models.
:param user_id:
:return:
"""
models = GPT4All.list_models()
builder = InlineKeyboardBuilder()
for model in models:
builder.row(InlineKeyboardButton(
text=model["name"],
callback_data=Gpt4AllModel(user_id=str(user_id), model_index=str(models.index(model))).pack())
)
builder.row(InlineKeyboardButton(text="🔙 Вернуться к списку",
callback_data=GptBackMenu(user_id=user_id, back_to="category").pack()))
builder.row(InlineKeyboardButton(text="Спасибо, не надо ❌",
callback_data=GptStop(user_id=str(user_id)).pack()))
return builder.as_markup()
def gpt4all_model_menu(user_id: int, index: int) -> InlineKeyboardMarkup:
"""
Generating menu for selection on of GPT4ALL models
:param user_id:
:param index:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Выбрать ✅",
callback_data=Gpt4AllSelect(user_id=user_id, model_index=str(index)).pack())],
[InlineKeyboardButton(text="🔙 Вернуться к списку",
callback_data=GptBackMenu(user_id=user_id, back_to="g4amodels").pack())],
[InlineKeyboardButton(text="Спасибо, не надо ❌",
callback_data=GptStop(user_id=str(user_id)).pack())]
])
return kb
# Universal response from GPT / LLM keyboard
def response_keyboard(user_id: int) -> InlineKeyboardMarkup:
"""
Generating menu for response from GPT
:param user_id:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(user_id)).pack())],
[InlineKeyboardButton(text="Завершить диалог 🚫", callback_data=GptStop(user_id=str(user_id)).pack())]
])
return kb
# Admin related keyboards
# Ban / Unban keyboards
def ban_keyboard(admin_id: int, ban_id: int) -> InlineKeyboardMarkup:
"""
Generating menu for /ban command.
:param admin_id:
:param ban_id:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[[
InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())
], [
InlineKeyboardButton(text="Разбанить 🛠️", callback_data=UnbanData(user_id_unban=str(ban_id),
user_id_clicked=str(admin_id)).pack())
]])
return kb
def unban_keyboard(admin_id: int, ban_id: int) -> InlineKeyboardMarkup:
"""
Generating menu for /unban command.
:param admin_id:
:param ban_id:
:return:
"""
print(ban_id)
kb = InlineKeyboardMarkup(inline_keyboard=[[
InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())
], [
InlineKeyboardButton(text="Забанить 🛠️", callback_data=BanData(user_id_ban=str(ban_id),
user_id_clicked=str(admin_id)).pack())
]])
return kb
# Mute / Unmute keyboards
def mute_keyboard(admin_id: int, ban_id: int) -> InlineKeyboardMarkup:
"""
Generating menu for /mute command.
:param admin_id:
:param ban_id:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())],
[InlineKeyboardButton(text="Размутить 🛠️",
callback_data=UnmuteData(user_id_unmute=ban_id, user_id_clicked=admin_id).pack())]])
return kb
def unmute_keyboard(admin_id: int, ban_id: int) -> InlineKeyboardMarkup:
"""
Generating menu for /unmute command.
:param admin_id:
:param ban_id:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())],
[InlineKeyboardButton(text="Замутить 🛠️", callback_data=MuteData(user_id_mute=ban_id, user_id_clicked=admin_id).pack())]])
return kb
# Invite keyboard
def invite_keyboard(link: str, admin_id: int, chat_name: str) -> InlineKeyboardMarkup:
"""
Generating menu for /invite command. Should be reworked.
:param link:
:param admin_id:
:param chat_name:
:return:
"""
link = link.replace("https://", "")
kb = InlineKeyboardMarkup(inline_keyboard=[[
InlineKeyboardButton(text=chat_name, url=link)],
[InlineKeyboardButton(text="Отозвать 🛠️", callback_data=RevokeCallbackData(admin_id=admin_id, link=link).pack())],
[InlineKeyboardButton(text="Спасибо ✅",
callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())]])
return kb
# Close / Open thread commands related keyboards
def close_thread_keyboard(user_id: int) -> InlineKeyboardMarkup:
"""
Generate menu for /close command
:param user_id:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Окрыть обсуждение 🛠️", callback_data=OpenThread(user_id=user_id).pack())],
[InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(user_id)).pack())]
])
return kb
def open_thread_keyboard(user_id: int) -> InlineKeyboardMarkup:
"""
Generate menu for /open command
:param user_id:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Закрыть обсуждение 🛠️", callback_data=CloseThread(user_id=user_id).pack())],
[InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(user_id)).pack())]
])
return kb
# Pin / Unpin command
def pin_msg_keyboard(user_id: int, msg_id: int) -> InlineKeyboardMarkup:
"""
Generate menu for /pin command
:param user_id:
:param msg_id:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Открепить сообщение 📌", callback_data=UnpinMsg(user_id=user_id, msg_id=msg_id).pack())],
[InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(user_id)).pack())]
])
return kb
def unpin_msg_keyboard(user_id: int, msg_id: int) -> InlineKeyboardMarkup:
"""
Generate menu for /unpin command
:param user_id:
:param msg_id:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Открепить сообщение 📌", callback_data=PinMsg(user_id=user_id, msg_id=msg_id).pack())],
[InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(user_id)).pack())]
])
return kb
about_keyboard = InlineKeyboardBuilder()
about_keyboard.button(
text="Bozo Development", url="https://t.me/BozoDevelopment"
)