{config['reason']}, до даты {config['ban_time']}
",
+ reply_markup=delete_keyboard(admin_id=banned_user.user.id))
+ elif config["reason"]:
+ await msg.bot.send_message(chat_id=where_send[send_to_dm],
+ text="Удача ✅\n"
+ f"{msg.reply_to_message.from_user.mention_html('Этот пользователь')} "
+ f"был заблокирован {msg.reply_to_message.from_user.mention_html('этим пользователем')}.\n"
+ f"По причине {config['reason']}
.",
+ reply_markup=ban_keyboard(admin_id=msg.from_user.id,
+ ban_id=msg.reply_to_message.from_user.id))
+ if send_notification:
+ await msg.bot.send_message(chat_id=banned_user.user.id,
+ text=f"Вы "
+ f"были заблокированы {msg.from_user.mention_html('этим пользователем')} в чате {msg.chat.title}
.\n"
+ f"По причине {config['reason']}
.",
+ reply_markup=delete_keyboard(admin_id=banned_user.user.id))
+ elif config["ban_time"]:
+ await msg.bot.send_message(chat_id=where_send[send_to_dm],
+ text="Удача ✅\n"
+ f"{msg.reply_to_message.from_user.mention_html('Этот пользователь')} "
+ f"был заблокирован {msg.from_user.mention_html('этим пользователем')}, до даты {config['ban_time']}
",
+ reply_markup=ban_keyboard(admin_id=msg.from_user.id,
+ ban_id=msg.reply_to_message.from_user.id))
+ if send_notification:
+ await msg.bot.send_message(chat_id=banned_user.user.id,
+ text=f"Вы "
+ f"были заблокированы {msg.from_user.mention_html('этим пользователем')} в чате {msg.chat.title}
.\n"
+ f"До даты {config['ban_time']}
.",
+ reply_markup=delete_keyboard(admin_id=banned_user.user.id))
+ else:
+ await msg.bot.send_message(chat_id=where_send[send_to_dm],
+ text="Удача ✅\n"
+ f"{msg.reply_to_message.from_user.mention_html('Этот пользователь')}"
+ f" был заблокирован {msg.from_user.mention_html('этим пользователем')}.",
+ reply_markup=ban_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
+ if send_notification:
+ await msg.bot.send_message(chat_id=banned_user.user.id,
+ text=f"Вы "
+ f"были заблокированы {msg.from_user.mention_html('этим пользователем')} в чате "
+ f"{msg.chat.title}
.\n",
+ reply_markup=delete_keyboard(admin_id=banned_user.user.id))
+
+ @staticmethod
+ async def telegram_unban_cmd_handler(msg: Message, command: CommandObject,
+ session_maker: async_sessionmaker) -> None:
+ """
+ /unban command function
+ :param msg: Message telegram object
+ :param command: Object of telegram command
+ :param session_maker: Session maker object of SqlAlchemy
+ """
+ await SolutionSimpler.unban_user(msg, session_maker)
+
+ unbanned_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
+ send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
+ setting=list_of_features["Admin"][4])
+ send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
+ setting=list_of_features["Admin"][5])
+
+ where_send = {
+ True: msg.from_user.id,
+ False: msg.chat.id
+ }
+
+ if unbanned_user.is_member and unbanned_user.status != ChatMemberStatus.KICKED:
+ await msg.bot.send_message(
+ chat_id=where_send[send_to_dm],
+ text="Ошибка ❌\n"
+ "Этот пользователь не находится в бане.",
+ reply_markup=delete_keyboard(admin_id=msg.from_user.id)
+ )
+ return
+ elif not command.text:
+ await msg.bot.send_message(
+ chat_id=where_send[send_to_dm],
+ text="Удача ✅\n"
+ f"{msg.reply_to_message.from_user.mention_html('Этот пользователь')} был разблокирован "
+ f"{msg.from_user.mention_html('этим пользователем')}.\n",
+ reply_markup=unban_keyboard(admin_id=msg.from_user.id, ban_id=msg.reply_to_message.from_user.id)
+ )
+ if send_notification:
+ await msg.bot.send_message(
+ chat_id=unbanned_user.user.id,
+ text=f"{msg.reply_to_message.from_user.mention_html('Вы')} "
+ f"был разблокированы {msg.from_user.mention_html('этим пользователем')} в чате {msg.chat.title}
.\n",
+ reply_markup=delete_keyboard(admin_id=unbanned_user.user.id)
+ )
+ else:
+ await msg.bot.send_message(
+ chat_id=where_send[send_to_dm],
+ text="Удача ✅\n"
+ f"Пользователь {msg.reply_to_message.from_user.mention_html()} был разблокирован пользователем {msg.from_user.mention_html()}.\n"
+ f"По причине {CommandObject.text}.",
+ reply_markup=delete_keyboard(admin_id=unbanned_user.user.id)
+ )
+ if send_notification:
+ await msg.bot.send_message(
+ chat_id=unbanned_user.user.id,
+ text=f"{msg.reply_to_message.from_user.mention_html('Вы')} "
+ f"был разблокированы {msg.from_user.mention_html('этим пользователем')} в чате {msg.chat.title}
.\n"
+ f"По причине {CommandObject.text}
",
+ reply_markup=delete_keyboard(admin_id=unbanned_user.user.id)
+ )
+
+ @staticmethod
+ async def telegram_mute_callback_handler(call: CallbackQuery, callback_data: MuteData,
+ session_maker: async_sessionmaker) -> None:
+ """
+ Query, what mutes users after callback
+ :param call: CallBackQuery telegram object
+ :param callback_data: BanData object
+ :param session_maker: AsyncSessionmaker object
+ :return:
+ """
+ clicked_user = await call.message.chat.get_member(call.from_user.id)
+ muted_user = await call.message.chat.get_member(int(callback_data.user_id_mute))
+
+ if call.from_user.id != callback_data.user_id_clicked \
+ and clicked_user.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.CREATOR]:
+ return
+ await SolutionSimpler.inline_mute_user(call=call, data=callback_data, session=session_maker)
+
+ if not muted_user.can_send_messages and muted_user.status == ChatMemberStatus.RESTRICTED:
+ await call.answer("Уже замучен ✅")
+ else:
+ await call.answer("Успешно замучен ✅")
+
+ await call.message.edit_text(
+ "Удача ✅\n"
+ f"{muted_user.user.mention_html('Этот пользователь')} был замучен {call.from_user.mention_html('этим пользователем')}.",
+ reply_markup=mute_keyboard(admin_id=call.from_user.id, mute_id=callback_data.user_id_mute)
+ )
+
+ send_notification = await get_chat_config_value(chat_id=call.message.chat.id, session=session_maker,
+ setting=list_of_features["Admin"][5])
+ if send_notification:
+ await call.message.bot.send_message(
+ chat_id=muted_user.user.id,
+ text=f"{muted_user.user.mention_html('Вы')} были замучены {call.from_user.mention_html('этим пользователем')} в чате {call.message.chat.id}
.",
+ reply_markup=delete_keyboard(admin_id=muted_user.user.id)
+ )
+
+ logging.log(msg=f"Muted user @{muted_user.user.full_name} user_id=f{muted_user.user.id}", level=logging.INFO)
+
+ @staticmethod
+ async def telegram_unmute_callback_handler(call: CallbackQuery, callback_data: UnmuteData,
+ session_maker: async_sessionmaker) -> None:
+ """
+ Query, what unbannes users after callback
+ :param call: CallBackQuery telegram object
+ :param callback_data: UnbanData object
+ :param session_maker: AsyncSessionmaker object
+ :return:
+ """
+ clicked_user = await call.message.chat.get_member(call.from_user.id)
+ unmuted_user = await call.message.chat.get_member(int(callback_data.user_id_unmute))
+ if call.from_user.id != callback_data.user_id_clicked \
+ and clicked_user.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.CREATOR]:
+ return
+
+ await SolutionSimpler.inline_unmute_user(call=call, data=callback_data, session=session_maker)
+
+ if unmuted_user.can_send_messages or unmuted_user.status == ChatMemberStatus.RESTRICTED:
+ await call.answer("Уже размучен ✅")
+ else:
+ await call.answer("Успешно размучен ✅")
+ await call.message.edit_text(
+ "Удача ✅\n"
+ f"{unmuted_user.user.mention_html('Этот пользователь')} был размучен {call.from_user.mention_html('этим пользователем')}.",
+ reply_markup=unmute_keyboard(admin_id=call.from_user.id, unmute_id=unmuted_user.user.id)
+ )
+
+ send_notification = await get_chat_config_value(chat_id=call.message.chat.id, session=session_maker,
+ setting=list_of_features["Admin"][5])
+ if send_notification:
+ await call.message.bot.send_message(
+ chat_id=unmuted_user.user.id,
+ text=f"{unmuted_user.user.mention_html('Вы')} были размучены {call.from_user.mention_html('этим пользователем')} в чате {call.message.chat.id}
.",
+ reply_markup=delete_keyboard(admin_id=unmuted_user.user.id)
+ )
+
+ logging.log(msg=f"Unbanned user @{unmuted_user.user.full_name} user_id=f{unmuted_user.user.id}",
+ level=logging.INFO)
+
+ @staticmethod
+ async def telegram_mute_cmd_handler(msg: Message, command: CommandObject,
+ session_maker: async_sessionmaker) -> None:
+ """
+ Handler of command /mute
+ Restricts member from using chat
+ :param msg: Message telegram object
+ :param command: Object of telegram command
+ :param session_maker: Session maker object of SqlAlchemy
+ :return: Nothing
+ """
+ mute_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
+
+ send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
+ setting=list_of_features["Admin"][4])
+ send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
+ setting=list_of_features["Admin"][5])
+
+ where_send = {
+ True: msg.from_user.id,
+ False: msg.chat.id
+ }
+
+ if mute_user.status == ChatMemberStatus.LEFT or mute_user.status == ChatMemberStatus.KICKED:
+ return
+ config = await SolutionSimpler.mute_user(msg, command, session_maker)
+ if config["mute_time"] and config["reason"] != "":
+ await msg.bot.send_message(
+ chat_id=where_send[send_to_dm],
+ text="Удача ✅\n"
+ f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
+ f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n"
+ f"По причине {config['reason']}
, до даты {config['mute_time']}
",
+ reply_markup=mute_keyboard(msg.from_user.id, mute_user.user.id))
+ if send_notification:
+ await msg.bot.send_message(
+ chat_id=mute_user.user.id,
+ text=f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
+ f"сообщения {msg.reply_to_message.from_user.mention_html('вам')} в чате {msg.chat.title}.\n"
+ f"По причине {config['reason']}
, до даты {config['mute_time']}
",
+ reply_markup=delete_keyboard(admin_id=mute_user.user.id))
+
+ elif config["reason"] != "":
+ await msg.bot.send_message(
+ chat_id=where_send[send_to_dm],
+ text="Удача ✅\n"
+ f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
+ f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n"
+ f"По причине {config['reason']}
.",
+ reply_markup=mute_keyboard(msg.from_user.id, mute_user.user.id))
+ if send_notification:
+ await msg.bot.send_message(
+ chat_id=mute_user.user.id,
+ text=f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
+ f"сообщения {msg.reply_to_message.from_user.mention_html('вам')} в чате {msg.chat.title}.\n"
+ f"По причине {config['reason']}
.",
+ reply_markup=delete_keyboard(admin_id=mute_user.user.id))
+ elif config["mute_time"]:
+ await msg.bot.send_message(
+ chat_id=where_send[send_to_dm],
+ text="Удача ✅\n"
+ f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
+ f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n"
+ f"До даты {config['mute_time']}
",
+ reply_markup=mute_keyboard(msg.from_user.id, mute_user.user.id))
+ if send_notification:
+ await msg.bot.send_message(
+ chat_id=mute_user.user.id,
+ text=f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
+ f"сообщения {msg.reply_to_message.from_user.mention_html('вам')} в чате {msg.chat.title}.\n"
+ f"До даты {config['mute_time']}
",
+ reply_markup=delete_keyboard(admin_id=mute_user.user.id))
+ else:
+ await msg.bot.send_message(
+ chat_id=where_send[send_to_dm],
+ text="Удача ✅\n"
+ f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
+ f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n",
+ reply_markup=mute_keyboard(msg.from_user.id, mute_user.user.id))
+ if send_notification:
+ await msg.bot.send_message(
+ chat_id=mute_user.user.id,
+ text=f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
+ f"сообщения {msg.reply_to_message.from_user.mention_html('вам')} в чате {msg.chat.title}.\n",
+ reply_markup=delete_keyboard(admin_id=mute_user.user.id))
+
+ @staticmethod
+ async def telegram_unmute_cmd_handler(msg: Message, session_maker: async_sessionmaker) -> None:
+ """
+ Handler of command /unmute
+ Gives access member to send messages into chat
+ :param msg: Message telegram object
+ :param session_maker: Session maker object of SqlAlchemy
+ :return: Nothing
+ """
+ await SolutionSimpler.unmute_user(msg, session_maker)
+
+ send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
+ setting=list_of_features["Admin"][4])
+ send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
+ setting=list_of_features["Admin"][5])
+
+ where_send = {
+ True: msg.from_user.id,
+ False: msg.chat.id
+ }
+
+ await msg.bot.send_message(
+ user_id=where_send[send_to_dm],
+ text="Удача ✅"
+ f"{msg.from_user.mention_html('Этот пользователь')} разрешил писать\n"
+ f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}",
+ reply_markup=unmute_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
+ if send_notification:
+ await msg.bot.send_message(
+ user_id=msg.reply_to_message.from_user.id,
+ text=f"{msg.from_user.mention_html('Этот пользователь')} разрешил писать\n"
+ f"сообщения {msg.reply_to_message.from_user.mention_html('вам')}",
+ reply_markup=delete_keyboard(admin_id=msg.reply_to_message.from_user.id))
+
+ def __init__(self):
+ """
+ All information about feature
+ will be inside this function
+ """
+ super().__init__()
+ self.cmd_description: str = "Your description of command"
+ # Telegram feature settings
+ self.telegram_setting = None
+ self.telegram_commands: list[str | None] = ["start"]
+ self.telegram_cmd_avaible = True # Is a feature have a commands
+ self.telegram_callback_factory = None
+ self.telegram_message_handlers = {
+ # Your message handlers
+ }
+ self.telegram_callback_handlers = {
+ # Start menu
+ }
diff --git a/bozenka/features/admin/pins.py b/bozenka/features/admin/pins.py
new file mode 100644
index 0000000..55b551e
--- /dev/null
+++ b/bozenka/features/admin/pins.py
@@ -0,0 +1,104 @@
+from aiogram.types import Message, CallbackQuery
+
+from bozenka.features import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import PinMsg, UnpinMsg
+from bozenka.instances.telegram.utils.keyboards import unpin_msg_keyboard, delete_keyboard, pin_msg_keyboard
+from bozenka.instances.telegram.utils.simpler import SolutionSimpler
+
+
+class Pins(BasicFeature):
+ """
+ A class of pins related commands
+ All staff related to it will be here
+ """
+
+ @staticmethod
+ async def telegram_pin_callback_handler(call: CallbackQuery, callback_data: PinMsg) -> None:
+ """
+ Query, what pins message
+ :param call:
+ :param callback_data:
+ :return:
+ """
+ if callback_data.user_id == call.from_user.id:
+ return
+
+ await call.message.chat.pin_message(message_id=callback_data.msg_id)
+ await call.message.edit_text("Удача ✅\n"
+ "Сообщение было закреплено 📌",
+ reply_markup=pin_msg_keyboard(user_id=call.from_user.id,
+ msg_id=callback_data.msg_id))
+
+ @staticmethod
+ async def telegram_unpin_callback_handler(call: CallbackQuery, callback_data: UnpinMsg) -> None:
+ """
+ Query, what unpins message
+ :param call:
+ :param callback_data:
+ :return:
+ """
+ if callback_data.user_id == call.from_user.id:
+ return
+
+ await call.message.chat.pin_message(message_id=callback_data.msg_id)
+ await call.message.edit_text("Удача ✅\n"
+ "Сообщение было откреплено 📌",
+ reply_markup=unpin_msg_keyboard(user_id=call.from_user.id,
+ msg_id=callback_data.msg_id))
+
+ @staticmethod
+ async def telegram_pin_cmd(msg: Message) -> None:
+ """
+ /pin command function, pins replied command
+ :param msg: Message telegram object
+ :return: Nothing
+ """
+ await SolutionSimpler.pin_msg(msg)
+ await msg.answer("Удача ✅\n"
+ "Сообщение было закреплено 📌",
+ reply_markup=pin_msg_keyboard(msg_id=msg.reply_to_message.message_id,
+ user_id=msg.from_user.id))
+
+ @staticmethod
+ async def telegram_unpin_cmd(msg: Message) -> None:
+ """
+ /unpin command function, unpins replied command
+ :param msg: Message telegram object
+ :return: Nothing
+ """
+ await SolutionSimpler.unpin_msg(msg)
+ await msg.answer("Удача ✅\n"
+ "Сообщение было откреплено 📌",
+ reply_markup=unpin_msg_keyboard(msg_id=msg.reply_to_message.message_id,
+ user_id=msg.from_user.id))
+
+ @staticmethod
+ async def telegram_unpinall_cmd(msg: Message) -> None:
+ """
+ /unpin_all command function, unpins all messages in chat
+ :param msg: Message telegram object
+ :return: Nothing
+ """
+ await SolutionSimpler.unpin_all_messages(msg)
+ await msg.answer("Удача ✅\n"
+ "Все сообщения были откреплены 📌",
+ reply_markup=delete_keyboard(admin_id=msg.from_user.id))
+
+ def __init__(self):
+ """
+ All information about feature
+ will be inside this function
+ """
+ super().__init__()
+ self.cmd_description: str = "Your description of command"
+ # Telegram feature settings
+ self.telegram_setting = None
+ self.telegram_commands: list[str | None] = ["start"]
+ self.telegram_cmd_avaible = True # Is a feature have a commands
+ self.telegram_callback_factory = None
+ self.telegram_message_handlers = {
+
+ }
+ self.telegram_callback_handlers = {
+
+ }
diff --git a/bozenka/features/admin/topics.py b/bozenka/features/admin/topics.py
new file mode 100644
index 0000000..b81187d
--- /dev/null
+++ b/bozenka/features/admin/topics.py
@@ -0,0 +1,152 @@
+from aiogram import F, Bot
+from aiogram.enums import ChatType
+from aiogram.filters import Command
+from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery, InlineKeyboardButton
+from aiogram.utils.keyboard import InlineKeyboardBuilder
+
+from bozenka.features import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import HelpCategory, HelpBackCategory, HelpFeature, HelpBack, \
+ PinMsg, UnpinMsg, CloseThread, OpenThread
+from bozenka.instances.telegram.utils.keyboards import help_category_keyboard, help_keyboard, \
+ help_feature_keyboard, gpt_categories_keyboard, unpin_msg_keyboard, delete_keyboard, pin_msg_keyboard, \
+ close_thread_keyboard, open_thread_keyboard
+from bozenka.instances.telegram.utils.simpler import list_of_features, SolutionSimpler
+from bozenka.instances.version import build, is_updated
+
+
+class Threads(BasicFeature):
+ """
+ A class of topics / threads related commands
+ All staff related to it will be here
+ """
+
+ @staticmethod
+ async def telegram_close_topic_cmd_handler(msg: Message, bot: Bot) -> None:
+ """
+ /close command function. Closing thread
+ :param msg: Message telegram object
+ :param bot: Object of telegram bot
+ :return: Nothing
+ """
+ config = await SolutionSimpler.close_topic(msg=msg)
+ await msg.answer(config[0],
+ reply_markup=close_thread_keyboard(user_id=msg.from_user.id)
+ if config[1] else delete_keyboard(msg.from_user.id))
+
+ @staticmethod
+ async def telegram_reopen_topic_cmd_handler(msg: Message, bot: Bot) -> None:
+ """
+ /open command function. Opens thread
+ :param msg: Message telegram object
+ :param bot: Object of telegram bot
+ :return: Nothing
+ """
+ config = await SolutionSimpler.open_topic(msg=msg)
+ await msg.answer(config[0],
+ reply_markup=open_thread_keyboard(user_id=msg.from_user.id)
+ if config[1] else delete_keyboard(msg.from_user.id))
+
+ @staticmethod
+ async def telegram_close_general_topic_cmd_handler(msg: Message, bot: Bot) -> None:
+ """
+ /close_general command function. Closes general thread
+ :param msg: Message telegram object
+ :param bot: Object of telegram bot
+ :return: Nothing
+ """
+ config = await SolutionSimpler.close_general_topic(msg=msg)
+ await msg.answer(config[0],
+ reply_markup=close_thread_keyboard(user_id=msg.from_user.id)
+ if config[1] else delete_keyboard(msg.from_user.id))
+
+ @staticmethod
+ async def telegram_reopen_general_topic_cmd(msg: Message, bot: Bot) -> None:
+ """
+ /open_general command function. Opens general thread
+ :param msg: Message telegram object
+ :param bot: Object of telegram bot
+ :return: Nothing
+ """
+ config = await SolutionSimpler.open_general_topic(msg=msg)
+ await msg.answer(config[0],
+ reply_markup=open_thread_keyboard(user_id=msg.from_user.id)
+ if config[1] else delete_keyboard(msg.from_user.id))
+
+ @staticmethod
+ async def telegram_hide_general_topic_cmd_handler(msg: Message, bot: Bot) -> None:
+ """
+ /hide_general command function. Hides general thread
+ :param msg: Message telegram object
+ :param bot: Object of telegram bot
+ :return: Nothing
+ """
+ config = await SolutionSimpler.hide_general_topic(msg=msg)
+ await msg.answer(config[0],
+ reply_markup=delete_keyboard(msg.from_user.id))
+
+ @staticmethod
+ async def telegram_unhide_general_topic_cmd(msg: Message, bot: Bot) -> None:
+ """
+ /show_general command function. Shows back general thread.
+ :param msg: Message telegram object
+ :param bot: Object of telegram bot
+ :return: Nothing
+ """
+ config = await SolutionSimpler.show_general_topic(msg=msg)
+ await msg.answer(config[0],
+ reply_markup=delete_keyboard(msg.from_user.id))
+
+ @staticmethod
+ async def telegram_close_thread_callback_handler(call: CallbackQuery, callback_data: CloseThread) -> None:
+ """
+ Query, what close thread
+ :param call: CallbackQuery object
+ :param callback_data: ClosetThread object
+ :return: None
+ """
+
+ if callback_data.user_id != call.from_user.id or not call.message.chat.is_forum:
+ return
+ config = await SolutionSimpler.close_topic(msg=call.message, call=call)
+ await call.message.edit_text(
+ config[0],
+ reply_markup=close_thread_keyboard(user_id=call.from_user.id) if config[1] else
+ delete_keyboard(admin_id=call.from_user.id)
+ )
+
+ @staticmethod
+ async def inline_open_thread(call: CallbackQuery, callback_data: OpenThread) -> None:
+ """
+ Query, what opens thread
+ :param call: CallbackQuery object
+ :param callback_data: OpenThread
+ :return: None
+ """
+
+ if callback_data.user_id != call.from_user.id or not call.message.chat.is_forum:
+ return
+ config = await SolutionSimpler.open_topic(msg=call.message, call=call)
+ await call.message.edit_text(
+ config[0],
+ reply_markup=open_thread_keyboard(user_id=call.from_user.id) if config[1] else
+ delete_keyboard(admin_id=call.from_user.id)
+ )
+
+ def __init__(self):
+ """
+ All information about feature
+ will be inside this function
+ """
+ super().__init__()
+ self.cmd_description: str = "Your description of command"
+ # Telegram feature settings
+ self.telegram_setting = None
+ self.telegram_commands: list[str | None] = ["start"]
+ self.telegram_cmd_avaible = True # Is a feature have a commands
+ self.telegram_callback_factory = None
+ self.telegram_message_handlers = {
+
+ }
+ self.telegram_callback_handlers = {
+
+ }
diff --git a/bozenka/features/basic/__init__.py b/bozenka/features/basic/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bozenka/features/basic/setup.py b/bozenka/features/basic/setup.py
new file mode 100644
index 0000000..e69de29
diff --git a/bozenka/features/basic/start.py b/bozenka/features/basic/start.py
new file mode 100644
index 0000000..c7e38c6
--- /dev/null
+++ b/bozenka/features/basic/start.py
@@ -0,0 +1,225 @@
+from aiogram import F
+from aiogram.enums import ChatType
+from aiogram.filters import Command
+from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery, InlineKeyboardButton
+from aiogram.utils.keyboard import InlineKeyboardBuilder
+
+from bozenka.features import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import HelpCategory, HelpBackCategory, HelpFeature, HelpBack
+from bozenka.instances.telegram.utils.keyboards import help_category_keyboard, help_keyboard, \
+ help_feature_keyboard, gpt_categories_keyboard
+from bozenka.instances.telegram.utils.simpler import list_of_features
+from bozenka.instances.version import build, is_updated
+
+
+class Start(BasicFeature):
+ """
+ A class of /start command
+ All staff related to it will be here
+ """
+ cmd_description: str = "Basic command to show main menu"
+ main_text = """
+Привет 👋
+Я - бозенька, бот с открытым исходным кодом, который поможет тебе в различных задачах.
+
+Вот что ты можешь сделать с помощью меню:
+• Добавить в чат: добавляет меня в групповой чат, чтобы я мог выполнять свои функции внутри него.
+• Функционал: показывает список доступных функций и команд, которые я могу выполнить.
+• О разработчиках: предоставляет информацию о команде разработчиков, которые создали и поддерживают этого бота.
+• О запущенном экземпляре: выводит информацию о текущей версии и состоянии запущенного экземпляра бота.
+• Начать диалог с ИИ: позволяет начать диалог с искусственным интеллектом, который может отвечать на вопросы и предоставлять информацию.
+• Генерация изображений: позволяет сгенерировать изображения на основе заданных параметров и промта
+
+Вот нужные ссылки обо мне:
+• Канал с новостями об разработке
+• Исходный код на Github
+
+Чтобы воспользоваться какой-либо функцией, просто нажми на соответствующую кнопку ниже.
+Если у тебя возникнут вопросы или проблемы, не стесняйся обратиться к команде разработчиков или написать в обсуждении телеграм канала.
+Удачного использования!
+ """
+ telegram_main_menu = InlineKeyboardMarkup(
+ inline_keyboard=[
+ [InlineKeyboardButton(text="Добавить в ваш групповой чат 🔌", callback_data="addtochat")],
+ [InlineKeyboardButton(text="Информация об функционале бота 🔨", callback_data="functional")],
+ [InlineKeyboardButton(text="Об данном проекте ℹ️", callback_data="aboutdevs")],
+ [InlineKeyboardButton(text="О данном запущенном экзепляре ℹ️", callback_data="aboutbot")],
+ [InlineKeyboardButton(text="Начать диалог с текстовым ИИ 🤖", callback_data="dialogai")],
+ [InlineKeyboardButton(text="Начать генерацию изображений 🖼", callback_data="dialogimage")],
+ ]
+ )
+
+ # There starting a help category of handlers
+ # It's related to one of menus
+ # Showing information about features, will be remade later :D
+ @staticmethod
+ async def back_help_categories_handler(call: CallbackQuery, callback_data: HelpBack) -> None:
+ """
+ Query, what shows list of features to get support back.
+ :param call: CallbackQuery object
+ :param callback_data: Helpback class
+ :return: None
+ """
+ await call.message.edit_text("Выберите категорию, по которой нужна помощь:",
+ reply_markup=help_keyboard())
+ await call.answer()
+
+ @staticmethod
+ async def help_features_handler(call: CallbackQuery, callback_data: HelpCategory | HelpBackCategory) -> None:
+ """
+ Handler of CallbackQuery, what shows list of features to get support.
+ :param call: CallbackQuery object
+ :param callback_data: HelpCategory or HelpBack class
+ :return: None
+ """
+ await call.message.edit_text("Выберите функцию, по которой нужна помощь",
+ reply_markup=help_category_keyboard(category=callback_data.category_name))
+ await call.answer()
+
+ @staticmethod
+ async def feature_info_handler(call: CallbackQuery, callback_data: HelpFeature) -> None:
+ """
+ Handler of CallbackQuery, what shows information about bozenka feature
+ :param call: CallbackQuery ojbect
+ :param callback_data: HelpFeature object
+ :return: None
+ """
+ await call.message.edit_text(
+ list_of_features[callback_data.feature_category][callback_data.feature_index].description,
+ reply_markup=help_feature_keyboard(category=callback_data.feature_category))
+ await call.answer()
+
+ @staticmethod
+ async def help_menu_handler(call: CallbackQuery) -> None:
+ """
+ Handler of CallbackQuery, what shows menu of help
+ :param call: CallbackQuery object
+ :return: None
+ """
+ await call.message.edit_text("Выберите категорию функций, по которой вам нужна помощь 🤖",
+ reply_markup=help_keyboard())
+ await call.answer()
+
+ @staticmethod
+ async def add_to_menu_handler(call: CallbackQuery) -> None:
+ """
+ Handler of CallbackQuery, what shows a link to add bozenka into user group chat
+ :param call: CallbackQuery object
+ :return: None
+ """
+ # Getting bot
+ me = await call.message.bot.me()
+
+ # Generating special keyboard
+ kb = InlineKeyboardBuilder()
+ kb.button(text="Добавить в ваш груповой чат 🔌",
+ url="https://t.me/"
+ f"{me.username}?"
+ "startgroup&"
+ "admin=promote_members+delete_messages+restrict_members+invite_users+pin_messages+manage_video_chats")
+ kb.row(InlineKeyboardButton(text="Вернуться 🔙", callback_data="back"))
+
+ # Answering
+ await call.message.edit_text("Чтобы добавить бозеньку в ваш групповой чат, нажмите на кнопку под сообщением:",
+ reply_markup=kb.as_markup())
+ await call.answer()
+
+ @staticmethod
+ async def about_instance_callback_handler(call: CallbackQuery) -> None:
+ """
+ Handler of CallbackQuery, what shows information about current running instance
+ :param call: CallbackQuery object
+ :return: Nothing
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[[
+ InlineKeyboardButton(text="Вернуться 🔙", callback_data="back")
+ ]])
+ me = await call.message.bot.get_me()
+ update_status = {False: "требуется обновление бота 🔼",
+ True: "обновление не требуется, последняя версия ✅"}
+ await call.message.edit_text(
+ f"Информация об данном запущенном экземпляре бозеньки:\n"
+ f"Аккаунт бота: {me.mention_html()}\n"
+ f"Запущенная версия бота {build}
\n",
+ f"Нужно ли обновление: {update_status[is_updated]}",
+ reply_markup=kb)
+ await call.answer()
+
+ @staticmethod
+ async def about_developers_handler(call: CallbackQuery) -> None:
+ """
+ Handler of CallbackQuery, what shows information about bozenka & it's development
+ :param call: CallbackQuery object
+ :return: Nothing
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[[
+ InlineKeyboardButton(text="Вернуться 🔙", callback_data="back")
+ ]])
+ await call.message.edit_text("""
+ Бозенька - это мультифункциональный (в будущем кроссплатформенный) бот.\n
+ Он умеет работать с групповыми чатами и готовыми нейронными сетями для генерации текста и изображений.
+ Бозенька разрабатывается коммандой, которая состоит на данный момент из одного человека.\n
+ Исходный код проекта\n
+ Исходный код находится под лицензией GPL-3.0, исходный код проекта можно посмотреть всегда здесь
+ Канал с новостями разработки находится здесь
+ """, reply_markup=kb, disable_web_page_preview=True)
+
+ @staticmethod
+ async def start_dialog_handler(call: CallbackQuery) -> None:
+ """
+ Handler of CallbackQuery, what shows list of Categories, avaible to use as chatbot
+ :param call: CallbackQuery object
+ :return: Nothing
+ """
+ await call.message.edit_text("Пожалуста, выберите сервиc / библиотеку, через которую вы будете общаться",
+ reply_markup=gpt_categories_keyboard
+ (user_id=call.from_user.id))
+
+ async def start_callback_handler(self, call: CallbackQuery) -> None:
+ """
+ /start command function handler. Just back it by clicking on button.
+ Shows menu and basic information about bozenka
+ :param call: Message telegram object
+ :return: Nothing
+ """
+ await call.message.edit_text(self.main_text,
+ reply_markup=self.telegram_main_menu, disable_web_page_preview=True)
+
+ async def start_cmd_handler(self, msg: Message) -> None:
+ """
+ /start command function handler
+ Shows menu and basic information about bozenka
+ :param msg: Message telegram object
+ :return: Nothing
+ """
+ await msg.answer(self.main_text,
+ reply_markup=self.telegram_main_menu, disable_web_page_preview=True)
+
+ def __init__(self):
+ """
+ All information about feature
+ will be inside this function
+ """
+ super().__init__()
+ self.cmd_description: str = "Your description of command"
+ # Telegram feature settings
+ self.telegram_setting = None
+ self.telegram_commands: list[str | None] = ["start"]
+ self.telegram_cmd_avaible = True # Is a feature have a commands
+ self.telegram_callback_factory = None
+ self.telegram_message_handlers = {
+ self.start_cmd_handler: [Command(commands=["start"]), F.chat.type == ChatType.PRIVATE],
+
+ }
+ self.telegram_callback_handlers = {
+ # Start menu
+ self.start_dialog_handler: [F.data == "dialogai"],
+ self.add_to_menu_handler: [F.data == "addtochat"],
+ self.about_developers_handler: [F.data == "aboutdevs"],
+ self.about_instance_callback_handler: [F.data == "aboutbot"],
+ self.start_callback_handler: [F.data == "back"],
+ # Help menu
+ self.feature_info_handler: [HelpFeature.filter() or HelpBackCategory.filter()],
+ self.help_menu_handler: [HelpCategory.filter() or HelpBack.filter(F.back_to == "category")],
+
+ }
diff --git a/bozenka/features/user/__init__.py b/bozenka/features/user/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bozenka/features/user/image_generation.py b/bozenka/features/user/image_generation.py
new file mode 100644
index 0000000..e69de29
diff --git a/bozenka/features/user/text_generation.py b/bozenka/features/user/text_generation.py
new file mode 100644
index 0000000..e69de29
diff --git a/bozenka/features/user/welcome.py b/bozenka/features/user/welcome.py
new file mode 100644
index 0000000..e69de29
diff --git a/bozenka/instances/telegram/handlers/main/__init__.py b/bozenka/instances/telegram/handlers/main/__init__.py
index aef1768..43f3947 100644
--- a/bozenka/instances/telegram/handlers/main/__init__.py
+++ b/bozenka/instances/telegram/handlers/main/__init__.py
@@ -19,7 +19,11 @@ def register_main_cmd(router: Router) -> None:
logging.log(msg="Registering main related commands", level=logging.INFO)
# Start command handler
+ """
router.message.register(start_cmd, Command(commands=["start"]), F.chat.type == ChatType.PRIVATE)
+ """
+
+ router.message.register(start_cmd, *[Command(commands=["start"]), F.chat.type == ChatType.PRIVATE])
# Registering command /setup
router.message.register(setup_cmd, Command(commands=["setup"]), ~(F.chat.type == ChatType.PRIVATE))
diff --git a/bozenka/instances/telegram/utils/callbacks_factory/start.py b/bozenka/instances/telegram/utils/callbacks_factory/start.py
index a4ef63d..0c4048d 100644
--- a/bozenka/instances/telegram/utils/callbacks_factory/start.py
+++ b/bozenka/instances/telegram/utils/callbacks_factory/start.py
@@ -28,7 +28,7 @@ class HelpBackCategory(CallbackData, prefix="hbc"):
Callback data to back to list of features in one
of categories in menu
"""
- back_to_category: str
+ category_name: str
class BackStart(CallbackData, prefix="start"):
diff --git a/bozenka/instances/telegram/utils/middleware/__init__.py b/bozenka/instances/telegram/utils/middleware/__init__.py
index a2f4542..4b6f273 100644
--- a/bozenka/instances/telegram/utils/middleware/__init__.py
+++ b/bozenka/instances/telegram/utils/middleware/__init__.py
@@ -3,8 +3,7 @@ import logging
from aiogram import Router, Dispatcher
from bozenka.instances.telegram.utils.middleware.antiflood import MessageThrottlingMiddleware, \
- CallbackThrottlingMiddleware
-from bozenka.instances.telegram.utils.middleware.retry import RetryMessageMiddleware, RetryCallbackMiddleware
+ CallbackThrottlingMiddleware, CounterMiddleware
def register_middlewares(dp: Dispatcher) -> None:
@@ -16,8 +15,13 @@ def register_middlewares(dp: Dispatcher) -> None:
logging.log(msg=f"Registering middlewares of bot", level=logging.INFO)
# Throttling middlewares
- dp.message.middleware.register(MessageThrottlingMiddleware)
+
+ """
+ dp.message.middleware(CounterMiddleware)
dp.callback_query.middleware(CallbackThrottlingMiddleware)
# Retry middlewares
+ """
+ """
dp.error.middleware(RetryMessageMiddleware)
dp.error.middleware(RetryCallbackMiddleware)
+ """
diff --git a/bozenka/instances/telegram/utils/middleware/antiflood.py b/bozenka/instances/telegram/utils/middleware/antiflood.py
index c683343..2332079 100644
--- a/bozenka/instances/telegram/utils/middleware/antiflood.py
+++ b/bozenka/instances/telegram/utils/middleware/antiflood.py
@@ -5,6 +5,22 @@ from aiogram.types import Update, Message, CallbackQuery
from cachetools import TTLCache
+class CounterMiddleware(BaseMiddleware):
+ def __init__(self) -> None:
+ self.counter = 0
+
+ async def __call__(
+ self,
+ handler: Callable[[Message, Dict[str, Any]], Awaitable[Any]],
+ event: Message,
+ data: Dict[str, Any],
+ **kwargs: Any
+ ) -> Any:
+ self.counter += 1
+ print(self.counter)
+ return await handler(event, data)
+
+
class MessageThrottlingMiddleware(BaseMiddleware):
"""
This middleware is skidded from public codes
diff --git a/bozenka/instances/telegram/utils/middleware/retry.py b/bozenka/instances/telegram/utils/middleware/retry.py
index 0fbd268..d8198a8 100644
--- a/bozenka/instances/telegram/utils/middleware/retry.py
+++ b/bozenka/instances/telegram/utils/middleware/retry.py
@@ -6,31 +6,3 @@ from aiogram.exceptions import TelegramRetryAfter
from aiogram.types import Message, ErrorEvent, Update, CallbackQuery
-class RetryMessageMiddleware(BaseMiddleware):
- """
- Protects from user don't get update by message
- """
-
- async def __call__(
- self,
- handler: Callable[[Message, Dict[str, Any]], Awaitable[Any]],
- event: ErrorEvent[TelegramRetryAfter, Update],
- data: Dict[str, Any]
- ) -> Any:
- time.sleep(event.exception.retry_after)
- return await handler(event.update.message, data)
-
-
-class RetryCallbackMiddleware(BaseMiddleware):
- """
- Protects from user don't get update by callbackquery
- """
-
- async def __call__(
- self,
- handler: Callable[[CallbackQuery, Dict[str, Any]], Awaitable[Any]],
- event: ErrorEvent[TelegramRetryAfter, Update],
- data: Dict[str, Any]
- ) -> Any:
- time.sleep(event.exception.retry_after)
- return await handler(event.update.callback_query, data)
--
2.30.2
From 348a8c7245b4700b3b2cc6546b4f811ad5d6de2e Mon Sep 17 00:00:00 2001
From: kittyneverdies <85691197+KittyNeverDies@users.noreply.github.com>
Date: Thu, 8 Feb 2024 16:51:08 +0300
Subject: [PATCH 03/13] It is still getting developed. Changelog: - Added all
features of bozenka - Added features_list.py - Some refactors and starting
writing code of registering all features handlers
---
bozenka/features/__init__.py | 79 +--
bozenka/features/admin/__init__.py | 4 +
bozenka/features/admin/invite.py | 83 +++
bozenka/features/admin/moderation.py | 74 ++-
bozenka/features/admin/pins.py | 32 +-
bozenka/features/admin/topics.py | 86 ++-
bozenka/features/basic/__init__.py | 2 +
bozenka/features/basic/setup.py | 103 ++++
bozenka/features/basic/start.py | 3 +-
bozenka/features/features_list.py | 30 +
bozenka/features/user/__init__.py | 3 +
bozenka/features/user/image_generation.py | 157 +++++
bozenka/features/user/text_generation.py | 559 ++++++++++++++++++
bozenka/features/user/welcome.py | 82 +++
.../telegram/handlers/chat_admin/__init__.py | 2 -
.../telegram/handlers/dev/image_generation.py | 12 +-
.../telegram/handlers/queries/setup.py | 8 +-
.../telegram/utils/callbacks_factory/setup.py | 2 +-
.../utils/simpler/lists_of_content.py | 4 +-
19 files changed, 1189 insertions(+), 136 deletions(-)
create mode 100644 bozenka/features/features_list.py
diff --git a/bozenka/features/__init__.py b/bozenka/features/__init__.py
index 401b1df..8343157 100644
--- a/bozenka/features/__init__.py
+++ b/bozenka/features/__init__.py
@@ -1,11 +1,3 @@
-from typing import Callable
-
-from aiogram import Dispatcher
-from aiogram.filters import CommandObject
-from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery
-from sqlalchemy.ext.asyncio import async_sessionmaker
-
-from bozenka.database.tables.telegram import TelegramChatSettings
class BasicFeature:
@@ -13,60 +5,29 @@ class BasicFeature:
A classic class of lineral (basic)
feature of bozenka. IN FUTURE!
"""
- cmd_description: str = "Your description of command"
-
- '''
- Here is example of code you can add:
-
- async def generate_telegram_inline_keyboard(self) -> InlineKeyboardMarkup:
- """
- Generates a special telegram keyboard (menu)
- :return: Inline Keyboard
- """
- pass
-
- async def telegram_command_handler(self, msg: Message, cmd: CommandObject, session_maker: async_sessionmaker) -> None:
- """
- A special telegram handler for command (if exist)
- It is just an example
- :param msg: Telegram message object
- :param cmd: Aiogram command object
- :param session_maker: Async session maker object of SQLAlchemy
- :return: Nothing
- """
- pass
-
- async def telegram_callback_handler(self, call: CallbackQuery, callback_data, session_maker: async_sessionmaker) -> None:
- """
- A special telegram handler for command (if exist)
- It is just an example
- :param call: Telegram callbackquery object
- :param callback_data: A custom callback data created by callback factory
- :param session_maker: Async session maker object of SQLAlchemy
- :return: Nothing
- """
- pass
- '''
def __init__(self):
"""
All information about feature
will be inside this function
"""
- self.cmd_description: str = "Your description of command"
- # Telegram feature settings
- self.telegram_setting = TelegramChatSettings.text_generation
- self.telegram_commands: list[str | None] = ["test"]
- self.telegram_cmd_avaible = True # Is a feature have a commands
- self.telegram_callback_factory = None
- self.telegram_message_handlers = {
- """
- Format is
- Handler: [Filters]
- """
- }
- self.telegram_callback_handlers = {
- """
- Format is
- Handler: [Filters]
- """
+
+ # Telegram setting info
+ self.telegram_setting_in_list = False # Does feature shows in /setup list
+ self.telegram_setting_name = None # Setting title in /setup command
+ self.telegram_setting_description = None # Setting description in /setup command
+ self.telegram_db_name = None # Name of TelegramChatSettings column will be affected
+ # Telegram commands list of feature
+ self.telegram_commands: dict[str: str] = {
+ #
+ # Format is "CommandNameHere": "Command description is here"
+ #
+ "example": "Its an example"
}
+ self.telegram_cmd_avaible = True # Does this feature have a telegram commands
+ # All handlers
+ self.telegram_message_handlers = (
+ # Format is [Handler, [Filters]]
+ )
+ self.telegram_callback_handlers = (
+ # Format is [Handler, [Filters]]
+ )
\ No newline at end of file
diff --git a/bozenka/features/admin/__init__.py b/bozenka/features/admin/__init__.py
index e69de29..f14b364 100644
--- a/bozenka/features/admin/__init__.py
+++ b/bozenka/features/admin/__init__.py
@@ -0,0 +1,4 @@
+from invite import Invite
+from moderation import Moderation
+from pins import Pins
+from topics import Threads
diff --git a/bozenka/features/admin/invite.py b/bozenka/features/admin/invite.py
index e69de29..b39c107 100644
--- a/bozenka/features/admin/invite.py
+++ b/bozenka/features/admin/invite.py
@@ -0,0 +1,83 @@
+import logging
+
+from aiogram.enums import ChatMemberStatus
+from aiogram.filters import Command
+from aiogram.types import Message, CallbackQuery
+
+from bozenka.database.tables.telegram import TelegramChatSettings
+from bozenka.features import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import RevokeCallbackData
+from bozenka.instances.telegram.utils.keyboards import invite_keyboard
+from bozenka.instances.telegram.utils.simpler import ru_cmds
+
+
+class Invite(BasicFeature):
+ """
+ A class with information about invite feature
+ All codes will be here
+ """
+
+ @staticmethod
+ async def telegram_invite_command_handler(msg: Message) -> None:
+ """
+ Generating invite to group by /invite command
+ :param msg: Message telegram object
+ :return: None
+ """
+ logging.log(msg=f"Generating invite for user_id={msg.from_user.id}",
+ level=logging.INFO)
+ link = await msg.chat.create_invite_link()
+
+ await msg.answer(
+ f" Держите ваше приглашение в чат, {msg.from_user.mention_html('пользователь')} 👋",
+ reply_markup=invite_keyboard(link=str(link.invite_link), admin_id=msg.from_user.id,
+ chat_name=msg.chat.full_name)
+ )
+
+ @staticmethod
+ async def telegram_revoke_callback_handler(call: CallbackQuery, callback_data: RevokeCallbackData) -> None:
+ """
+ Handler of CallbackQuery, revokes link after pressing button
+ :param call: CallbackQuery aioram object
+ :param callback_data: RevokeCallbackData object
+ :return: Nothing
+ """
+ user_clicked = await call.message.chat.get_member(call.from_user.id)
+
+ if callback_data.admin_id != call.from_user.id and \
+ user_clicked.status != ChatMemberStatus.ADMINISTRATOR and user_clicked.status == ChatMemberStatus.CREATOR:
+ return
+ logging.log(msg=f"Revoking link for user_id={call.from_user.id}",
+ level=logging.INFO)
+ await call.message.chat.revoke_invite_link(invite_link="https://" + str(callback_data.link))
+ await call.answer("Удача ✅")
+ await call.message.delete()
+
+ def __init__(self):
+ """
+ All information about feature
+ will be inside this function
+ """
+ super().__init__()
+ """
+ Telegram feature settings
+ """
+ # Telegram setting info
+ self.telegram_setting_in_list = True
+ self.telegram_setting_name = "Приглашения в Чат ✉"
+ self.telegram_setting_description = "Генератор приглашения в Чат ✉\n" \
+ "Разрешает использование комманды /invite
в чате, для созданния приглашений.\n" \
+ "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
+ self.telegram_db_name = TelegramChatSettings.invite_generator
+ # Telegram commands
+ self.telegram_commands: dict[str: str] = {"/invite": 'Generates invite into current chat'}
+ self.telegram_cmd_avaible = True # Is a feature have a commands
+ # List of aiogram handlers
+ self.telegram_message_handlers = (
+ # Format is [Handler, [Filters]]
+ [self.telegram_invite_command_handler, [Command(commands=["invite"])]]
+ )
+ self.telegram_callback_handlers = (
+ # Format is [Handler, [Filters]]
+ [self.telegram_revoke_callback_handler, [RevokeCallbackData.filter()]]
+ )
diff --git a/bozenka/features/admin/moderation.py b/bozenka/features/admin/moderation.py
index 4e39e53..637b969 100644
--- a/bozenka/features/admin/moderation.py
+++ b/bozenka/features/admin/moderation.py
@@ -1,21 +1,18 @@
import logging
from aiogram import F
-from aiogram.enums import ChatType, ChatMemberStatus
-from aiogram.filters import Command, CommandObject
-from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery, InlineKeyboardButton
-from aiogram.utils.keyboard import InlineKeyboardBuilder
+from aiogram.enums import ChatMemberStatus
+from aiogram.filters import CommandObject, Command
+from aiogram.types import Message, CallbackQuery
from sqlalchemy.ext.asyncio import async_sessionmaker
-from bozenka.database.tables.telegram import get_chat_config_value
+from bozenka.database.tables.telegram import get_chat_config_value, TelegramChatSettings
from bozenka.features import BasicFeature
-from bozenka.instances.telegram.utils.callbacks_factory import HelpCategory, HelpBackCategory, HelpFeature, HelpBack, \
- UnbanData, BanData, UnmuteData, MuteData
-from bozenka.instances.telegram.utils.keyboards import help_category_keyboard, help_keyboard, \
- help_feature_keyboard, gpt_categories_keyboard, ban_keyboard, delete_keyboard, mute_keyboard, unmute_keyboard, \
+from bozenka.instances.telegram.utils.callbacks_factory import UnbanData, BanData, UnmuteData, MuteData
+from bozenka.instances.telegram.utils.filters import IsAdminFilter, BotHasPermissions, UserHasPermissions
+from bozenka.instances.telegram.utils.keyboards import ban_keyboard, delete_keyboard, mute_keyboard, unmute_keyboard, \
unban_keyboard
from bozenka.instances.telegram.utils.simpler import list_of_features, SolutionSimpler
-from bozenka.instances.version import build, is_updated
class Moderation(BasicFeature):
@@ -23,7 +20,6 @@ class Moderation(BasicFeature):
A class of moderation related feature
All staff related to it will be here
"""
- cmd_description: str = "Basic command to show main menu"
@staticmethod
async def telegram_ban_callback_handler(call: CallbackQuery, callback_data: BanData,
@@ -455,15 +451,49 @@ class Moderation(BasicFeature):
will be inside this function
"""
super().__init__()
- self.cmd_description: str = "Your description of command"
- # Telegram feature settings
- self.telegram_setting = None
- self.telegram_commands: list[str | None] = ["start"]
+ # Telegram setting info
+ self.telegram_setting_in_list = True
+ self.telegram_setting_name = "Модерация чата 🕵️"
+ self.telegram_setting_description = "Модерация чата🕵️\nДанная настройка включает следущие комманды:" \
+ "\n/ban [время блокировки] [причина блокировки] - блокировка пользователя" \
+ "\n/unban - разблокировка пользователя\n" \
+ "/mute [время мута] [причина мута] - мут пользователя\n" \
+ "/unmute - Размут пользователя
\n" \
+ "Время обозначается как:" \
+ "1h - один час, " \
+ "1d - один день, " \
+ "1m - одна минута, " \
+ "1s - одна секунда
\n" \
+ "Для того, " \
+ "чтобы выполнить одну из комманд по отношению к пользователю, " \
+ "ответьте на сообщение пользователя и используйте команду\n" \
+ "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
+ self.telegram_db_name = TelegramChatSettings.moderation
+ # Telegram commands
+ self.telegram_commands: dict[str: str] = {
+ "ban": "Command to ban user in chat",
+ 'unban': 'Command to unban user in chat',
+ 'mute': 'Command to mute user in chat',
+ 'unmute': 'Command to unmute user in chat',
+ }
self.telegram_cmd_avaible = True # Is a feature have a commands
- self.telegram_callback_factory = None
- self.telegram_message_handlers = {
- # Your message handlers
- }
- self.telegram_callback_handlers = {
- # Start menu
- }
+ # All handlers
+ self.telegram_message_handlers = (
+ # Format is [Handler, [Filters]]
+ [self.telegram_ban_cmd_handler, [Command(commands="ban"),
+ IsAdminFilter(True), F.reply_to_message.text]],
+ [self.telegram_unban_cmd_handler, [Command(commands="unban"),
+ IsAdminFilter(True), F.reply_to_message.text]],
+ [self.telegram_mute_cmd_handler, [Command(commands=["mute", "re"]),
+ UserHasPermissions(["can_restrict_members"]),
+ BotHasPermissions(["can_restrict_members"])]],
+ [self.telegram_unmute_cmd_handler, [Command(commands=["unmute"]),
+ UserHasPermissions(["can_restrict_members"]),
+ BotHasPermissions(["can_restrict_members"])]]
+ )
+ self.telegram_callback_handlers = (
+ # Format is [Handler, [Filters]]
+ [self.telegram_ban_callback_handler, [BanData.filter()]],
+ [self.telegram_unban_callback_handler, [UnbanData.filter()]],
+ [self.telegram_mute_callback_handler, [MuteData.filter()]],
+ [self.telegram_unmute_callback_handler, [UnmuteData.filter()]])
diff --git a/bozenka/features/admin/pins.py b/bozenka/features/admin/pins.py
index 55b551e..10e0614 100644
--- a/bozenka/features/admin/pins.py
+++ b/bozenka/features/admin/pins.py
@@ -1,7 +1,11 @@
+from aiogram import F
+from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery
+from bozenka.database.tables.telegram import TelegramChatSettings
from bozenka.features import BasicFeature
from bozenka.instances.telegram.utils.callbacks_factory import PinMsg, UnpinMsg
+from bozenka.instances.telegram.utils.filters import UserHasPermissions, BotHasPermissions, IsAdminFilter
from bozenka.instances.telegram.utils.keyboards import unpin_msg_keyboard, delete_keyboard, pin_msg_keyboard
from bozenka.instances.telegram.utils.simpler import SolutionSimpler
@@ -92,13 +96,31 @@ class Pins(BasicFeature):
super().__init__()
self.cmd_description: str = "Your description of command"
# Telegram feature settings
- self.telegram_setting = None
- self.telegram_commands: list[str | None] = ["start"]
+ self.telegram_setting_in_list = True
+ self.telegram_setting_name = "Закреп 📌"
+ self.telegram_setting_description = "Закреп📌" \
+ "\nДанная функция включает команды:" \
+ "/pin - закрепляет сообщение\n" \
+ "/unpin - открепляет сообщение\n" \
+ "/unpin_all - открепляет все сообщения, которые видит бот
\n" \
+ "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
+ self.telegram_db_name = TelegramChatSettings.pins
+ # Telegram commands
+ self.telegram_commands: dict[str: str] = {
+ 'pin': 'Pin fast any message in chat',
+ 'unpin': 'Unpin fast any message in chat',
+ }
self.telegram_cmd_avaible = True # Is a feature have a commands
- self.telegram_callback_factory = None
+ # Telegram Handler
self.telegram_message_handlers = {
-
+ self.telegram_pin_cmd: [Command(commands="pin"), UserHasPermissions(["can_pin_messages"]),
+ BotHasPermissions(["can_pin_messages"]), F.reply_to_message],
+ self.telegram_unpin_cmd: [Command(commands="unpin"), UserHasPermissions(["can_pin_messages"]),
+ BotHasPermissions(["can_pin_messages"]), F.reply_to_message],
+ self.telegram_unpinall_cmd: [Command(commands="unpin_all"), IsAdminFilter(True),
+ BotHasPermissions(["can_pin_messages"]), F.reply_to_message.text],
}
self.telegram_callback_handlers = {
-
+ self.telegram_pin_callback_handler: [PinMsg.filter()],
+ self.telegram_unpin_callback_handler: [UnpinMsg.filter()]
}
diff --git a/bozenka/features/admin/topics.py b/bozenka/features/admin/topics.py
index b81187d..247061a 100644
--- a/bozenka/features/admin/topics.py
+++ b/bozenka/features/admin/topics.py
@@ -1,17 +1,13 @@
-from aiogram import F, Bot
-from aiogram.enums import ChatType
+from aiogram import F
from aiogram.filters import Command
-from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery, InlineKeyboardButton
-from aiogram.utils.keyboard import InlineKeyboardBuilder
+from aiogram.types import Message, CallbackQuery
+from bozenka.database.tables.telegram import TelegramChatSettings
from bozenka.features import BasicFeature
-from bozenka.instances.telegram.utils.callbacks_factory import HelpCategory, HelpBackCategory, HelpFeature, HelpBack, \
- PinMsg, UnpinMsg, CloseThread, OpenThread
-from bozenka.instances.telegram.utils.keyboards import help_category_keyboard, help_keyboard, \
- help_feature_keyboard, gpt_categories_keyboard, unpin_msg_keyboard, delete_keyboard, pin_msg_keyboard, \
- close_thread_keyboard, open_thread_keyboard
-from bozenka.instances.telegram.utils.simpler import list_of_features, SolutionSimpler
-from bozenka.instances.version import build, is_updated
+from bozenka.instances.telegram.utils.callbacks_factory import CloseThread, OpenThread
+from bozenka.instances.telegram.utils.filters import UserHasPermissions, BotHasPermissions
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard, close_thread_keyboard, open_thread_keyboard
+from bozenka.instances.telegram.utils.simpler import SolutionSimpler
class Threads(BasicFeature):
@@ -21,11 +17,10 @@ class Threads(BasicFeature):
"""
@staticmethod
- async def telegram_close_topic_cmd_handler(msg: Message, bot: Bot) -> None:
+ async def telegram_close_topic_cmd_handler(msg: Message) -> None:
"""
/close command function. Closing thread
:param msg: Message telegram object
- :param bot: Object of telegram bot
:return: Nothing
"""
config = await SolutionSimpler.close_topic(msg=msg)
@@ -34,11 +29,10 @@ class Threads(BasicFeature):
if config[1] else delete_keyboard(msg.from_user.id))
@staticmethod
- async def telegram_reopen_topic_cmd_handler(msg: Message, bot: Bot) -> None:
+ async def telegram_reopen_topic_cmd_handler(msg: Message) -> None:
"""
/open command function. Opens thread
:param msg: Message telegram object
- :param bot: Object of telegram bot
:return: Nothing
"""
config = await SolutionSimpler.open_topic(msg=msg)
@@ -47,11 +41,10 @@ class Threads(BasicFeature):
if config[1] else delete_keyboard(msg.from_user.id))
@staticmethod
- async def telegram_close_general_topic_cmd_handler(msg: Message, bot: Bot) -> None:
+ async def telegram_close_general_topic_cmd_handler(msg: Message) -> None:
"""
/close_general command function. Closes general thread
:param msg: Message telegram object
- :param bot: Object of telegram bot
:return: Nothing
"""
config = await SolutionSimpler.close_general_topic(msg=msg)
@@ -60,11 +53,10 @@ class Threads(BasicFeature):
if config[1] else delete_keyboard(msg.from_user.id))
@staticmethod
- async def telegram_reopen_general_topic_cmd(msg: Message, bot: Bot) -> None:
+ async def telegram_reopen_general_topic_cmd(msg: Message) -> None:
"""
/open_general command function. Opens general thread
:param msg: Message telegram object
- :param bot: Object of telegram bot
:return: Nothing
"""
config = await SolutionSimpler.open_general_topic(msg=msg)
@@ -73,11 +65,10 @@ class Threads(BasicFeature):
if config[1] else delete_keyboard(msg.from_user.id))
@staticmethod
- async def telegram_hide_general_topic_cmd_handler(msg: Message, bot: Bot) -> None:
+ async def telegram_hide_general_topic_cmd_handler(msg: Message) -> None:
"""
/hide_general command function. Hides general thread
:param msg: Message telegram object
- :param bot: Object of telegram bot
:return: Nothing
"""
config = await SolutionSimpler.hide_general_topic(msg=msg)
@@ -85,11 +76,10 @@ class Threads(BasicFeature):
reply_markup=delete_keyboard(msg.from_user.id))
@staticmethod
- async def telegram_unhide_general_topic_cmd(msg: Message, bot: Bot) -> None:
+ async def telegram_unhide_general_topic_cmd(msg: Message) -> None:
"""
/show_general command function. Shows back general thread.
:param msg: Message telegram object
- :param bot: Object of telegram bot
:return: Nothing
"""
config = await SolutionSimpler.show_general_topic(msg=msg)
@@ -138,15 +128,51 @@ class Threads(BasicFeature):
will be inside this function
"""
super().__init__()
- self.cmd_description: str = "Your description of command"
- # Telegram feature settings
- self.telegram_setting = None
- self.telegram_commands: list[str | None] = ["start"]
+ # Telegram setting info
+ self.telegram_setting_in_list = True
+ self.telegram_setting_name = "Работа с Форумом 💬"
+ self.telegram_setting_description = "Работа с Форумом💬\nДанная настройка включает следущие комманды:\n" \
+ "/open - открывают тему форума\n" \
+ "/close - закрывают тему форума\n" \
+ "/open_general - открывают основную тему форума\n" \
+ "/close_general - закрывает основную тему форума\n" \
+ "/hide_general - прячет основную тему форума\n" \
+ "/show_general - показывает основную тему форума
\n" \
+ "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота. Также должен быть" \
+ "включен форум"
+ self.telegram_db_name = TelegramChatSettings.topics
+ # Telegram commands
+ self.telegram_commands: dict[str: str] = {
+ 'close': 'Close fast topic (not general) in chat',
+ 'open': 'Open fast topic (not general) in chat',
+ 'hide_general': 'Hide general topic in chat',
+ 'show_general': 'Show general topic in chat',
+ "close_general": 'Closes general topic in chat',
+ "open_general": 'Opens general topic in chat',
+ }
self.telegram_cmd_avaible = True # Is a feature have a commands
- self.telegram_callback_factory = None
+ # All handlers
self.telegram_message_handlers = {
-
+ self.telegram_close_topic_cmd_handler: [Command(commands=["close_topic", "close"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
+ self.telegram_reopen_topic_cmd_handler: [Command(commands=["reopen_topic", "open_topic", "open"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
+ self.telegram_close_general_topic_cmd_handler: [Command(commands=["close_general"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
+ self.telegram_reopen_general_topic_cmd: [Command(commands=["reopen_general", "open_general"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
+ self.telegram_hide_general_topic_cmd_handler: [Command(commands=["hide_general"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
+ self.telegram_unhide_general_topic_cmd: [Command(commands=["unhide_general", "show_general"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum]
}
self.telegram_callback_handlers = {
-
+ self.telegram_close_thread_callback_handler: [CloseThread.filter()],
+ self.telegram_reopen_topic_cmd_handler: [OpenThread.filter()]
}
diff --git a/bozenka/features/basic/__init__.py b/bozenka/features/basic/__init__.py
index e69de29..b34966c 100644
--- a/bozenka/features/basic/__init__.py
+++ b/bozenka/features/basic/__init__.py
@@ -0,0 +1,2 @@
+from setup import Setup
+from start import Start
diff --git a/bozenka/features/basic/setup.py b/bozenka/features/basic/setup.py
index e69de29..13d3398 100644
--- a/bozenka/features/basic/setup.py
+++ b/bozenka/features/basic/setup.py
@@ -0,0 +1,103 @@
+from aiogram import F
+from aiogram.enums import ChatType
+from aiogram.filters import Command
+from aiogram.types import Message, CallbackQuery
+from sqlalchemy import Update
+from sqlalchemy.ext.asyncio import async_sessionmaker
+
+from bozenka.database.tables.telegram import get_chat_config_value, TelegramChatSettings
+from bozenka.features import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import SetupAction, SetupFeature, SetupCategory
+from bozenka.instances.telegram.utils.keyboards import setup_keyboard, setup_category_keyboard, setup_feature_keyboard
+from bozenka.instances.telegram.utils.simpler import list_of_features
+
+
+class Setup(BasicFeature):
+ """
+ A class of /setup command
+ All staff related to it will be here
+ """
+
+ @staticmethod
+ async def telegram_setup_cmd_handler(msg: Message) -> None:
+ """
+ /setup telegram handler
+ :param msg: Telegram message object
+ :return: Nothing
+ """
+ await msg.answer("Привет владелец чата 👋\n"
+ "Чтобы меня настроить, используй меню под данным сообщением",
+ reply_markup=setup_keyboard())
+
+ @staticmethod
+ async def telegram_setup_categories_handler(call: CallbackQuery, callback_data: SetupCategory | SetupAction):
+ """
+ Query, what shows list of features to enable.
+ :param call:
+ :param callback_data:
+ :return:
+ """
+ await call.message.edit_text("Выберите настройку, которую хотите изменить",
+ reply_markup=setup_category_keyboard(category=callback_data.category_name))
+
+ @staticmethod
+ async def telegram_setup_edit_feature_handler(call: CallbackQuery, callback_data: SetupFeature, session_maker: async_sessionmaker):
+ """
+ Query, what shows menu to enable / disable feature
+ :param call:
+ :param callback_data:
+ :param session_maker:
+ :return:
+ """
+ is_enabled = await get_chat_config_value(
+ chat_id=call.message.chat.id,
+ session=session_maker,
+ setting=list_of_features[callback_data.feature_category][callback_data.feature_index]
+ )
+
+ await call.message.edit_text(
+ list_of_features[callback_data.feature_category][callback_data.feature_index].description,
+ reply_markup=await setup_feature_keyboard(category=callback_data.feature_category,
+ index=callback_data.feature_index,
+ is_enabled=is_enabled))
+
+ @staticmethod
+ async def telegram_features_edit_handler(call: CallbackQuery, callback_data: SetupAction, session_maker: async_sessionmaker):
+ """
+ Query, what shows menu to enable / disable feature
+ after editing
+ :param call:
+ :param callback_data:
+ :param session_maker:
+ :return:
+ """
+ async with session_maker() as session:
+ async with session.begin():
+ await session.execute(Update(TelegramChatSettings)
+ .values(
+ {list_of_features[callback_data.category_name][callback_data.feature_index].settings_name: callback_data.action == "enable"})
+ .where(TelegramChatSettings.chat_id == call.message.chat.id))
+ await call.message.edit_text(
+ list_of_features[callback_data.category_name][callback_data.feature_index].description,
+ reply_markup=await setup_feature_keyboard(category=callback_data.category_name,
+ index=callback_data.afeature_index,
+ is_enabled=callback_data.action == "enable"))
+
+ def __init__(self):
+ """
+ All information about feature
+ will be inside this function
+ """
+ super().__init__()
+ # Telegram feature settings
+ self.telegram_setting_in_list = False
+ self.telegram_commands = {"setup": 'Command to setup bozenka features in chat'}
+ self.telegram_cmd_avaible = True
+ self.telegram_message_handlers = {
+ self.telegram_setup_cmd_handler: [Command(commands=["setup"]), ~(F.chat.type == ChatType.PRIVATE)]
+ }
+ self.telegram_callback_handlers = {
+ self.telegram_features_edit_handler: [SetupAction.filter(F.action == "disable" or F.action == "enable")],
+ self.telegram_setup_edit_feature_handler: [SetupFeature.filter()],
+ self.telegram_setup_categories_handler: [SetupAction.filter(F.action == "back")]
+ }
diff --git a/bozenka/features/basic/start.py b/bozenka/features/basic/start.py
index c7e38c6..ba20c1d 100644
--- a/bozenka/features/basic/start.py
+++ b/bozenka/features/basic/start.py
@@ -201,10 +201,9 @@ class Start(BasicFeature):
will be inside this function
"""
super().__init__()
- self.cmd_description: str = "Your description of command"
# Telegram feature settings
self.telegram_setting = None
- self.telegram_commands: list[str | None] = ["start"]
+ self.telegram_commands: dict[str: str] = {"start": "Command to start work with bozenka the bot"}
self.telegram_cmd_avaible = True # Is a feature have a commands
self.telegram_callback_factory = None
self.telegram_message_handlers = {
diff --git a/bozenka/features/features_list.py b/bozenka/features/features_list.py
new file mode 100644
index 0000000..e86bd98
--- /dev/null
+++ b/bozenka/features/features_list.py
@@ -0,0 +1,30 @@
+from aiogram import Dispatcher
+
+from bozenka.features import BasicFeature
+from bozenka.features.admin import *
+from bozenka.features.user import *
+from bozenka.features.basic import *
+
+features_list = [
+ # Admin related category
+ Moderation,
+ Invite,
+ Pins,
+ Threads,
+ # User related category
+ ImageGeneratrion,
+ TextGeneratrion,
+ Welcome,
+ # Basic Functions
+ Setup,
+ Start
+]
+
+
+def register_all_features(features_list: list[BasicFeature], dispatcher: Dispatcher) -> None:
+ """
+ Registers all features / handlers avaible in bozenka
+ :param features_list: List of features
+ :return: None
+ """
+ pass
diff --git a/bozenka/features/user/__init__.py b/bozenka/features/user/__init__.py
index e69de29..26b1d3c 100644
--- a/bozenka/features/user/__init__.py
+++ b/bozenka/features/user/__init__.py
@@ -0,0 +1,3 @@
+from image_generation import ImageGeneratrion
+from text_generation import TextGeneratrion
+from welcome import Welcome
diff --git a/bozenka/features/user/image_generation.py b/bozenka/features/user/image_generation.py
index e69de29..3f94c9b 100644
--- a/bozenka/features/user/image_generation.py
+++ b/bozenka/features/user/image_generation.py
@@ -0,0 +1,157 @@
+import logging
+from typing import Callable
+
+from aiogram import Dispatcher
+from aiogram.filters import CommandObject, Command
+from aiogram.fsm.context import FSMContext
+from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery, FSInputFile
+from sqlalchemy.ext.asyncio import async_sessionmaker
+
+from bozenka.database.tables.telegram import TelegramChatSettings
+from bozenka.features import BasicFeature
+from bozenka.generative.kadinsky import kadinsky_gen
+from bozenka.instances.telegram.utils.callbacks_factory import ImageGenerationCategory, ImageGeneration
+from bozenka.instances.telegram.utils.keyboards import image_resolution_keyboard, delete_keyboard, \
+ image_generation_keyboard, image_response_keyboard
+from bozenka.instances.telegram.utils.simpler import GeneratingImages
+
+
+class ImageGeneratrion(BasicFeature):
+ """
+ A classic class of lineral (basic)
+ feature of bozenka. IN FUTURE!
+ """
+ cmd_description: str = "Your description of command"
+
+ @staticmethod
+ async def telegram_select_image_size_handler(call: CallbackQuery, callback_data: ImageGenerationCategory,
+ state: FSMContext) -> None:
+ """
+ Query, what shows menu for image size to generate in
+ :param call: CallbackQuery object
+ :param callback_data: ImageGenerationCategory
+ :param state: FSMContext aiogram object
+ :return: None
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+
+ await state.update_data(set_category=callback_data.category)
+ await state.set_state(GeneratingImages.set_size)
+ await call.message.edit_text("Пожалуста, выберите размер изображения 🖼",
+ reply_markup=image_resolution_keyboard(user_id=call.from_user.id,
+ category=callback_data.category))
+
+ @staticmethod
+ async def telegram_end_generation_handler(call: CallbackQuery, callback_data: ImageGeneration, state: FSMContext) -> None:
+ """
+ Query, what shows menu for image size to generate in
+ :param call:
+ :param callback_data:
+ :param state:
+ :return: None
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+ await state.update_data(set_size=callback_data.size)
+ await state.set_state(GeneratingImages.ready_to_generate)
+ await call.message.edit_text(
+ f"Вы выбрали {callback_data.category} для генерации изображений в размере {callback_data.size}.\n"
+ "Напишите /cancel для отмены",
+ reply_markup=delete_keyboard(admin_id=call.from_user.id))
+
+ @staticmethod
+ async def telegram_already_generating_handler(msg: Message, state: FSMContext) -> None:
+ """
+ Giving response, if generating image for user right now,
+ but user still asks something
+ :param msg: Message telegram object
+ :param state: FSM state of bot
+ :return:
+ """
+ await msg.answer(
+ "Подождите пожалуйста, мы уже генерируем изображение для вас, подождите, когда мы ответим на ваш передыдущий вопрос",
+ reply_markup=delete_keyboard(admin_id=msg.from_user.id))
+
+ @staticmethod
+ async def telegram_imagine_handler(msg: Message, state: FSMContext) -> None:
+ """
+ /imagine command handler, start menu
+ :param msg: Message telegram object
+ :param state: FSM state of bot
+ :return:
+ """
+ if await state.get_state():
+ return
+ await msg.answer("Пожалуста, выберите сервис / модель для генерации изображений",
+ reply_markup=image_generation_keyboard(user_id=msg.from_user.id))
+
+ @staticmethod
+ async def telegram_kadinsky_generating_handler(msg: Message, state: FSMContext) -> None:
+ """
+ Message handler for kandinsky to generate image by text from message
+ :param msg: Message telegram object
+ :param state: FSM state of bot
+ :return:
+ """
+ await state.set_state(GeneratingImages.generating)
+ message = await msg.answer("Пожалуйста подождите, мы генерируем изображение ⏰\n"
+ "Если что-то пойдет не так, мы вам сообщим 👌")
+ data = await state.get_data()
+
+ try:
+
+ model_id = kadinsky_gen.get_model()
+ width, height = data["set_size"].split("x")
+ generating = kadinsky_gen.generate(model=model_id,
+ prompt=msg.text,
+ width=int(width),
+ height=int(height))
+ result = kadinsky_gen.check_generation(request_id=generating)
+
+ if result:
+ path = kadinsky_gen.save_image(result[0], f"telegram_{msg.from_user.id}")
+ photo = FSInputFile(path)
+ await msg.answer_photo(photo=photo,
+ caption=msg.text,
+ reply_markup=image_response_keyboard(user_id=msg.from_user.id))
+ await message.delete()
+ else:
+ await message.edit_text("Простите, произошла ошибка 😔\n"
+ "Убедитесь, что севрера kadinsky работают и ваш промт не является неподобающим и неприемлимым\n"
+ "Если это продолжается, пожалуйста используйте /cancel",
+ reply_markup=image_response_keyboard(user_id=msg.from_user.id))
+
+ except Exception as ex:
+ logging.log(msg=f"Get an exception for generating answer={ex}",
+ level=logging.ERROR)
+ finally:
+ logging.log(msg=f"Generated image for user_id={msg.from_user.id} with promt",
+ level=logging.INFO)
+ await state.set_state(GeneratingImages.ready_to_generate)
+
+ def __init__(self):
+ """
+ All information about feature
+ will be inside this function
+ """
+ super().__init__()
+ # Telegram feature settings
+ self.telegram_setting = TelegramChatSettings.image_generation
+ self.telegram_commands: dict[str: str] = {'imagine', 'Starts conversation with image generative ai'}
+ self.telegram_setting_in_list = True
+ self.telegram_setting_name = "Генерация изображений 📸"
+ self.telegram_setting_description = "Генерация изображений 🤖" \
+ "\nНаходится в разработке.\n" \
+ "На текущий момент есть поддержка:\n" \
+ "- Kadinksy\n" \
+ " Следите за обновлениями 😘"
+ self.telegram_cmd_avaible = True # Is a feature have a commands
+ self.telegram_message_handlers = {
+ self.telegram_kadinsky_generating_handler: [GeneratingImages.ready_to_generate, ~Command(commands=["cancel"])],
+ self.telegram_imagine_handler: [Command(commands=["imagine"])]
+ }
+ self.telegram_callback_handlers = {
+ self.telegram_select_image_size_handler: [ImageGenerationCategory.filter()],
+ self.telegram_end_generation_handler: [ImageGeneration.filter()]
+ }
diff --git a/bozenka/features/user/text_generation.py b/bozenka/features/user/text_generation.py
index e69de29..359abca 100644
--- a/bozenka/features/user/text_generation.py
+++ b/bozenka/features/user/text_generation.py
@@ -0,0 +1,559 @@
+import logging
+
+import g4f
+from aiogram import F
+from aiogram.filters import Command
+from aiogram.fsm.context import FSMContext
+from aiogram.types import Message, CallbackQuery
+from gpt4all import GPT4All
+
+from bozenka.database.tables.telegram import TelegramChatSettings
+from bozenka.features import BasicFeature
+from bozenka.generative.gpt4all import model_path, check
+from bozenka.generative.gpt4free import generate_gpt4free_providers
+from bozenka.instances.telegram.utils.callbacks_factory import Gpt4FreeProvsModelPage, Gpt4FreeProviderPage, \
+ Gpt4AllSelect, Gpt4AllModel, GptCategory, Gpt4freeResult, \
+ Gpt4FreeProvider, GptBackMenu, Gpt4FreeModel, Gpt4FreeCategory, Gpt4FreeModelPage, GptStop
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard, \
+ text_response_keyboard, gpt_categories_keyboard, \
+ gpt4free_models_by_provider_keyboard, gpt4free_providers_keyboard, gpt4all_model_menu, generate_gpt4all_page, \
+ gpt4free_categories_keyboard, gpt4free_models_keyboard
+from bozenka.instances.telegram.utils.simpler import AnsweringGPT4Free, AnsweringGpt4All
+
+
+class TextGeneratrion(BasicFeature):
+ """
+ A class, what have inside all handlers / functions
+ related to text generation of bozenka
+ """
+ cmd_description: str = "Your description of command"
+
+ @staticmethod
+ async def telegram_already_answering_handler(msg: Message, state: FSMContext) -> None:
+ """
+ Giving response, if answering user now,
+ but he still asks something
+ :param msg: Message telegram object
+ :param state: FSM state of bot
+ :return: Nothing
+ """
+ await msg.answer(
+ "Подождите пожалуйста, мы уже генерируем ответ для вас, подождите, когда мы ответим на ваш передыдущий вопрос",
+ reply_markup=delete_keyboard(admin_id=msg.from_user.id))
+
+ @staticmethod
+ async def telegram_conversation_cmd_handler(msg: Message, state: FSMContext) -> None:
+ """
+ /conversation command handler, start
+ :param msg: Message telegram object
+ :param state: FSM state of bot
+ :return:
+ """
+ if await state.get_state():
+ return
+ await msg.answer("Пожалуста, выберите сервис для ИИ.",
+ reply_markup=gpt_categories_keyboard
+ (user_id=msg.from_user.id))
+
+ @staticmethod
+ async def telegram_cancel_cmd_handler(msg: Message, state: FSMContext) -> None:
+ """
+ Canceling dialog with generative model
+ Works on command /cancel
+ :param msg: Message telegram object
+ :param state: FSM state of bot
+ :return:
+ """
+ current = await state.get_state()
+ if current is None:
+ return
+ await state.clear()
+ await msg.answer("Удача ✅\n"
+ "Диалог отменён!", reply_markup=delete_keyboard(admin_id=msg.from_user.id))
+
+ # G4F telegram category
+ # All handlers and other stuff
+ # All code and comments
+ @staticmethod
+ async def telegram_g4f_generate_handler(msg: Message, state: FSMContext) -> None:
+ """
+ Generating answer if GPT4Free model and provider has been selected
+ :param msg: Message telegram object
+ :param state: FSM state of bot
+ :return:
+ """
+ await state.set_state(AnsweringGPT4Free.answering)
+
+ info = await state.get_data()
+
+ providers = generate_gpt4free_providers()
+ reply = await msg.reply("Пожалуйста подождите, мы генерируем ответ от провайдера ⏰\n"
+ "Если что-то пойдет не так, мы вам сообщим 👌")
+
+ current_messages = []
+ if info.get("ready_to_answer"):
+ for message in info["ready_to_answer"]:
+ current_messages.append(message)
+
+ if not info.get("set_provider"):
+ info["set_provider"] = None
+
+ current_messages.append({"role": "user", "content": msg.text})
+
+ response = ""
+ try:
+ response = await g4f.ChatCompletion.create_async(
+ model=info["set_model"],
+ messages=current_messages,
+ provider=None if info["set_provider"] is None else providers[info["set_provider"]],
+ stream=False
+ )
+
+ except NameError or SyntaxError:
+ try:
+ response = g4f.ChatCompletion.create(
+ model=info["set_model"],
+ messages=current_messages,
+ provider=None if info["set_provider"] is None else providers[info["set_provider"]],
+ stream=False
+ )
+ except Exception as S:
+ response = "Простите, произошла ошибка 😔\nЕсли это продолжается, пожалуйста используйте /cancel"
+ logging.log(msg=f"Get an exception for generating answer={S}",
+ level=logging.ERROR)
+ except Exception as S:
+ response = "Простите, произошла ошибка 😔\nЕсли это продолжается, пожалуйста используйте /cancel"
+ logging.log(msg=f"Get an exception for generating answer={S}",
+ level=logging.ERROR)
+ finally:
+ await reply.edit_text(text=response, reply_markup=text_response_keyboard(user_id=msg.from_user.id))
+ current_messages.append({"role": "assistant", "content": response})
+ await state.update_data(ready_to_answer=current_messages)
+ await state.set_state(AnsweringGPT4Free.ready_to_answer)
+
+ @staticmethod
+ async def telegram_instart_conversation_handler(call: CallbackQuery, callback_data: GptBackMenu, state: FSMContext) -> None:
+ """
+ Query, what shows when clicking on button in /start menu
+ :param call: CallbackQuery class
+ :param state: FSMContext aiogram class
+ :param callback_data: GptBackMenu class
+ :return: Nothing
+ """
+ if call.from_user.id != callback_data.user_id or await state.get_state():
+ return
+ await call.message.edit_text("Пожалуста, выберите сервис для ИИ.",
+ reply_markup=gpt_categories_keyboard(user_id=call.from_user.id))
+
+ @staticmethod
+ async def telegram_g4f_providers_handlers(call: CallbackQuery, callback_data: Gpt4FreeCategory,
+ state: FSMContext) -> None:
+ """
+ Query, what creating providers selecting menu.
+ :param call: CallbackQuery class
+ :param state: FSMContext aiogram class
+ :param callback_data: Gpt4FreeCategory
+ return: Nothing
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+
+ logging.log(msg=f"Selected gpt4free category by user_id={call.from_user.id}",
+ level=logging.INFO)
+
+ await call.answer("Вы выбрали провайдеры 🤖")
+
+ await state.set_state(AnsweringGPT4Free.set_provider)
+ await call.message.edit_text("Выберите пожалуйста одного из провайдеров 👨💻",
+ reply_markup=gpt4free_providers_keyboard(user_id=call.from_user.id, page=0))
+
+ @staticmethod
+ async def telegram_g4f_models_handler(call: CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
+ """
+ Query, what creating models selecting menu
+ :param call: CallbackQuery class
+ :param state: FSMContext aiogram class
+ :param callback_data: GptCategory
+ return: Nothing
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+
+ await state.set_state(AnsweringGPT4Free.set_model)
+
+ await call.answer("Вы выбрали модели 🤖")
+
+ await call.message.edit_text("Выберите модель, с которой будете общаться 🤖",
+ reply_markup=gpt4free_models_keyboard(user_id=call.from_user.id, page=0))
+
+ @staticmethod
+ async def telegram_end_g4f_model_handler(call: CallbackQuery, callback_data: Gpt4FreeModel, state: FSMContext) -> None:
+ """
+ Query, what ending g4f model selecting
+ :param call: CallbackQuery class
+ :param callback_data: Gpt4FreeModel model
+ :param state: FSMContext aiogram class
+ :return: Nothing
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+
+ await state.update_data(set_model=callback_data.model)
+ await state.set_state(AnsweringGPT4Free.ready_to_answer)
+
+ await call.answer("Вы можете начать общаться 🤖")
+
+ await call.message.edit_text("Удача ✅\n"
+ "Вы теперь можете спокойно вести диалог 🤖\n"
+ f"Вы выбрали модель {callback_data.model}👾\n"
+ "Чтобы прекратить общение, используйте /cancel ",
+ reply_markup=delete_keyboard(admin_id=call.from_user.id))
+
+ @staticmethod
+ async def telegram_g4f_next_model_handler(call: CallbackQuery, callback_data: Gpt4FreeModelPage,
+ state: FSMContext) -> None:
+ """
+ Query, what creating models selecting menu
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery class
+ :param callback_data: Gpt4FreeModelPage class
+ :return: None
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+
+ await call.answer(f"Вы перелистнули на страницу {callback_data.page + 1}📄")
+
+ await call.message.edit_text("Выберите модель, с которой будете общаться 🤖",
+ reply_markup=gpt4free_models_keyboard(user_id=call.from_user.id,
+ page=callback_data.page))
+
+ @staticmethod
+ async def telegram_g4f_category_handler(call: CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
+ """
+ Query, what creating providers selecting menu.
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery class
+ :param callback_data: GptCategory class
+ :return: None
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+
+ logging.log(msg=f"Selected gpt4free category by user_id={call.from_user.id}",
+ level=logging.INFO)
+
+ await state.update_data(set_category=callback_data.category)
+ await call.answer("Вы выбрали Gpt4Free 🤖")
+ await call.message.edit_text("Выберите, по какому пункту мы будем вести диалог с нейронной сети 🤖",
+ reply_markup=gpt4free_categories_keyboard(user_id=call.from_user.id))
+ await call.answer("Выберите, по какому пункту мы будем вести диалог с нейронной сети 🤖")
+
+ @staticmethod
+ async def telegram_g4f_back_provider_handler(call: CallbackQuery, callback_data: GptBackMenu,
+ state: FSMContext) -> None:
+ """
+ Query, what creating providers selecting menu.
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery telegram class
+ :param callback_data: GptBackMenu class
+ :return: None
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+
+ logging.log(msg=f"Back to providers menu by user_id={call.from_user.id}",
+ level=logging.INFO)
+ await state.set_state(AnsweringGPT4Free.set_provider)
+
+ await call.message.edit_text("Выберите пожалуйста одного из провайдеров 👨💻",
+ reply_markup=gpt4free_providers_keyboard(page=0, user_id=callback_data.user_id))
+ await call.answer("Выберите пожалуйста одного из провайдеров 👨💻")
+
+ @staticmethod
+ async def inline_g4f_provider_models(call: CallbackQuery, callback_data: Gpt4FreeProvider,
+ state: FSMContext) -> None:
+ """
+ Query, what creating models selecting menu.
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery telegram class
+ :param callback_data: Gpt4FreeProvider Class
+ :return: None
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+
+ logging.log(msg=f"Selected gpt4free provider {callback_data.provider} by user_id={call.from_user.id}",
+ level=logging.INFO)
+
+ await state.update_data(set_provider=callback_data.provider)
+ await state.set_state(AnsweringGPT4Free.set_model)
+
+ await call.message.edit_text("Выберите пожалуйста модель ИИ 👾",
+ reply_markup=gpt4free_models_by_provider_keyboard(
+ user_id=callback_data.user_id,
+ provider=callback_data.provider,
+ page=0
+ ))
+ await call.answer("Выберите пожалуйста модель ИИ 👾")
+
+ @staticmethod
+ async def telegram_g4f_ready_handler(call: CallbackQuery, callback_data: Gpt4freeResult, state: FSMContext) -> None:
+ """
+ Query, what says about getting ready to questions for ChatGPT from Gpt4Free.
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery telegram class
+ :param callback_data: Gpt4freeResult
+ :return: None
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+
+ logging.log(msg=f"Selected gpt4free model {callback_data.model} by user_id={call.from_user.id}",
+ level=logging.INFO)
+
+ await state.update_data(set_model=callback_data.model)
+ await state.set_state(AnsweringGPT4Free.ready_to_answer)
+
+ logging.log(msg=f"Loaded GPT answering status for user_id={call.from_user.id}",
+ level=logging.INFO)
+
+ await call.message.edit_text("Удача ✅\n"
+ "Вы теперь можете спокойно вести диалог 🤖\n"
+ f"Вы выбрали модель {callback_data.model}👾, от провайдера {callback_data.provider}👨💻\n"
+ "Чтобы прекратить общение, используйте /cancel ",
+ reply_markup=delete_keyboard(admin_id=callback_data.user_id))
+ await call.answer("Вы теперь можете спокойно вести диалог 🤖")
+
+ @staticmethod
+ async def telegram_g4f_models_by_provider_handler(call: CallbackQuery, callback_data: Gpt4FreeProvsModelPage,
+ state: FSMContext) -> None:
+ """
+ Query, what generates a next page of models for user.
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery telegram class
+ :param callback_data: Gpt4FreeProvsModelPage
+ :return: None
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+ logging.log(msg=f"Changed page to {str(callback_data.page + 1)} user_id={call.from_user.id}",
+ level=logging.INFO)
+ await call.message.edit_text(call.message.text,
+ reply_markup=gpt4free_models_by_provider_keyboard(
+ user_id=callback_data.user_id,
+ provider=callback_data.provider,
+ page=callback_data.page
+ ))
+ await call.answer(f"Вы перелистали на страницу {callback_data.page + 1}📄")
+
+ @staticmethod
+ async def telegram_next_g4f_providers_handler(call: CallbackQuery, callback_data: Gpt4FreeProviderPage,
+ state: FSMContext) -> None:
+ """
+ Query, what generates a next page of providers for user
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery telegram class
+ :param callback_data: Gpt4FreeProviderPage class
+ :return: None
+ """
+ if call.from_user.id != callback_data.user_id:
+ return
+ logging.log(msg=f"Changed page to {str(callback_data.page + 1)} user_id={call.from_user.id}",
+ level=logging.INFO)
+ await call.message.edit_text(call.message.text,
+ reply_markup=gpt4free_providers_keyboard(user_id=callback_data.user_id,
+ page=callback_data.page))
+ await call.answer(f"Вы перелистнули на страницу {callback_data.page + 1}📄")
+
+ # G4A telegram handlers section
+ # All code and commentaries here
+ # All handlers here
+
+ @staticmethod
+ async def telegram_g4a_generate_handler(msg: Message, state: FSMContext) -> None:
+ """
+ Generating answer if Gpt4All has been selected
+ :param msg: Message telegram object
+ :param state: FSM state of bot
+ :return:
+ """
+ await state.set_state(AnsweringGpt4All.answering)
+
+ models = GPT4All.list_models()
+ info = await state.get_data()
+ answer = ""
+
+ main_msg = await msg.answer("Пожалуйста подождите, мы генерируем вам ответ ⏰\n"
+ "Если что-то пойдет не так, мы вам сообщим 👌",
+ reply_markup=text_response_keyboard(user_id=msg.from_user.id))
+
+ if not check(models[info["set_model"]]["filename"]):
+ main_msg = await main_msg.edit_text(main_msg.text + "\nПодождите пожалуста, мы скачиваем модель...",
+ reply_markup=main_msg.reply_markup)
+
+ try:
+ # Setting Gpt4All model
+ model = GPT4All(model_name=models[info['set_model']]['filename'],
+ model_path=model_path,
+ allow_download=True)
+ # Setting our chat session if exist
+ model.current_chat_session = [] if not info.get("ready_to_answer") else info["ready_to_answer"]
+ # Generating answer
+ with model.chat_session():
+ answer = model.generate(msg.text)
+ await state.update_data(ready_to_answer=model.current_chat_session)
+
+ except Exception as S:
+ answer = "Простите, произошла ошибка 😔\nЕсли это продолжается, пожалуйста используйте /cancel"
+ logging.log(msg=f"Get an exception for generating answer={S}",
+ level=logging.ERROR)
+ finally:
+ await main_msg.edit_text(answer, reply_markup=text_response_keyboard(user_id=msg.from_user.id))
+
+ await state.set_state(AnsweringGpt4All.ready_to_answer)
+
+ @staticmethod
+ async def telegram_g4a_handler(call: CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
+ """
+ Query, what shows list for gpt4all models
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery telegram class
+ :param callback_data: GptCategory class
+ :return: None
+ """
+ if callback_data.user_id != call.from_user.id:
+ return
+ await state.set_state(AnsweringGpt4All.set_model)
+ await call.message.edit_text("Выберите пожалуйста модель ИИ 👾",
+ reply_markup=generate_gpt4all_page(user_id=call.from_user.id))
+
+ @staticmethod
+ async def telegram_g4a_back_handler(call: CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
+ """
+ Query, what shows list for gpt4all models back
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery telegram class
+ :param callback_data: GptCategory class
+ :return: None
+ """
+ if callback_data.user_id != call.from_user.id:
+ return
+ await state.set_state(AnsweringGpt4All.set_model)
+ await call.message.edit_text("Выберите пожалуйста модель ИИ 👾",
+ reply_markup=generate_gpt4all_page(user_id=call.from_user.id))
+
+ @staticmethod
+ async def telegram_g4a_infomration_handler(call: CallbackQuery, callback_data: Gpt4AllModel, state: FSMContext) -> None:
+ """
+ Query, what show information about clicked gpt4all model from list
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery telegram class
+ :param callback_data: Gpt4AllModel class
+ :return: None
+ """
+ if callback_data.user_id != call.from_user.id:
+ return
+ models = GPT4All.list_models()
+ name = models[callback_data.index]['name']
+ await call.message.edit_text(f"{name}\n"
+ f"Обученно на основе {models[callback_data.index]['parameters']} строк 👨💻",
+ reply_markup=gpt4all_model_menu(user_id=call.from_user.id,
+ index=callback_data.index))
+
+ @staticmethod
+ async def telegram_g4a_end_handler(call: CallbackQuery, callback_data: Gpt4AllSelect,
+ state: FSMContext) -> None:
+ """
+ Query, what says about getting ready for question for Gpt4All model
+ :param state: FSMContext aiogram class
+ :param call: CallbackQuery telegram class
+ :param callback_data: Gpt4AllSelect class
+ :return: None
+ """
+ if callback_data.user_id != call.from_user.id:
+ return
+ await state.update_data(set_model=callback_data.index)
+ await state.set_state(AnsweringGpt4All.ready_to_answer)
+ models = GPT4All.list_models()
+
+ await call.message.edit_text("Удача ✅\n"
+ "Вы теперь можете спокойно вести диалог 🤖\n"
+ f"Вы выбрали модель {models[callback_data.index]['name']}👾 от Gpt4All\n"
+ "Чтобы прекратить общение, используйте /cancel ",
+ reply_markup=delete_keyboard(admin_id=callback_data.user_id))
+
+ @staticmethod
+ async def telegram_pages_handler(call: CallbackQuery) -> None:
+ """
+ Query, made for helping purposes.
+ Shows current page.
+ :param call: CallbackQuery telegram class
+ :return: None
+ """
+ logging.log(msg=f"Showed helping info for user_id={call.from_user.id}",
+ level=logging.INFO)
+ await call.answer("Здесь расположается текущая странница 📃")
+
+ @staticmethod
+ async def telegram_stop_dialog_handler(call: CallbackQuery, callback_data: GptStop, state: FSMContext) -> None:
+ """
+ Query, what stops dialog
+ :param call: CallbackQuery telegram class
+ :param callback_data: GptStop class
+ :param state: None
+ """
+ # Checking user_id of user
+ if callback_data.user_id != call.from_user.id:
+ return
+ # Clearing state
+ await state.clear()
+ # Answering something
+ await call.answer("Хорошо ✅")
+ if await state.get_state() == AnsweringGPT4Free.ready_to_answer or await state.get_state() == AnsweringGpt4All.answering:
+ await call.message.edit_text(text=call.message.text + "\n\nДиалог остановлен ✅\n",
+ reply_markup=delete_keyboard(admin_id=call.from_user.id))
+ else:
+ await call.message.delete()
+
+ def __init__(self):
+ """
+ All information about feature
+ will be inside this function
+ """
+ super().__init__()
+ # Telegram feature settings
+ self.telegram_setting = TelegramChatSettings.text_generation
+ self.telegram_setting_in_list = True
+ self.telegram_setting_name = "ИИ ЧатБот 🤖"
+ self.telegram_setting_description = "ИИ ЧатБот 🤖" \
+ "\nЕсть поддержка:\n" \
+ "- Моделей Gpt4All\n" \
+ "- Провайдеров Gpt4Free и моделей\n" \
+ "Для использования:\n" \
+ "/conversations
" \
+ "\nНаходится в разработке, планируется в будущем. Следите за обновлениями 😘"
+ self.telegram_commands: dict[str: str] = {
+ 'conversation': 'Starts conversation with text generative ai'
+ }
+ self.telegram_cmd_avaible = True # Is a feature have a commands
+ self.telegram_message_handlers = {
+ self.telegram_conversation_cmd_handler: [Command(commands=["conversation"])],
+ self.telegram_g4a_generate_handler: [AnsweringGpt4All.ready_to_answer, ~Command(commands=["cancel"])],
+ self.telegram_g4f_generate_handler: [AnsweringGPT4Free.ready_to_answer, ~Command(commands=["cancel"])],
+ self.telegram_already_answering_handler: [AnsweringGPT4Free.answering, AnsweringGpt4All.answering]
+ }
+ self.telegram_callback_handlers = {
+ # g4a
+ self.telegram_g4a_handler: [GptCategory.filter(F.category == "Gpt4All")],
+ self.telegram_g4a_infomration_handler: [Gpt4AllModel.filter()],
+ self.telegram_g4a_end_handler: [Gpt4AllSelect.filter()],
+ # g4f
+ self.telegram_g4f_category_handler: [GptCategory.filter(F.category == "Gpt4Free")],
+ self.telegram_g4f_models_handler: [Gpt4FreeCategory.filter(F.category == "models")],
+ self.telegram_g4f_providers_handlers: [Gpt4FreeCategory.filter(F.category == "providers")],
+ self.telegram_g4f_models_by_provider_handler: [Gpt4FreeProvider.filter()],
+ self.telegram_next_g4f_providers_handler: [Gpt4FreeProviderPage.filter()],
+ # stop talking
+ self.telegram_stop_dialog_handler: [GptStop.filter()]
+ }
diff --git a/bozenka/features/user/welcome.py b/bozenka/features/user/welcome.py
index e69de29..3584425 100644
--- a/bozenka/features/user/welcome.py
+++ b/bozenka/features/user/welcome.py
@@ -0,0 +1,82 @@
+import logging
+
+from aiogram import Bot
+from aiogram.types import Message, CallbackQuery
+from sqlalchemy.ext.asyncio import async_sessionmaker
+
+from bozenka.database.tables.telegram import TelegramChatSettings
+from bozenka.features import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import PinMsg, UnpinMsg
+from bozenka.instances.telegram.utils.keyboards import unpin_msg_keyboard, delete_keyboard, pin_msg_keyboard
+from bozenka.instances.telegram.utils.simpler import SolutionSimpler
+
+
+class Welcome(BasicFeature):
+ """
+ A class of pins related commands
+ All staff related to it will be here
+ """
+
+ @staticmethod
+ async def telegram_join_handler(msg: Message, session_maker: async_sessionmaker) -> None:
+ """
+ Message handler.
+ Send welcome message, after adding new member to chat.
+ Also works on adding bot to chat and sending welcome message.
+ :param msg: Message telegram object
+ :param session_maker: AsyncSessionmaker object
+ :return: None
+ """
+ for new in msg.new_chat_members:
+ if new.id != msg.bot.id:
+ logging.log(msg=f"Saing welcome for user_id={new.id}, chat_id={msg.chat.id}",
+ level=logging.INFO)
+ await msg.answer(
+ f"Пользователь {new.mention_html()} переехал в конфу, благодаря {msg.from_user.mention_html()}👋",
+ )
+ await msg.delete()
+ else:
+ logging.log(msg=f"Saing welcome to administrators for chat_id={msg.chat.id}",
+ level=logging.INFO)
+ await msg.answer("Здраствуйте администраторы чата 👋\n"
+ "Я - бозенька, мультифункциональный бот, разрабатываемый Bozo Developement\n"
+ "Выдайте мне полные права администратора для моей полной работы.\n"
+ "Чтобы настроить функционал, используйте /setup или кнопку под сообщением", )
+ await SolutionSimpler.auto_settings(msg=msg, session=session_maker)
+
+ @staticmethod
+ async def telegram_leave_handler(msg: Message, bot: Bot) -> None:
+ """
+ Sens goodbye message, after deleting member from chat
+ :param msg: Message telegram object
+ :param bot: Aiogram bot object
+ :return: Nothing
+ """
+ await msg.delete()
+ if msg.from_user.id == bot.id:
+ return
+ logging.log(msg=f"Saing goodbye for user_id={msg.left_chat_member.id}, chat_id={msg.chat.id}",
+ level=logging.INFO)
+ await msg.answer(
+ f"Пользователь {msg.left_chat_member.mention_html()} съехал с конфы, благодаря {msg.from_user.mention_html()}👋"
+ )
+
+ def __init__(self):
+ """
+ All information about feature
+ will be inside this function
+ """
+ super().__init__()
+ self.cmd_description: str = "Your description of command"
+ # Telegram feature settings
+ self.telegram_setting = TelegramChatSettings.welcome_messages
+ self.telegram_commands: dict[str: str] = {}
+ self.telegram_setting_in_list = True
+ self.telegram_setting_name = "Приветсвенные сообщения 👋"
+ self.telegram_setting_description = "Приветсвенные сообщения 👋" \
+ "\nПриветсвенные сообщения новым и ушедшим пользователям.",
+ self.telegram_cmd_avaible = False # Is a feature have a commands
+ self.telegram_message_handlers = {
+
+ }
+ self.telegram_callback_handlers = {}
diff --git a/bozenka/instances/telegram/handlers/chat_admin/__init__.py b/bozenka/instances/telegram/handlers/chat_admin/__init__.py
index 10651b4..06a94a9 100644
--- a/bozenka/instances/telegram/handlers/chat_admin/__init__.py
+++ b/bozenka/instances/telegram/handlers/chat_admin/__init__.py
@@ -23,8 +23,6 @@ def register_admin_cmd(router: Router) -> None:
logging.log(msg="Registering administrator commands", level=logging.INFO)
# Ban / Unban commands handler
- router.message.register(ban_command, Command(commands="ban"),
- IsAdminFilter(True))
router.message.register(ban_command, Command(commands="ban"),
IsAdminFilter(True), F.reply_to_message.text)
router.message.register(unban_command, Command(commands="unban"),
diff --git a/bozenka/instances/telegram/handlers/dev/image_generation.py b/bozenka/instances/telegram/handlers/dev/image_generation.py
index 5abc24c..9359bfe 100644
--- a/bozenka/instances/telegram/handlers/dev/image_generation.py
+++ b/bozenka/instances/telegram/handlers/dev/image_generation.py
@@ -1,18 +1,12 @@
import logging
-import os
-import g4f
-import base64
-from gpt4all import GPT4All
from aiogram.fsm.context import FSMContext
from aiogram.types import Message as Message, FSInputFile
from bozenka.generative.kadinsky import kadinsky_gen
-from bozenka.instances.telegram.utils.keyboards import gpt_categories_keyboard, delete_keyboard, text_response_keyboard, \
- image_generation_keyboard, image_response_keyboard
-from bozenka.instances.telegram.utils.simpler import AnsweringGpt4All, \
- AnsweringGPT4Free, GeneratingImages
-from bozenka.generative.gpt4free import generate_gpt4free_providers
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard, image_generation_keyboard, \
+ image_response_keyboard
+from bozenka.instances.telegram.utils.simpler import GeneratingImages
async def already_generating(msg: Message, state: FSMContext):
diff --git a/bozenka/instances/telegram/handlers/queries/setup.py b/bozenka/instances/telegram/handlers/queries/setup.py
index e56239a..715ad81 100644
--- a/bozenka/instances/telegram/handlers/queries/setup.py
+++ b/bozenka/instances/telegram/handlers/queries/setup.py
@@ -27,7 +27,7 @@ async def inline_setup_category_back(call: CallbackQuery, callback_data: SetupAc
:return:
"""
await call.message.edit_text("Выберите настройку, которую хотите изменить",
- reply_markup=setup_category_keyboard(category=callback_data.feature_category))
+ reply_markup=setup_category_keyboard(category=callback_data.category_name))
async def inline_edit_feature(call: CallbackQuery, callback_data: SetupFeature, session_maker: async_sessionmaker):
@@ -63,11 +63,11 @@ async def inline_feature_edited(call: CallbackQuery, callback_data: SetupAction,
async with session_maker() as session:
async with session.begin():
await session.execute(Update(TelegramChatSettings)
- .values({list_of_features[callback_data.feature_category][callback_data.feature_index].settings_name:
+ .values({list_of_features[callback_data.category_name][callback_data.feature_index].settings_name:
callback_data.action == "enable"})
.where(TelegramChatSettings.chat_id == call.message.chat.id))
await call.message.edit_text(
- list_of_features[callback_data.feature_category][callback_data.feature_index].description,
- reply_markup=await setup_feature_keyboard(category=callback_data.feature_category,
+ list_of_features[callback_data.category_name][callback_data.feature_index].description,
+ reply_markup=await setup_feature_keyboard(category=callback_data.category_name,
index=callback_data.feature_index,
is_enabled=callback_data.action == "enable"))
diff --git a/bozenka/instances/telegram/utils/callbacks_factory/setup.py b/bozenka/instances/telegram/utils/callbacks_factory/setup.py
index 5a41c6c..1426531 100644
--- a/bozenka/instances/telegram/utils/callbacks_factory/setup.py
+++ b/bozenka/instances/telegram/utils/callbacks_factory/setup.py
@@ -28,7 +28,7 @@ class SetupAction(CallbackData, prefix="sa"):
Callback with information to do with a feature
"""
action: str
- feature_category: str
+ category_name: str
feature_index: int
diff --git a/bozenka/instances/telegram/utils/simpler/lists_of_content.py b/bozenka/instances/telegram/utils/simpler/lists_of_content.py
index 34327aa..69e4598 100644
--- a/bozenka/instances/telegram/utils/simpler/lists_of_content.py
+++ b/bozenka/instances/telegram/utils/simpler/lists_of_content.py
@@ -92,7 +92,7 @@ list_of_features = {
BaseFeature(
name="Приглашения в Чат ✉",
description="Генератор приглашения в Чат ✉\n"
- "Разрешает использование комманды /invite в чате, для созданния приглашений.\n"
+ "Разрешает использование комманды /invite
в чате, для созданния приглашений.\n"
"Для исполнения требует соответсвующих прав от пользователя и их наличие у бота.",
callback_name="invites",
settings_name="invite_generator",
@@ -288,7 +288,7 @@ list_of_commands = {
("open_general", 'Opens general topic in chat'),
# AI related
('conversation', 'Starts conversation with text generative ai'),
- ('imagine', 'Starts conversation with image generative ai'), \
+ ('imagine', 'Starts conversation with image generative ai'),
# Basic features
('invite', 'Generates invite into current chat'),
('about', 'Sends information about bozenka'),
--
2.30.2
From 9b2fd5d7505b4e241c1a11bc4239ce07437f6595 Mon Sep 17 00:00:00 2001
From: kittyneverdies <85691197+KittyNeverDies@users.noreply.github.com>
Date: Sat, 10 Feb 2024 22:14:31 +0300
Subject: [PATCH 04/13] Before removing old code Full refactoring Errors fixed
New features introducing
---
bozenka/features/__init__.py | 33 ++--
bozenka/features/admin/__init__.py | 8 +-
bozenka/features/admin/invite.py | 54 +++--
bozenka/features/admin/moderation.py | 184 +++++++++++-------
bozenka/features/admin/pins.py | 102 ++++++----
bozenka/features/admin/topics.py | 113 ++++++-----
bozenka/features/basic/__init__.py | 4 +-
bozenka/features/basic/setup.py | 38 ++--
bozenka/features/basic/start.py | 145 ++++++++------
bozenka/features/features_list.py | 11 +-
bozenka/features/user/__init__.py | 6 +-
bozenka/features/user/image_generation.py | 55 +++---
bozenka/features/user/text_generation.py | 131 ++++++-------
bozenka/features/user/welcome.py | 37 ++--
bozenka/instances/telegram/__init__.py | 38 +++-
.../telegram/utils/filters/permissions.py | 81 ++++++--
.../telegram/utils/keyboards/inline.py | 8 +-
17 files changed, 580 insertions(+), 468 deletions(-)
diff --git a/bozenka/features/__init__.py b/bozenka/features/__init__.py
index 8343157..fad29b1 100644
--- a/bozenka/features/__init__.py
+++ b/bozenka/features/__init__.py
@@ -5,29 +5,22 @@ class BasicFeature:
A classic class of lineral (basic)
feature of bozenka. IN FUTURE!
"""
- def __init__(self):
- """
- All information about feature
- will be inside this function
- """
-
- # Telegram setting info
- self.telegram_setting_in_list = False # Does feature shows in /setup list
- self.telegram_setting_name = None # Setting title in /setup command
- self.telegram_setting_description = None # Setting description in /setup command
- self.telegram_db_name = None # Name of TelegramChatSettings column will be affected
- # Telegram commands list of feature
- self.telegram_commands: dict[str: str] = {
+ telegram_setting_in_list = False # Does feature shows in /setup list
+ telegram_setting_name = None # Setting title in /setup command
+ telegram_setting_description = None # Setting description in /setup command
+ telegram_db_name = None # Name of TelegramChatSettings column will be affected
+ # Telegram commands list of feature
+ telegram_commands: dict[str: str] = {
#
# Format is "CommandNameHere": "Command description is here"
#
"example": "Its an example"
- }
- self.telegram_cmd_avaible = True # Does this feature have a telegram commands
- # All handlers
- self.telegram_message_handlers = (
+ }
+ telegram_cmd_avaible = True # Does this feature have a telegram commands
+ # All handlers
+ telegram_message_handlers = [
# Format is [Handler, [Filters]]
- )
- self.telegram_callback_handlers = (
+ ]
+ telegram_callback_handlers = [
# Format is [Handler, [Filters]]
- )
\ No newline at end of file
+ ]
diff --git a/bozenka/features/admin/__init__.py b/bozenka/features/admin/__init__.py
index f14b364..8e7fa94 100644
--- a/bozenka/features/admin/__init__.py
+++ b/bozenka/features/admin/__init__.py
@@ -1,4 +1,4 @@
-from invite import Invite
-from moderation import Moderation
-from pins import Pins
-from topics import Threads
+from .invite import Invite
+from .moderation import Moderation
+from .pins import Pins
+from .topics import Threads
diff --git a/bozenka/features/admin/invite.py b/bozenka/features/admin/invite.py
index b39c107..c8bc720 100644
--- a/bozenka/features/admin/invite.py
+++ b/bozenka/features/admin/invite.py
@@ -17,7 +17,6 @@ class Invite(BasicFeature):
All codes will be here
"""
- @staticmethod
async def telegram_invite_command_handler(msg: Message) -> None:
"""
Generating invite to group by /invite command
@@ -34,7 +33,6 @@ class Invite(BasicFeature):
chat_name=msg.chat.full_name)
)
- @staticmethod
async def telegram_revoke_callback_handler(call: CallbackQuery, callback_data: RevokeCallbackData) -> None:
"""
Handler of CallbackQuery, revokes link after pressing button
@@ -48,36 +46,30 @@ class Invite(BasicFeature):
user_clicked.status != ChatMemberStatus.ADMINISTRATOR and user_clicked.status == ChatMemberStatus.CREATOR:
return
logging.log(msg=f"Revoking link for user_id={call.from_user.id}",
- level=logging.INFO)
+ level=logging.INFO)
await call.message.chat.revoke_invite_link(invite_link="https://" + str(callback_data.link))
await call.answer("Удача ✅")
await call.message.delete()
- def __init__(self):
- """
- All information about feature
- will be inside this function
- """
- super().__init__()
- """
- Telegram feature settings
- """
- # Telegram setting info
- self.telegram_setting_in_list = True
- self.telegram_setting_name = "Приглашения в Чат ✉"
- self.telegram_setting_description = "Генератор приглашения в Чат ✉\n" \
- "Разрешает использование комманды /invite
в чате, для созданния приглашений.\n" \
- "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
- self.telegram_db_name = TelegramChatSettings.invite_generator
- # Telegram commands
- self.telegram_commands: dict[str: str] = {"/invite": 'Generates invite into current chat'}
- self.telegram_cmd_avaible = True # Is a feature have a commands
- # List of aiogram handlers
- self.telegram_message_handlers = (
- # Format is [Handler, [Filters]]
- [self.telegram_invite_command_handler, [Command(commands=["invite"])]]
- )
- self.telegram_callback_handlers = (
- # Format is [Handler, [Filters]]
- [self.telegram_revoke_callback_handler, [RevokeCallbackData.filter()]]
- )
+ """
+ Telegram feature settings
+ """
+ # Telegram setting info
+ telegram_setting_in_list = True
+ telegram_setting_name = "Приглашения в Чат ✉"
+ telegram_setting_description = "Генератор приглашения в Чат ✉\n" \
+ "Разрешает использование комманды /invite
в чате, для созданния приглашений.\n" \
+ "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
+ telegram_db_name = TelegramChatSettings.invite_generator
+ # Telegram commands
+ telegram_commands: dict[str: str] = {"/invite": 'Generates invite into current chat'}
+ telegram_cmd_avaible = True # Is a feature have a commands
+ # List of aiogram handlers
+ telegram_message_handlers = [
+ # Format is [Handler, [Filters]]
+ [telegram_invite_command_handler, [Command(commands=["invite"])]]
+ ]
+ telegram_callback_handlers = [
+ # Format is [Handler, [Filters]]
+ [telegram_revoke_callback_handler, [RevokeCallbackData.filter()]]
+ ]
diff --git a/bozenka/features/admin/moderation.py b/bozenka/features/admin/moderation.py
index 637b969..fa76e48 100644
--- a/bozenka/features/admin/moderation.py
+++ b/bozenka/features/admin/moderation.py
@@ -1,7 +1,7 @@
import logging
from aiogram import F
-from aiogram.enums import ChatMemberStatus
+from aiogram.enums import ChatMemberStatus, ChatType
from aiogram.filters import CommandObject, Command
from aiogram.types import Message, CallbackQuery
from sqlalchemy.ext.asyncio import async_sessionmaker
@@ -21,7 +21,6 @@ class Moderation(BasicFeature):
All staff related to it will be here
"""
- @staticmethod
async def telegram_ban_callback_handler(call: CallbackQuery, callback_data: BanData,
session_maker: async_sessionmaker) -> None:
"""
@@ -35,7 +34,7 @@ class Moderation(BasicFeature):
banned_user = await call.message.chat.get_member(int(callback_data.user_id_ban))
send_notification = await get_chat_config_value(chat_id=call.message.chat.id, session=session_maker,
- setting=list_of_features["Admin"][5])
+ setting=list_of_features["Admins"][5])
if call.from_user.id != callback_data.user_id_clicked \
and clicked_user.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.CREATOR]:
@@ -62,7 +61,6 @@ class Moderation(BasicFeature):
logging.log(msg=f"Banned user @{banned_user.user.full_name} user_id=f{banned_user.user.id}", level=logging.INFO)
- @staticmethod
async def telegram_unban_callback_handler(call: CallbackQuery, callback_data: UnbanData,
session_maker: async_sessionmaker) -> None:
"""
@@ -92,7 +90,7 @@ class Moderation(BasicFeature):
)
if await get_chat_config_value(chat_id=call.message.chat.id, session=session_maker,
- setting=list_of_features["Admin"][5]):
+ setting=list_of_features["Admins"][5]):
await call.message.bot.send_message(
chat_id=unbanned_user.user.id,
text=f"{unbanned_user.user.mention_html('Вы')} были разблокирован {call.from_user.mention_html('этим пользователем')} в чате {call.message.chat.id}
.",
@@ -102,7 +100,6 @@ class Moderation(BasicFeature):
logging.log(msg=f"Unbanned user @{unbanned_user.user.full_name} user_id=f{unbanned_user.user.id}",
level=logging.INFO)
- @staticmethod
async def telegram_ban_cmd_handler(msg: Message, command: CommandObject, session_maker: async_sessionmaker) -> None:
"""
/ban command function, supports time and reasons.
@@ -113,9 +110,9 @@ class Moderation(BasicFeature):
"""
banned_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admin"][4])
+ setting=list_of_features["Admins"][4])
send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admin"][5])
+ setting=list_of_features["Admins"][5])
where_send = {
True: msg.from_user.id,
@@ -183,7 +180,6 @@ class Moderation(BasicFeature):
f"{msg.chat.title}
.\n",
reply_markup=delete_keyboard(admin_id=banned_user.user.id))
- @staticmethod
async def telegram_unban_cmd_handler(msg: Message, command: CommandObject,
session_maker: async_sessionmaker) -> None:
"""
@@ -196,9 +192,9 @@ class Moderation(BasicFeature):
unbanned_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admin"][4])
+ setting=list_of_features["Admins"][4])
send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admin"][5])
+ setting=list_of_features["Admins"][5])
where_send = {
True: msg.from_user.id,
@@ -245,7 +241,6 @@ class Moderation(BasicFeature):
reply_markup=delete_keyboard(admin_id=unbanned_user.user.id)
)
- @staticmethod
async def telegram_mute_callback_handler(call: CallbackQuery, callback_data: MuteData,
session_maker: async_sessionmaker) -> None:
"""
@@ -285,7 +280,6 @@ class Moderation(BasicFeature):
logging.log(msg=f"Muted user @{muted_user.user.full_name} user_id=f{muted_user.user.id}", level=logging.INFO)
- @staticmethod
async def telegram_unmute_callback_handler(call: CallbackQuery, callback_data: UnmuteData,
session_maker: async_sessionmaker) -> None:
"""
@@ -325,7 +319,6 @@ class Moderation(BasicFeature):
logging.log(msg=f"Unbanned user @{unmuted_user.user.full_name} user_id=f{unmuted_user.user.id}",
level=logging.INFO)
- @staticmethod
async def telegram_mute_cmd_handler(msg: Message, command: CommandObject,
session_maker: async_sessionmaker) -> None:
"""
@@ -336,12 +329,14 @@ class Moderation(BasicFeature):
:param session_maker: Session maker object of SqlAlchemy
:return: Nothing
"""
+ print(msg.reply_to_message)
+ print("341414124")
mute_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admin"][4])
+ setting=list_of_features["Admins"][4])
send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admin"][5])
+ setting=list_of_features["Admins"][5])
where_send = {
True: msg.from_user.id,
@@ -411,7 +406,6 @@ class Moderation(BasicFeature):
f"сообщения {msg.reply_to_message.from_user.mention_html('вам')} в чате {msg.chat.title}.\n",
reply_markup=delete_keyboard(admin_id=mute_user.user.id))
- @staticmethod
async def telegram_unmute_cmd_handler(msg: Message, session_maker: async_sessionmaker) -> None:
"""
Handler of command /unmute
@@ -423,9 +417,9 @@ class Moderation(BasicFeature):
await SolutionSimpler.unmute_user(msg, session_maker)
send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admin"][4])
+ setting=list_of_features["Admins"][4])
send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admin"][5])
+ setting=list_of_features["Admins"][5])
where_send = {
True: msg.from_user.id,
@@ -445,55 +439,107 @@ class Moderation(BasicFeature):
f"сообщения {msg.reply_to_message.from_user.mention_html('вам')}",
reply_markup=delete_keyboard(admin_id=msg.reply_to_message.from_user.id))
- def __init__(self):
+ # Help moderation telegram
+ # Code part
+ async def telegram_help_ban_handler(msg: Message) -> None:
"""
- All information about feature
- will be inside this function
+ Shows help message for /ban
+ :param msg: Message telegram object
+ :return: Nothing
"""
- super().__init__()
- # Telegram setting info
- self.telegram_setting_in_list = True
- self.telegram_setting_name = "Модерация чата 🕵️"
- self.telegram_setting_description = "Модерация чата🕵️\nДанная настройка включает следущие комманды:" \
- "\n/ban [время блокировки] [причина блокировки] - блокировка пользователя" \
- "\n/unban - разблокировка пользователя\n" \
- "/mute [время мута] [причина мута] - мут пользователя\n" \
- "/unmute - Размут пользователя
\n" \
- "Время обозначается как:" \
- "1h - один час, " \
- "1d - один день, " \
- "1m - одна минута, " \
- "1s - одна секунда
\n" \
- "Для того, " \
- "чтобы выполнить одну из комманд по отношению к пользователю, " \
- "ответьте на сообщение пользователя и используйте команду\n" \
- "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
- self.telegram_db_name = TelegramChatSettings.moderation
- # Telegram commands
- self.telegram_commands: dict[str: str] = {
- "ban": "Command to ban user in chat",
- 'unban': 'Command to unban user in chat',
- 'mute': 'Command to mute user in chat',
- 'unmute': 'Command to unmute user in chat',
- }
- self.telegram_cmd_avaible = True # Is a feature have a commands
- # All handlers
- self.telegram_message_handlers = (
- # Format is [Handler, [Filters]]
- [self.telegram_ban_cmd_handler, [Command(commands="ban"),
- IsAdminFilter(True), F.reply_to_message.text]],
- [self.telegram_unban_cmd_handler, [Command(commands="unban"),
- IsAdminFilter(True), F.reply_to_message.text]],
- [self.telegram_mute_cmd_handler, [Command(commands=["mute", "re"]),
- UserHasPermissions(["can_restrict_members"]),
- BotHasPermissions(["can_restrict_members"])]],
- [self.telegram_unmute_cmd_handler, [Command(commands=["unmute"]),
- UserHasPermissions(["can_restrict_members"]),
- BotHasPermissions(["can_restrict_members"])]]
- )
- self.telegram_callback_handlers = (
- # Format is [Handler, [Filters]]
- [self.telegram_ban_callback_handler, [BanData.filter()]],
- [self.telegram_unban_callback_handler, [UnbanData.filter()]],
- [self.telegram_mute_callback_handler, [MuteData.filter()]],
- [self.telegram_unmute_callback_handler, [UnmuteData.filter()]])
+ await msg.answer("Использование:\n"
+ "/ban [время блокировки] [причина блокировки]
\n"
+ "Ответьте на сообщение, чтобы заблокировать пользователя",
+ reply_markup=delete_keyboard(msg.from_user.id))
+
+ async def telegram_help_unban_handler(msg: Message) -> None:
+ """
+ Shows help message for /unban
+ :param msg: Message telegram object
+ :return: Nothing
+ """
+ await msg.answer("Использование:\n"
+ "/unban
\n"
+ "Ответьте на сообщение, чтобы разблокировать пользователя",
+ reply_markup=delete_keyboard(msg.from_user.id))
+
+ async def telegram_help_mute_handler(msg: Message) -> None:
+ """
+ Shows help message for /mute
+ :param msg: Message telegram object
+ :return: Nothing
+ """
+ await msg.answer("Использование:\n"
+ "/mute [время мута] [причина мута]
\n"
+ "Ответьте на сообщение, чтобы замутить пользователя",
+ reply_markup=delete_keyboard(msg.from_user.id))
+
+ async def telegram_help_unmute_handler(msg: Message) -> None:
+ """
+ Shows help message for /unmute
+ :param msg: Message telegram object
+ :return: Nothing
+ """
+ await msg.answer("Использование:\n"
+ "/unmute
\n"
+ "Ответьте на сообщение, чтобы замутить пользователя",
+ reply_markup=delete_keyboard(msg.from_user.id))
+
+ telegram_setting_in_list = True
+ telegram_setting_name = "Модерация чата 🕵️"
+ telegram_setting_description = "Модерация чата🕵️\nДанная настройка включает следущие комманды:" \
+ "\n/ban [время блокировки] [причина блокировки] - блокировка пользователя" \
+ "\n/unban - разблокировка пользователя\n" \
+ "/mute [время мута] [причина мута] - мут пользователя\n" \
+ "/unmute - Размут пользователя
\n" \
+ "Время обозначается как:" \
+ "1h - один час, " \
+ "1d - один день, " \
+ "1m - одна минута, " \
+ "1s - одна секунда
\n" \
+ "Для того, " \
+ "чтобы выполнить одну из комманд по отношению к пользователю, " \
+ "ответьте на сообщение пользователя и используйте команду\n" \
+ "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
+
+ telegram_db_name = TelegramChatSettings.moderation
+ # Telegram commands
+ telegram_commands: dict[str: str] = {
+ "ban": "Command to ban user in chat",
+ "unban": "Command to unban user in chat",
+ "mute": "Command to mute user in chat",
+ "unmute": "Command to unmute user in chat",
+ }
+ telegram_cmd_avaible = True # Is a feature have a commands
+ # All handlers
+ telegram_message_handlers = [
+ # Format is [Handler, [Filters]]
+ [telegram_ban_cmd_handler, [Command(commands="ban"),
+ IsAdminFilter(True, True), F.reply_to_message.text,
+ ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_unban_cmd_handler, [Command(commands="unban"),
+ IsAdminFilter(True, True), F.reply_to_message.text,
+ ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_mute_cmd_handler, [Command(commands=["mute", "re"]),
+ UserHasPermissions(["can_restrict_members"]),
+ BotHasPermissions(["can_restrict_members"]), ~(F.chat.type == ChatType.PRIVATE), F.reply_to_message.text]],
+ [telegram_unmute_cmd_handler, [Command(commands=["unmute"]),
+ UserHasPermissions(["can_restrict_members"]),
+ BotHasPermissions(["can_restrict_members"]),
+ ~(F.chat.type == ChatType.PRIVATE), F.reply_to_message.text]],
+ [telegram_help_ban_handler,
+ [Command(commands="ban"), IsAdminFilter(True, True), ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_help_unban_handler,
+ [Command(commands="unban"), IsAdminFilter(True, True), ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_help_mute_handler, [Command(commands=["mute", "re"]), UserHasPermissions(["can_restrict_members"]),
+ BotHasPermissions(["can_restrict_members"]), ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_help_unmute_handler,
+ [Command(commands="unmute"), ~(F.chat.type == ChatType.PRIVATE), UserHasPermissions(["can_restrict_members"]),
+ BotHasPermissions(["can_restrict_members"])]]
+ ]
+ telegram_callback_handlers = [
+ # Format is [Handler, [Filters]]
+ [telegram_ban_callback_handler, [BanData.filter()]],
+ [telegram_unban_callback_handler, [UnbanData.filter()]],
+ [telegram_mute_callback_handler, [MuteData.filter()]],
+ [telegram_unmute_callback_handler, [UnmuteData.filter()]]]
diff --git a/bozenka/features/admin/pins.py b/bozenka/features/admin/pins.py
index 10e0614..afa4f9c 100644
--- a/bozenka/features/admin/pins.py
+++ b/bozenka/features/admin/pins.py
@@ -1,4 +1,5 @@
from aiogram import F
+from aiogram.enums import ChatType
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery
@@ -16,7 +17,6 @@ class Pins(BasicFeature):
All staff related to it will be here
"""
- @staticmethod
async def telegram_pin_callback_handler(call: CallbackQuery, callback_data: PinMsg) -> None:
"""
Query, what pins message
@@ -33,7 +33,6 @@ class Pins(BasicFeature):
reply_markup=pin_msg_keyboard(user_id=call.from_user.id,
msg_id=callback_data.msg_id))
- @staticmethod
async def telegram_unpin_callback_handler(call: CallbackQuery, callback_data: UnpinMsg) -> None:
"""
Query, what unpins message
@@ -50,7 +49,6 @@ class Pins(BasicFeature):
reply_markup=unpin_msg_keyboard(user_id=call.from_user.id,
msg_id=callback_data.msg_id))
- @staticmethod
async def telegram_pin_cmd(msg: Message) -> None:
"""
/pin command function, pins replied command
@@ -63,7 +61,6 @@ class Pins(BasicFeature):
reply_markup=pin_msg_keyboard(msg_id=msg.reply_to_message.message_id,
user_id=msg.from_user.id))
- @staticmethod
async def telegram_unpin_cmd(msg: Message) -> None:
"""
/unpin command function, unpins replied command
@@ -76,7 +73,6 @@ class Pins(BasicFeature):
reply_markup=unpin_msg_keyboard(msg_id=msg.reply_to_message.message_id,
user_id=msg.from_user.id))
- @staticmethod
async def telegram_unpinall_cmd(msg: Message) -> None:
"""
/unpin_all command function, unpins all messages in chat
@@ -88,39 +84,67 @@ class Pins(BasicFeature):
"Все сообщения были откреплены 📌",
reply_markup=delete_keyboard(admin_id=msg.from_user.id))
- def __init__(self):
+ async def telegram_help_pin_cmd(msg: Message) -> None:
"""
- All information about feature
- will be inside this function
+ Shows help message for /mute
+ :param msg: Message telegram object
+ :return: Nothing
"""
- super().__init__()
- self.cmd_description: str = "Your description of command"
- # Telegram feature settings
- self.telegram_setting_in_list = True
- self.telegram_setting_name = "Закреп 📌"
- self.telegram_setting_description = "Закреп📌" \
- "\nДанная функция включает команды:" \
- "/pin - закрепляет сообщение\n" \
- "/unpin - открепляет сообщение\n" \
- "/unpin_all - открепляет все сообщения, которые видит бот
\n" \
- "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
- self.telegram_db_name = TelegramChatSettings.pins
- # Telegram commands
- self.telegram_commands: dict[str: str] = {
- 'pin': 'Pin fast any message in chat',
- 'unpin': 'Unpin fast any message in chat',
- }
- self.telegram_cmd_avaible = True # Is a feature have a commands
- # Telegram Handler
- self.telegram_message_handlers = {
- self.telegram_pin_cmd: [Command(commands="pin"), UserHasPermissions(["can_pin_messages"]),
- BotHasPermissions(["can_pin_messages"]), F.reply_to_message],
- self.telegram_unpin_cmd: [Command(commands="unpin"), UserHasPermissions(["can_pin_messages"]),
- BotHasPermissions(["can_pin_messages"]), F.reply_to_message],
- self.telegram_unpinall_cmd: [Command(commands="unpin_all"), IsAdminFilter(True),
- BotHasPermissions(["can_pin_messages"]), F.reply_to_message.text],
- }
- self.telegram_callback_handlers = {
- self.telegram_pin_callback_handler: [PinMsg.filter()],
- self.telegram_unpin_callback_handler: [UnpinMsg.filter()]
- }
+ await msg.answer("Использование:\n"
+ "/pin
\n"
+ "Ответьте на сообщение, чтобы закрепить сообщение",
+ reply_markup=delete_keyboard(msg.from_user.id))
+
+ async def telegramm_help_unpin_cmd(msg: Message) -> None:
+ """
+ Shows help message for /mute
+ :param msg: Message telegram object
+ :return: Nothing
+ """
+ await msg.answer("Использование:\n"
+ "/unpin
\n"
+ "Ответьте на сообщение, чтобы открепить сообщение",
+ reply_markup=delete_keyboard(msg.from_user.id))
+
+ """
+ Telegram feature settings
+ """
+ # Telegram feature settings
+ telegram_setting_in_list = True
+ telegram_setting_name = "Закреп 📌"
+ telegram_setting_description = "Закреп📌" \
+ "\nДанная функция включает команды:" \
+ "/pin - закрепляет сообщение\n" \
+ "/unpin - открепляет сообщение\n" \
+ "/unpin_all - открепляет все сообщения, которые видит бот
\n" \
+ "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
+ telegram_db_name = TelegramChatSettings.pins
+ # Telegram commands
+ telegram_commands: dict[str: str] = {
+ 'pin': 'Pin fast any message in chat',
+ 'unpin': 'Unpin fast any message in chat',
+ }
+ telegram_cmd_avaible = True # Is a feature have a commands
+ # Telegram Handler
+ telegram_message_handlers = [
+ # Format is [Handler, [Filters]]
+ [telegram_pin_cmd, [Command(commands="pin"), UserHasPermissions(["can_pin_messages"]),
+ BotHasPermissions(["can_pin_messages"]), F.reply_to_message,
+ ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_unpin_cmd, [Command(commands="unpin"), UserHasPermissions(["can_pin_messages"]),
+ BotHasPermissions(["can_pin_messages"]), F.reply_to_message,
+ ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_unpinall_cmd, [Command(commands="unpin_all"), IsAdminFilter(True, False),
+ BotHasPermissions(["can_pin_messages"]), F.reply_to_message.text,
+ ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_help_pin_cmd, [Command(commands="pin"), UserHasPermissions(["can_pin_messages"]),
+ BotHasPermissions(["can_pin_messages"]), ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegramm_help_unpin_cmd, [Command(commands="unpin"), UserHasPermissions(["can_pin_messages"]),
+ BotHasPermissions(["can_pin_messages"]), ~(F.chat.type == ChatType.PRIVATE)]]
+
+ ]
+ telegram_callback_handlers = [
+ # Format is [Handler, [Filters]]
+ [telegram_pin_callback_handler, [PinMsg.filter()]],
+ [telegram_unpin_callback_handler, [UnpinMsg.filter()]]
+ ]
diff --git a/bozenka/features/admin/topics.py b/bozenka/features/admin/topics.py
index 247061a..9b3e068 100644
--- a/bozenka/features/admin/topics.py
+++ b/bozenka/features/admin/topics.py
@@ -1,4 +1,5 @@
from aiogram import F
+from aiogram.enums import ChatType
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery
@@ -16,7 +17,6 @@ class Threads(BasicFeature):
All staff related to it will be here
"""
- @staticmethod
async def telegram_close_topic_cmd_handler(msg: Message) -> None:
"""
/close command function. Closing thread
@@ -28,7 +28,6 @@ class Threads(BasicFeature):
reply_markup=close_thread_keyboard(user_id=msg.from_user.id)
if config[1] else delete_keyboard(msg.from_user.id))
- @staticmethod
async def telegram_reopen_topic_cmd_handler(msg: Message) -> None:
"""
/open command function. Opens thread
@@ -40,7 +39,6 @@ class Threads(BasicFeature):
reply_markup=open_thread_keyboard(user_id=msg.from_user.id)
if config[1] else delete_keyboard(msg.from_user.id))
- @staticmethod
async def telegram_close_general_topic_cmd_handler(msg: Message) -> None:
"""
/close_general command function. Closes general thread
@@ -52,7 +50,6 @@ class Threads(BasicFeature):
reply_markup=close_thread_keyboard(user_id=msg.from_user.id)
if config[1] else delete_keyboard(msg.from_user.id))
- @staticmethod
async def telegram_reopen_general_topic_cmd(msg: Message) -> None:
"""
/open_general command function. Opens general thread
@@ -64,7 +61,6 @@ class Threads(BasicFeature):
reply_markup=open_thread_keyboard(user_id=msg.from_user.id)
if config[1] else delete_keyboard(msg.from_user.id))
- @staticmethod
async def telegram_hide_general_topic_cmd_handler(msg: Message) -> None:
"""
/hide_general command function. Hides general thread
@@ -75,7 +71,6 @@ class Threads(BasicFeature):
await msg.answer(config[0],
reply_markup=delete_keyboard(msg.from_user.id))
- @staticmethod
async def telegram_unhide_general_topic_cmd(msg: Message) -> None:
"""
/show_general command function. Shows back general thread.
@@ -86,7 +81,6 @@ class Threads(BasicFeature):
await msg.answer(config[0],
reply_markup=delete_keyboard(msg.from_user.id))
- @staticmethod
async def telegram_close_thread_callback_handler(call: CallbackQuery, callback_data: CloseThread) -> None:
"""
Query, what close thread
@@ -104,7 +98,6 @@ class Threads(BasicFeature):
delete_keyboard(admin_id=call.from_user.id)
)
- @staticmethod
async def inline_open_thread(call: CallbackQuery, callback_data: OpenThread) -> None:
"""
Query, what opens thread
@@ -122,57 +115,61 @@ class Threads(BasicFeature):
delete_keyboard(admin_id=call.from_user.id)
)
- def __init__(self):
"""
- All information about feature
- will be inside this function
+ Telegram feature settings
"""
- super().__init__()
# Telegram setting info
- self.telegram_setting_in_list = True
- self.telegram_setting_name = "Работа с Форумом 💬"
- self.telegram_setting_description = "Работа с Форумом💬\nДанная настройка включает следущие комманды:\n" \
- "/open - открывают тему форума\n" \
- "/close - закрывают тему форума\n" \
- "/open_general - открывают основную тему форума\n" \
- "/close_general - закрывает основную тему форума\n" \
- "/hide_general - прячет основную тему форума\n" \
- "/show_general - показывает основную тему форума
\n" \
- "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота. Также должен быть" \
- "включен форум"
- self.telegram_db_name = TelegramChatSettings.topics
- # Telegram commands
- self.telegram_commands: dict[str: str] = {
- 'close': 'Close fast topic (not general) in chat',
- 'open': 'Open fast topic (not general) in chat',
- 'hide_general': 'Hide general topic in chat',
- 'show_general': 'Show general topic in chat',
- "close_general": 'Closes general topic in chat',
- "open_general": 'Opens general topic in chat',
- }
- self.telegram_cmd_avaible = True # Is a feature have a commands
- # All handlers
- self.telegram_message_handlers = {
- self.telegram_close_topic_cmd_handler: [Command(commands=["close_topic", "close"]),
+
+ telegram_setting_in_list = True
+ telegram_setting_name = "Работа с Форумом 💬"
+ telegram_setting_description = "Работа с Форумом💬\nДанная настройка включает следущие комманды:\n" \
+ "/open - открывают тему форума\n" \
+ "/close - закрывают тему форума\n" \
+ "/open_general - открывают основную тему форума\n" \
+ "/close_general - закрывает основную тему форума\n" \
+ "/hide_general - прячет основную тему форума\n" \
+ "/show_general - показывает основную тему форума
\n" \
+ "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота. Также должен быть" \
+ "включен форум"
+ telegram_db_name = TelegramChatSettings.topics
+ # Telegram commands
+ telegram_commands: dict[str: str] = {
+ 'close': 'Close fast topic (not general) in chat',
+ 'open': 'Open fast topic (not general) in chat',
+ 'hide_general': 'Hide general topic in chat',
+ 'show_general': 'Show general topic in chat',
+ "close_general": 'Closes general topic in chat',
+ "open_general": 'Opens general topic in chat',
+ }
+ telegram_cmd_avaible = True # Is a feature have a commands
+ # All handlers
+ telegram_message_handlers = [
+ [telegram_close_topic_cmd_handler, [Command(commands=["close_topic", "close"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum,
+ ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_reopen_topic_cmd_handler, [Command(commands=["reopen_topic", "open_topic", "open"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum,
+ ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_close_general_topic_cmd_handler, [Command(commands=["close_general"]),
UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
- self.telegram_reopen_topic_cmd_handler: [Command(commands=["reopen_topic", "open_topic", "open"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
- self.telegram_close_general_topic_cmd_handler: [Command(commands=["close_general"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
- self.telegram_reopen_general_topic_cmd: [Command(commands=["reopen_general", "open_general"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
- self.telegram_hide_general_topic_cmd_handler: [Command(commands=["hide_general"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum],
- self.telegram_unhide_general_topic_cmd: [Command(commands=["unhide_general", "show_general"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum]
- }
- self.telegram_callback_handlers = {
- self.telegram_close_thread_callback_handler: [CloseThread.filter()],
- self.telegram_reopen_topic_cmd_handler: [OpenThread.filter()]
- }
+ BotHasPermissions(["can_manage_topics"]),
+ F.chat.is_forum]],
+ [telegram_reopen_general_topic_cmd, [Command(commands=["reopen_general", "open_general"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum,
+ ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_hide_general_topic_cmd_handler, [Command(commands=["hide_general"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum,
+ ~(F.chat.type == ChatType.PRIVATE)]],
+ [telegram_unhide_general_topic_cmd, [Command(commands=["unhide_general", "show_general"]),
+ UserHasPermissions(["can_manage_topics"]),
+ BotHasPermissions(["can_manage_topics"]), F.chat.is_forum,
+ ~(F.chat.type == ChatType.PRIVATE)]]
+ ]
+ telegram_callback_handlers = [
+ [telegram_close_thread_callback_handler, [CloseThread.filter()]],
+ [telegram_reopen_topic_cmd_handler, [OpenThread.filter()]]
+ ]
diff --git a/bozenka/features/basic/__init__.py b/bozenka/features/basic/__init__.py
index b34966c..c5a2f52 100644
--- a/bozenka/features/basic/__init__.py
+++ b/bozenka/features/basic/__init__.py
@@ -1,2 +1,2 @@
-from setup import Setup
-from start import Start
+from .setup import Setup
+from .start import Start
diff --git a/bozenka/features/basic/setup.py b/bozenka/features/basic/setup.py
index 13d3398..2966dff 100644
--- a/bozenka/features/basic/setup.py
+++ b/bozenka/features/basic/setup.py
@@ -18,7 +18,6 @@ class Setup(BasicFeature):
All staff related to it will be here
"""
- @staticmethod
async def telegram_setup_cmd_handler(msg: Message) -> None:
"""
/setup telegram handler
@@ -29,7 +28,6 @@ class Setup(BasicFeature):
"Чтобы меня настроить, используй меню под данным сообщением",
reply_markup=setup_keyboard())
- @staticmethod
async def telegram_setup_categories_handler(call: CallbackQuery, callback_data: SetupCategory | SetupAction):
"""
Query, what shows list of features to enable.
@@ -40,7 +38,6 @@ class Setup(BasicFeature):
await call.message.edit_text("Выберите настройку, которую хотите изменить",
reply_markup=setup_category_keyboard(category=callback_data.category_name))
- @staticmethod
async def telegram_setup_edit_feature_handler(call: CallbackQuery, callback_data: SetupFeature, session_maker: async_sessionmaker):
"""
Query, what shows menu to enable / disable feature
@@ -61,7 +58,6 @@ class Setup(BasicFeature):
index=callback_data.feature_index,
is_enabled=is_enabled))
- @staticmethod
async def telegram_features_edit_handler(call: CallbackQuery, callback_data: SetupAction, session_maker: async_sessionmaker):
"""
Query, what shows menu to enable / disable feature
@@ -83,21 +79,19 @@ class Setup(BasicFeature):
index=callback_data.afeature_index,
is_enabled=callback_data.action == "enable"))
- def __init__(self):
- """
- All information about feature
- will be inside this function
- """
- super().__init__()
- # Telegram feature settings
- self.telegram_setting_in_list = False
- self.telegram_commands = {"setup": 'Command to setup bozenka features in chat'}
- self.telegram_cmd_avaible = True
- self.telegram_message_handlers = {
- self.telegram_setup_cmd_handler: [Command(commands=["setup"]), ~(F.chat.type == ChatType.PRIVATE)]
- }
- self.telegram_callback_handlers = {
- self.telegram_features_edit_handler: [SetupAction.filter(F.action == "disable" or F.action == "enable")],
- self.telegram_setup_edit_feature_handler: [SetupFeature.filter()],
- self.telegram_setup_categories_handler: [SetupAction.filter(F.action == "back")]
- }
+ """
+ Telegram feature settings
+ """
+ # Telegram feature settings
+ telegram_setting_in_list = False
+ telegram_commands = {"setup": 'Command to setup bozenka features in chat'}
+ telegram_cmd_avaible = True
+ telegram_message_handlers = [
+ [telegram_setup_cmd_handler, [Command(commands=["setup"]), ~(F.chat.type == ChatType.PRIVATE)]]
+ ]
+ telegram_callback_handlers = [
+ [telegram_features_edit_handler, [SetupAction.filter(F.action == "disable")]],
+ [telegram_features_edit_handler, [SetupAction.filter(F.action == "enable")]],
+ [telegram_setup_edit_feature_handler, [SetupFeature.filter()]],
+ [telegram_setup_categories_handler, [SetupAction.filter(F.action == "back")]]
+ ]
diff --git a/bozenka/features/basic/start.py b/bozenka/features/basic/start.py
index ba20c1d..41e60e6 100644
--- a/bozenka/features/basic/start.py
+++ b/bozenka/features/basic/start.py
@@ -11,34 +11,7 @@ from bozenka.instances.telegram.utils.keyboards import help_category_keyboard, h
from bozenka.instances.telegram.utils.simpler import list_of_features
from bozenka.instances.version import build, is_updated
-
-class Start(BasicFeature):
- """
- A class of /start command
- All staff related to it will be here
- """
- cmd_description: str = "Basic command to show main menu"
- main_text = """
-Привет 👋
-Я - бозенька, бот с открытым исходным кодом, который поможет тебе в различных задачах.
-
-Вот что ты можешь сделать с помощью меню:
-• Добавить в чат: добавляет меня в групповой чат, чтобы я мог выполнять свои функции внутри него.
-• Функционал: показывает список доступных функций и команд, которые я могу выполнить.
-• О разработчиках: предоставляет информацию о команде разработчиков, которые создали и поддерживают этого бота.
-• О запущенном экземпляре: выводит информацию о текущей версии и состоянии запущенного экземпляра бота.
-• Начать диалог с ИИ: позволяет начать диалог с искусственным интеллектом, который может отвечать на вопросы и предоставлять информацию.
-• Генерация изображений: позволяет сгенерировать изображения на основе заданных параметров и промта
-
-Вот нужные ссылки обо мне:
-• Канал с новостями об разработке
-• Исходный код на Github
-
-Чтобы воспользоваться какой-либо функцией, просто нажми на соответствующую кнопку ниже.
-Если у тебя возникнут вопросы или проблемы, не стесняйся обратиться к команде разработчиков или написать в обсуждении телеграм канала.
-Удачного использования!
- """
- telegram_main_menu = InlineKeyboardMarkup(
+telegram_main_menu = InlineKeyboardMarkup(
inline_keyboard=[
[InlineKeyboardButton(text="Добавить в ваш групповой чат 🔌", callback_data="addtochat")],
[InlineKeyboardButton(text="Информация об функционале бота 🔨", callback_data="functional")],
@@ -49,9 +22,17 @@ class Start(BasicFeature):
]
)
+
+class Start(BasicFeature):
+ """
+ A class of /start command
+ All staff related to it will be here
+ """
+
# There starting a help category of handlers
# It's related to one of menus
# Showing information about features, will be remade later :D
+
@staticmethod
async def back_help_categories_handler(call: CallbackQuery, callback_data: HelpBack) -> None:
"""
@@ -156,12 +137,12 @@ class Start(BasicFeature):
InlineKeyboardButton(text="Вернуться 🔙", callback_data="back")
]])
await call.message.edit_text("""
- Бозенька - это мультифункциональный (в будущем кроссплатформенный) бот.\n
- Он умеет работать с групповыми чатами и готовыми нейронными сетями для генерации текста и изображений.
- Бозенька разрабатывается коммандой, которая состоит на данный момент из одного человека.\n
- Исходный код проекта\n
- Исходный код находится под лицензией GPL-3.0, исходный код проекта можно посмотреть всегда здесь
- Канал с новостями разработки находится здесь
+Бозенька - это мультифункциональный (в будущем кроссплатформенный) бот.\n
+Он умеет работать с групповыми чатами и готовыми нейронными сетями для генерации текста и изображений.
+Бозенька разрабатывается коммандой, которая состоит на данный момент из одного человека.\n
+Исходный код проекта\n
+Исходный код находится под лицензией GPL-3.0, исходный код проекта можно посмотреть всегда здесь
+Канал с новостями разработки находится здесь
""", reply_markup=kb, disable_web_page_preview=True)
@staticmethod
@@ -175,50 +156,86 @@ class Start(BasicFeature):
reply_markup=gpt_categories_keyboard
(user_id=call.from_user.id))
- async def start_callback_handler(self, call: CallbackQuery) -> None:
+ @staticmethod
+ async def start_callback_handler(call: CallbackQuery) -> None:
"""
/start command function handler. Just back it by clicking on button.
Shows menu and basic information about bozenka
:param call: Message telegram object
:return: Nothing
"""
- await call.message.edit_text(self.main_text,
- reply_markup=self.telegram_main_menu, disable_web_page_preview=True)
+ await call.message.edit_text("""
+Привет 👋
+Я - бозенька, бот с открытым исходным кодом, который поможет тебе в различных задачах.
- async def start_cmd_handler(self, msg: Message) -> None:
+Вот что ты можешь сделать с помощью меню:
+• Добавить в чат: добавляет меня в групповой чат, чтобы я мог выполнять свои функции внутри него.
+• Функционал: показывает список доступных функций и команд, которые я могу выполнить.
+• О разработчиках: предоставляет информацию о команде разработчиков, которые создали и поддерживают этого бота.
+• О запущенном экземпляре: выводит информацию о текущей версии и состоянии запущенного экземпляра бота.
+• Начать диалог с ИИ: позволяет начать диалог с искусственным интеллектом, который может отвечать на вопросы и предоставлять информацию.
+• Генерация изображений: позволяет сгенерировать изображения на основе заданных параметров и промта
+
+Вот нужные ссылки обо мне:
+• Канал с новостями об разработке
+• Исходный код на Github
+
+Чтобы воспользоваться какой-либо функцией, просто нажми на соответствующую кнопку ниже.
+Если у тебя возникнут вопросы или проблемы, не стесняйся обратиться к команде разработчиков или написать в обсуждении телеграм канала.
+Удачного использования!
+ """, reply_markup=telegram_main_menu, disable_web_page_preview=True)
+
+ @staticmethod
+ async def start_cmd_handler(msg: Message) -> None:
"""
/start command function handler
Shows menu and basic information about bozenka
:param msg: Message telegram object
:return: Nothing
"""
- await msg.answer(self.main_text,
- reply_markup=self.telegram_main_menu, disable_web_page_preview=True)
+ await msg.answer("""
+Привет 👋
+Я - бозенька, бот с открытым исходным кодом, который поможет тебе в различных задачах.
- def __init__(self):
- """
- All information about feature
- will be inside this function
- """
- super().__init__()
- # Telegram feature settings
- self.telegram_setting = None
- self.telegram_commands: dict[str: str] = {"start": "Command to start work with bozenka the bot"}
- self.telegram_cmd_avaible = True # Is a feature have a commands
- self.telegram_callback_factory = None
- self.telegram_message_handlers = {
- self.start_cmd_handler: [Command(commands=["start"]), F.chat.type == ChatType.PRIVATE],
+Вот что ты можешь сделать с помощью меню:
+• Добавить в чат: добавляет меня в групповой чат, чтобы я мог выполнять свои функции внутри него.
+• Функционал: показывает список доступных функций и команд, которые я могу выполнить.
+• О разработчиках: предоставляет информацию о команде разработчиков, которые создали и поддерживают этого бота.
+• О запущенном экземпляре: выводит информацию о текущей версии и состоянии запущенного экземпляра бота.
+• Начать диалог с ИИ: позволяет начать диалог с искусственным интеллектом, который может отвечать на вопросы и предоставлять информацию.
+• Генерация изображений: позволяет сгенерировать изображения на основе заданных параметров и промта
- }
- self.telegram_callback_handlers = {
+Вот нужные ссылки обо мне:
+• Канал с новостями об разработке
+• Исходный код на Github
+
+Чтобы воспользоваться какой-либо функцией, просто нажми на соответствующую кнопку ниже.
+Если у тебя возникнут вопросы или проблемы, не стесняйся обратиться к команде разработчиков или написать в обсуждении телеграм канала.
+Удачного использования!
+ """, reply_markup=telegram_main_menu, disable_web_page_preview=True)
+
+ """
+ Telegram feature settings
+ """
+ # Telegram feature settings
+ telegram_setting = None
+ telegram_commands: dict[str: str] = {"start": "Command to start work with bozenka the bot"}
+ telegram_cmd_avaible = True # Is a feature have a commands
+ telegram_callback_factory = None
+ telegram_message_handlers = [
+ [start_cmd_handler, [Command(commands=["start"]), F.chat.type == ChatType.PRIVATE]],
+ ]
+ telegram_callback_handlers = [
# Start menu
- self.start_dialog_handler: [F.data == "dialogai"],
- self.add_to_menu_handler: [F.data == "addtochat"],
- self.about_developers_handler: [F.data == "aboutdevs"],
- self.about_instance_callback_handler: [F.data == "aboutbot"],
- self.start_callback_handler: [F.data == "back"],
+ [start_dialog_handler, [F.data == "dialogai"]],
+ [add_to_menu_handler, [F.data == "addtochat"]],
+ [about_developers_handler, [F.data == "aboutdevs"]],
+ [about_instance_callback_handler, [F.data == "aboutbot"]],
+ [start_callback_handler, [F.data == "back"]],
# Help menu
- self.feature_info_handler: [HelpFeature.filter() or HelpBackCategory.filter()],
- self.help_menu_handler: [HelpCategory.filter() or HelpBack.filter(F.back_to == "category")],
-
- }
+ [help_menu_handler, [F.data == "functional"]],
+ [feature_info_handler, [HelpFeature.filter()]],
+ [help_features_handler, [HelpBackCategory.filter()]],
+ [help_features_handler, [HelpCategory.filter()]],
+ [help_menu_handler, [HelpBack.filter(F.back_to == "category")]]
+ ]
diff --git a/bozenka/features/features_list.py b/bozenka/features/features_list.py
index e86bd98..6c9ff5a 100644
--- a/bozenka/features/features_list.py
+++ b/bozenka/features/features_list.py
@@ -1,4 +1,5 @@
-from aiogram import Dispatcher
+from aiogram import Dispatcher, Bot
+from aiogram.types import BotCommand
from bozenka.features import BasicFeature
from bozenka.features.admin import *
@@ -21,10 +22,4 @@ features_list = [
]
-def register_all_features(features_list: list[BasicFeature], dispatcher: Dispatcher) -> None:
- """
- Registers all features / handlers avaible in bozenka
- :param features_list: List of features
- :return: None
- """
- pass
+
diff --git a/bozenka/features/user/__init__.py b/bozenka/features/user/__init__.py
index 26b1d3c..e33fcdf 100644
--- a/bozenka/features/user/__init__.py
+++ b/bozenka/features/user/__init__.py
@@ -1,3 +1,3 @@
-from image_generation import ImageGeneratrion
-from text_generation import TextGeneratrion
-from welcome import Welcome
+from .image_generation import ImageGeneratrion
+from .text_generation import TextGeneratrion
+from .welcome import Welcome
diff --git a/bozenka/features/user/image_generation.py b/bozenka/features/user/image_generation.py
index 3f94c9b..8e63a1c 100644
--- a/bozenka/features/user/image_generation.py
+++ b/bozenka/features/user/image_generation.py
@@ -23,7 +23,6 @@ class ImageGeneratrion(BasicFeature):
"""
cmd_description: str = "Your description of command"
- @staticmethod
async def telegram_select_image_size_handler(call: CallbackQuery, callback_data: ImageGenerationCategory,
state: FSMContext) -> None:
"""
@@ -42,8 +41,8 @@ class ImageGeneratrion(BasicFeature):
reply_markup=image_resolution_keyboard(user_id=call.from_user.id,
category=callback_data.category))
- @staticmethod
- async def telegram_end_generation_handler(call: CallbackQuery, callback_data: ImageGeneration, state: FSMContext) -> None:
+ async def telegram_end_generation_handler(call: CallbackQuery, callback_data: ImageGeneration,
+ state: FSMContext) -> None:
"""
Query, what shows menu for image size to generate in
:param call:
@@ -60,7 +59,6 @@ class ImageGeneratrion(BasicFeature):
"Напишите /cancel для отмены",
reply_markup=delete_keyboard(admin_id=call.from_user.id))
- @staticmethod
async def telegram_already_generating_handler(msg: Message, state: FSMContext) -> None:
"""
Giving response, if generating image for user right now,
@@ -73,7 +71,6 @@ class ImageGeneratrion(BasicFeature):
"Подождите пожалуйста, мы уже генерируем изображение для вас, подождите, когда мы ответим на ваш передыдущий вопрос",
reply_markup=delete_keyboard(admin_id=msg.from_user.id))
- @staticmethod
async def telegram_imagine_handler(msg: Message, state: FSMContext) -> None:
"""
/imagine command handler, start menu
@@ -86,7 +83,6 @@ class ImageGeneratrion(BasicFeature):
await msg.answer("Пожалуста, выберите сервис / модель для генерации изображений",
reply_markup=image_generation_keyboard(user_id=msg.from_user.id))
- @staticmethod
async def telegram_kadinsky_generating_handler(msg: Message, state: FSMContext) -> None:
"""
Message handler for kandinsky to generate image by text from message
@@ -130,28 +126,25 @@ class ImageGeneratrion(BasicFeature):
level=logging.INFO)
await state.set_state(GeneratingImages.ready_to_generate)
- def __init__(self):
- """
- All information about feature
- will be inside this function
- """
- super().__init__()
- # Telegram feature settings
- self.telegram_setting = TelegramChatSettings.image_generation
- self.telegram_commands: dict[str: str] = {'imagine', 'Starts conversation with image generative ai'}
- self.telegram_setting_in_list = True
- self.telegram_setting_name = "Генерация изображений 📸"
- self.telegram_setting_description = "Генерация изображений 🤖" \
- "\nНаходится в разработке.\n" \
- "На текущий момент есть поддержка:\n" \
- "- Kadinksy\n" \
- " Следите за обновлениями 😘"
- self.telegram_cmd_avaible = True # Is a feature have a commands
- self.telegram_message_handlers = {
- self.telegram_kadinsky_generating_handler: [GeneratingImages.ready_to_generate, ~Command(commands=["cancel"])],
- self.telegram_imagine_handler: [Command(commands=["imagine"])]
- }
- self.telegram_callback_handlers = {
- self.telegram_select_image_size_handler: [ImageGenerationCategory.filter()],
- self.telegram_end_generation_handler: [ImageGeneration.filter()]
- }
+ """
+ Telegram feature settings
+ """
+ # Telegram feature settings
+ telegram_setting = TelegramChatSettings.image_generation
+ telegram_commands: dict[str: str] = {'imagine': 'Starts conversation with image generative ai'}
+ telegram_setting_in_list = True
+ telegram_setting_name = "Генерация изображений 📸"
+ telegram_setting_description = "Генерация изображений 🤖" \
+ "\nНаходится в разработке.\n" \
+ "На текущий момент есть поддержка:\n" \
+ "- Kadinksy\n" \
+ " Следите за обновлениями 😘"
+ telegram_cmd_avaible = True # Is a feature have a commands
+ telegram_message_handlers = [
+ [telegram_kadinsky_generating_handler, [GeneratingImages.ready_to_generate, ~Command(commands=["cancel"])]],
+ [telegram_imagine_handler, [Command(commands=["imagine"])]]
+ ]
+ telegram_callback_handlers = [
+ [telegram_select_image_size_handler, [ImageGenerationCategory.filter()]],
+ [telegram_end_generation_handler, [ImageGeneration.filter()]]
+ ]
diff --git a/bozenka/features/user/text_generation.py b/bozenka/features/user/text_generation.py
index 359abca..e7760e8 100644
--- a/bozenka/features/user/text_generation.py
+++ b/bozenka/features/user/text_generation.py
@@ -26,9 +26,7 @@ class TextGeneratrion(BasicFeature):
A class, what have inside all handlers / functions
related to text generation of bozenka
"""
- cmd_description: str = "Your description of command"
- @staticmethod
async def telegram_already_answering_handler(msg: Message, state: FSMContext) -> None:
"""
Giving response, if answering user now,
@@ -41,7 +39,6 @@ class TextGeneratrion(BasicFeature):
"Подождите пожалуйста, мы уже генерируем ответ для вас, подождите, когда мы ответим на ваш передыдущий вопрос",
reply_markup=delete_keyboard(admin_id=msg.from_user.id))
- @staticmethod
async def telegram_conversation_cmd_handler(msg: Message, state: FSMContext) -> None:
"""
/conversation command handler, start
@@ -55,7 +52,6 @@ class TextGeneratrion(BasicFeature):
reply_markup=gpt_categories_keyboard
(user_id=msg.from_user.id))
- @staticmethod
async def telegram_cancel_cmd_handler(msg: Message, state: FSMContext) -> None:
"""
Canceling dialog with generative model
@@ -74,7 +70,6 @@ class TextGeneratrion(BasicFeature):
# G4F telegram category
# All handlers and other stuff
# All code and comments
- @staticmethod
async def telegram_g4f_generate_handler(msg: Message, state: FSMContext) -> None:
"""
Generating answer if GPT4Free model and provider has been selected
@@ -131,8 +126,8 @@ class TextGeneratrion(BasicFeature):
await state.update_data(ready_to_answer=current_messages)
await state.set_state(AnsweringGPT4Free.ready_to_answer)
- @staticmethod
- async def telegram_instart_conversation_handler(call: CallbackQuery, callback_data: GptBackMenu, state: FSMContext) -> None:
+ async def telegram_instart_conversation_handler(call: CallbackQuery, callback_data: GptBackMenu,
+ state: FSMContext) -> None:
"""
Query, what shows when clicking on button in /start menu
:param call: CallbackQuery class
@@ -145,7 +140,6 @@ class TextGeneratrion(BasicFeature):
await call.message.edit_text("Пожалуста, выберите сервис для ИИ.",
reply_markup=gpt_categories_keyboard(user_id=call.from_user.id))
- @staticmethod
async def telegram_g4f_providers_handlers(call: CallbackQuery, callback_data: Gpt4FreeCategory,
state: FSMContext) -> None:
"""
@@ -167,7 +161,6 @@ class TextGeneratrion(BasicFeature):
await call.message.edit_text("Выберите пожалуйста одного из провайдеров 👨💻",
reply_markup=gpt4free_providers_keyboard(user_id=call.from_user.id, page=0))
- @staticmethod
async def telegram_g4f_models_handler(call: CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
"""
Query, what creating models selecting menu
@@ -186,8 +179,8 @@ class TextGeneratrion(BasicFeature):
await call.message.edit_text("Выберите модель, с которой будете общаться 🤖",
reply_markup=gpt4free_models_keyboard(user_id=call.from_user.id, page=0))
- @staticmethod
- async def telegram_end_g4f_model_handler(call: CallbackQuery, callback_data: Gpt4FreeModel, state: FSMContext) -> None:
+ async def telegram_g4f_model_ready_handler(call: CallbackQuery, callback_data: Gpt4FreeModel,
+ state: FSMContext) -> None:
"""
Query, what ending g4f model selecting
:param call: CallbackQuery class
@@ -209,7 +202,6 @@ class TextGeneratrion(BasicFeature):
"Чтобы прекратить общение, используйте /cancel ",
reply_markup=delete_keyboard(admin_id=call.from_user.id))
- @staticmethod
async def telegram_g4f_next_model_handler(call: CallbackQuery, callback_data: Gpt4FreeModelPage,
state: FSMContext) -> None:
"""
@@ -228,8 +220,7 @@ class TextGeneratrion(BasicFeature):
reply_markup=gpt4free_models_keyboard(user_id=call.from_user.id,
page=callback_data.page))
- @staticmethod
- async def telegram_g4f_category_handler(call: CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
+ async def telegram_g4f_category_handler(call: CallbackQuery, callback_data: GptCategory | GptBackMenu, state: FSMContext) -> None:
"""
Query, what creating providers selecting menu.
:param state: FSMContext aiogram class
@@ -243,13 +234,14 @@ class TextGeneratrion(BasicFeature):
logging.log(msg=f"Selected gpt4free category by user_id={call.from_user.id}",
level=logging.INFO)
- await state.update_data(set_category=callback_data.category)
+ if type(callback_data) == GptCategory:
+ await state.update_data(set_category=callback_data.category)
+
await call.answer("Вы выбрали Gpt4Free 🤖")
await call.message.edit_text("Выберите, по какому пункту мы будем вести диалог с нейронной сети 🤖",
reply_markup=gpt4free_categories_keyboard(user_id=call.from_user.id))
await call.answer("Выберите, по какому пункту мы будем вести диалог с нейронной сети 🤖")
- @staticmethod
async def telegram_g4f_back_provider_handler(call: CallbackQuery, callback_data: GptBackMenu,
state: FSMContext) -> None:
"""
@@ -270,9 +262,8 @@ class TextGeneratrion(BasicFeature):
reply_markup=gpt4free_providers_keyboard(page=0, user_id=callback_data.user_id))
await call.answer("Выберите пожалуйста одного из провайдеров 👨💻")
- @staticmethod
- async def inline_g4f_provider_models(call: CallbackQuery, callback_data: Gpt4FreeProvider,
- state: FSMContext) -> None:
+ async def telegram_g4f_by_provider_models(call: CallbackQuery, callback_data: Gpt4FreeProvider,
+ state: FSMContext) -> None:
"""
Query, what creating models selecting menu.
:param state: FSMContext aiogram class
@@ -297,8 +288,7 @@ class TextGeneratrion(BasicFeature):
))
await call.answer("Выберите пожалуйста модель ИИ 👾")
- @staticmethod
- async def telegram_g4f_ready_handler(call: CallbackQuery, callback_data: Gpt4freeResult, state: FSMContext) -> None:
+ async def telegram_g4f_provider_ready_handler(call: CallbackQuery, callback_data: Gpt4freeResult, state: FSMContext) -> None:
"""
Query, what says about getting ready to questions for ChatGPT from Gpt4Free.
:param state: FSMContext aiogram class
@@ -325,7 +315,6 @@ class TextGeneratrion(BasicFeature):
reply_markup=delete_keyboard(admin_id=callback_data.user_id))
await call.answer("Вы теперь можете спокойно вести диалог 🤖")
- @staticmethod
async def telegram_g4f_models_by_provider_handler(call: CallbackQuery, callback_data: Gpt4FreeProvsModelPage,
state: FSMContext) -> None:
"""
@@ -347,7 +336,6 @@ class TextGeneratrion(BasicFeature):
))
await call.answer(f"Вы перелистали на страницу {callback_data.page + 1}📄")
- @staticmethod
async def telegram_next_g4f_providers_handler(call: CallbackQuery, callback_data: Gpt4FreeProviderPage,
state: FSMContext) -> None:
"""
@@ -370,7 +358,6 @@ class TextGeneratrion(BasicFeature):
# All code and commentaries here
# All handlers here
- @staticmethod
async def telegram_g4a_generate_handler(msg: Message, state: FSMContext) -> None:
"""
Generating answer if Gpt4All has been selected
@@ -413,7 +400,6 @@ class TextGeneratrion(BasicFeature):
await state.set_state(AnsweringGpt4All.ready_to_answer)
- @staticmethod
async def telegram_g4a_handler(call: CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
"""
Query, what shows list for gpt4all models
@@ -428,7 +414,6 @@ class TextGeneratrion(BasicFeature):
await call.message.edit_text("Выберите пожалуйста модель ИИ 👾",
reply_markup=generate_gpt4all_page(user_id=call.from_user.id))
- @staticmethod
async def telegram_g4a_back_handler(call: CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
"""
Query, what shows list for gpt4all models back
@@ -443,8 +428,8 @@ class TextGeneratrion(BasicFeature):
await call.message.edit_text("Выберите пожалуйста модель ИИ 👾",
reply_markup=generate_gpt4all_page(user_id=call.from_user.id))
- @staticmethod
- async def telegram_g4a_infomration_handler(call: CallbackQuery, callback_data: Gpt4AllModel, state: FSMContext) -> None:
+ async def telegram_g4a_infomration_handler(call: CallbackQuery, callback_data: Gpt4AllModel,
+ state: FSMContext) -> None:
"""
Query, what show information about clicked gpt4all model from list
:param state: FSMContext aiogram class
@@ -461,7 +446,6 @@ class TextGeneratrion(BasicFeature):
reply_markup=gpt4all_model_menu(user_id=call.from_user.id,
index=callback_data.index))
- @staticmethod
async def telegram_g4a_end_handler(call: CallbackQuery, callback_data: Gpt4AllSelect,
state: FSMContext) -> None:
"""
@@ -483,7 +467,6 @@ class TextGeneratrion(BasicFeature):
"Чтобы прекратить общение, используйте /cancel ",
reply_markup=delete_keyboard(admin_id=callback_data.user_id))
- @staticmethod
async def telegram_pages_handler(call: CallbackQuery) -> None:
"""
Query, made for helping purposes.
@@ -495,7 +478,6 @@ class TextGeneratrion(BasicFeature):
level=logging.INFO)
await call.answer("Здесь расположается текущая странница 📃")
- @staticmethod
async def telegram_stop_dialog_handler(call: CallbackQuery, callback_data: GptStop, state: FSMContext) -> None:
"""
Query, what stops dialog
@@ -516,44 +498,49 @@ class TextGeneratrion(BasicFeature):
else:
await call.message.delete()
- def __init__(self):
- """
- All information about feature
- will be inside this function
- """
- super().__init__()
- # Telegram feature settings
- self.telegram_setting = TelegramChatSettings.text_generation
- self.telegram_setting_in_list = True
- self.telegram_setting_name = "ИИ ЧатБот 🤖"
- self.telegram_setting_description = "ИИ ЧатБот 🤖" \
- "\nЕсть поддержка:\n" \
- "- Моделей Gpt4All\n" \
- "- Провайдеров Gpt4Free и моделей\n" \
- "Для использования:\n" \
- "/conversations
" \
- "\nНаходится в разработке, планируется в будущем. Следите за обновлениями 😘"
- self.telegram_commands: dict[str: str] = {
- 'conversation': 'Starts conversation with text generative ai'
- }
- self.telegram_cmd_avaible = True # Is a feature have a commands
- self.telegram_message_handlers = {
- self.telegram_conversation_cmd_handler: [Command(commands=["conversation"])],
- self.telegram_g4a_generate_handler: [AnsweringGpt4All.ready_to_answer, ~Command(commands=["cancel"])],
- self.telegram_g4f_generate_handler: [AnsweringGPT4Free.ready_to_answer, ~Command(commands=["cancel"])],
- self.telegram_already_answering_handler: [AnsweringGPT4Free.answering, AnsweringGpt4All.answering]
- }
- self.telegram_callback_handlers = {
- # g4a
- self.telegram_g4a_handler: [GptCategory.filter(F.category == "Gpt4All")],
- self.telegram_g4a_infomration_handler: [Gpt4AllModel.filter()],
- self.telegram_g4a_end_handler: [Gpt4AllSelect.filter()],
- # g4f
- self.telegram_g4f_category_handler: [GptCategory.filter(F.category == "Gpt4Free")],
- self.telegram_g4f_models_handler: [Gpt4FreeCategory.filter(F.category == "models")],
- self.telegram_g4f_providers_handlers: [Gpt4FreeCategory.filter(F.category == "providers")],
- self.telegram_g4f_models_by_provider_handler: [Gpt4FreeProvider.filter()],
- self.telegram_next_g4f_providers_handler: [Gpt4FreeProviderPage.filter()],
- # stop talking
- self.telegram_stop_dialog_handler: [GptStop.filter()]
- }
+ # Telegram feature settings
+ telegram_setting = TelegramChatSettings.text_generation
+ telegram_setting_in_list = True
+ telegram_setting_name = "ИИ ЧатБот 🤖"
+ telegram_setting_description = "ИИ ЧатБот 🤖" \
+ "\nЕсть поддержка:\n" \
+ "- Моделей Gpt4All\n" \
+ "- Провайдеров Gpt4Free и моделей\n" \
+ "Для использования:\n" \
+ "/conversations
" \
+ "\nНаходится в разработке, планируется в будущем. Следите за обновлениями 😘"
+ telegram_commands: dict[str: str] = {
+ 'conversation': 'Starts conversation with text generative ai'
+ }
+ telegram_cmd_avaible = True # Is a feature have a commands
+ telegram_message_handlers = (
+ [telegram_conversation_cmd_handler, [Command(commands=["conversation"])]],
+ [telegram_g4a_generate_handler, [AnsweringGpt4All.ready_to_answer, ~Command(commands=["cancel"])]],
+ [telegram_g4f_generate_handler, [AnsweringGPT4Free.ready_to_answer, ~Command(commands=["cancel"])]],
+ [telegram_already_answering_handler, [AnsweringGPT4Free.answering, AnsweringGpt4All.answering]]
+ )
+ telegram_callback_handlers = (
+ # g4a
+ [telegram_g4a_handler, [GptCategory.filter(F.category == "Gpt4All")]],
+ [telegram_g4a_infomration_handler, [Gpt4AllModel.filter()]],
+ [telegram_g4a_end_handler, [Gpt4AllSelect.filter()]],
+ # g4f
+ [telegram_g4f_category_handler, [GptCategory.filter(F.category == "Gpt4Free")]],
+ [telegram_g4f_category_handler, [GptBackMenu.filter(F.back_to == "g4fcategory")]],
+ # categories
+ [telegram_g4f_models_handler, [Gpt4FreeCategory.filter(F.category == "models")]],
+ [telegram_g4f_providers_handlers, [Gpt4FreeCategory.filter(F.category == "providers")]],
+ # providers list
+ [telegram_g4f_providers_handlers, [GptBackMenu.filter(F.back_to == "providers")]],
+ [telegram_next_g4f_providers_handler, [Gpt4FreeProviderPage.filter()]],
+ # models by provider list
+ [telegram_g4f_models_by_provider_handler, [Gpt4FreeProvsModelPage.filter()]],
+ [telegram_g4f_by_provider_models, [Gpt4FreeProvider.filter()]],
+ # models list
+ [telegram_g4f_next_model_handler, [Gpt4FreeModelPage.filter()]],
+ # end features
+ [telegram_g4f_model_ready_handler, [Gpt4FreeModel.filter()]],
+ [telegram_g4f_provider_ready_handler, [Gpt4freeResult.filter()]],
+ # stop talking
+ [telegram_stop_dialog_handler, [GptStop.filter()]]
+ )
diff --git a/bozenka/features/user/welcome.py b/bozenka/features/user/welcome.py
index 3584425..d94c7d6 100644
--- a/bozenka/features/user/welcome.py
+++ b/bozenka/features/user/welcome.py
@@ -1,6 +1,7 @@
import logging
-from aiogram import Bot
+from aiogram import Bot, F
+from aiogram.enums import ContentType
from aiogram.types import Message, CallbackQuery
from sqlalchemy.ext.asyncio import async_sessionmaker
@@ -17,7 +18,6 @@ class Welcome(BasicFeature):
All staff related to it will be here
"""
- @staticmethod
async def telegram_join_handler(msg: Message, session_maker: async_sessionmaker) -> None:
"""
Message handler.
@@ -44,7 +44,6 @@ class Welcome(BasicFeature):
"Чтобы настроить функционал, используйте /setup или кнопку под сообщением", )
await SolutionSimpler.auto_settings(msg=msg, session=session_maker)
- @staticmethod
async def telegram_leave_handler(msg: Message, bot: Bot) -> None:
"""
Sens goodbye message, after deleting member from chat
@@ -61,22 +60,16 @@ class Welcome(BasicFeature):
f"Пользователь {msg.left_chat_member.mention_html()} съехал с конфы, благодаря {msg.from_user.mention_html()}👋"
)
- def __init__(self):
- """
- All information about feature
- will be inside this function
- """
- super().__init__()
- self.cmd_description: str = "Your description of command"
- # Telegram feature settings
- self.telegram_setting = TelegramChatSettings.welcome_messages
- self.telegram_commands: dict[str: str] = {}
- self.telegram_setting_in_list = True
- self.telegram_setting_name = "Приветсвенные сообщения 👋"
- self.telegram_setting_description = "Приветсвенные сообщения 👋" \
- "\nПриветсвенные сообщения новым и ушедшим пользователям.",
- self.telegram_cmd_avaible = False # Is a feature have a commands
- self.telegram_message_handlers = {
-
- }
- self.telegram_callback_handlers = {}
+ # Telegram feature settings
+ telegram_setting = TelegramChatSettings.welcome_messages
+ telegram_commands: dict[str: str] = {}
+ telegram_setting_in_list = True
+ telegram_setting_name = "Приветсвенные сообщения 👋"
+ telegram_setting_description = "Приветсвенные сообщения 👋" \
+ "\nПриветсвенные сообщения новым и ушедшим пользователям.",
+ telegram_cmd_avaible = False # Is a feature have a commands
+ telegram_message_handlers = [
+ [telegram_leave_handler, [F.content_type == ContentType.LEFT_CHAT_MEMBER]],
+ [telegram_join_handler, [F.content_type == ContentType.NEW_CHAT_MEMBERS]]
+ ]
+ telegram_callback_handlers = []
diff --git a/bozenka/instances/telegram/__init__.py b/bozenka/instances/telegram/__init__.py
index d63faf5..9576011 100644
--- a/bozenka/instances/telegram/__init__.py
+++ b/bozenka/instances/telegram/__init__.py
@@ -5,10 +5,39 @@ from aiogram import Dispatcher, Bot
from aiogram.types import BotCommand
from sqlalchemy.ext.asyncio import async_sessionmaker
+from bozenka.features import BasicFeature
+from bozenka.features.features_list import features_list
+from bozenka.features.admin import *
+from bozenka.features.basic import *
+from bozenka.features.user import *
from bozenka.instances.telegram.handlers import register_handlers
from bozenka.instances.telegram.utils.simpler import list_of_commands
+async def register_all_features(list_of_features: list[BasicFeature], dispatcher: Dispatcher, bot: Bot) -> None:
+ """
+ Registers all features / handlers avaible in bozenka
+ :param list_of_features: List of features
+ :param dispatcher: Dispatcher aiogram class
+ :param bot: Bot aiogram class
+ :return: None
+ """
+ cmd_list = []
+ for feature in list_of_features:
+
+ if feature.telegram_cmd_avaible:
+ for command, description in feature.telegram_commands.items():
+ cmd_list.append(BotCommand(command=command, description=description))
+
+ for message_handler in feature.telegram_message_handlers:
+ dispatcher.message.register(message_handler[0], *message_handler[1])
+
+ for callback_query_handler in feature.telegram_callback_handlers:
+ dispatcher.callback_query.register(callback_query_handler[0], *callback_query_handler[1])
+
+ await bot.set_my_commands(cmd_list)
+
+
async def launch_telegram_instance(session_maker: async_sessionmaker) -> None:
"""
Launches telegram bot with token from enviroment
@@ -19,10 +48,7 @@ async def launch_telegram_instance(session_maker: async_sessionmaker) -> None:
bot = Bot(token=os.getenv("tg_bot_token"), parse_mode="HTML")
- cmd_of_bot = []
- for command in list_of_commands:
- cmd_of_bot.append(BotCommand(command=command[0], description=command[1]))
- await bot.set_my_commands(cmd_of_bot)
-
dp = Dispatcher()
- await dp.start_polling(bot, session_maker=session_maker, on_startup=[register_handlers(dp)])
+
+ await register_all_features(list_of_features=features_list, dispatcher=dp, bot=bot)
+ await dp.start_polling(bot, session_maker=session_maker, on_startup=[])
diff --git a/bozenka/instances/telegram/utils/filters/permissions.py b/bozenka/instances/telegram/utils/filters/permissions.py
index 1b2cccd..eb597e4 100644
--- a/bozenka/instances/telegram/utils/filters/permissions.py
+++ b/bozenka/instances/telegram/utils/filters/permissions.py
@@ -1,6 +1,7 @@
from typing import Any
from aiogram.filters import Filter
+from aiogram.methods import GetChatMember
from aiogram.types import Message, ChatPermissions
from aiogram.enums import ChatMemberStatus
from bozenka.instances.telegram.utils.simpler import ru_cmds
@@ -39,7 +40,8 @@ class UserHasPermissions(Filter):
def __init__(self, perms: list[Any]) -> None:
self.perms = perms
- async def check_permissions(self, permission, msg: Message) -> bool:
+ @staticmethod
+ async def check_permissions(permission, msg: Message) -> bool:
"""
Checking permissions, included to user.
:return:
@@ -52,19 +54,29 @@ class UserHasPermissions(Filter):
def generate_perms_list(self, user) -> list[Any]:
"""
- Generates list of permissions, included to user
- :param user:
- :return:
+ Generates list of permissions for user.
+ :param user: User telegram object
+ :return: List
"""
permission = []
for rule in self.perms:
- if rule in permission:
+ if rule in self.permissions:
exec(f"permission.append(user.{rule})")
return permission
async def __call__(self, msg: Message) -> bool:
+ """
+ Working after catching a call from aiogram
+ :param msg: Message telegram object
+ :param self: A self object of this class
+ :return: None
+ """
user = await msg.chat.get_member(msg.from_user.id)
- permission = self.generate_perms_list(user)
+ if user.status != ChatMemberStatus.CREATOR:
+ permission = self.generate_perms_list(user)
+ else:
+ permission = None
+
return True if user.status == ChatMemberStatus.CREATOR else self.check_permissions(permission, msg)
@@ -72,20 +84,39 @@ class BotHasPermissions(UserHasPermissions):
"""
Check, does bot have permissions, what user need to work with bot.
"""
- async def __call__(self, msg: Message, *args, **kwargs):
+
+ async def __call__(self, msg: Message, *args, **kwargs) -> bool:
+ """
+ Working after catching a call from aiogram
+ :param msg: Message telegram object
+ :param self: A self object of this class
+ :return: None
+ """
bot = await msg.chat.get_member(msg.chat.bot.id)
permission = self.generate_perms_list(bot)
- return self.check_permissions(permission, msg)
+ return await self.check_permissions(permission, msg)
class IsOwner(Filter):
"""
- Checks, is User are owner of chat
+ Checks, is memeber is owner of this chat
"""
+
def __init__(self, is_admin: bool) -> None:
+ """
+ Basic init class
+ :param is_admin: Is admin status
+ :return: Nothing
+ """
self.is_admin = is_admin
async def __call__(self, msg: Message) -> bool:
+ """
+ Working after catching a call from aiogram
+ :param msg: Message telegram object
+ :param self: A self object of this class
+ :return: None
+ """
user = await msg.chat.get_member(msg.from_user.id)
if ChatMemberStatus.CREATOR != user.status:
await msg.answer(ru_cmds["no-perms"])
@@ -93,12 +124,36 @@ class IsOwner(Filter):
class IsAdminFilter(Filter):
- def __init__(self, is_admin: bool) -> None:
- self.is_admin = is_admin
+ """
+ Checks, is member of chat is admin and
+ does bot have administration rights
+ """
+
+ def __init__(self, is_user_admin: bool, is_bot_admin: bool) -> None:
+ """
+ Basic init class
+
+ """
+ self.is_user_admin = is_user_admin
+ self.is_bot_admin = is_bot_admin
async def __call__(self, msg: Message) -> bool:
+ """
+ Working after catching a call from aiogram
+ :param msg: Message telegram object
+ :param self: A self object of this class
+ :return: None
+ """
user = await msg.chat.get_member(msg.from_user.id)
+ bot = await msg.chat.get_member(msg.bot.id)
+ if ChatMemberStatus.ADMINISTRATOR != user.status and ChatMemberStatus.CREATOR != user.status:
+ if bot.status != ChatMemberStatus.ADMINISTRATOR:
+ await msg.reply("Ошибка ❌\n"
+ "У вас нет прав на использование этой комманды. У меня нет прав на использование 🚫")
+ else:
+ await msg.reply("Ошибка ❌\n"
+ "У вас нет прав на использование этой комманды 🚫")
+ return False
if ChatMemberStatus.CREATOR == user.status:
return True
- return ChatMemberStatus.ADMINISTRATOR == user.status
-
+ return ChatMemberStatus.ADMINISTRATOR == user.status or ChatMemberStatus.CREATOR == user.status
diff --git a/bozenka/instances/telegram/utils/keyboards/inline.py b/bozenka/instances/telegram/utils/keyboards/inline.py
index fa4b510..17f6274 100644
--- a/bozenka/instances/telegram/utils/keyboards/inline.py
+++ b/bozenka/instances/telegram/utils/keyboards/inline.py
@@ -28,10 +28,10 @@ def start_keyboard() -> InlineKeyboardMarkup:
inline_keyboard=[
[InlineKeyboardButton(text="Добавить в ваш групповой чат 🔌", callback_data="addtochat")],
[InlineKeyboardButton(text="Информация об функционале бота 🔨", callback_data="functional")],
- [InlineKeyboardButton(text="Об данном проекте ℹ️", callback_data="aboutdevs")],
+ [InlineKeyboardButton(text="О данном проекте ℹ️", callback_data="aboutdevs")],
[InlineKeyboardButton(text="О данном запущенном экзепляре ℹ️", callback_data="aboutbot")],
[InlineKeyboardButton(text="Начать диалог с текстовым ИИ 🤖", callback_data="dialogai")],
- [InlineKeyboardButton(text="Начать генерацию изображений 🖼", callback_data="dialogimage")],
+ [InlineKeyboardButton(text="Начать генерировать изображения 🖼", callback_data="dialogimage")],
]
)
return kb
@@ -82,7 +82,7 @@ def help_feature_keyboard(category: str) -> InlineKeyboardMarkup:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="🔙 Назад к функциям",
- callback_data=HelpBackCategory(back_to_category=category).pack())]
+ callback_data=HelpBackCategory(category_name=category).pack())]
])
return kb
@@ -414,7 +414,7 @@ def generate_gpt4all_page(user_id: int) -> InlineKeyboardMarkup:
callback_data=Gpt4AllModel(user_id=str(user_id), index=str(models.index(model))).pack())
)
builder.row(InlineKeyboardButton(text="🔙 Вернуться к списку",
- callback_data=GptBackMenu(user_id=user_id, back_to="category").pack()))
+ callback_data=GptBackMenu(user_id=user_id, back_to="g4fcategory").pack()))
builder.row(InlineKeyboardButton(text="Спасибо, не надо ❌",
callback_data=GptStop(user_id=str(user_id)).pack()))
return builder.as_markup()
--
2.30.2
From 4d3b9513f06e7683d8ea878dc52751045c73dcb8 Mon Sep 17 00:00:00 2001
From: kittyneverdies <85691197+KittyNeverDies@users.noreply.github.com>
Date: Sat, 10 Feb 2024 22:24:05 +0300
Subject: [PATCH 05/13] A little bit changes too X2
---
.../telegram/handlers/queries/__init__.py | 2 +-
.../telegram/handlers/queries/delete.py | 4 +-
.../instances/telegram/queries/__init__.py | 0
bozenka/instances/telegram/queries/menu.py | 39 +++++++++++++++++++
.../utils/callbacks_factory/__init__.py | 7 ++--
.../{admin.py => administration.py} | 3 ++
.../{setup.py => basic_functional.py} | 30 ++++++++++++++
.../utils/callbacks_factory/delete.py | 8 ----
.../utils/callbacks_factory/menu_controler.py | 15 +++++++
.../telegram/utils/callbacks_factory/start.py | 38 ------------------
.../telegram/utils/keyboards/inline.py | 24 ++++++------
11 files changed, 105 insertions(+), 65 deletions(-)
create mode 100644 bozenka/instances/telegram/queries/__init__.py
create mode 100644 bozenka/instances/telegram/queries/menu.py
rename bozenka/instances/telegram/utils/callbacks_factory/{admin.py => administration.py} (91%)
rename bozenka/instances/telegram/utils/callbacks_factory/{setup.py => basic_functional.py} (59%)
delete mode 100644 bozenka/instances/telegram/utils/callbacks_factory/delete.py
create mode 100644 bozenka/instances/telegram/utils/callbacks_factory/menu_controler.py
delete mode 100644 bozenka/instances/telegram/utils/callbacks_factory/start.py
diff --git a/bozenka/instances/telegram/handlers/queries/__init__.py b/bozenka/instances/telegram/handlers/queries/__init__.py
index fef7601..ee5323b 100644
--- a/bozenka/instances/telegram/handlers/queries/__init__.py
+++ b/bozenka/instances/telegram/handlers/queries/__init__.py
@@ -33,7 +33,7 @@ def register_queries(router: Router) -> None:
# Revoke telegram invite link button
router.callback_query.register(inline_revoke, RevokeCallbackData.filter())
# Delete button message reaction
- router.callback_query.register(inline_delete, DeleteCallbackData.filter())
+ router.callback_query.register(inline_delete, DeleteMenu.filter())
# Threads (Close/Open)
router.callback_query.register(inline_close_thread, CloseThread.filter())
diff --git a/bozenka/instances/telegram/handlers/queries/delete.py b/bozenka/instances/telegram/handlers/queries/delete.py
index 0f05718..20f24cf 100644
--- a/bozenka/instances/telegram/handlers/queries/delete.py
+++ b/bozenka/instances/telegram/handlers/queries/delete.py
@@ -2,11 +2,11 @@ import logging
from aiogram import types
-from bozenka.instances.telegram.utils.callbacks_factory import DeleteCallbackData
+from bozenka.instances.telegram.utils.callbacks_factory import DeleteMenu
from aiogram.enums import ChatMemberStatus
-async def inline_delete(call: types.CallbackQuery, callback_data: DeleteCallbackData) -> None:
+async def inline_delete(call: types.CallbackQuery, callback_data: DeleteMenu) -> None:
"""
Deletes messsage, after special callback
:param call:
diff --git a/bozenka/instances/telegram/queries/__init__.py b/bozenka/instances/telegram/queries/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bozenka/instances/telegram/queries/menu.py b/bozenka/instances/telegram/queries/menu.py
new file mode 100644
index 0000000..627b091
--- /dev/null
+++ b/bozenka/instances/telegram/queries/menu.py
@@ -0,0 +1,39 @@
+import logging
+
+from aiogram import types
+
+from bozenka.instances.telegram.utils.callbacks_factory import DeleteMenu
+from aiogram.enums import ChatMemberStatus
+
+from bozenka.instances.telegram.utils.callbacks_factory.menu_controler import HideMenu
+
+
+async def delete_callback_handler(call: types.CallbackQuery, callback_data: DeleteMenu) -> None:
+ """
+ Deletes messsage, after special callback
+ :param call: CallbackQuery telegram object
+ :param callback_data: DeleteMenu object
+ :return: None
+ """
+ user_clicked = await call.message.chat.get_member(call.from_user.id)
+ if call.from_user.id == callback_data.user_id_clicked or user_clicked.status == ChatMemberStatus.ADMINISTRATOR:
+ await call.answer("Хорошо ✅")
+ logging.log(msg=f"Deleted message with message_id={call.message.message_id}",
+ level=logging.INFO)
+ await call.message.delete()
+
+
+async def hide_menu_handler(call: types.CallbackQuery, callback_data: HideMenu):
+ """
+ Hide InlineKeyboard, after special callback
+ :param call: CallbackQuery telegram object
+ :param callback_data: HideMenu object
+ :return: None
+ """
+ user_clicked = await call.message.chat.get_member(call.from_user.id)
+ if call.from_user.id == callback_data.user_id_clicked or user_clicked.status == ChatMemberStatus.ADMINISTRATOR:
+ await call.answer("Хорошо ✅")
+ logging.log(msg=f"Hide inline keyboard message with message_id={call.message.message_id}",
+ level=logging.INFO)
+ await call.message.edit_text(call.message.text, reply_markup=None)
+
diff --git a/bozenka/instances/telegram/utils/callbacks_factory/__init__.py b/bozenka/instances/telegram/utils/callbacks_factory/__init__.py
index c7d0fea..cd876be 100644
--- a/bozenka/instances/telegram/utils/callbacks_factory/__init__.py
+++ b/bozenka/instances/telegram/utils/callbacks_factory/__init__.py
@@ -1,6 +1,5 @@
-from .admin import *
-from .delete import DeleteCallbackData
+from .administration import *
+from .menu_controler import DeleteMenu
from .text_generation import *
-from .setup import *
-from .start import *
+from .basic_functional import *
from .img_generation import *
diff --git a/bozenka/instances/telegram/utils/callbacks_factory/admin.py b/bozenka/instances/telegram/utils/callbacks_factory/administration.py
similarity index 91%
rename from bozenka/instances/telegram/utils/callbacks_factory/admin.py
rename to bozenka/instances/telegram/utils/callbacks_factory/administration.py
index 5a8b83e..f1c7986 100644
--- a/bozenka/instances/telegram/utils/callbacks_factory/admin.py
+++ b/bozenka/instances/telegram/utils/callbacks_factory/administration.py
@@ -5,6 +5,7 @@ from aiogram.filters.callback_data import CallbackData
class BanData(CallbackData, prefix="ban"):
"""
Callback with information to ban user
+ and handle clicking on button ban
"""
user_id_ban: int
user_id_clicked: int
@@ -13,6 +14,7 @@ class BanData(CallbackData, prefix="ban"):
class UnbanData(CallbackData, prefix="unban"):
"""
Callback with information to unban user
+ and handle clicking on button unban
"""
user_id_unban: int
user_id_clicked: int
@@ -22,6 +24,7 @@ class UnbanData(CallbackData, prefix="unban"):
class MuteData(CallbackData, prefix="mute"):
"""
Callback with information to mute user
+ and handle clicking on button unmute
"""
user_id_mute: int
user_id_clicked: int
diff --git a/bozenka/instances/telegram/utils/callbacks_factory/setup.py b/bozenka/instances/telegram/utils/callbacks_factory/basic_functional.py
similarity index 59%
rename from bozenka/instances/telegram/utils/callbacks_factory/setup.py
rename to bozenka/instances/telegram/utils/callbacks_factory/basic_functional.py
index 1426531..c8edcf3 100644
--- a/bozenka/instances/telegram/utils/callbacks_factory/setup.py
+++ b/bozenka/instances/telegram/utils/callbacks_factory/basic_functional.py
@@ -39,3 +39,33 @@ class SetupEditFeature(CallbackData, prefix="sef"):
enable: bool
feature_index: int
feature_category: str
+
+
+class HelpCategory(CallbackData, prefix="hc"):
+ """
+ Callback data of help categories
+ """
+ category_name: str
+
+
+class HelpFeature(CallbackData, prefix="hf"):
+ """
+ Callback data of features category
+ """
+ feature_index: int
+ feature_category: str
+
+
+class HelpBack(CallbackData, prefix="hb"):
+ """
+ Callback data to back to categories in help menu
+ """
+ back_to: str
+
+
+class HelpBackCategory(CallbackData, prefix="hbc"):
+ """
+ Callback data to back to list of features in one
+ of categories in menu
+ """
+ category_name: str
diff --git a/bozenka/instances/telegram/utils/callbacks_factory/delete.py b/bozenka/instances/telegram/utils/callbacks_factory/delete.py
deleted file mode 100644
index 68845c2..0000000
--- a/bozenka/instances/telegram/utils/callbacks_factory/delete.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from aiogram.filters.callback_data import CallbackData
-
-
-class DeleteCallbackData(CallbackData, prefix="delete"):
- """
- Callback with information to delete message
- """
- user_id_clicked: int
diff --git a/bozenka/instances/telegram/utils/callbacks_factory/menu_controler.py b/bozenka/instances/telegram/utils/callbacks_factory/menu_controler.py
new file mode 100644
index 0000000..296b679
--- /dev/null
+++ b/bozenka/instances/telegram/utils/callbacks_factory/menu_controler.py
@@ -0,0 +1,15 @@
+from aiogram.filters.callback_data import CallbackData
+
+
+class DeleteMenu(CallbackData, prefix="delete"):
+ """
+ Callback with information to delete message
+ """
+ user_id_clicked: int
+
+
+class HideMenu(CallbackData, prefix="hide"):
+ """
+ Callback with information to hide message
+ """
+ user_id_clicked: int
diff --git a/bozenka/instances/telegram/utils/callbacks_factory/start.py b/bozenka/instances/telegram/utils/callbacks_factory/start.py
deleted file mode 100644
index 0c4048d..0000000
--- a/bozenka/instances/telegram/utils/callbacks_factory/start.py
+++ /dev/null
@@ -1,38 +0,0 @@
-from aiogram.filters.callback_data import CallbackData
-
-
-class HelpCategory(CallbackData, prefix="hc"):
- """
- Callback data of help categories
- """
- category_name: str
-
-
-class HelpFeature(CallbackData, prefix="hf"):
- """
- Callback data of features category
- """
- feature_index: int
- feature_category: str
-
-
-class HelpBack(CallbackData, prefix="hb"):
- """
- Callback data to back to categories in help menu
- """
- back_to: str
-
-
-class HelpBackCategory(CallbackData, prefix="hbc"):
- """
- Callback data to back to list of features in one
- of categories in menu
- """
- category_name: str
-
-
-class BackStart(CallbackData, prefix="start"):
- """
- Callback data to back to /start
- """
- pass
diff --git a/bozenka/instances/telegram/utils/keyboards/inline.py b/bozenka/instances/telegram/utils/keyboards/inline.py
index 17f6274..e377704 100644
--- a/bozenka/instances/telegram/utils/keyboards/inline.py
+++ b/bozenka/instances/telegram/utils/keyboards/inline.py
@@ -156,7 +156,7 @@ def delete_keyboard(admin_id: int) -> InlineKeyboardMarkup:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[[
- InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())
+ InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())
]])
return kb
@@ -445,7 +445,7 @@ def text_response_keyboard(user_id: int) -> InlineKeyboardMarkup:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(user_id)).pack())],
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())],
[InlineKeyboardButton(text="Завершить диалог 🚫", callback_data=GptStop(user_id=str(user_id)).pack())]
])
return kb
@@ -458,7 +458,7 @@ def image_response_keyboard(user_id: int) -> InlineKeyboardMarkup:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(user_id)).pack())],
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())],
[InlineKeyboardButton(text="Хватит 🚫", callback_data=GptStop(user_id=str(user_id)).pack())]
])
return kb
@@ -474,7 +474,7 @@ def ban_keyboard(admin_id: int, ban_id: int) -> InlineKeyboardMarkup:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[[
- InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())
+ InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(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())
@@ -491,7 +491,7 @@ def unban_keyboard(admin_id: int, ban_id: int) -> InlineKeyboardMarkup:
"""
print(ban_id)
kb = InlineKeyboardMarkup(inline_keyboard=[[
- InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())
+ InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(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())
@@ -509,7 +509,7 @@ def mute_keyboard(admin_id: int, mute_id: int) -> InlineKeyboardMarkup:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Спасибо ✅",
- callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())],
+ callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())],
[InlineKeyboardButton(text="Размутить 🛠️",
callback_data=UnmuteData(user_id_unmute=mute_id, user_id_clicked=admin_id).pack())]])
return kb
@@ -524,7 +524,7 @@ def unmute_keyboard(admin_id: int, unmute_id: int) -> InlineKeyboardMarkup:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Спасибо ✅",
- callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())],
+ callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())],
[InlineKeyboardButton(text="Замутить 🛠️",
callback_data=MuteData(user_id_mute=unmute_id, user_id_clicked=admin_id).pack())]])
return kb
@@ -545,7 +545,7 @@ def invite_keyboard(link: str, admin_id: int, chat_name: str) -> InlineKeyboardM
[InlineKeyboardButton(text="Отозвать 🛠️",
callback_data=RevokeCallbackData(admin_id=admin_id, link=link).pack())],
[InlineKeyboardButton(text="Спасибо ✅",
- callback_data=DeleteCallbackData(user_id_clicked=str(admin_id)).pack())]])
+ callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())]])
return kb
@@ -558,7 +558,7 @@ def close_thread_keyboard(user_id: int) -> InlineKeyboardMarkup:
"""
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())]
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())]
])
return kb
@@ -571,7 +571,7 @@ def open_thread_keyboard(user_id: int) -> InlineKeyboardMarkup:
"""
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())]
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())]
])
return kb
@@ -587,7 +587,7 @@ def pin_msg_keyboard(user_id: int, msg_id: int) -> InlineKeyboardMarkup:
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())]
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())]
])
return kb
@@ -602,7 +602,7 @@ def unpin_msg_keyboard(user_id: int, msg_id: int) -> InlineKeyboardMarkup:
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())]
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())]
])
return kb
--
2.30.2
From 347c666a78485879f0cb5021bb5daeda8d7b1dfb Mon Sep 17 00:00:00 2001
From: kittyneverdies <85691197+KittyNeverDies@users.noreply.github.com>
Date: Sat, 10 Feb 2024 22:24:42 +0300
Subject: [PATCH 06/13] Removed other source code
---
.../instances/telegram/handlers/__init__.py | 25 --
.../telegram/handlers/chat_admin/__init__.py | 72 ----
.../telegram/handlers/chat_admin/bans.py | 114 ------
.../telegram/handlers/chat_admin/help.py | 76 ----
.../telegram/handlers/chat_admin/mutes.py | 59 ---
.../telegram/handlers/chat_admin/pins.py | 40 --
.../telegram/handlers/chat_admin/topics.py | 93 -----
.../telegram/handlers/chat_user/__init__.py | 29 --
.../telegram/handlers/chat_user/about.py | 19 -
.../telegram/handlers/chat_user/info.py | 32 --
.../telegram/handlers/chat_user/invite.py | 22 --
.../telegram/handlers/chat_user/welcome.py | 50 ---
.../telegram/handlers/dev/__init__.py | 31 --
.../instances/telegram/handlers/dev/hello.py | 28 --
.../telegram/handlers/dev/image_generation.py | 95 -----
.../telegram/handlers/dev/text_generation.py | 156 --------
.../telegram/handlers/main/__init__.py | 33 --
.../instances/telegram/handlers/main/setup.py | 31 --
.../instances/telegram/handlers/main/start.py | 36 --
.../telegram/handlers/queries/__init__.py | 128 -------
.../telegram/handlers/queries/ban.py | 67 ----
.../telegram/handlers/queries/delete.py | 21 -
.../handlers/queries/image_generation.py | 60 ---
.../telegram/handlers/queries/mute.py | 67 ----
.../telegram/handlers/queries/pins.py | 36 --
.../telegram/handlers/queries/revoke.py | 24 --
.../telegram/handlers/queries/setup.py | 73 ----
.../telegram/handlers/queries/start.py | 168 --------
.../handlers/queries/text_generation.py | 358 ------------------
.../telegram/handlers/queries/threads.py | 41 --
30 files changed, 2084 deletions(-)
delete mode 100644 bozenka/instances/telegram/handlers/__init__.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_admin/__init__.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_admin/bans.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_admin/help.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_admin/mutes.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_admin/pins.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_admin/topics.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_user/__init__.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_user/about.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_user/info.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_user/invite.py
delete mode 100644 bozenka/instances/telegram/handlers/chat_user/welcome.py
delete mode 100644 bozenka/instances/telegram/handlers/dev/__init__.py
delete mode 100644 bozenka/instances/telegram/handlers/dev/hello.py
delete mode 100644 bozenka/instances/telegram/handlers/dev/image_generation.py
delete mode 100644 bozenka/instances/telegram/handlers/dev/text_generation.py
delete mode 100644 bozenka/instances/telegram/handlers/main/__init__.py
delete mode 100644 bozenka/instances/telegram/handlers/main/setup.py
delete mode 100644 bozenka/instances/telegram/handlers/main/start.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/__init__.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/ban.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/delete.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/image_generation.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/mute.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/pins.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/revoke.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/setup.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/start.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/text_generation.py
delete mode 100644 bozenka/instances/telegram/handlers/queries/threads.py
diff --git a/bozenka/instances/telegram/handlers/__init__.py b/bozenka/instances/telegram/handlers/__init__.py
deleted file mode 100644
index 5ff430f..0000000
--- a/bozenka/instances/telegram/handlers/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import logging
-
-from aiogram import Dispatcher
-
-from bozenka.instances.telegram.handlers.chat_admin import register_admin_cmd
-from bozenka.instances.telegram.handlers.queries import register_queries
-from bozenka.instances.telegram.handlers.dev import register_dev_cmd
-from bozenka.instances.telegram.handlers.main import register_main_cmd
-from bozenka.instances.telegram.handlers.chat_user import register_user_cmd
-from bozenka.instances.telegram.utils.middleware import register_middlewares
-
-
-def register_handlers(dp: Dispatcher) -> None:
- """
- Registers all handlers
- :param dp:
- :return:
- """
- logging.log(msg="Starting registering all handlers", level=logging.INFO)
- register_dev_cmd(dp)
- register_user_cmd(dp)
- register_admin_cmd(dp)
- register_main_cmd(dp)
- register_queries(dp)
- register_middlewares(dp)
diff --git a/bozenka/instances/telegram/handlers/chat_admin/__init__.py b/bozenka/instances/telegram/handlers/chat_admin/__init__.py
deleted file mode 100644
index 06a94a9..0000000
--- a/bozenka/instances/telegram/handlers/chat_admin/__init__.py
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-import logging
-
-from aiogram import Router, F
-from aiogram.filters import Command
-
-from bozenka.instances.telegram.handlers.chat_admin.help import *
-from bozenka.instances.telegram.handlers.chat_admin.mutes import mute, unmute
-from bozenka.instances.telegram.handlers.chat_admin.pins import pin, unpin, unpin_all
-from bozenka.instances.telegram.handlers.chat_admin.topics import *
-from bozenka.instances.telegram.handlers.chat_admin.bans import ban_command, unban_command
-from bozenka.instances.telegram.utils.filters import *
-
-
-def register_admin_cmd(router: Router) -> None:
- """
- Registers all commands related to administrators in group.
- All commands there require access to some group perms.
- :param router:
- :return:
- """
- logging.log(msg="Registering administrator commands", level=logging.INFO)
-
- # Ban / Unban commands handler
- router.message.register(ban_command, Command(commands="ban"),
- IsAdminFilter(True), F.reply_to_message.text)
- router.message.register(unban_command, Command(commands="unban"),
- IsAdminFilter(True), F.reply_to_message.text)
-
- # Mute / Unmute commands handler
- router.message.register(mute, Command(commands=["mute", "re"]), UserHasPermissions(["can_restrict_members"]),
- BotHasPermissions(["can_restrict_members"]))
- router.message.register(unmute, Command(commands=["unmute"]), UserHasPermissions(["can_restrict_members"]),
- BotHasPermissions(["can_restrict_members"]))
-
- # Pin / Unpin / Unpinall commands handler
- router.message.register(pin, Command(commands="pin"), UserHasPermissions(["can_pin_messages"]),
- BotHasPermissions(["can_pin_messages"]), F.reply_to_message.text)
- router.message.register(unpin, Command(commands="unpin"), UserHasPermissions(["can_pin_messages"]),
- BotHasPermissions(["can_pin_messages"]), F.reply_to_message.text)
- router.message.register(unpin_all, Command(commands="unpin_all"), IsAdminFilter(True),
- BotHasPermissions(["can_pin_messages"]), F.reply_to_message.text)
-
- # Topic managment handlers
- router.message.register(reopen_topic, Command(commands=["reopen_topic", "open_topic", "open"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum)
- router.message.register(close_topic, Command(commands=["close_topic", "close"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum)
- router.message.register(close_general_topic, Command(commands=["close_general"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum)
- router.message.register(reopen_general_topic, Command(commands=["reopen_general", "open_general"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum)
- router.message.register(hide_general_topic, Command(commands=["hide_general"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum)
- router.message.register(unhide_general_topic, Command(commands=["unhide_general", "show_general"]),
- UserHasPermissions(["can_manage_topics"]),
- BotHasPermissions(["can_manage_topics"]), F.chat.is_forum)
-
- # Helpig handlers
- router.message.register(help_ban, Command(commands=["ban"]))
- router.message.register(help_unban, Command(commands=["unban"]))
- router.message.register(help_mute, Command(commands=["mute"]))
- router.message.register(help_unmute, Command(commands=["mute"]))
- router.message.register(help_pin, Command(commands=["pin"]))
- router.message.register(help_unpin, Command(commands=["unpin"]))
-
diff --git a/bozenka/instances/telegram/handlers/chat_admin/bans.py b/bozenka/instances/telegram/handlers/chat_admin/bans.py
deleted file mode 100644
index fc52bd2..0000000
--- a/bozenka/instances/telegram/handlers/chat_admin/bans.py
+++ /dev/null
@@ -1,114 +0,0 @@
-from aiogram.filters import CommandObject
-from aiogram.types import Message
-from aiogram.enums import ChatMemberStatus
-from sqlalchemy.ext.asyncio import async_sessionmaker
-
-from bozenka.database.tables.telegram import get_chat_config_value
-from bozenka.instances.telegram.utils.keyboards import ban_keyboard, delete_keyboard
-
-from bozenka.instances.telegram.utils.simpler import SolutionSimpler, ru_cmds, list_of_features
-
-
-async def ban_command(msg: Message, command: CommandObject, session_maker: async_sessionmaker) -> None:
- """
- /ban command function, supports time and reasons.
- :param msg: Message telegram object
- :param command: Object of telegram command
- :param session_maker: Session maker object of SqlAlchemy
- :return: Nothing
- """
- banned_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
- send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker, setting=list_of_features["Admin"][4])
- send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker, setting=list_of_features["Admin"][5])
-
- where_send = {
- True: msg.from_user.id,
- False: msg.chat.id
- }
-
- if banned_user.status == ChatMemberStatus.KICKED:
- await msg.bot.send_message(chat_id=where_send[send_to_dm],
- text="Ошибка ❌\n"
- "Этот пользователь уже удален из группы",
- reply_markup=delete_keyboard(msg.from_user.id))
- await msg.answer()
- return
-
- config = await SolutionSimpler.ban_user(msg, command, session_maker)
- if config["reason"] and config["ban_time"]:
- await msg.answer("Удача ✅\n"
- f"Пользователь {msg.reply_to_message.from_user.mention_html()} был заблокирован пользователем {msg.from_user.mention_html()}.\n"
- f"По причине {config['reason']}, до даты {config['ban_time']}",
- reply_markup=ban_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
- elif config["reason"]:
- await msg.answer(
- "Удача ✅\n"
- f"Пользователь {msg.reply_to_message.from_user.mention_html()} был заблокирован пользователем {msg.reply_to_message.from_user.mention_html()}.\n"
- f"По причине {config['reason']}.",
- reply_markup=ban_keyboard(admin_id=msg.from_user.id, ban_id=msg.reply_to_message.from_user.id)
- )
- elif config["ban_time"]:
- await msg.answer(
- "Удача ✅\n"
- f"Пользователь {msg.reply_to_message.from_user.mention_html()} был заблокирован пользователем {msg.from_user.mention_html()}, до даты {config['ban_time']}",
- reply_markup=ban_keyboard(admin_id=msg.from_user.id, ban_id=msg.reply_to_message.from_user.id)
- )
- else:
- await msg.answer(
- "Удача ✅\n"
- f"Пользователь {msg.reply_to_message.from_user.mention_html()} был заблокирован пользователем {msg.from_user.mention_html()}.",
- reply_markup=ban_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id)
- )
-
-
-async def unban_command(msg: Message, command: CommandObject, session_maker: async_sessionmaker) -> None:
- """
- /unban command function
- :param msg: Message telegram object
- :param command: Object of telegram command
- :param session_maker: Session maker object of SqlAlchemy
- """
- await SolutionSimpler.unban_user(msg, session_maker)
- unbanned_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
- if unbanned_user.is_member and unbanned_user.status != ChatMemberStatus.KICKED:
- await msg.answer(
- "Ошибка ❌\n"
- "Этот пользователь не находится в бане.",
- reply_markup=delete_keyboard(admin_id=msg.from_user.id)
- )
- elif not command.text:
- await msg.answer(
- "Удача ✅\n"
- f"Пользователь {msg.reply_to_message.from_user.mention_html()} был разблокирован пользователем {msg.from_user.mention_html()}.\n",
- reply_markup=ban_keyboard(admin_id=msg.from_user.id, ban_id=msg.reply_to_message.from_user.id)
- )
- else:
- await msg.answer(
- "Удача ✅\n"
- f"Пользователь {msg.reply_to_message.from_user.mention_html()} был разблокирован пользователем {msg.from_user.mention_html()}.\n"
- f"По причине {CommandObject.text}.",
- reply_markup=ban_keyboard(admin_id=msg.from_user.id, ban_id=msg.reply_to_message.from_user.id)
- )
-
-
-async def status_command(msg: Message, session_maker: async_sessionmaker) -> None:
- """
- /status command function
- Checks is user banned and muted
- :param msg: Message telegram object
- :param session_maker: Session maker object of SqlAlchemy
- :return:
- """
- config = await SolutionSimpler.get_status(msg, session_maker)
- msg_text = ""
- if config["is_banned"]:
- msg_text += "Находится в бане"
- if config["ban_reason"]:
- msg_text += f"по причине {config['ban_reason']}
"
- msg_text += "🔨\n"
- if config["is_muted"]:
- msg_text += "Находится в муте"
- if config["mute_reason"]:
- msg_text += f"по причине {config['mute_reason']}
"
- msg_text += "🤐\n"
- await msg.answer(msg_text, reply_markup=delete_keyboard(msg.from_user.id))
diff --git a/bozenka/instances/telegram/handlers/chat_admin/help.py b/bozenka/instances/telegram/handlers/chat_admin/help.py
deleted file mode 100644
index f2ed75b..0000000
--- a/bozenka/instances/telegram/handlers/chat_admin/help.py
+++ /dev/null
@@ -1,76 +0,0 @@
-from aiogram.types import Message
-
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
-
-
-async def help_ban(msg: Message) -> None:
- """
- Shows help message for /ban
- :param msg: Message telegram object
- :return: Nothing
- """
- await msg.answer("Использование:\n"
- "/ban [время блокировки] [причина блокировки]
\n"
- "Ответьте на сообщение, чтобы заблокировать пользователя",
- reply_markup=delete_keyboard(msg.from_user.id))
-
-
-async def help_unban(msg: Message) -> None:
- """
- Shows help message for /unban
- :param msg: Message telegram object
- :return: Nothing
- """
- await msg.answer("Использование:\n"
- "/unban
\n"
- "Ответьте на сообщение, чтобы разблокировать пользователя",
- reply_markup=delete_keyboard(msg.from_user.id))
-
-
-async def help_mute(msg: Message) -> None:
- """
- Shows help message for /mute
- :param msg: Message telegram object
- :return: Nothing
- """
- await msg.answer("Использование:\n"
- "/mute [время мута] [причина мута]
\n"
- "Ответьте на сообщение, чтобы замутить пользователя",
- reply_markup=delete_keyboard(msg.from_user.id))
-
-
-async def help_unmute(msg: Message) -> None:
- """
- Shows help message for /unmute
- :param msg: Message telegram object
- :return: Nothing
- """
- await msg.answer("Использование:\n"
- "/unmute
\n"
- "Ответьте на сообщение, чтобы замутить пользователя",
- reply_markup=delete_keyboard(msg.from_user.id))
-
-
-async def help_pin(msg: Message) -> None:
- """
- Shows help message for /mute
- :param msg: Message telegram object
- :return: Nothing
- """
- await msg.answer("Использование:\n"
- "/pin
\n"
- "Ответьте на сообщение, чтобы закрепить сообщение",
- reply_markup=delete_keyboard(msg.from_user.id))
-
-
-async def help_unpin(msg: Message) -> None:
- """
- Shows help message for /mute
- :param msg: Message telegram object
- :return: Nothing
- """
- await msg.answer("Использование:\n"
- "/unpin
\n"
- "Ответьте на сообщение, чтобы открепить сообщение",
- reply_markup=delete_keyboard(msg.from_user.id))
-
diff --git a/bozenka/instances/telegram/handlers/chat_admin/mutes.py b/bozenka/instances/telegram/handlers/chat_admin/mutes.py
deleted file mode 100644
index 1981cb2..0000000
--- a/bozenka/instances/telegram/handlers/chat_admin/mutes.py
+++ /dev/null
@@ -1,59 +0,0 @@
-from aiogram.filters import CommandObject
-from aiogram.types import Message as Message
-from aiogram.enums import ChatMemberStatus
-from sqlalchemy.ext.asyncio import async_sessionmaker
-from bozenka.instances.telegram.utils.keyboards import mute_keyboard, unmute_keyboard
-from bozenka.instances.telegram.utils.simpler import SolutionSimpler
-
-
-async def mute(msg: Message, command: CommandObject, session_maker: async_sessionmaker) -> None:
- """
- Handler of command /mute
- Restricts member from using chat
- :param msg: Message telegram object
- :param command: Object of telegram command
- :param session_maker: Session maker object of SqlAlchemy
- :return: Nothing
- """
- restricting = await msg.chat.get_member(msg.reply_to_message.from_user.id)
- if restricting.status == ChatMemberStatus.LEFT or restricting.status == ChatMemberStatus.KICKED:
- return
- config = await SolutionSimpler.mute_user(msg, command, session_maker)
- if config["mute_time"] and config["reason"] != "":
- await msg.answer("Удача ✅\n"
- f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
- f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n"
- f"По причине {config['reason']}, до даты {config['mute_time']}",
- reply_markup=mute_keyboard(msg.from_user.id, restricting.user.id))
- elif config["reason"] != "":
- await msg.answer("Удача ✅\n"
- f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
- f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n"
- f"По причине {config['reason']}",
- reply_markup=mute_keyboard(msg.from_user.id, restricting.user.id))
- elif config["mute_time"]:
- await msg.answer("Удача ✅\n"
- f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
- f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n"
- f"До даты {config['mute_time']}",
- reply_markup=mute_keyboard(msg.from_user.id, restricting.user.id))
- else:
- await msg.answer("Удача ✅\n"
- f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
- f"сообщения пользователю {msg.reply_to_message.from_user.mention_html()}.\n",
- reply_markup=mute_keyboard(msg.from_user.id, restricting.user.id))
-
-
-async def unmute(msg: Message, session_maker: async_sessionmaker) -> None:
- """
- Handler of command /unmute
- Gives access member to send messages into chat
- :param msg: Message telegram object
- :param session_maker: Session maker object of SqlAlchemy
- :return: Nothing
- """
- await SolutionSimpler.unmute_user(msg, session_maker)
- await msg.answer("Удача ✅"
- f"{msg.from_user.mention_html('Этот пользователь')} разрешил писать\n"
- f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}",
- reply_markup=unmute_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
diff --git a/bozenka/instances/telegram/handlers/chat_admin/pins.py b/bozenka/instances/telegram/handlers/chat_admin/pins.py
deleted file mode 100644
index 5ae4d0c..0000000
--- a/bozenka/instances/telegram/handlers/chat_admin/pins.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from aiogram.types import Message as Message
-from bozenka.instances.telegram.utils.keyboards import unpin_msg_keyboard, pin_msg_keyboard, delete_keyboard
-from bozenka.instances.telegram.utils.simpler import SolutionSimpler
-
-
-async def pin(msg: Message) -> None:
- """
- /pin command function, pins replied command
- :param msg: Message telegram object
- :return: Nothing
- """
- await SolutionSimpler.pin_msg(msg)
- await msg.answer("Удача ✅\n"
- "Сообщение было закреплено 📌",
- reply_markup=pin_msg_keyboard(msg_id=msg.reply_to_message.message_id, user_id=msg.from_user.id))
-
-
-async def unpin(msg: Message) -> None:
- """
- /unpin command function, unpins replied command
- :param msg: Message telegram object
- :return: Nothing
- """
- await SolutionSimpler.unpin_msg(msg)
- await msg.answer("Удача ✅\n"
- "Сообщение было откреплено 📌",
- reply_markup=unpin_msg_keyboard(msg_id=msg.reply_to_message.message_id, user_id=msg.from_user.id))
-
-
-async def unpin_all(msg: Message) -> None:
- """
- /unpin_all command function, unpins all messages in chat
- :param msg: Message telegram object
- :return: Nothing
- """
- await SolutionSimpler.unpin_all_messages(msg)
- await msg.answer("Удача ✅\n"
- "Все сообщения были откреплены 📌",
- reply_markup=delete_keyboard(admin_id=msg.from_user.id))
-
diff --git a/bozenka/instances/telegram/handlers/chat_admin/topics.py b/bozenka/instances/telegram/handlers/chat_admin/topics.py
deleted file mode 100644
index f211ba9..0000000
--- a/bozenka/instances/telegram/handlers/chat_admin/topics.py
+++ /dev/null
@@ -1,93 +0,0 @@
-from aiogram import Bot
-from aiogram.filters import CommandObject
-from aiogram.types import Message as Message
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard, close_thread_keyboard, open_thread_keyboard
-from bozenka.instances.telegram.utils.simpler import SolutionSimpler
-
-
-async def close_topic(msg: Message, bot: Bot) -> None:
- """
- /close command function. Closing thread
- :param msg: Message telegram object
- :param bot: Object of telegram bot
- :return: Nothing
- """
- config = await SolutionSimpler.close_topic(msg=msg)
- await msg.answer(config[0],
- reply_markup=close_thread_keyboard(user_id=msg.from_user.id)
- if config[1] else delete_keyboard(msg.from_user.id))
-
-
-async def reopen_topic(msg: Message, bot: Bot) -> None:
- """
- /open command function. Opens thread
- :param msg: Message telegram object
- :param bot: Object of telegram bot
- :return: Nothing
- """
- config = await SolutionSimpler.open_topic(msg=msg)
- await msg.answer(config[0],
- reply_markup=open_thread_keyboard(user_id=msg.from_user.id)
- if config[1] else delete_keyboard(msg.from_user.id))
-
-
-async def close_general_topic(msg: Message, bot: Bot) -> None:
- """
- /close_general command function. Closes general thread
- :param msg: Message telegram object
- :param bot: Object of telegram bot
- :return: Nothing
- """
- config = await SolutionSimpler.close_general_topic(msg=msg)
- await msg.answer(config[0],
- reply_markup=close_thread_keyboard(user_id=msg.from_user.id)
- if config[1] else delete_keyboard(msg.from_user.id))
-
-
-async def reopen_general_topic(msg: Message, bot: Bot) -> None:
- """
- /open_general command function. Opens general thread
- :param msg: Message telegram object
- :param bot: Object of telegram bot
- :return: Nothing
- """
- config = await SolutionSimpler.open_general_topic(msg=msg)
- await msg.answer(config[0],
- reply_markup=open_thread_keyboard(user_id=msg.from_user.id)
- if config[1] else delete_keyboard(msg.from_user.id))
-
-
-async def hide_general_topic(msg: Message, bot: Bot) -> None:
- """
- /hide_general command function. Hides general thread
- :param msg: Message telegram object
- :param bot: Object of telegram bot
- :return: Nothing
- """
- config = await SolutionSimpler.hide_general_topic(msg=msg)
- await msg.answer(config[0],
- reply_markup=delete_keyboard(msg.from_user.id))
-
-
-async def unhide_general_topic(msg: Message, bot: Bot) -> None:
- """
- /show_general command function. Shows back general thread.
- :param msg: Message telegram object
- :param bot: Object of telegram bot
- :return: Nothing
- """
- config = await SolutionSimpler.show_general_topic(msg=msg)
- await msg.answer(config[0],
- reply_markup=delete_keyboard(msg.from_user.id))
-
-
-async def rename_topic(msg: Message, bot: Bot, command: CommandObject) -> None:
- """
- /rename command function. Rename thread to a new name
- :param msg: Message telegram object
- :param bot: Object of telegram bot
- :param command: Object of telegram command
- :return: Nothing
- """
- await msg.general_forum_topic_unhidden
- await bot.edit_forum_topic(name=command.text, chat_id=msg.chat.id, message_thread_id=msg.message_thread_id)
diff --git a/bozenka/instances/telegram/handlers/chat_user/__init__.py b/bozenka/instances/telegram/handlers/chat_user/__init__.py
deleted file mode 100644
index 35e6c06..0000000
--- a/bozenka/instances/telegram/handlers/chat_user/__init__.py
+++ /dev/null
@@ -1,29 +0,0 @@
-
-import logging
-
-from aiogram.enums import ContentType
-from aiogram.filters import Command
-from aiogram import Router, F
-
-from bozenka.instances.telegram.handlers.chat_user.about import about
-from bozenka.instances.telegram.handlers.chat_user.invite import invite
-from bozenka.instances.telegram.handlers.chat_user.info import chat_info
-from bozenka.instances.telegram.handlers.chat_user.welcome import *
-
-
-def register_user_cmd(router: Router) -> None:
- """
- Registers all commands related to users, and can be used by them.
- Some of them require access to some perms for bot.
- :param router:
- :return:
- """
- logging.log(msg="Registering user commands", level=logging.INFO)
-
- router.message.register(invite, Command(commands=["invite"]))
- router.message.register(about, Command(commands=["about"]))
-
- router.message.register(leave, F.content_type == ContentType.LEFT_CHAT_MEMBER)
- router.message.register(join, F.content_type == ContentType.NEW_CHAT_MEMBERS)
-
- router.message.register(chat_info, Command(commands=["info"]))
diff --git a/bozenka/instances/telegram/handlers/chat_user/about.py b/bozenka/instances/telegram/handlers/chat_user/about.py
deleted file mode 100644
index e6f7b06..0000000
--- a/bozenka/instances/telegram/handlers/chat_user/about.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import logging
-
-from aiogram.types import Message as Message
-from bozenka.instances.telegram.utils.keyboards import about_keyboard
-
-
-async def about(msg: Message):
- """
- Sending information about bot by command `/about`
- Will be deleted by its use
- :param msg:
- :return:
- """
- logging.log(msg=f"Sending about information for user_id={msg.from_user.id}",
- level=logging.INFO)
- await msg.answer("Кто я? 👁"
- "\nЯ - многозадачный бот, разрабатываемый Bozo Developement и всё ещё нахожусь в разработке"
- "\n(Ссылочки на нас внизу короче)☺️",
- reply_markup=about_keyboard.as_markup())
diff --git a/bozenka/instances/telegram/handlers/chat_user/info.py b/bozenka/instances/telegram/handlers/chat_user/info.py
deleted file mode 100644
index 90854f1..0000000
--- a/bozenka/instances/telegram/handlers/chat_user/info.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import logging
-
-from aiogram.types import Message
-from bozenka.instances.telegram.utils.simpler import ru_cmds
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
-
-
-async def chat_info(msg: Message):
- """
- Shows information about chat by command `/info`
- :param msg:
- :return:
- """
- logging.log(msg=f"Sending information about chat user_id={msg.from_user.id}",
- level=logging.INFO)
- chat = await msg.bot.get_chat(msg.chat.id)
- # Related texts
- texts = {
- "chat_types": {"group": "группой", "supergroup": "cупер группой"},
- "forum_type": {True: "форумом,", False: ", не является форумом,", None: ", не является форумом,"},
- "required_invite": {True: "требуется одобрение заявки на вступление", False: "заявка не требуется.",
- None: "заявка не требуется."},
- "hidden_members": {True: "присуствуют", False: "отсуствуют", None: "отсуствуют"},
- "isprotected": {True: "пересылать сообщения из группы можно.", False: "пересылать сообщения из группы нельзя.",
- None: "пересылать сообщения из группы можно."},
- }
-
- await msg.answer(f"{chat.title}\n"
- f"{chat.description}\n\n"
- f"Является {texts['chat_types'][chat.type]} {texts['forum_type'][chat.is_forum]} {texts['required_invite'][chat.join_by_request]}\n"
- f"Скрытые пользователи {texts['hidden_members'][chat.has_hidden_members]}, {texts['isprotected'][chat.has_protected_content]}",
- reply_markup=delete_keyboard(admin_id=msg.from_user.id))
\ No newline at end of file
diff --git a/bozenka/instances/telegram/handlers/chat_user/invite.py b/bozenka/instances/telegram/handlers/chat_user/invite.py
deleted file mode 100644
index fce300d..0000000
--- a/bozenka/instances/telegram/handlers/chat_user/invite.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import logging
-
-from aiogram.types import Message
-from bozenka.instances.telegram.utils.keyboards import invite_keyboard
-from bozenka.instances.telegram.utils.simpler import ru_cmds
-
-
-async def invite(msg: Message):
- """
- Generating invite to group by /invite command
- :param msg:
- :return:
- """
- logging.log(msg=f"Generating invite for user_id={msg.from_user.id}",
- level=logging.INFO)
- link = await msg.chat.create_invite_link()
- print(link.invite_link[0])
- await msg.answer(
- ru_cmds["invite_generation"].replace("user", msg.from_user.mention_html(ru_cmds["sir"])),
- reply_markup=invite_keyboard(link=str(link.invite_link), admin_id=msg.from_user.id, chat_name=msg.chat.full_name)
- )
-
diff --git a/bozenka/instances/telegram/handlers/chat_user/welcome.py b/bozenka/instances/telegram/handlers/chat_user/welcome.py
deleted file mode 100644
index 66bd64e..0000000
--- a/bozenka/instances/telegram/handlers/chat_user/welcome.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import logging
-
-from aiogram import Bot
-from aiogram.types import Message as Message
-from sqlalchemy.ext.asyncio import async_sessionmaker
-
-from bozenka.instances.telegram.utils.simpler import SolutionSimpler
-
-
-async def join(msg: Message, session_maker: async_sessionmaker):
- """
- Send welcome message, after adding new member to chat.
- Also works on adding bot to chat and sending welcome message.
- :param msg:
- :param session_maker:
- :return:
- """
- for new in msg.new_chat_members:
- if new.id != msg.bot.id:
- logging.log(msg=f"Saing welcome for user_id={new.id}, chat_id={msg.chat.id}",
- level=logging.INFO)
- await msg.answer(
- f"Пользователь {new.mention_html()} переехал в конфу, благодаря {msg.from_user.mention_html()}👋",
- )
- await msg.delete()
- else:
- logging.log(msg=f"Saing welcome to administrators for chat_id={msg.chat.id}",
- level=logging.INFO)
- await msg.answer("Здраствуйте администраторы чата 👋\n"
- "Я - бозенька, мультифункциональный бот, разрабатываемый Bozo Developement\n"
- "Выдайте мне полные права администратора для моей полной работы.\n"
- "Чтобы настроить функционал, используйте /setup или кнопку под сообщением", )
- await SolutionSimpler.auto_settings(msg=msg, session=session_maker)
-
-
-async def leave(msg: Message, bot: Bot):
- """
- Sens goodbye message, after deleting member from chat
- :param msg:
- :param bot:
- :return:
- """
- await msg.delete()
- if msg.from_user.id == bot.id:
- return
- logging.log(msg=f"Saing goodbye for user_id={msg.left_chat_member.id}, chat_id={msg.chat.id}",
- level=logging.INFO)
- await msg.answer(
- f"Пользователь {msg.left_chat_member.mention_html()} съехал с конфы, благодаря {msg.from_user.mention_html()}👋"
- )
diff --git a/bozenka/instances/telegram/handlers/dev/__init__.py b/bozenka/instances/telegram/handlers/dev/__init__.py
deleted file mode 100644
index 3db5fd7..0000000
--- a/bozenka/instances/telegram/handlers/dev/__init__.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import logging
-
-from aiogram.filters import Command
-
-from bozenka.instances.telegram.handlers.dev.hello import hi, testing
-from bozenka.instances.telegram.handlers.dev.text_generation import *
-from bozenka.instances.telegram.handlers.dev.image_generation import *
-
-from bozenka.instances.telegram.utils.simpler import AnsweringGPT4Free, AnsweringGpt4All, GeneratingImages
-from aiogram import Router
-
-
-def register_dev_cmd(router: Router) -> None:
- """
- Registering testing commands in development or planned in future and need much time to realise it.
- Don't need any special perms in group.
- :param router:
- :return:
- """
- logging.log(msg="Registering developer commands", level=logging.INFO)
- router.message.register(hi, Command(commands=["hi", "welcome", "sup", "wassup", "hello", "priv",
- "privet", "хай", "прив", "привет", "ку"]))
- router.message.register(start_dialog_cmd, Command(commands=["conversation"]))
- router.message.register(g4f_generate_answer, AnsweringGPT4Free.ready_to_answer, ~Command(commands=["cancel"]))
- router.message.register(already_answering, AnsweringGpt4All.answering, ~Command(commands=["cancel"]))
- router.message.register(already_answering, AnsweringGPT4Free.answering, ~Command(commands=["cancel"]))
- router.message.register(g4a_generate_answer, AnsweringGpt4All.ready_to_answer, ~Command(commands=["cancel"]))
- router.message.register(kadinsky_generating_images, GeneratingImages.ready_to_generate, ~Command(commands=["cancel"]))
- router.message.register(start_imagine_cmd, Command(commands=["imagine"]))
- router.message.register(cancel_answering, Command(commands=["cancel"]))
- router.message.register(testing, Command(commands=["testingtest"]))
diff --git a/bozenka/instances/telegram/handlers/dev/hello.py b/bozenka/instances/telegram/handlers/dev/hello.py
deleted file mode 100644
index c43638b..0000000
--- a/bozenka/instances/telegram/handlers/dev/hello.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from aiogram import Bot
-from aiogram.filters import CommandObject
-from aiogram.types import Message as Message, User, Chat
-from sqlalchemy.ext.asyncio import async_sessionmaker
-
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
-
-
-async def hi(msg: Message):
- """
- Test command, sending welcome message.
- Made for testing bot working status.
- :param msg:
- :return:
- """
- await msg.answer(
- f"Привет, {msg.from_user.mention_html('')} 👋",
- reply_markup=delete_keyboard(msg.from_user.id)
- )
-
-
-async def testing(msg: Message, session_maker: async_sessionmaker, command: CommandObject, user: User, target: User, chat: Chat, bot: Bot):
- print(user.full_name)
- print(target.full_name)
- print(msg)
- print(command.args)
- print(command.mention)
- print(command.command)
diff --git a/bozenka/instances/telegram/handlers/dev/image_generation.py b/bozenka/instances/telegram/handlers/dev/image_generation.py
deleted file mode 100644
index 9359bfe..0000000
--- a/bozenka/instances/telegram/handlers/dev/image_generation.py
+++ /dev/null
@@ -1,95 +0,0 @@
-import logging
-
-from aiogram.fsm.context import FSMContext
-from aiogram.types import Message as Message, FSInputFile
-
-from bozenka.generative.kadinsky import kadinsky_gen
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard, image_generation_keyboard, \
- image_response_keyboard
-from bozenka.instances.telegram.utils.simpler import GeneratingImages
-
-
-async def already_generating(msg: Message, state: FSMContext):
- """
- Giving response, if generating image for user right now,
- but user still asks something
- :param msg: Message telegram object
- :param state: FSM state of bot
- :return:
- """
- await msg.answer(
- "Подождите пожалуйста, мы уже генерируем изображение для вас, подождите, когда мы ответим на ваш передыдущий вопрос",
- reply_markup=delete_keyboard(admin_id=msg.from_user.id))
-
-
-async def start_imagine_cmd(msg: Message, state: FSMContext):
- """
- /iamgine command handler, start menu
- :param msg: Message telegram object
- :param state: FSM state of bot
- :return:
- """
- if await state.get_state():
- return
- await msg.answer("Пожалуста, выберите сервис / модель для генерации изображений",
- reply_markup=image_generation_keyboard(user_id=msg.from_user.id))
-
-
-async def kadinsky_generating_images(msg: Message, state: FSMContext):
- """
- Message handler for kandinsky to generate image by text from message
- :param msg: Message telegram object
- :param state: FSM state of bot
- :return:
- """
- await state.set_state(GeneratingImages.generating)
- message = await msg.answer("Пожалуйста подождите, мы генерируем изображение ⏰\n"
- "Если что-то пойдет не так, мы вам сообщим 👌")
- data = await state.get_data()
-
- try:
-
- model_id = kadinsky_gen.get_model()
- width, height = data["set_size"].split("x")
- generating = kadinsky_gen.generate(model=model_id,
- prompt=msg.text,
- width=int(width),
- height=int(height))
- result = kadinsky_gen.check_generation(request_id=generating)
-
- if result:
- path = kadinsky_gen.save_image(result[0], f"telegram_{msg.from_user.id}")
- photo = FSInputFile(path)
- await msg.answer_photo(photo=photo,
- caption=msg.text,
- reply_markup=image_response_keyboard(user_id=msg.from_user.id))
- await message.delete()
- else:
- await message.edit_text("Простите, произошла ошибка 😔\n"
- "Убедитесь, что севрера kadinsky работают и ваш промт не является неподобающим и неприемлимым\n"
- "Если это продолжается, пожалуйста используйте /cancel",
- reply_markup=image_response_keyboard(user_id=msg.from_user.id))
-
- except Exception as ex:
- logging.log(msg=f"Get an exception for generating answer={ex}",
- level=logging.ERROR)
- finally:
- logging.log(msg=f"Generated image for user_id={msg.from_user.id} with promt",
- level=logging.INFO)
- await state.set_state(GeneratingImages.ready_to_generate)
-
-
-async def cancefl_answering(msg: Message, state: FSMContext):
- """
- Canceling generating images for user
- Works on command /cancel
- :param msg: Message telegram object
- :param state: FSM state of bot
- :return:
- """
- current = await state.get_state()
- if current is None:
- return
- await state.clear()
- await msg.answer("Удача ✅\n"
- "Диалог отменён!", reply_markup=delete_keyboard(admin_id=msg.from_user.id))
diff --git a/bozenka/instances/telegram/handlers/dev/text_generation.py b/bozenka/instances/telegram/handlers/dev/text_generation.py
deleted file mode 100644
index 738aaaa..0000000
--- a/bozenka/instances/telegram/handlers/dev/text_generation.py
+++ /dev/null
@@ -1,156 +0,0 @@
-import logging
-import os.path
-
-import g4f
-from gpt4all import GPT4All
-from aiogram.fsm.context import FSMContext
-from aiogram.types import Message as Message
-
-from bozenka.generative.gpt4all import check, model_path
-from bozenka.instances.telegram.utils.keyboards import gpt_categories_keyboard, delete_keyboard, text_response_keyboard
-from bozenka.instances.telegram.utils.simpler import AnsweringGpt4All, \
- AnsweringGPT4Free
-from bozenka.generative.gpt4free import generate_gpt4free_providers
-
-
-async def already_answering(msg: Message, state: FSMContext):
- """
- Giving response, if answering user now,
- but he still asks something
- :param msg: Message telegram object
- :param state: FSM state of bot
- :return:
- """
- await msg.answer("Подождите пожалуйста, мы уже генерируем ответ для вас, подождите, когда мы ответим на ваш передыдущий вопрос",
- reply_markup=delete_keyboard(admin_id=msg.from_user.id))
-
-
-async def start_dialog_cmd(msg: Message, state: FSMContext):
- """
- /conversation command handler, start
- :param msg: Message telegram object
- :param state: FSM state of bot
- :return:
- """
- if await state.get_state():
- return
- await msg.answer("Пожалуста, выберите сервис для ИИ.",
- reply_markup=gpt_categories_keyboard
- (user_id=msg.from_user.id))
-
-
-async def cancel_answering(msg: Message, state: FSMContext):
- """
- Canceling dialog with generative model
- Works on command /cancel
- :param msg: Message telegram object
- :param state: FSM state of bot
- :return:
- """
- current = await state.get_state()
- if current is None:
- return
- await state.clear()
- await msg.answer("Удача ✅\n"
- "Диалог отменён!", reply_markup=delete_keyboard(admin_id=msg.from_user.id))
-
-
-async def g4a_generate_answer(msg: Message, state: FSMContext):
- """
- Generating answer if Gpt4All has been selected
- :param msg: Message telegram object
- :param state: FSM state of bot
- :return:
- """
- await state.set_state(AnsweringGpt4All.answering)
-
- models = GPT4All.list_models()
- info = await state.get_data()
- answer = ""
-
- main_msg = await msg.answer("Пожалуйста подождите, мы генерируем вам ответ ⏰\n"
- "Если что-то пойдет не так, мы вам сообщим 👌",
- reply_markup=text_response_keyboard(user_id=msg.from_user.id))
-
- if not check(models[info["set_model"]]["filename"]):
- main_msg = await main_msg.edit_text(main_msg.text + "\nПодождите пожалуста, мы скачиваем модель...",
- reply_markup=main_msg.reply_markup)
-
- try:
- # Setting Gpt4All model
- model = GPT4All(model_name=models[info['set_model']]['filename'],
- model_path=model_path,
- allow_download=True)
- # Setting our chat session if exist
- model.current_chat_session = [] if not info.get("ready_to_answer") else info["ready_to_answer"]
- # Generating answer
- with model.chat_session():
- answer = model.generate(msg.text)
- await state.update_data(ready_to_answer=model.current_chat_session)
-
- except Exception as S:
- answer = "Простите, произошла ошибка 😔\nЕсли это продолжается, пожалуйста используйте /cancel"
- logging.log(msg=f"Get an exception for generating answer={S}",
- level=logging.ERROR)
- finally:
- await main_msg.edit_text(answer, reply_markup=text_response_keyboard(user_id=msg.from_user.id))
-
- await state.set_state(AnsweringGpt4All.ready_to_answer)
-
-
-async def g4f_generate_answer(msg: Message, state: FSMContext):
- """
- Generating answer if GPT4Free model and provider has been selected
- :param msg: Message telegram object
- :param state: FSM state of bot
- :return:
- """
- await state.set_state(AnsweringGPT4Free.answering)
-
- info = await state.get_data()
-
- providers = generate_gpt4free_providers()
- reply = await msg.reply("Пожалуйста подождите, мы генерируем ответ от провайдера ⏰\n"
- "Если что-то пойдет не так, мы вам сообщим 👌")
-
- current_messages = []
- if info.get("ready_to_answer"):
- for message in info["ready_to_answer"]:
- current_messages.append(message)
-
- if not info.get("set_provider"):
- info["set_provider"] = None
-
- current_messages.append({"role": "user", "content": msg.text})
-
- response = ""
- try:
- response = await g4f.ChatCompletion.create_async(
- model=info["set_model"],
- messages=current_messages,
- provider=None if info["set_provider"] is None else providers[info["set_provider"]],
- stream=False
- )
-
- except NameError or SyntaxError:
- try:
- response = g4f.ChatCompletion.create(
- model=info["set_model"],
- messages=current_messages,
- provider=None if info["set_provider"] is None else providers[info["set_provider"]],
- stream=False
- )
- except Exception as S:
- response = "Простите, произошла ошибка 😔\nЕсли это продолжается, пожалуйста используйте /cancel"
- logging.log(msg=f"Get an exception for generating answer={S}",
- level=logging.ERROR)
- except Exception as S:
- response = "Простите, произошла ошибка 😔\nЕсли это продолжается, пожалуйста используйте /cancel"
- logging.log(msg=f"Get an exception for generating answer={S}",
- level=logging.ERROR)
- finally:
- await reply.edit_text(text=response, reply_markup=text_response_keyboard(user_id=msg.from_user.id))
- current_messages.append({"role": "assistant", "content": response})
- await state.update_data(ready_to_answer=current_messages)
- await state.set_state(AnsweringGPT4Free.ready_to_answer)
-
diff --git a/bozenka/instances/telegram/handlers/main/__init__.py b/bozenka/instances/telegram/handlers/main/__init__.py
deleted file mode 100644
index 43f3947..0000000
--- a/bozenka/instances/telegram/handlers/main/__init__.py
+++ /dev/null
@@ -1,33 +0,0 @@
-
-import logging
-
-from aiogram import Router, F
-from aiogram.enums import ContentType
-from aiogram.filters import Command, CommandStart
-
-from bozenka.instances.telegram.handlers.main.setup import *
-from bozenka.instances.telegram.handlers.main.start import *
-
-
-def register_main_cmd(router: Router) -> None:
- """
- Registers all commands related to basic commands or main commands in bot.
- Don't require any special perms for bot in group.
- :param router:
- :return:
- """
- logging.log(msg="Registering main related commands", level=logging.INFO)
-
- # Start command handler
- """
- router.message.register(start_cmd, Command(commands=["start"]), F.chat.type == ChatType.PRIVATE)
- """
-
- router.message.register(start_cmd, *[Command(commands=["start"]), F.chat.type == ChatType.PRIVATE])
-
- # Registering command /setup
- router.message.register(setup_cmd, Command(commands=["setup"]), ~(F.chat.type == ChatType.PRIVATE))
-
- # After adding to chat handler
- router.message.register(group_adding_handler, F.content_type == ContentType.SUPERGROUP_CHAT_CREATED)
- router.message.register(group_adding_handler, F.content_type == ContentType.GROUP_CHAT_CREATED)
diff --git a/bozenka/instances/telegram/handlers/main/setup.py b/bozenka/instances/telegram/handlers/main/setup.py
deleted file mode 100644
index 10881b5..0000000
--- a/bozenka/instances/telegram/handlers/main/setup.py
+++ /dev/null
@@ -1,31 +0,0 @@
-from aiogram.types import Message as Message
-from sqlalchemy.ext.asyncio import async_sessionmaker
-
-from bozenka.instances.telegram.utils.simpler import SolutionSimpler
-from bozenka.instances.telegram.utils.keyboards import setup_keyboard
-
-
-async def setup_cmd(msg: Message):
- """
- /setup handler
- :param msg:
- :param session:
- :return:
- """
- await msg.answer("Привет владелец чата 👋\n"
- "Чтобы меня настроить, используй меню под данным сообщением",
- reply_markup=setup_keyboard())
-
-
-async def group_adding_handler(msg: Message, session_maker: async_sessionmaker):
- """
- Send message after adding bozenka into group chat
- :param msg:
- :param session_maker:
- :return:
- """
- await SolutionSimpler.auto_settings(msg=msg, session=session_maker)
- await msg.answer("Здраствуйте администраторы чата 👋\n"
- "Я - бозенька, мультифункциональный бот, разрабатываемый Bozo Developement\n"
- "Выдайте мне полные права администратора для моей полной работы, если не выдали."
- "Чтобы настроить функционал, используйте /setup или кнопку под сообщением")
diff --git a/bozenka/instances/telegram/handlers/main/start.py b/bozenka/instances/telegram/handlers/main/start.py
deleted file mode 100644
index 4462a1c..0000000
--- a/bozenka/instances/telegram/handlers/main/start.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from aiogram.enums import ChatType
-from aiogram.types import Message as Message
-from aiogram.utils.keyboard import InlineKeyboardBuilder
-
-from bozenka.instances.telegram.utils.keyboards import help_keyboard, start_keyboard
-
-
-async def start_cmd(msg: Message) -> None:
- """
- /start command function handler
- Shows menu and basic information about bozenka
- :param msg: Message telegram object
- :return: Nothing
- """
- await msg.answer(
- """
- Привет 👋
-Я - бозенька, бот с открытым исходным кодом, который поможет тебе в различных задачах.
-
-Вот что ты можешь сделать с помощью меню:
-• Добавить в чат: добавляет меня в групповой чат, чтобы я мог выполнять свои функции внутри него.
-• Функционал: показывает список доступных функций и команд, которые я могу выполнить.
-• О разработчиках: предоставляет информацию о команде разработчиков, которые создали и поддерживают этого бота.
-• О запущенном экземпляре: выводит информацию о текущей версии и состоянии запущенного экземпляра бота.
-• Начать диалог с ИИ: позволяет начать диалог с искусственным интеллектом, который может отвечать на вопросы и предоставлять информацию.
-• Генерация изображений: позволяет сгенерировать изображения на основе заданных параметров и промта
-
-Вот нужные ссылки обо мне:
-• Канал с новостями об разработке
-• Исходный код на Github
-
-Чтобы воспользоваться какой-либо функцией, просто нажми на соответствующую кнопку ниже.
-Если у тебя возникнут вопросы или проблемы, не стесняйся обратиться к команде разработчиков или написать в обсуждении телеграм канала.
-Удачного использования!
- """,
- reply_markup=start_keyboard(), disable_web_page_preview=True)
diff --git a/bozenka/instances/telegram/handlers/queries/__init__.py b/bozenka/instances/telegram/handlers/queries/__init__.py
deleted file mode 100644
index ee5323b..0000000
--- a/bozenka/instances/telegram/handlers/queries/__init__.py
+++ /dev/null
@@ -1,128 +0,0 @@
-from aiogram import Router, F
-
-from bozenka.instances.telegram.handlers.queries.image_generation import inline_image_size, inline_image_ready
-from bozenka.instances.telegram.handlers.queries.mute import *
-from bozenka.instances.telegram.handlers.queries.start import *
-from bozenka.instances.telegram.utils.callbacks_factory import *
-from bozenka.instances.telegram.handlers.queries.ban import *
-from bozenka.instances.telegram.handlers.queries.pins import *
-from bozenka.instances.telegram.handlers.queries.threads import *
-from bozenka.instances.telegram.handlers.queries.delete import *
-from bozenka.instances.telegram.handlers.queries.revoke import *
-from bozenka.instances.telegram.handlers.queries.text_generation import *
-from bozenka.instances.telegram.handlers.queries.setup import *
-
-
-def register_queries(router: Router) -> None:
- """
- Register all callback queries.
- :param router:
- :return:
- """
- logging.log(msg="Registering callback queries", level=logging.INFO)
-
- # Moderation
- # Ban / Unban buttons reactions
- router.callback_query.register(inline_ban, BanData.filter())
- router.callback_query.register(inline_unban, UnbanData.filter())
-
- # Mute / Un,ute buttons reactions
- router.callback_query.register(inline_mute, MuteData.filter())
- router.callback_query.register(inline_unmute, UnmuteData.filter())
-
- # Revoke telegram invite link button
- router.callback_query.register(inline_revoke, RevokeCallbackData.filter())
- # Delete button message reaction
- router.callback_query.register(inline_delete, DeleteMenu.filter())
-
- # Threads (Close/Open)
- router.callback_query.register(inline_close_thread, CloseThread.filter())
- router.callback_query.register(inline_open_thread, OpenThread.filter())
-
- # Pins (Pin/Unpin)
- router.callback_query.register(inline_pin_msg, PinMsg.filter())
- router.callback_query.register(inline_unpin_msg, UnpinMsg.filter())
-
- # GPT Related queries
-
- # Back to gpt categories
- router.callback_query.register(inline_start_gpt, GptBackMenu.filter(F.back_to == "category"))
-
- # Gpt4Free menus (Providers/Models)
- router.callback_query.register(inline_g4f_categories, GptCategory.filter(F.category == "Gpt4Free"))
- router.callback_query.register(inline_g4f_categories, GptBackMenu.filter(F.back_to == "g4fcategory"))
-
- router.callback_query.register(inline_g4f_provider_models, Gpt4FreeProvider.filter())
-
- router.callback_query.register(inline_g4f_models, Gpt4FreeCategory.filter(F.category == "models"))
- router.callback_query.register(inline_g4f_providers, Gpt4FreeCategory.filter(F.category == "providers"))
-
- router.callback_query.register(inline_g4f_model_select, Gpt4FreeModel.filter())
- router.callback_query.register(inline_g4f_next_models, Gpt4FreeModelPage.filter())
-
- # Get back to menu state
- router.callback_query.register(inline_g4f_providers_back, GptBackMenu.filter(F.back_to == "providers"))
-
- # Generates next pages (Providers/Models)
- router.callback_query.register(inline_next_g4f_models, Gpt4FreeProvsModelPage.filter(), flags={"rate_limit": {"rate": 5}})
- router.callback_query.register(inline_next_g4f_providers, Gpt4FreeProviderPage.filter(),
- flags={"rate_limit": {"rate": 5}})
-
- # Help information (for page button under menu)
- router.callback_query.register(inline_return_pages, F.data == "gotpages")
- router.callback_query.register(inline_g4f_ready, Gpt4freeResult.filter())
-
- # Image generation menu
- # Size setting
- router.callback_query.register(inline_image_size, ImageGenerationCategory.filter())
-
- # Ready status
- router.callback_query.register(inline_image_ready, ImageGeneration.filter())
-
- # Gpt4All menus
- # Gpt4All model menu
- router.callback_query.register(inline_g4a, GptCategory.filter(F.category == "Gpt4All"))
-
- # Gpt4All back
- router.callback_query.register(inline_g4a_back, GptBackMenu.filter(F.back_to == "g4amodels"))
-
- # Gpt4All selected model menu
- router.callback_query.register(inline_g4a_model, Gpt4AllModel.filter())
- router.callback_query.register(inline_g4a_select_model, Gpt4AllSelect.filter())
-
- # Stop dialog button under gpt message answer
- router.callback_query.register(inline_stop_dialog, GptStop.filter())
-
- # /setup command related queries
- # List of features based on category
- router.callback_query.register(inline_setup_category, SetupCategory.filter())
-
- # Menu of feature to enable or disable
- router.callback_query.register(inline_edit_feature, SetupFeature.filter())
- router.callback_query.register(inline_feature_edited, SetupAction.filter(F.action == "enable"))
- router.callback_query.register(inline_feature_edited, SetupAction.filter(F.action == "disable"))
-
- # Back from feature to category
- router.callback_query.register(inline_setup_category_back, SetupAction.filter(F.action == "back"))
-
- # /start command related queries
- # Help of features based on category
- router.callback_query.register(inline_help_features, HelpCategory.filter())
- router.callback_query.register(inline_back_help_categories, HelpBack.filter(F.back_to == "category"))
- router.callback_query.register(inline_back_help_features, HelpBackCategory.filter())
-
- # Menu to back
- router.callback_query.register(inline_help_feature, HelpFeature.filter())
-
- # Back to /start
- router.callback_query.register(inline_start, F.data == "back")
-
- # Categories of menu
- router.callback_query.register(inline_about_developers, F.data == "aboutdevs")
- router.callback_query.register(inline_add_to_chat, F.data == "addtochat")
- router.callback_query.register(inline_start_chatbot, F.data == "dialogai")
- router.callback_query.register(inline_help, F.data == "functional")
- router.callback_query.register(inline_about_instance, F.data == "aboutbot")
-
-
-
diff --git a/bozenka/instances/telegram/handlers/queries/ban.py b/bozenka/instances/telegram/handlers/queries/ban.py
deleted file mode 100644
index 667296c..0000000
--- a/bozenka/instances/telegram/handlers/queries/ban.py
+++ /dev/null
@@ -1,67 +0,0 @@
-import logging
-
-from aiogram import types
-from sqlalchemy.ext.asyncio import async_sessionmaker
-
-from bozenka.instances.telegram.utils.callbacks_factory import BanData, UnbanData
-from aiogram.enums import ChatMemberStatus
-
-from bozenka.instances.telegram.utils.keyboards import ban_keyboard, unban_keyboard
-from bozenka.instances.telegram.utils.simpler import SolutionSimpler
-
-
-async def inline_ban(call: types.CallbackQuery, callback_data: BanData, session_maker: async_sessionmaker) -> None:
- """
- Query, what bannes users after callback
- :param call: CallBackQuery telegram object
- :param callback_data: BanData object
- :param session_maker: AsyncSessionmaker object
- :return:
- """
- clicked_user = await call.message.chat.get_member(call.from_user.id)
- banned_user = await call.message.chat.get_member(int(callback_data.user_id_ban))
-
- if call.from_user.id != callback_data.user_id_clicked \
- and clicked_user.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.CREATOR]:
- return
- await SolutionSimpler.inline_ban_user(call=call, data=callback_data, session=session_maker)
-
- if not banned_user.is_member and banned_user.status == ChatMemberStatus.KICKED:
- await call.answer("Уже заблокирован ✅")
- else:
- await call.answer("Успешно заблокирован ✅")
-
- await call.message.edit_text(
- "Удача ✅\n"
- f"{banned_user.user.mention_html('Этот пользователь')} был заблокирован {call.from_user.mention_html('этим пользователем')}.",
- reply_markup=ban_keyboard(admin_id=call.from_user.id, ban_id=banned_user.user.id)
- )
- logging.log(msg=f"Banned user @{banned_user.user.full_name} user_id=f{banned_user.user.id}", level=logging.INFO)
-
-
-async def inline_unban(call: types.CallbackQuery, callback_data: UnbanData, session_maker: async_sessionmaker) -> None:
- """
- Query, what unbannes users after callback
- :param call: CallBackQuery telegram object
- :param callback_data: UnbanData object
- :param session_maker: AsyncSessionmaker object
- :return:
- """
- clicked_user = await call.message.chat.get_member(call.from_user.id)
- unbanned_user = await call.message.chat.get_member(int(callback_data.user_id_unban))
- if call.from_user.id != callback_data.user_id_clicked \
- and clicked_user.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.CREATOR]:
- return
-
- await SolutionSimpler.inline_unban_user(call=call, data=callback_data, session=session_maker)
-
- if unbanned_user.is_member and unbanned_user.status != ChatMemberStatus.KICKED:
- await call.answer("Уже разблокирован ✅")
- else:
- await call.answer("Успешно разблокирован ✅")
- await call.message.edit_text(
- "Удача ✅\n"
- f"{unbanned_user.user.mention_html('Этот пользователь')} был разблокирован {call.from_user.mention_html('этим пользователем')}.",
- reply_markup=unban_keyboard(admin_id=call.from_user.id, ban_id=unbanned_user.user.id)
- )
- logging.log(msg=f"Unbanned user @{unbanned_user.user.full_name} user_id=f{unbanned_user.user.id}", level=logging.INFO)
diff --git a/bozenka/instances/telegram/handlers/queries/delete.py b/bozenka/instances/telegram/handlers/queries/delete.py
deleted file mode 100644
index 20f24cf..0000000
--- a/bozenka/instances/telegram/handlers/queries/delete.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import logging
-
-from aiogram import types
-
-from bozenka.instances.telegram.utils.callbacks_factory import DeleteMenu
-from aiogram.enums import ChatMemberStatus
-
-
-async def inline_delete(call: types.CallbackQuery, callback_data: DeleteMenu) -> None:
- """
- Deletes messsage, after special callback
- :param call:
- :param callback_data:
- :return:
- """
- user_clicked = await call.message.chat.get_member(call.from_user.id)
- if call.from_user.id == callback_data.user_id_clicked or user_clicked.status == ChatMemberStatus.ADMINISTRATOR:
- await call.answer("Хорошо ✅")
- logging.log(msg=f"Deleted message with message_id={call.message.message_id}",
- level=logging.INFO)
- await call.message.delete()
diff --git a/bozenka/instances/telegram/handlers/queries/image_generation.py b/bozenka/instances/telegram/handlers/queries/image_generation.py
deleted file mode 100644
index 01eb78d..0000000
--- a/bozenka/instances/telegram/handlers/queries/image_generation.py
+++ /dev/null
@@ -1,60 +0,0 @@
-import logging
-
-from aiogram import types
-from aiogram.fsm.context import FSMContext
-from gpt4all import GPT4All
-
-from bozenka.instances.telegram.utils.simpler.fsm_states import *
-
-# Callbacks for GPT
-from bozenka.instances.telegram.utils.callbacks_factory import (
- ImageGeneration,
- ImageGenerationCategory
-)
-# Keyboards for messages
-from bozenka.instances.telegram.utils.keyboards import (
- gpt4free_models_by_provider_keyboard,
- gpt4free_providers_keyboard,
- delete_keyboard, gpt_categories_keyboard, generate_gpt4all_page, gpt4all_model_menu, image_resolution_keyboard
-)
-# Simpler utlilities
-from bozenka.instances.telegram.utils.simpler import (
- AnsweringGPT4Free,
- AnsweringGpt4All,
-)
-
-
-async def inline_image_size(call: types.CallbackQuery, callback_data: ImageGenerationCategory, state: FSMContext) -> None:
- """
- Query, what shows menu for image size to generate in
- :param call:
- :param callback_data:
- :param state:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
-
- await state.update_data(set_category=callback_data.category)
- await state.set_state(GeneratingImages.set_size)
- await call.message.edit_text("Пожалуста, выберите размер изображения 🖼",
- reply_markup=image_resolution_keyboard(user_id=call.from_user.id,
- category=callback_data.category))
-
-
-async def inline_image_ready(call: types.CallbackQuery, callback_data: ImageGeneration, state: FSMContext) -> None:
- """
- Query, what shows menu for image size to generate in
- :param call:
- :param callback_data:
- :param state:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
- await state.update_data(set_size=callback_data.size)
- await state.set_state(GeneratingImages.ready_to_generate)
- await call.message.edit_text(f"Вы выбрали {callback_data.category} для генерации изображений в размере {callback_data.size}.\n"
- "Напишите /cancel для отмены",
- reply_markup=delete_keyboard(admin_id=call.from_user.id))
-
diff --git a/bozenka/instances/telegram/handlers/queries/mute.py b/bozenka/instances/telegram/handlers/queries/mute.py
deleted file mode 100644
index 92c1f43..0000000
--- a/bozenka/instances/telegram/handlers/queries/mute.py
+++ /dev/null
@@ -1,67 +0,0 @@
-import logging
-
-from aiogram import types
-from sqlalchemy.ext.asyncio import async_sessionmaker
-
-from bozenka.instances.telegram.utils.callbacks_factory import UnmuteData, MuteData
-from aiogram.enums import ChatMemberStatus
-
-from bozenka.instances.telegram.utils.keyboards import ban_keyboard, unban_keyboard, mute_keyboard, unmute_keyboard
-from bozenka.instances.telegram.utils.simpler import SolutionSimpler
-
-
-async def inline_mute(call: types.CallbackQuery, callback_data: MuteData, session_maker: async_sessionmaker) -> None:
- """
- Query, what mutes users after callback
- :param call: CallBackQuery telegram object
- :param callback_data: BanData object
- :param session_maker: AsyncSessionmaker object
- :return:
- """
- clicked_user = await call.message.chat.get_member(call.from_user.id)
- muted_user = await call.message.chat.get_member(int(callback_data.user_id_mute))
-
- if call.from_user.id != callback_data.user_id_clicked \
- and clicked_user.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.CREATOR]:
- return
- await SolutionSimpler.inline_mute_user(call=call, data=callback_data, session=session_maker)
-
- if not muted_user.can_send_messages and muted_user.status == ChatMemberStatus.RESTRICTED:
- await call.answer("Уже замучен ✅")
- else:
- await call.answer("Успешно замучен ✅")
-
- await call.message.edit_text(
- "Удача ✅\n"
- f"{muted_user.user.mention_html('Этот пользователь')} был замучен {call.from_user.mention_html('этим пользователем')}.",
- reply_markup=mute_keyboard(admin_id=call.from_user.id, mute_id=callback_data.user_id_mute)
- )
- logging.log(msg=f"Banned user @{muted_user.user.full_name} user_id=f{muted_user.user.id}", level=logging.INFO)
-
-
-async def inline_unmute(call: types.CallbackQuery, callback_data: UnmuteData, session_maker: async_sessionmaker) -> None:
- """
- Query, what unbannes users after callback
- :param call: CallBackQuery telegram object
- :param callback_data: UnbanData object
- :param session_maker: AsyncSessionmaker object
- :return:
- """
- clicked_user = await call.message.chat.get_member(call.from_user.id)
- unmuted_user = await call.message.chat.get_member(int(callback_data.user_id_unmute))
- if call.from_user.id != callback_data.user_id_clicked \
- and clicked_user.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.CREATOR]:
- return
-
- await SolutionSimpler.inline_unmute_user(call=call, data=callback_data, session=session_maker)
-
- if unmuted_user.can_send_messages or unmuted_user.status == ChatMemberStatus.RESTRICTED:
- await call.answer("Уже размучен ✅")
- else:
- await call.answer("Успешно размучен ✅")
- await call.message.edit_text(
- "Удача ✅\n"
- f"{unmuted_user.user.mention_html('Этот пользователь')} был размучен {call.from_user.mention_html('этим пользователем')}.",
- reply_markup=unmute_keyboard(admin_id=call.from_user.id, unmute_id=unmuted_user.user.id)
- )
- logging.log(msg=f"Unbanned user @{unmuted_user.user.full_name} user_id=f{unmuted_user.user.id}", level=logging.INFO)
diff --git a/bozenka/instances/telegram/handlers/queries/pins.py b/bozenka/instances/telegram/handlers/queries/pins.py
deleted file mode 100644
index 599a03e..0000000
--- a/bozenka/instances/telegram/handlers/queries/pins.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from aiogram import types
-
-from bozenka.instances.telegram.utils.callbacks_factory import PinMsg, UnpinMsg
-from bozenka.instances.telegram.utils.keyboards import unpin_msg_keyboard, pin_msg_keyboard
-
-
-async def inline_pin_msg(call: types.CallbackQuery, callback_data: PinMsg) -> None:
- """
- Query, what pins message
- :param call:
- :param callback_data:
- :return:
- """
- if callback_data.user_id == call.from_user.id:
- return
-
- await call.message.chat.pin_message(message_id=callback_data.msg_id)
- await call.message.edit_text("Удача ✅\n"
- "Сообщение было закреплено 📌",
- reply_markup=pin_msg_keyboard(user_id=call.from_user.id, msg_id=callback_data.msg_id))
-
-
-async def inline_unpin_msg(call: types.CallbackQuery, callback_data: UnpinMsg) -> None:
- """
- Query, what unpins message
- :param call:
- :param callback_data:
- :return:
- """
- if callback_data.user_id == call.from_user.id:
- return
-
- await call.message.chat.pin_message(message_id=callback_data.msg_id)
- await call.message.edit_text("Удача ✅\n"
- "Сообщение было откреплено 📌",
- reply_markup=unpin_msg_keyboard(user_id=call.from_user.id, msg_id=callback_data.msg_id))
diff --git a/bozenka/instances/telegram/handlers/queries/revoke.py b/bozenka/instances/telegram/handlers/queries/revoke.py
deleted file mode 100644
index 09601fc..0000000
--- a/bozenka/instances/telegram/handlers/queries/revoke.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import logging
-
-from aiogram import types
-
-from bozenka.instances.telegram.utils.callbacks_factory import RevokeCallbackData
-from aiogram.enums import ChatMemberStatus
-
-from bozenka.instances.telegram.utils.simpler import ru_cmds
-
-
-async def inline_revoke(call: types.CallbackQuery, callback_data: RevokeCallbackData):
- """
- Revokes invite link
- :param call:
- :param callback_data:
- :return:
- """
- user_clicked = await call.message.chat.get_member(call.from_user.id)
- if callback_data.admin_id == call.from_user.id or user_clicked.status == ChatMemberStatus.ADMINISTRATOR or user_clicked.status == ChatMemberStatus.CREATOR:
- logging.log(msg=f"Revoking link for user_id={call.from_user.id}",
- level=logging.INFO)
- await call.message.chat.revoke_invite_link(invite_link="https://" + str(callback_data.link))
- await call.answer("Удача ✅")
- await call.message.delete()
diff --git a/bozenka/instances/telegram/handlers/queries/setup.py b/bozenka/instances/telegram/handlers/queries/setup.py
deleted file mode 100644
index 715ad81..0000000
--- a/bozenka/instances/telegram/handlers/queries/setup.py
+++ /dev/null
@@ -1,73 +0,0 @@
-from aiogram.types import CallbackQuery, Message
-from sqlalchemy import select, Update
-from sqlalchemy.ext.asyncio import async_sessionmaker
-
-from bozenka.database.tables.telegram import TelegramChatSettings, get_chat_config_value
-from bozenka.instances.telegram.utils.callbacks_factory import SetupCategory, SetupFeature, SetupAction
-from bozenka.instances.telegram.utils.keyboards import setup_category_keyboard, setup_feature_keyboard
-from bozenka.instances.telegram.utils.simpler import list_of_features
-
-
-async def inline_setup_category(call: CallbackQuery, callback_data: SetupCategory):
- """
- Query, what shows list of features to enable.
- :param call:
- :param callback_data:
- :return:
- """
- await call.message.edit_text("Выберите настройку, которую хотите изменить",
- reply_markup=setup_category_keyboard(category=callback_data.category_name))
-
-
-async def inline_setup_category_back(call: CallbackQuery, callback_data: SetupAction):
- """
- Query, what shows list of features to enable.
- :param call:
- :param callback_data:
- :return:
- """
- await call.message.edit_text("Выберите настройку, которую хотите изменить",
- reply_markup=setup_category_keyboard(category=callback_data.category_name))
-
-
-async def inline_edit_feature(call: CallbackQuery, callback_data: SetupFeature, session_maker: async_sessionmaker):
- """
- Query, what shows menu to enable / disable feature
- :param call:
- :param callback_data:
- :param session_maker:
- :return:
- """
- is_enabled = await get_chat_config_value(
- chat_id=call.message.chat.id,
- session=session_maker,
- setting=list_of_features[callback_data.feature_category][callback_data.feature_index]
- )
-
- await call.message.edit_text(
- list_of_features[callback_data.feature_category][callback_data.feature_index].description,
- reply_markup=await setup_feature_keyboard(category=callback_data.feature_category,
- index=callback_data.feature_index,
- is_enabled=is_enabled))
-
-
-async def inline_feature_edited(call: CallbackQuery, callback_data: SetupAction, session_maker: async_sessionmaker):
- """
- Query, what shows menu to enable / disable feature
- after editing
- :param call:
- :param callback_data:
- :param session_maker:
- :return:
- """
- async with session_maker() as session:
- async with session.begin():
- await session.execute(Update(TelegramChatSettings)
- .values({list_of_features[callback_data.category_name][callback_data.feature_index].settings_name:
- callback_data.action == "enable"})
- .where(TelegramChatSettings.chat_id == call.message.chat.id))
- await call.message.edit_text(
- list_of_features[callback_data.category_name][callback_data.feature_index].description,
- reply_markup=await setup_feature_keyboard(category=callback_data.category_name,
- index=callback_data.feature_index,
- is_enabled=callback_data.action == "enable"))
diff --git a/bozenka/instances/telegram/handlers/queries/start.py b/bozenka/instances/telegram/handlers/queries/start.py
deleted file mode 100644
index b114f49..0000000
--- a/bozenka/instances/telegram/handlers/queries/start.py
+++ /dev/null
@@ -1,168 +0,0 @@
-import git
-
-from aiogram.types import *
-
-from bozenka.instances.telegram.utils.callbacks_factory import *
-from bozenka.instances.telegram.utils.keyboards import *
-from bozenka.instances.telegram.utils.simpler import list_of_features
-from bozenka.instances.version import is_updated, build
-
-
-async def inline_start(call: CallbackQuery):
- """
- Query, what shows back menu of /start
- :param call:
- :return:
- """
- await call.message.edit_text(
- """
- Привет 👋
-Я - бозенька, бот с открытым исходным кодом, который поможет тебе в различных задачах.
-
-Вот что ты можешь сделать с помощью меню:
-• Добавить в чат: добавляет меня в групповой чат, чтобы я мог выполнять свои функции внутри него.
-• Функционал: показывает список доступных функций и команд, которые я могу выполнить.
-• О разработчиках: предоставляет информацию о команде разработчиков, которые создали и поддерживают этого бота.
-• О запущенном экземпляре: выводит информацию о текущей версии и состоянии запущенного экземпляра бота.
-• Начать диалог с ИИ: позволяет начать диалог с искусственным интеллектом, который может отвечать на вопросы и предоставлять информацию.
-• Генерация изображений: позволяет сгенерировать изображения на основе заданных параметров и промта
-
-Вот нужные ссылки обо мне:
-• Канал с новостями об разработке
-• Исходный код на Github
-
-Чтобы воспользоваться какой-либо функцией, просто нажми на соответствующую кнопку ниже.
-Если у тебя возникнут вопросы или проблемы, не стесняйся обратиться к команде разработчиков или написать в обсуждении телеграм канала.
-Удачного использования!
- """,
- reply_markup=start_keyboard(),
- disable_web_page_preview=True
- )
-
-
-async def inline_start_chatbot(call: CallbackQuery):
- """
- Query, what shows list of Categories, avaible to use as chatbot
- :param call:
- :return:
- """
- await call.message.edit_text("Пожалуста, выберите сервиc / библиотеку, через которую вы будете общаться",
- reply_markup=gpt_categories_keyboard
- (user_id=call.from_user.id))
-
-
-async def inline_help(call: CallbackQuery):
- """
- Query, what shows information about bozenka and it's development
- :param call:
- :return:
- """
- await call.message.edit_text("Выберите категорию, по которой нужна помощь:",
- reply_markup=help_keyboard())
-
-
-async def inline_about_developers(call: CallbackQuery):
- """
- Query, what shows information about bozenka and it's development
- :param call:
- :return:
- """
- kb = InlineKeyboardMarkup(inline_keyboard=[[
- InlineKeyboardButton(text="Вернуться 🔙", callback_data="back")
- ]])
- await call.message.edit_text("""
-Бозенька - это мультифункциональный (в будущем кроссплатформенный) бот.\n
-Он умеет работать с групповыми чатами и готовыми нейронными сетями для генерации текста и изображений.
-Бозенька разрабатывается коммандой, которая состоит на данный момент из одного человека.\n
-Исходный код проекта\n
-Исходный код находится под лицензией GPL-3.0, исходный код проекта можно посмотреть всегда здесь
-Канал с новостями разработки находится здесь
- """, reply_markup=kb, disable_web_page_preview=True)
-
-
-async def inline_about_instance(call: CallbackQuery):
- """
- Query, what shows information about runned instance
- :param call:
- :return:
- """
- kb = InlineKeyboardMarkup(inline_keyboard=[[
- InlineKeyboardButton(text="Вернуться 🔙", callback_data="back")
- ]])
- me = await call.message.bot.get_me()
- update_status = {False: "требуется обновление бота 🔼",
- True: "обновление не требуется, последняя версия ✅"}
- await call.message.edit_text(
- f"Информация об данном запущенном экземпляре бозеньки:\n"
- f"Аккаунт бота: {me.mention_html()}\n"
- f"Запущенная версия бота {build}
\n",
- f"Нужно ли обновление: {update_status[is_updated]}",
- reply_markup=kb)
-
-
-async def inline_add_to_chat(call: CallbackQuery):
- """
- Query, what shows a link to add bozenka into user chat
- :param call:
- :return:
- """
- # Getting bot
- me = await call.message.bot.me()
-
- # Generating special keyboard
- kb = InlineKeyboardBuilder()
- kb.button(text="Добавить в ваш груповой чат 🔌",
- url="https://t.me/"
- f"{me.username}?"
- "startgroup&"
- "admin=promote_members+delete_messages+restrict_members+invite_users+pin_messages+manage_video_chats")
- kb.row(InlineKeyboardButton(text="Вернуться 🔙", callback_data="back"))
-
- # Answering
- await call.message.edit_text("Чтобы добавить бозеньку в ваш групповой чат, нажмите на кнопку под сообщением:",
- reply_markup=kb.as_markup())
-
-
-async def inline_help_features(call: CallbackQuery, callback_data: HelpCategory):
- """
- Query, what shows list of features to get support.
- :param call:
- :param callback_data:
- :return:
- """
- await call.message.edit_text("Выберите функцию, по которой нужна помощь",
- reply_markup=help_category_keyboard(category=callback_data.category_name))
-
-
-async def inline_back_help_features(call: CallbackQuery, callback_data: HelpBackCategory):
- """
- Query, what shows list of features to get support.
- :param call:
- :param callback_data:
- :return:
- """
- await call.message.edit_text("Выберите функцию, по которой нужна помощь",
- reply_markup=help_category_keyboard(category=callback_data.back_to_category))
-
-
-async def inline_back_help_categories(call: CallbackQuery, callback_data: HelpBack):
- """
- Query, what shows list of features to get support back.
- :param call:
- :param callback_data:
- :return:
- """
- await call.message.edit_text("Выберите категорию, по которой нужна помощь:",
- reply_markup=help_keyboard())
-
-
-async def inline_help_feature(call: CallbackQuery, callback_data: HelpFeature):
- """
- Query, what shows list of features to get support.
- :param call:
- :param callback_data:
- :return:
- """
- await call.message.edit_text(
- list_of_features[callback_data.feature_category][callback_data.feature_index].description,
- reply_markup=help_feature_keyboard(category=callback_data.feature_category))
diff --git a/bozenka/instances/telegram/handlers/queries/text_generation.py b/bozenka/instances/telegram/handlers/queries/text_generation.py
deleted file mode 100644
index 1475141..0000000
--- a/bozenka/instances/telegram/handlers/queries/text_generation.py
+++ /dev/null
@@ -1,358 +0,0 @@
-import logging
-
-from aiogram import types
-from aiogram.fsm.context import FSMContext
-from gpt4all import GPT4All
-
-from bozenka.instances.telegram.utils.simpler.fsm_states import *
-
-# Callbacks for GPT
-from bozenka.instances.telegram.utils.callbacks_factory import (
- GptCategory,
- Gpt4FreeProvider,
- Gpt4freeResult,
- Gpt4FreeProviderPage,
- Gpt4FreeProvsModelPage, GptStop, GptBackMenu, Gpt4AllModel, Gpt4AllSelect, Gpt4FreeCategory, Gpt4FreeModelPage,
- Gpt4FreeModel
-)
-# Keyboards for messages
-from bozenka.instances.telegram.utils.keyboards import (
- gpt4free_models_by_provider_keyboard,
- gpt4free_providers_keyboard,
- delete_keyboard, gpt_categories_keyboard, generate_gpt4all_page, gpt4all_model_menu, gpt4free_categories_keyboard,
- gpt4free_models_keyboard
-)
-# Simpler utlilities
-from bozenka.instances.telegram.utils.simpler import (
- AnsweringGPT4Free,
- AnsweringGpt4All,
-)
-
-
-async def inline_start_gpt(call: types.CallbackQuery, callback_data: GptBackMenu, state: FSMContext) -> None:
- """
- Query, what shows when clicking on button in /start menu
- :param call:
- :param state:
- :param callback_data:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
- await call.message.edit_text("Пожалуста, выберите сервис для ИИ.",
- reply_markup=gpt_categories_keyboard(user_id=call.from_user.id))
-
-
-async def inline_g4f_providers(call: types.CallbackQuery, callback_data: Gpt4FreeCategory, state: FSMContext) -> None:
- """
- Query, what creating providers selecting menu.
- :param state:
- :param call:
- :param callback_data:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
-
- logging.log(msg=f"Selected gpt4free category by user_id={call.from_user.id}",
- level=logging.INFO)
-
- await call.answer("Вы выбрали провайдеры 🤖")
-
- await state.set_state(AnsweringGPT4Free.set_provider)
- await call.message.edit_text("Выберите пожалуйста одного из провайдеров 👨💻",
- reply_markup=gpt4free_providers_keyboard(user_id=call.from_user.id, page=0))
-
-
-async def inline_g4f_models(call: types.CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
- """
- Query, what creating models selecting menu
- :param state:
- :param call:
- :param callback_data:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
-
- await state.set_state(AnsweringGPT4Free.set_model)
-
- await call.answer("Вы выбрали модели 🤖")
-
- await call.message.edit_text("Выберите модель, с которой будете общаться 🤖",
- reply_markup=gpt4free_models_keyboard(user_id=call.from_user.id, page=0))
-
-
-async def inline_g4f_model_select(call: types.CallbackQuery, callback_data: Gpt4FreeModel, state: FSMContext):
- """
- Query, what ending model selecting
- :param call:
- :param callback_data:
- :param state:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
-
- await state.update_data(set_model=callback_data.model)
- await state.set_state(AnsweringGPT4Free.ready_to_answer)
-
- await call.answer("Вы можете начать общаться 🤖")
-
- await call.message.edit_text("Удача ✅\n"
- "Вы теперь можете спокойно вести диалог 🤖\n"
- f"Вы выбрали модель {callback_data.model}👾\n"
- "Чтобы прекратить общение, используйте /cancel ", reply_markup=delete_keyboard(admin_id=call.from_user.id))
-
-
-async def inline_g4f_next_models(call: types.CallbackQuery, callback_data: Gpt4FreeModelPage, state: FSMContext) -> None:
- """
- Query, what creating models selecting menu
- :param state:
- :param call:
- :param callback_data:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
-
- await call.answer(f"Вы перелистнули на страницу {callback_data.page + 1}📄")
-
- await call.message.edit_text("Выберите модель, с которой будете общаться 🤖",
- reply_markup=gpt4free_models_keyboard(user_id=call.from_user.id, page=callback_data.page))
-
-
-async def inline_g4f_categories(call: types.CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
- """
- Query, what creating providers selecting menu.
- :param state:
- :param call:
- :param callback_data:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
-
- logging.log(msg=f"Selected gpt4free category by user_id={call.from_user.id}",
- level=logging.INFO)
-
- await state.update_data(set_category=callback_data.category)
- await call.answer("Вы выбрали Gpt4Free 🤖")
- await call.message.edit_text("Выберите, по какому пункту мы будем вести диалог с нейронной сети 🤖",
- reply_markup=gpt4free_categories_keyboard(user_id=call.from_user.id))
- await call.answer("Выберите, по какому пункту мы будем вести диалог с нейронной сети 🤖")
-
-
-async def inline_g4f_providers_back(call: types.CallbackQuery, callback_data: GptBackMenu, state: FSMContext) -> None:
- """
- Query, what creating providers selecting menu.
- :param state:
- :param call:
- :param callback_data:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
-
- logging.log(msg=f"Back to providers menu by user_id={call.from_user.id}",
- level=logging.INFO)
- await state.set_state(AnsweringGPT4Free.set_provider)
-
- await call.message.edit_text("Выберите пожалуйста одного из провайдеров 👨💻",
- reply_markup=gpt4free_providers_keyboard(page=0, user_id=callback_data.user_id))
- await call.answer("Выберите пожалуйста одного из провайдеров 👨💻")
-
-
-async def inline_g4f_provider_models(call: types.CallbackQuery, callback_data: Gpt4FreeProvider, state: FSMContext) -> None:
- """
- Query, what creating models selecting menu.
- :param state:
- :param call:
- :param callback_data:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
-
- logging.log(msg=f"Selected gpt4free provider {callback_data.provider} by user_id={call.from_user.id}",
- level=logging.INFO)
-
- await state.update_data(set_provider=callback_data.provider)
- await state.set_state(AnsweringGPT4Free.set_model)
-
- await call.message.edit_text("Выберите пожалуйста модель ИИ 👾", reply_markup=gpt4free_models_by_provider_keyboard(
- user_id=callback_data.user_id,
- provider=callback_data.provider,
- page=0
- ))
- await call.answer("Выберите пожалуйста модель ИИ 👾")
-
-
-async def inline_g4f_ready(call: types.CallbackQuery, callback_data: Gpt4freeResult, state: FSMContext) -> None:
- """
- Query, what says about getting ready to questions for ChatGPT from Gpt4Free.
- :param state:
- :param call:
- :param callback_data:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
-
- logging.log(msg=f"Selected gpt4free model {callback_data.model} by user_id={call.from_user.id}",
- level=logging.INFO)
-
- await state.update_data(set_model=callback_data.model)
- await state.set_state(AnsweringGPT4Free.ready_to_answer)
-
- logging.log(msg=f"Loaded GPT answering status for user_id={call.from_user.id}",
- level=logging.INFO)
-
- await call.message.edit_text("Удача ✅\n"
- "Вы теперь можете спокойно вести диалог 🤖\n"
- f"Вы выбрали модель {callback_data.model}👾, от провайдера {callback_data.provider}👨💻\n"
- "Чтобы прекратить общение, используйте /cancel ",
- reply_markup=delete_keyboard(admin_id=callback_data.user_id))
- await call.answer("Вы теперь можете спокойно вести диалог 🤖")
-
-
-async def inline_g4a(call: types.CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
- """
- Query, what shows list for gpt4all models
- :param call:
- :param callback_data:
- :param state:
- :return:
- """
- if callback_data.user_id != call.from_user.id:
- return
- await state.set_state(AnsweringGpt4All.set_model)
- await call.message.edit_text("Выберите пожалуйста модель ИИ 👾",
- reply_markup=generate_gpt4all_page(user_id=call.from_user.id))
-
-
-async def inline_g4a_back(call: types.CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
- """
- Query, what shows list for gpt4all models back
- :param call:
- :param callback_data:
- :param state:
- :return:
- """
- if callback_data.user_id != call.from_user.id:
- return
- await state.set_state(AnsweringGpt4All.set_model)
- await call.message.edit_text("Выберите пожалуйста модель ИИ 👾",
- reply_markup=generate_gpt4all_page(user_id=call.from_user.id))
-
-
-async def inline_g4a_model(call: types.CallbackQuery, callback_data: Gpt4AllModel, state: FSMContext) -> None:
- """
- Query, what show information about clicked gpt4all model from list
- :param call:
- :param callback_data:
- :param state:
- :return:
- """
- if callback_data.user_id != call.from_user.id:
- return
- models = GPT4All.list_models()
- name = models[callback_data.index]['name']
- await call.message.edit_text(f"{name}\n"
- f"Обученно на основе {models[callback_data.index]['parameters']} строк 👨💻",
- reply_markup=gpt4all_model_menu(user_id=call.from_user.id, index=callback_data.index))
-
-
-async def inline_g4a_select_model(call: types.CallbackQuery, callback_data: Gpt4AllSelect, state: FSMContext) -> None:
- """
- Query, what says about getting ready for question for Gpt4All model
- :param call:
- :param callback_data:
- :param state:
- :return:
- """
- if callback_data.user_id != call.from_user.id:
- return
- await state.update_data(set_model=callback_data.index)
- await state.set_state(AnsweringGpt4All.ready_to_answer)
- models = GPT4All.list_models()
-
- await call.message.edit_text("Удача ✅\n"
- "Вы теперь можете спокойно вести диалог 🤖\n"
- f"Вы выбрали модель {models[callback_data.index]['name']}👾 от Gpt4All\n"
- "Чтобы прекратить общение, используйте /cancel ",
- reply_markup=delete_keyboard(admin_id=callback_data.user_id))
-
-
-async def inline_next_g4f_providers(call: types.CallbackQuery, callback_data: Gpt4FreeProviderPage,
- state: FSMContext) -> None:
- """
- Query, what generates a next page of providers for user
- :param call:
- :param callback_data:
- :param state:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
- logging.log(msg=f"Changed page to {str(callback_data.page + 1)} user_id={call.from_user.id}",
- level=logging.INFO)
- await call.message.edit_text(call.message.text,
- reply_markup=gpt4free_providers_keyboard(user_id=callback_data.user_id,
- page=callback_data.page))
- await call.answer(f"Вы перелистнули на страницу {callback_data.page + 1}📄")
-
-
-async def inline_next_g4f_models(call: types.CallbackQuery, callback_data: Gpt4FreeProvsModelPage,
- state: FSMContext) -> None:
- """
- Query, what generates a next page of models for user.
- :param call:
- :param callback_data:
- :param state:
- :return:
- """
- if call.from_user.id != callback_data.user_id:
- return
- logging.log(msg=f"Changed page to {str(callback_data.page + 1)} user_id={call.from_user.id}",
- level=logging.INFO)
- await call.message.edit_text(call.message.text,
- reply_markup=gpt4free_models_by_provider_keyboard(
- user_id=callback_data.user_id,
- provider=callback_data.provider,
- page=callback_data.page
- ))
- await call.answer(f"Вы перелистали на страницу {callback_data.page + 1}📄")
-
-
-async def inline_return_pages(call: types.CallbackQuery) -> None:
- """
- Query, made for helping purposes.
- Shows current page.
- :param call:
- :return:
- """
- logging.log(msg=f"Showed helping info for user_id={call.from_user.id}",
- level=logging.INFO)
- await call.answer("Здесь расположается текущая странница 📃")
-
-
-async def inline_stop_dialog(call: types.CallbackQuery, callback_data: GptStop, state: FSMContext) -> None:
- """
- Query, what stops dialog
- :param call:
- :param callback_data:
- :param state:
- """
- # Checking user_id of user
- if callback_data.user_id != call.from_user.id:
- return
- # Clearing state
- await state.clear()
- # Answering something
- await call.answer("Хорошо ✅")
- if await state.get_state() == AnsweringGPT4Free.ready_to_answer or await state.get_state() == AnsweringGpt4All.answering:
- await call.message.edit_text(text=call.message.text + "\n\nДиалог остановлен ✅\n",
- reply_markup=delete_keyboard(admin_id=call.from_user.id))
- else:
- await call.message.delete()
diff --git a/bozenka/instances/telegram/handlers/queries/threads.py b/bozenka/instances/telegram/handlers/queries/threads.py
deleted file mode 100644
index 4ca6993..0000000
--- a/bozenka/instances/telegram/handlers/queries/threads.py
+++ /dev/null
@@ -1,41 +0,0 @@
-from aiogram import types
-
-from bozenka.instances.telegram.utils.callbacks_factory import CloseThread, OpenThread
-from bozenka.instances.telegram.utils.keyboards import open_thread_keyboard, close_thread_keyboard, delete_keyboard
-from bozenka.instances.telegram.utils.simpler import SolutionSimpler
-
-
-async def inline_close_thread(call: types.CallbackQuery, callback_data: CloseThread) -> None:
- """
- Query, what close thread
- :param call:
- :param callback_data:
- :return:
- """
-
- if callback_data.user_id != call.from_user.id or not call.message.chat.is_forum:
- return
- config = await SolutionSimpler.close_topic(msg=call.message, call=call)
- await call.message.edit_text(
- config[0],
- reply_markup=close_thread_keyboard(user_id=call.from_user.id) if config[1] else
- delete_keyboard(admin_id=call.from_user.id)
- )
-
-
-async def inline_open_thread(call: types.CallbackQuery, callback_data: OpenThread) -> None:
- """
- Query, what opens thread
- :param call:
- :param callback_data:
- :return:
- """
-
- if callback_data.user_id != call.from_user.id or not call.message.chat.is_forum:
- return
- config = await SolutionSimpler.open_topic(msg=call.message, call=call)
- await call.message.edit_text(
- config[0],
- reply_markup=open_thread_keyboard(user_id=call.from_user.id) if config[1] else
- delete_keyboard(admin_id=call.from_user.id)
- )
--
2.30.2
From 405c5f3cc1cb0aabd96b843a0c49ec12ab026f89 Mon Sep 17 00:00:00 2001
From: kittyneverdies <85691197+KittyNeverDies@users.noreply.github.com>
Date: Sun, 11 Feb 2024 16:18:01 +0300
Subject: [PATCH 07/13] Final recode of project
---
bozenka/features/__init__.py | 16 ++++--
bozenka/features/admin/__init__.py | 5 +-
bozenka/features/admin/information.py | 51 +++++++++++++++++++
.../admin/{invite.py => invite_generation.py} | 1 +
bozenka/features/admin/moderation.py | 2 +-
.../features/admin/{pins.py => msg_pins.py} | 1 +
bozenka/features/admin/topics.py | 1 +
bozenka/features/basic/setup.py | 15 +++---
bozenka/features/basic/start.py | 4 +-
bozenka/features/features_list.py | 25 ---------
bozenka/features/user/image_generation.py | 3 +-
bozenka/features/user/text_generation.py | 3 +-
bozenka/features/user/welcome.py | 1 +
bozenka/generative/__init__.py | 13 ++++-
bozenka/instances/features_list.py | 26 ++++++++++
bozenka/instances/telegram/__init__.py | 29 ++++++-----
.../instances/telegram/queries/__init__.py | 1 +
bozenka/instances/telegram/utils/__init__.py | 0
.../telegram/utils/filters/permissions.py | 11 ++--
.../telegram/utils/keyboards/inline.py | 22 ++++----
20 files changed, 159 insertions(+), 71 deletions(-)
create mode 100644 bozenka/features/admin/information.py
rename bozenka/features/admin/{invite.py => invite_generation.py} (99%)
rename bozenka/features/admin/{pins.py => msg_pins.py} (99%)
delete mode 100644 bozenka/features/features_list.py
create mode 100644 bozenka/instances/features_list.py
delete mode 100644 bozenka/instances/telegram/utils/__init__.py
diff --git a/bozenka/features/__init__.py b/bozenka/features/__init__.py
index fad29b1..3459743 100644
--- a/bozenka/features/__init__.py
+++ b/bozenka/features/__init__.py
@@ -1,14 +1,19 @@
+from bozenka.features.admin import *
+from bozenka.features.user import *
+from bozenka.features.basic import *
class BasicFeature:
"""
A classic class of lineral (basic)
feature of bozenka. IN FUTURE!
+ :param telegram_setting_in_list: Does feature shows in /setup list
"""
- telegram_setting_in_list = False # Does feature shows in /setup list
- telegram_setting_name = None # Setting title in /setup command
- telegram_setting_description = None # Setting description in /setup command
- telegram_db_name = None # Name of TelegramChatSettings column will be affected
+ telegram_setting_in_list: bool = False # Does feature shows in /setup list
+ telegram_setting_name: str | None = None # Setting title in /setup command
+ telegram_setting_description: str | None = None # Setting description in /setup command
+ telegram_db_name = None # Name of TelegramChatSettings column will be affected
+ telegram_category: str | None = None # Telegram category name, current
# Telegram commands list of feature
telegram_commands: dict[str: str] = {
#
@@ -17,7 +22,8 @@ class BasicFeature:
"example": "Its an example"
}
telegram_cmd_avaible = True # Does this feature have a telegram commands
- # All handlers
+
+ # All handlers to register automaticly by bozenka
telegram_message_handlers = [
# Format is [Handler, [Filters]]
]
diff --git a/bozenka/features/admin/__init__.py b/bozenka/features/admin/__init__.py
index 8e7fa94..227b147 100644
--- a/bozenka/features/admin/__init__.py
+++ b/bozenka/features/admin/__init__.py
@@ -1,4 +1,5 @@
-from .invite import Invite
+from .invite_generation import Invite
from .moderation import Moderation
-from .pins import Pins
+from .msg_pins import Pins
from .topics import Threads
+from .information import ChatInformation
diff --git a/bozenka/features/admin/information.py b/bozenka/features/admin/information.py
new file mode 100644
index 0000000..2a2fa6f
--- /dev/null
+++ b/bozenka/features/admin/information.py
@@ -0,0 +1,51 @@
+import logging
+
+from aiogram.filters import Command
+from aiogram.types import Message
+
+from bozenka.features import BasicFeature
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard
+
+
+class ChatInformation(BasicFeature):
+ """
+ Shows information about chat by sending one command.
+ (Private, public, etc)
+ """
+
+ async def telegram_basic_chat_info_handler(msg: Message) -> None:
+ """
+ Shows information about chat by command `/info`
+ :param msg: Message telegram object
+ :return: None
+ """
+ logging.log(msg=f"Sending information about chat user_id={msg.from_user.id}",
+ level=logging.INFO)
+ chat = await msg.bot.get_chat(msg.chat.id)
+ # Related texts
+ texts = {
+ "chat_types": {"group": "группой", "supergroup": "cупер группой"},
+ "forum_type": {True: "форумом,", False: ", не является форумом,", None: ", не является форумом,"},
+ "required_invite": {True: "требуется одобрение заявки на вступление", False: "заявка не требуется.",
+ None: "заявка не требуется."},
+ "hidden_members": {True: "присуствуют", False: "отсуствуют", None: "отсуствуют"},
+ "isprotected": {True: "пересылать сообщения из группы можно.",
+ False: "пересылать сообщения из группы нельзя.",
+ None: "пересылать сообщения из группы можно."},
+ }
+
+ await msg.answer(f"{chat.title}, {chat.get_member_count()} пользователей\n"
+ f"{chat.description}\n\n"
+ f"Является {texts['chat_types'][chat.type]} {texts['forum_type'][chat.is_forum]} {texts['required_invite'][chat.join_by_request]}\n"
+ f"Скрытые пользователи {texts['hidden_members'][chat.has_hidden_members]}, {texts['isprotected'][chat.has_protected_content]}",
+ reply_markup=delete_keyboard(admin_id=msg.from_user.id))
+
+ telegram_commands: dict[str: str] = {
+ 'info': 'Get information about chat'
+ }
+ telegram_cmd_avaible = True
+
+ # All handlers to register automaticly by bozenka
+ telegram_message_handlers = [
+ [telegram_basic_chat_info_handler, [Command(commands="info")]]
+ ]
diff --git a/bozenka/features/admin/invite.py b/bozenka/features/admin/invite_generation.py
similarity index 99%
rename from bozenka/features/admin/invite.py
rename to bozenka/features/admin/invite_generation.py
index c8bc720..6bd835d 100644
--- a/bozenka/features/admin/invite.py
+++ b/bozenka/features/admin/invite_generation.py
@@ -61,6 +61,7 @@ class Invite(BasicFeature):
"Разрешает использование комманды /invite
в чате, для созданния приглашений.\n" \
"Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
telegram_db_name = TelegramChatSettings.invite_generator
+ telegram_category = "admin"
# Telegram commands
telegram_commands: dict[str: str] = {"/invite": 'Generates invite into current chat'}
telegram_cmd_avaible = True # Is a feature have a commands
diff --git a/bozenka/features/admin/moderation.py b/bozenka/features/admin/moderation.py
index fa76e48..4930ab1 100644
--- a/bozenka/features/admin/moderation.py
+++ b/bozenka/features/admin/moderation.py
@@ -501,8 +501,8 @@ class Moderation(BasicFeature):
"чтобы выполнить одну из комманд по отношению к пользователю, " \
"ответьте на сообщение пользователя и используйте команду\n" \
"Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
-
telegram_db_name = TelegramChatSettings.moderation
+ telegram_category = "admin"
# Telegram commands
telegram_commands: dict[str: str] = {
"ban": "Command to ban user in chat",
diff --git a/bozenka/features/admin/pins.py b/bozenka/features/admin/msg_pins.py
similarity index 99%
rename from bozenka/features/admin/pins.py
rename to bozenka/features/admin/msg_pins.py
index afa4f9c..0a16fee 100644
--- a/bozenka/features/admin/pins.py
+++ b/bozenka/features/admin/msg_pins.py
@@ -119,6 +119,7 @@ class Pins(BasicFeature):
"/unpin_all - открепляет все сообщения, которые видит бот\n" \
"Для исполнения требует соответсвующих прав от пользователя и их наличие у бота."
telegram_db_name = TelegramChatSettings.pins
+ telegram_category = "admin"
# Telegram commands
telegram_commands: dict[str: str] = {
'pin': 'Pin fast any message in chat',
diff --git a/bozenka/features/admin/topics.py b/bozenka/features/admin/topics.py
index 9b3e068..f07e1d0 100644
--- a/bozenka/features/admin/topics.py
+++ b/bozenka/features/admin/topics.py
@@ -132,6 +132,7 @@ class Threads(BasicFeature):
"Для исполнения требует соответсвующих прав от пользователя и их наличие у бота. Также должен быть" \
"включен форум"
telegram_db_name = TelegramChatSettings.topics
+ telegram_category = "admin"
# Telegram commands
telegram_commands: dict[str: str] = {
'close': 'Close fast topic (not general) in chat',
diff --git a/bozenka/features/basic/setup.py b/bozenka/features/basic/setup.py
index 2966dff..43ac28d 100644
--- a/bozenka/features/basic/setup.py
+++ b/bozenka/features/basic/setup.py
@@ -8,6 +8,7 @@ from sqlalchemy.ext.asyncio import async_sessionmaker
from bozenka.database.tables.telegram import get_chat_config_value, TelegramChatSettings
from bozenka.features import BasicFeature
from bozenka.instances.telegram.utils.callbacks_factory import SetupAction, SetupFeature, SetupCategory
+from bozenka.instances.telegram.utils.filters import IsOwner
from bozenka.instances.telegram.utils.keyboards import setup_keyboard, setup_category_keyboard, setup_feature_keyboard
from bozenka.instances.telegram.utils.simpler import list_of_features
@@ -25,7 +26,8 @@ class Setup(BasicFeature):
:return: Nothing
"""
await msg.answer("Привет владелец чата 👋\n"
- "Чтобы меня настроить, используй меню под данным сообщением",
+ "Настрой меня - бота так, как тебе удобно, и я буду помогать тебе в чате с определенными функциями.\n"
+ "Используй меню настроек ниже, чтобы указать, какие функции, которые я умею, должен выполнять.",
reply_markup=setup_keyboard())
async def telegram_setup_categories_handler(call: CallbackQuery, callback_data: SetupCategory | SetupAction):
@@ -86,12 +88,13 @@ class Setup(BasicFeature):
telegram_setting_in_list = False
telegram_commands = {"setup": 'Command to setup bozenka features in chat'}
telegram_cmd_avaible = True
+ telegram_category = None
telegram_message_handlers = [
- [telegram_setup_cmd_handler, [Command(commands=["setup"]), ~(F.chat.type == ChatType.PRIVATE)]]
+ [telegram_setup_cmd_handler, [Command(commands=["setup"]), ~(F.chat.type == ChatType.PRIVATE), IsOwner(True)]]
]
telegram_callback_handlers = [
- [telegram_features_edit_handler, [SetupAction.filter(F.action == "disable")]],
- [telegram_features_edit_handler, [SetupAction.filter(F.action == "enable")]],
- [telegram_setup_edit_feature_handler, [SetupFeature.filter()]],
- [telegram_setup_categories_handler, [SetupAction.filter(F.action == "back")]]
+ [telegram_features_edit_handler, [SetupAction.filter(F.action == "disable"), IsOwner(True)]],
+ [telegram_features_edit_handler, [SetupAction.filter(F.action == "enable"), IsOwner(True)]],
+ [telegram_setup_edit_feature_handler, [SetupFeature.filter(), IsOwner(True)]],
+ [telegram_setup_categories_handler, [SetupAction.filter(F.action == "back"), IsOwner(True)]]
]
diff --git a/bozenka/features/basic/start.py b/bozenka/features/basic/start.py
index 41e60e6..3194b91 100644
--- a/bozenka/features/basic/start.py
+++ b/bozenka/features/basic/start.py
@@ -218,10 +218,10 @@ class Start(BasicFeature):
Telegram feature settings
"""
# Telegram feature settings
- telegram_setting = None
+ telegram_setting_in_list = False
+ telegram_category = None
telegram_commands: dict[str: str] = {"start": "Command to start work with bozenka the bot"}
telegram_cmd_avaible = True # Is a feature have a commands
- telegram_callback_factory = None
telegram_message_handlers = [
[start_cmd_handler, [Command(commands=["start"]), F.chat.type == ChatType.PRIVATE]],
]
diff --git a/bozenka/features/features_list.py b/bozenka/features/features_list.py
deleted file mode 100644
index 6c9ff5a..0000000
--- a/bozenka/features/features_list.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from aiogram import Dispatcher, Bot
-from aiogram.types import BotCommand
-
-from bozenka.features import BasicFeature
-from bozenka.features.admin import *
-from bozenka.features.user import *
-from bozenka.features.basic import *
-
-features_list = [
- # Admin related category
- Moderation,
- Invite,
- Pins,
- Threads,
- # User related category
- ImageGeneratrion,
- TextGeneratrion,
- Welcome,
- # Basic Functions
- Setup,
- Start
-]
-
-
-
diff --git a/bozenka/features/user/image_generation.py b/bozenka/features/user/image_generation.py
index 8e63a1c..a93f70e 100644
--- a/bozenka/features/user/image_generation.py
+++ b/bozenka/features/user/image_generation.py
@@ -130,7 +130,8 @@ class ImageGeneratrion(BasicFeature):
Telegram feature settings
"""
# Telegram feature settings
- telegram_setting = TelegramChatSettings.image_generation
+ telegram_category = "user"
+ telegram_db_name = TelegramChatSettings.image_generation
telegram_commands: dict[str: str] = {'imagine': 'Starts conversation with image generative ai'}
telegram_setting_in_list = True
telegram_setting_name = "Генерация изображений 📸"
diff --git a/bozenka/features/user/text_generation.py b/bozenka/features/user/text_generation.py
index e7760e8..332c8c1 100644
--- a/bozenka/features/user/text_generation.py
+++ b/bozenka/features/user/text_generation.py
@@ -499,7 +499,8 @@ class TextGeneratrion(BasicFeature):
await call.message.delete()
# Telegram feature settings
- telegram_setting = TelegramChatSettings.text_generation
+ telegram_category = "user"
+ telegram_db_name = TelegramChatSettings.text_generation
telegram_setting_in_list = True
telegram_setting_name = "ИИ ЧатБот 🤖"
telegram_setting_description = "ИИ ЧатБот 🤖" \
diff --git a/bozenka/features/user/welcome.py b/bozenka/features/user/welcome.py
index d94c7d6..9dbcfbe 100644
--- a/bozenka/features/user/welcome.py
+++ b/bozenka/features/user/welcome.py
@@ -62,6 +62,7 @@ class Welcome(BasicFeature):
# Telegram feature settings
telegram_setting = TelegramChatSettings.welcome_messages
+ telegram_category = "user"
telegram_commands: dict[str: str] = {}
telegram_setting_in_list = True
telegram_setting_name = "Приветсвенные сообщения 👋"
diff --git a/bozenka/generative/__init__.py b/bozenka/generative/__init__.py
index 9435300..f69fa20 100644
--- a/bozenka/generative/__init__.py
+++ b/bozenka/generative/__init__.py
@@ -1,3 +1,14 @@
+import dataclasses
+
+
+@dataclasses
+class QueryPosition:
+ """
+ Class of Query to generate something
+ with models
+ """
+ data: dict
+ instance: str
# List of text generative categories, what we support
text_generative_categories = [
@@ -17,4 +28,4 @@ image_generative_size = [
"576x1024",
"1024x680",
"680x1024"
-]
\ No newline at end of file
+]
diff --git a/bozenka/instances/features_list.py b/bozenka/instances/features_list.py
new file mode 100644
index 0000000..57b66e0
--- /dev/null
+++ b/bozenka/instances/features_list.py
@@ -0,0 +1,26 @@
+from bozenka.features import *
+
+features_list = [
+ # Admin related category
+ Moderation,
+ Invite,
+ Pins,
+ Threads,
+ ChatInformation,
+ # User related category
+ ImageGeneratrion,
+ TextGeneratrion,
+ Welcome,
+ # Basic Functions
+ Setup,
+ Start
+]
+
+customizable_features = {}
+
+for feature in features_list:
+ if feature.telegram_setting_in_list:
+ if feature.telegram_category in customizable_features.keys():
+ customizable_features[feature.telegram_category].append(feature)
+ else:
+ customizable_features[feature.telegram_category] = [feature]
diff --git a/bozenka/instances/telegram/__init__.py b/bozenka/instances/telegram/__init__.py
index 9576011..56b5c84 100644
--- a/bozenka/instances/telegram/__init__.py
+++ b/bozenka/instances/telegram/__init__.py
@@ -1,17 +1,14 @@
-import os
import logging
-import g4f
+import os
+
from aiogram import Dispatcher, Bot
from aiogram.types import BotCommand
from sqlalchemy.ext.asyncio import async_sessionmaker
from bozenka.features import BasicFeature
-from bozenka.features.features_list import features_list
-from bozenka.features.admin import *
-from bozenka.features.basic import *
-from bozenka.features.user import *
-from bozenka.instances.telegram.handlers import register_handlers
+from bozenka.instances.features_list import features_list
from bozenka.instances.telegram.utils.simpler import list_of_commands
+from bozenka.instances.telegram.queries import *
async def register_all_features(list_of_features: list[BasicFeature], dispatcher: Dispatcher, bot: Bot) -> None:
@@ -37,18 +34,24 @@ async def register_all_features(list_of_features: list[BasicFeature], dispatcher
await bot.set_my_commands(cmd_list)
+ # Registering other handlers
+ await dispatcher.callback_query.register(delete_callback_handler, DeleteMenu.filter())
+ await dispatcher.callback_query.register(hide_menu_handler, HideMenu.filter())
+
async def launch_telegram_instance(session_maker: async_sessionmaker) -> None:
"""
- Launches telegram bot with token from enviroment
- :param session_maker:
- :return:
+ Launch bozenka telegram instance with token from enviroment
+ :param session_maker: AsyncSessionMaker SqlAlchemy object
+ :return: None
"""
- logging.log(msg="-" * 50 + "TELEGRAM INSTANCE LAUNCH" + "-" * 50, level=logging.INFO)
+ logging.log(msg="-" * 50 + "TELEGRAM BOZENKA INSTANCE LAUNCH" + "-" * 50, level=logging.INFO)
bot = Bot(token=os.getenv("tg_bot_token"), parse_mode="HTML")
dp = Dispatcher()
- await register_all_features(list_of_features=features_list, dispatcher=dp, bot=bot)
- await dp.start_polling(bot, session_maker=session_maker, on_startup=[])
+ await dp.start_polling(bot,
+ session_maker=session_maker, # Pass your async_sessionmaker here, you can do dependency injection
+ on_startup=[await register_all_features(list_of_features=features_list, dispatcher=dp, bot=bot)]
+ )
diff --git a/bozenka/instances/telegram/queries/__init__.py b/bozenka/instances/telegram/queries/__init__.py
index e69de29..f2a417c 100644
--- a/bozenka/instances/telegram/queries/__init__.py
+++ b/bozenka/instances/telegram/queries/__init__.py
@@ -0,0 +1 @@
+from .menu import *
\ No newline at end of file
diff --git a/bozenka/instances/telegram/utils/__init__.py b/bozenka/instances/telegram/utils/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/bozenka/instances/telegram/utils/filters/permissions.py b/bozenka/instances/telegram/utils/filters/permissions.py
index eb597e4..100a196 100644
--- a/bozenka/instances/telegram/utils/filters/permissions.py
+++ b/bozenka/instances/telegram/utils/filters/permissions.py
@@ -2,7 +2,7 @@ from typing import Any
from aiogram.filters import Filter
from aiogram.methods import GetChatMember
-from aiogram.types import Message, ChatPermissions
+from aiogram.types import Message, ChatPermissions, CallbackQuery
from aiogram.enums import ChatMemberStatus
from bozenka.instances.telegram.utils.simpler import ru_cmds
@@ -110,16 +110,19 @@ class IsOwner(Filter):
"""
self.is_admin = is_admin
- async def __call__(self, msg: Message) -> bool:
+ async def __call__(self, msg: Message | CallbackQuery) -> bool:
"""
Working after catching a call from aiogram
- :param msg: Message telegram object
+ :param msg: Message or CallbackQuery telegram object
:param self: A self object of this class
:return: None
"""
+ if type(msg) is CallbackQuery:
+ msg = msg.message
user = await msg.chat.get_member(msg.from_user.id)
if ChatMemberStatus.CREATOR != user.status:
- await msg.answer(ru_cmds["no-perms"])
+ await msg.answer("Ошибка ❌\n"
+ "У вас нет прав на использование этой комманды 🚫")
return ChatMemberStatus.CREATOR == user.status
diff --git a/bozenka/instances/telegram/utils/keyboards/inline.py b/bozenka/instances/telegram/utils/keyboards/inline.py
index e377704..336ef1a 100644
--- a/bozenka/instances/telegram/utils/keyboards/inline.py
+++ b/bozenka/instances/telegram/utils/keyboards/inline.py
@@ -9,6 +9,7 @@ from gpt4all import GPT4All
from sqlalchemy.ext.asyncio import async_sessionmaker
from bozenka.database.tables.telegram import get_chat_config_value
+from bozenka.instances.features_list import customizable_features
from bozenka.instances.telegram.utils.callbacks_factory import *
from bozenka.instances.telegram.utils.simpler.lists_of_content import generate_list_of_features
from bozenka.generative.gpt4free import generate_gpt4free_models, generate_gpt4free_providers
@@ -69,7 +70,7 @@ def help_category_keyboard(category: str) -> InlineKeyboardMarkup:
feature_index=list_of_features.index(setting),
feature_category=category
).pack()))
- kb.row(InlineKeyboardButton(text="🔙 Назад к категориям",
+ kb.row(InlineKeyboardButton(text="🔙 Назад к списку категорий",
callback_data=HelpBack(back_to="category").pack()))
return kb.as_markup()
@@ -81,7 +82,7 @@ def help_feature_keyboard(category: str) -> InlineKeyboardMarkup:
:return:
"""
kb = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text="🔙 Назад к функциям",
+ [InlineKeyboardButton(text="🔙 Назад к списку функций",
callback_data=HelpBackCategory(category_name=category).pack())]
])
return kb
@@ -94,15 +95,16 @@ def setup_keyboard() -> InlineKeyboardMarkup:
:return:
"""
kb = InlineKeyboardBuilder()
+ translations = {
+ "admin": "Администраторы 👮♂",
+ "user": "Пользователи 👤"
+ }
- 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
+ for category in customizable_features:
+ kb.row(InlineKeyboardButton(text=translations[category],
+ callback_data=SetupCategory(category_name=category).pack()))
+
+ return kb.as_markup()
def setup_category_keyboard(category: str) -> InlineKeyboardMarkup:
--
2.30.2
From 01322df060a94640a2607e49148f7b547b318f0c Mon Sep 17 00:00:00 2001
From: kittyneverdies <85691197+KittyNeverDies@users.noreply.github.com>
Date: Sun, 11 Feb 2024 22:04:19 +0300
Subject: [PATCH 08/13] Refactoring a little bit
---
bozenka/database/tables/telegram.py | 2 +-
bozenka/features/__init__.py | 29 -
bozenka/features/admin/information.py | 2 +-
bozenka/features/admin/invite_generation.py | 32 +-
bozenka/features/admin/moderation.py | 136 ++--
bozenka/features/admin/msg_pins.py | 57 +-
bozenka/features/admin/topics.py | 49 +-
bozenka/features/basic/setup.py | 109 +++-
bozenka/features/basic/start.py | 60 +-
bozenka/features/main.py | 27 +
bozenka/features/user/image_generation.py | 67 +-
bozenka/features/user/text_generation.py | 272 +++++++-
bozenka/features/user/welcome.py | 4 +-
bozenka/generative/__init__.py | 8 -
bozenka/instances/__init__.py | 0
bozenka/instances/basic_features_list.py | 6 +
.../{version.py => current_version.py} | 0
.../instances/customizable_features_list.py | 30 +
bozenka/instances/features_list.py | 26 -
bozenka/instances/telegram/__init__.py | 21 +-
.../telegram/{utils => }/filters/__init__.py | 0
.../{utils => }/filters/chat_setting.py | 18 +-
.../{utils => }/filters/permissions.py | 24 +-
.../{utils => }/middleware/__init__.py | 5 +-
.../{utils => }/middleware/antiflood.py | 0
.../telegram/{utils => }/middleware/retry.py | 0
bozenka/instances/telegram/utils/__init__.py | 0
bozenka/instances/telegram/utils/delete.py | 16 +
.../telegram/utils/keyboards/__init__.py | 1 -
.../telegram/utils/keyboards/inline.py | 615 ------------------
.../utils/simpler/lists_of_content.py | 301 ---------
31 files changed, 787 insertions(+), 1130 deletions(-)
create mode 100644 bozenka/features/main.py
create mode 100644 bozenka/instances/__init__.py
create mode 100644 bozenka/instances/basic_features_list.py
rename bozenka/instances/{version.py => current_version.py} (100%)
create mode 100644 bozenka/instances/customizable_features_list.py
delete mode 100644 bozenka/instances/features_list.py
rename bozenka/instances/telegram/{utils => }/filters/__init__.py (100%)
rename bozenka/instances/telegram/{utils => }/filters/chat_setting.py (53%)
rename bozenka/instances/telegram/{utils => }/filters/permissions.py (85%)
rename bozenka/instances/telegram/{utils => }/middleware/__init__.py (74%)
rename bozenka/instances/telegram/{utils => }/middleware/antiflood.py (100%)
rename bozenka/instances/telegram/{utils => }/middleware/retry.py (100%)
create mode 100644 bozenka/instances/telegram/utils/__init__.py
create mode 100644 bozenka/instances/telegram/utils/delete.py
delete mode 100644 bozenka/instances/telegram/utils/keyboards/__init__.py
delete mode 100644 bozenka/instances/telegram/utils/keyboards/inline.py
delete mode 100644 bozenka/instances/telegram/utils/simpler/lists_of_content.py
diff --git a/bozenka/database/tables/telegram.py b/bozenka/database/tables/telegram.py
index f83b208..958b4ed 100644
--- a/bozenka/database/tables/telegram.py
+++ b/bozenka/database/tables/telegram.py
@@ -83,7 +83,7 @@ async def get_chat_config_value(chat_id: int, session: async_sessionmaker, setti
"""
async with session() as session:
async with session.begin():
- rows = (await session.execute(select(setting.db_name).where(TelegramChatSettings.chat_id == chat_id))).one()
+ rows = (await session.execute(select(setting).where(TelegramChatSettings.chat_id == chat_id))).one()
return rows[0]
diff --git a/bozenka/features/__init__.py b/bozenka/features/__init__.py
index 3459743..21e1a8e 100644
--- a/bozenka/features/__init__.py
+++ b/bozenka/features/__init__.py
@@ -1,32 +1,3 @@
from bozenka.features.admin import *
from bozenka.features.user import *
from bozenka.features.basic import *
-
-
-class BasicFeature:
- """
- A classic class of lineral (basic)
- feature of bozenka. IN FUTURE!
- :param telegram_setting_in_list: Does feature shows in /setup list
- """
- telegram_setting_in_list: bool = False # Does feature shows in /setup list
- telegram_setting_name: str | None = None # Setting title in /setup command
- telegram_setting_description: str | None = None # Setting description in /setup command
- telegram_db_name = None # Name of TelegramChatSettings column will be affected
- telegram_category: str | None = None # Telegram category name, current
- # Telegram commands list of feature
- telegram_commands: dict[str: str] = {
- #
- # Format is "CommandNameHere": "Command description is here"
- #
- "example": "Its an example"
- }
- telegram_cmd_avaible = True # Does this feature have a telegram commands
-
- # All handlers to register automaticly by bozenka
- telegram_message_handlers = [
- # Format is [Handler, [Filters]]
- ]
- telegram_callback_handlers = [
- # Format is [Handler, [Filters]]
- ]
diff --git a/bozenka/features/admin/information.py b/bozenka/features/admin/information.py
index 2a2fa6f..059fe9a 100644
--- a/bozenka/features/admin/information.py
+++ b/bozenka/features/admin/information.py
@@ -3,7 +3,7 @@ import logging
from aiogram.filters import Command
from aiogram.types import Message
-from bozenka.features import BasicFeature
+from bozenka.features.main import BasicFeature
from bozenka.instances.telegram.utils.keyboards import delete_keyboard
diff --git a/bozenka/features/admin/invite_generation.py b/bozenka/features/admin/invite_generation.py
index 6bd835d..53c6989 100644
--- a/bozenka/features/admin/invite_generation.py
+++ b/bozenka/features/admin/invite_generation.py
@@ -2,13 +2,31 @@ import logging
from aiogram.enums import ChatMemberStatus
from aiogram.filters import Command
-from aiogram.types import Message, CallbackQuery
+from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
from bozenka.database.tables.telegram import TelegramChatSettings
-from bozenka.features import BasicFeature
-from bozenka.instances.telegram.utils.callbacks_factory import RevokeCallbackData
-from bozenka.instances.telegram.utils.keyboards import invite_keyboard
-from bozenka.instances.telegram.utils.simpler import ru_cmds
+from bozenka.features.main import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import RevokeCallbackData, DeleteMenu
+
+
+# Invite keyboard
+def invite_telegram_keyboard(invite_link: str, admin_id: int, chat_name: str) -> InlineKeyboardMarkup:
+ """
+ Generating menu for /invite command. Should be reworked.
+ :param invite_link: Invite link to chat
+ :param admin_id: User_id of telegram administrator
+ :param chat_name: Name of group chat
+ :return: Nothing
+ """
+ invite_revoke_link = invite_link.replace("https://", "")
+ kb = InlineKeyboardMarkup(inline_keyboard=[[
+ InlineKeyboardButton(text=chat_name, url=invite_link)],
+ [InlineKeyboardButton(text="Отозвать 🛠️",
+ callback_data=RevokeCallbackData(admin_id=admin_id, link=invite_revoke_link).pack())],
+ [InlineKeyboardButton(text="Спасибо ✅",
+ callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())]])
+ return kb
+
class Invite(BasicFeature):
@@ -29,8 +47,8 @@ class Invite(BasicFeature):
await msg.answer(
f" Держите ваше приглашение в чат, {msg.from_user.mention_html('пользователь')} 👋",
- reply_markup=invite_keyboard(link=str(link.invite_link), admin_id=msg.from_user.id,
- chat_name=msg.chat.full_name)
+ reply_markup=invite_telegram_keyboard(invite_link=str(link.invite_link), admin_id=msg.from_user.id,
+ chat_name=msg.chat.full_name)
)
async def telegram_revoke_callback_handler(call: CallbackQuery, callback_data: RevokeCallbackData) -> None:
diff --git a/bozenka/features/admin/moderation.py b/bozenka/features/admin/moderation.py
index 4930ab1..5b11c90 100644
--- a/bozenka/features/admin/moderation.py
+++ b/bozenka/features/admin/moderation.py
@@ -3,16 +3,80 @@ import logging
from aiogram import F
from aiogram.enums import ChatMemberStatus, ChatType
from aiogram.filters import CommandObject, Command
-from aiogram.types import Message, CallbackQuery
+from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
from sqlalchemy.ext.asyncio import async_sessionmaker
from bozenka.database.tables.telegram import get_chat_config_value, TelegramChatSettings
-from bozenka.features import BasicFeature
-from bozenka.instances.telegram.utils.callbacks_factory import UnbanData, BanData, UnmuteData, MuteData
-from bozenka.instances.telegram.utils.filters import IsAdminFilter, BotHasPermissions, UserHasPermissions
-from bozenka.instances.telegram.utils.keyboards import ban_keyboard, delete_keyboard, mute_keyboard, unmute_keyboard, \
- unban_keyboard
-from bozenka.instances.telegram.utils.simpler import list_of_features, SolutionSimpler
+from bozenka.features.main import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import UnbanData, BanData, UnmuteData, MuteData, DeleteMenu
+from bozenka.instances.telegram.filters import IsAdminFilter, BotHasPermissions, UserHasPermissions
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard
+from bozenka.instances.telegram.utils.simpler import SolutionSimpler
+
+
+# Ban / Unban keyboards
+def telegram_ban_user_keyboard(admin_id: int, ban_id: int) -> InlineKeyboardMarkup:
+ """
+ Generating menu for /ban command.
+ :param admin_id: User_id of administrator in group chat
+ :param ban_id: User_id of banned member
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[[
+ InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(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 telegram_unban_user_keyboard(admin_id: int, unban_id: int) -> InlineKeyboardMarkup:
+ """
+ Generating menu for /unban command.
+ :param admin_id: User_id of administrator in group chat
+ :param unban_id: User_id of unbanned member
+ :return: InlineKeyboardMarkup
+ """
+ print(unban_id)
+ kb = InlineKeyboardMarkup(inline_keyboard=[[
+ InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())
+ ], [
+ InlineKeyboardButton(text="Забанить 🛠️", callback_data=BanData(user_id_ban=str(unban_id),
+ user_id_clicked=str(admin_id)).pack())
+ ]])
+ return kb
+
+
+# Mute / Unmute keyboards
+def telegram_mute_user_keyboard(admin_id: int, mute_id: int) -> InlineKeyboardMarkup:
+ """
+ Generating menu for /mute command.
+ :param admin_id: User_id of administrator in group chat
+ :param mute_id: User_id of restricted member
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[
+ [InlineKeyboardButton(text="Спасибо ✅",
+ callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())],
+ [InlineKeyboardButton(text="Размутить 🛠️",
+ callback_data=UnmuteData(user_id_unmute=mute_id, user_id_clicked=admin_id).pack())]])
+ return kb
+
+
+def telegram_unmute_user_keyboard(admin_id: int, unmute_id: int) -> InlineKeyboardMarkup:
+ """
+ Generating menu for /unmute command.
+ :param admin_id: User_id of administrator in group chat
+ :param unmute_id: User_id of unrestricted member
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[
+ [InlineKeyboardButton(text="Спасибо ✅",
+ callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())],
+ [InlineKeyboardButton(text="Замутить 🛠️",
+ callback_data=MuteData(user_id_mute=unmute_id, user_id_clicked=admin_id).pack())]])
+ return kb
class Moderation(BasicFeature):
@@ -34,7 +98,7 @@ class Moderation(BasicFeature):
banned_user = await call.message.chat.get_member(int(callback_data.user_id_ban))
send_notification = await get_chat_config_value(chat_id=call.message.chat.id, session=session_maker,
- setting=list_of_features["Admins"][5])
+ setting=TelegramChatSettings.restrict_notification)
if call.from_user.id != callback_data.user_id_clicked \
and clicked_user.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.CREATOR]:
@@ -49,7 +113,7 @@ class Moderation(BasicFeature):
await call.message.edit_text(
"Удача ✅\n"
f"{banned_user.user.mention_html('Этот пользователь')} был заблокирован {call.from_user.mention_html('этим пользователем')}.",
- reply_markup=ban_keyboard(admin_id=call.from_user.id, ban_id=banned_user.user.id)
+ reply_markup=telegram_ban_user_keyboard(admin_id=call.from_user.id, ban_id=banned_user.user.id)
)
if send_notification:
@@ -86,11 +150,11 @@ class Moderation(BasicFeature):
await call.message.edit_text(
"Удача ✅\n"
f"{unbanned_user.user.mention_html('Этот пользователь')} был разблокирован {call.from_user.mention_html('этим пользователем')}.",
- reply_markup=unban_keyboard(admin_id=call.from_user.id, ban_id=unbanned_user.user.id)
+ reply_markup=telegram_unban_user_keyboard(admin_id=call.from_user.id, unban_id=unbanned_user.user.id)
)
if await get_chat_config_value(chat_id=call.message.chat.id, session=session_maker,
- setting=list_of_features["Admins"][5]):
+ setting=TelegramChatSettings.restrict_notification):
await call.message.bot.send_message(
chat_id=unbanned_user.user.id,
text=f"{unbanned_user.user.mention_html('Вы')} были разблокирован {call.from_user.mention_html('этим пользователем')} в чате {call.message.chat.id}
.",
@@ -110,9 +174,9 @@ class Moderation(BasicFeature):
"""
banned_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admins"][4])
+ setting=TelegramChatSettings.results_in_dm)
send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admins"][5])
+ setting=TelegramChatSettings.restrict_notification)
where_send = {
True: msg.from_user.id,
@@ -133,7 +197,7 @@ class Moderation(BasicFeature):
f"{msg.reply_to_message.from_user.mention_html('Этот пользователь')} "
f"был заблокирован {msg.from_user.mention_html('этим пользователем')}.\n"
f"По причине {config['reason']}
, до даты {config['ban_time']}
",
- reply_markup=ban_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
+ reply_markup=telegram_ban_user_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
if send_notification:
await msg.bot.send_message(chat_id=banned_user.user.id,
text="Вы "
@@ -146,8 +210,8 @@ class Moderation(BasicFeature):
f"{msg.reply_to_message.from_user.mention_html('Этот пользователь')} "
f"был заблокирован {msg.reply_to_message.from_user.mention_html('этим пользователем')}.\n"
f"По причине {config['reason']}
.",
- reply_markup=ban_keyboard(admin_id=msg.from_user.id,
- ban_id=msg.reply_to_message.from_user.id))
+ reply_markup=telegram_ban_user_keyboard(admin_id=msg.from_user.id,
+ ban_id=msg.reply_to_message.from_user.id))
if send_notification:
await msg.bot.send_message(chat_id=banned_user.user.id,
text=f"Вы "
@@ -159,8 +223,8 @@ class Moderation(BasicFeature):
text="Удача ✅\n"
f"{msg.reply_to_message.from_user.mention_html('Этот пользователь')} "
f"был заблокирован {msg.from_user.mention_html('этим пользователем')}, до даты {config['ban_time']}
",
- reply_markup=ban_keyboard(admin_id=msg.from_user.id,
- ban_id=msg.reply_to_message.from_user.id))
+ reply_markup=telegram_ban_user_keyboard(admin_id=msg.from_user.id,
+ ban_id=msg.reply_to_message.from_user.id))
if send_notification:
await msg.bot.send_message(chat_id=banned_user.user.id,
text=f"Вы "
@@ -172,7 +236,7 @@ class Moderation(BasicFeature):
text="Удача ✅\n"
f"{msg.reply_to_message.from_user.mention_html('Этот пользователь')}"
f" был заблокирован {msg.from_user.mention_html('этим пользователем')}.",
- reply_markup=ban_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
+ reply_markup=telegram_ban_user_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
if send_notification:
await msg.bot.send_message(chat_id=banned_user.user.id,
text=f"Вы "
@@ -192,9 +256,9 @@ class Moderation(BasicFeature):
unbanned_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admins"][4])
+ setting=TelegramChatSettings.results_in_dm)
send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admins"][5])
+ setting=TelegramChatSettings.restrict_notification)
where_send = {
True: msg.from_user.id,
@@ -215,7 +279,7 @@ class Moderation(BasicFeature):
text="Удача ✅\n"
f"{msg.reply_to_message.from_user.mention_html('Этот пользователь')} был разблокирован "
f"{msg.from_user.mention_html('этим пользователем')}.\n",
- reply_markup=unban_keyboard(admin_id=msg.from_user.id, ban_id=msg.reply_to_message.from_user.id)
+ reply_markup=telegram_unban_user_keyboard(admin_id=msg.from_user.id, unban_id=msg.reply_to_message.from_user.id)
)
if send_notification:
await msg.bot.send_message(
@@ -266,11 +330,11 @@ class Moderation(BasicFeature):
await call.message.edit_text(
"Удача ✅\n"
f"{muted_user.user.mention_html('Этот пользователь')} был замучен {call.from_user.mention_html('этим пользователем')}.",
- reply_markup=mute_keyboard(admin_id=call.from_user.id, mute_id=callback_data.user_id_mute)
+ reply_markup=telegram_mute_user_keyboard(admin_id=call.from_user.id, mute_id=callback_data.user_id_mute)
)
send_notification = await get_chat_config_value(chat_id=call.message.chat.id, session=session_maker,
- setting=list_of_features["Admin"][5])
+ setting=TelegramChatSettings.restrict_notification)
if send_notification:
await call.message.bot.send_message(
chat_id=muted_user.user.id,
@@ -304,11 +368,11 @@ class Moderation(BasicFeature):
await call.message.edit_text(
"Удача ✅\n"
f"{unmuted_user.user.mention_html('Этот пользователь')} был размучен {call.from_user.mention_html('этим пользователем')}.",
- reply_markup=unmute_keyboard(admin_id=call.from_user.id, unmute_id=unmuted_user.user.id)
+ reply_markup=telegram_unmute_user_keyboard(admin_id=call.from_user.id, unmute_id=unmuted_user.user.id)
)
send_notification = await get_chat_config_value(chat_id=call.message.chat.id, session=session_maker,
- setting=list_of_features["Admin"][5])
+ setting=TelegramChatSettings.restrict_notification)
if send_notification:
await call.message.bot.send_message(
chat_id=unmuted_user.user.id,
@@ -329,14 +393,12 @@ class Moderation(BasicFeature):
:param session_maker: Session maker object of SqlAlchemy
:return: Nothing
"""
- print(msg.reply_to_message)
- print("341414124")
mute_user = await msg.chat.get_member(msg.reply_to_message.from_user.id)
send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admins"][4])
+ setting=TelegramChatSettings.results_in_dm)
send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admins"][5])
+ setting=TelegramChatSettings.restrict_notification)
where_send = {
True: msg.from_user.id,
@@ -353,7 +415,7 @@ class Moderation(BasicFeature):
f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n"
f"По причине {config['reason']}
, до даты {config['mute_time']}
",
- reply_markup=mute_keyboard(msg.from_user.id, mute_user.user.id))
+ reply_markup=telegram_mute_user_keyboard(msg.from_user.id, mute_user.user.id))
if send_notification:
await msg.bot.send_message(
chat_id=mute_user.user.id,
@@ -369,7 +431,7 @@ class Moderation(BasicFeature):
f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n"
f"По причине {config['reason']}
.",
- reply_markup=mute_keyboard(msg.from_user.id, mute_user.user.id))
+ reply_markup=telegram_mute_user_keyboard(msg.from_user.id, mute_user.user.id))
if send_notification:
await msg.bot.send_message(
chat_id=mute_user.user.id,
@@ -384,7 +446,7 @@ class Moderation(BasicFeature):
f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n"
f"До даты {config['mute_time']}
",
- reply_markup=mute_keyboard(msg.from_user.id, mute_user.user.id))
+ reply_markup=telegram_mute_user_keyboard(msg.from_user.id, mute_user.user.id))
if send_notification:
await msg.bot.send_message(
chat_id=mute_user.user.id,
@@ -398,7 +460,7 @@ class Moderation(BasicFeature):
text="Удача ✅\n"
f"{msg.from_user.mention_html('Этот пользователь')} запретил писать "
f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}.\n",
- reply_markup=mute_keyboard(msg.from_user.id, mute_user.user.id))
+ reply_markup=telegram_mute_user_keyboard(msg.from_user.id, mute_user.user.id))
if send_notification:
await msg.bot.send_message(
chat_id=mute_user.user.id,
@@ -417,9 +479,9 @@ class Moderation(BasicFeature):
await SolutionSimpler.unmute_user(msg, session_maker)
send_to_dm = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admins"][4])
+ setting=TelegramChatSettings.results_in_dm)
send_notification = await get_chat_config_value(chat_id=msg.chat.id, session=session_maker,
- setting=list_of_features["Admins"][5])
+ setting=TelegramChatSettings.restrict_notification)
where_send = {
True: msg.from_user.id,
@@ -431,7 +493,7 @@ class Moderation(BasicFeature):
text="Удача ✅"
f"{msg.from_user.mention_html('Этот пользователь')} разрешил писать\n"
f"сообщения {msg.reply_to_message.from_user.mention_html('этому пользователю')}",
- reply_markup=unmute_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
+ reply_markup=telegram_unmute_user_keyboard(msg.from_user.id, msg.reply_to_message.from_user.id))
if send_notification:
await msg.bot.send_message(
user_id=msg.reply_to_message.from_user.id,
diff --git a/bozenka/features/admin/msg_pins.py b/bozenka/features/admin/msg_pins.py
index 0a16fee..a2b8ace 100644
--- a/bozenka/features/admin/msg_pins.py
+++ b/bozenka/features/admin/msg_pins.py
@@ -1,16 +1,47 @@
from aiogram import F
from aiogram.enums import ChatType
from aiogram.filters import Command
-from aiogram.types import Message, CallbackQuery
+from aiogram.types import Message, CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
from bozenka.database.tables.telegram import TelegramChatSettings
-from bozenka.features import BasicFeature
-from bozenka.instances.telegram.utils.callbacks_factory import PinMsg, UnpinMsg
-from bozenka.instances.telegram.utils.filters import UserHasPermissions, BotHasPermissions, IsAdminFilter
-from bozenka.instances.telegram.utils.keyboards import unpin_msg_keyboard, delete_keyboard, pin_msg_keyboard
+from bozenka.features.main import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import PinMsg, UnpinMsg, DeleteMenu
+from bozenka.instances.telegram.filters import UserHasPermissions, BotHasPermissions, IsAdminFilter
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard
from bozenka.instances.telegram.utils.simpler import SolutionSimpler
+# Pin / Unpin command
+def telegram_pin_msg_keyboard(user_id: int, msg_id: int) -> InlineKeyboardMarkup:
+ """
+ Generate menu for /pin command
+ :param user_id: User_id of user pinned the message
+ :param msg_id: Message_id of pinned message
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[
+ [InlineKeyboardButton(text="Открепить сообщение 📌",
+ callback_data=UnpinMsg(user_id=user_id, msg_id=msg_id).pack())],
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())]
+ ])
+ return kb
+
+
+def telegram_unpin_msg_keyboard(user_id: int, msg_id: int) -> InlineKeyboardMarkup:
+ """
+ Generate menu for /unpin command
+ :param user_id: User_id of user unpinned the message
+ :param msg_id: Message_id of unpinned message
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[
+ [InlineKeyboardButton(text="Открепить сообщение 📌",
+ callback_data=PinMsg(user_id=user_id, msg_id=msg_id).pack())],
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())]
+ ])
+ return kb
+
+
class Pins(BasicFeature):
"""
A class of pins related commands
@@ -30,8 +61,8 @@ class Pins(BasicFeature):
await call.message.chat.pin_message(message_id=callback_data.msg_id)
await call.message.edit_text("Удача ✅\n"
"Сообщение было закреплено 📌",
- reply_markup=pin_msg_keyboard(user_id=call.from_user.id,
- msg_id=callback_data.msg_id))
+ reply_markup=telegram_pin_msg_keyboard(user_id=call.from_user.id,
+ msg_id=callback_data.msg_id))
async def telegram_unpin_callback_handler(call: CallbackQuery, callback_data: UnpinMsg) -> None:
"""
@@ -46,8 +77,8 @@ class Pins(BasicFeature):
await call.message.chat.pin_message(message_id=callback_data.msg_id)
await call.message.edit_text("Удача ✅\n"
"Сообщение было откреплено 📌",
- reply_markup=unpin_msg_keyboard(user_id=call.from_user.id,
- msg_id=callback_data.msg_id))
+ reply_markup=telegram_unpin_msg_keyboard(user_id=call.from_user.id,
+ msg_id=callback_data.msg_id))
async def telegram_pin_cmd(msg: Message) -> None:
"""
@@ -58,8 +89,8 @@ class Pins(BasicFeature):
await SolutionSimpler.pin_msg(msg)
await msg.answer("Удача ✅\n"
"Сообщение было закреплено 📌",
- reply_markup=pin_msg_keyboard(msg_id=msg.reply_to_message.message_id,
- user_id=msg.from_user.id))
+ reply_markup=telegram_pin_msg_keyboard(msg_id=msg.reply_to_message.message_id,
+ user_id=msg.from_user.id))
async def telegram_unpin_cmd(msg: Message) -> None:
"""
@@ -70,8 +101,8 @@ class Pins(BasicFeature):
await SolutionSimpler.unpin_msg(msg)
await msg.answer("Удача ✅\n"
"Сообщение было откреплено 📌",
- reply_markup=unpin_msg_keyboard(msg_id=msg.reply_to_message.message_id,
- user_id=msg.from_user.id))
+ reply_markup=telegram_unpin_msg_keyboard(msg_id=msg.reply_to_message.message_id,
+ user_id=msg.from_user.id))
async def telegram_unpinall_cmd(msg: Message) -> None:
"""
diff --git a/bozenka/features/admin/topics.py b/bozenka/features/admin/topics.py
index f07e1d0..e1311ef 100644
--- a/bozenka/features/admin/topics.py
+++ b/bozenka/features/admin/topics.py
@@ -1,16 +1,43 @@
from aiogram import F
from aiogram.enums import ChatType
from aiogram.filters import Command
-from aiogram.types import Message, CallbackQuery
+from aiogram.types import Message, CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
from bozenka.database.tables.telegram import TelegramChatSettings
-from bozenka.features import BasicFeature
-from bozenka.instances.telegram.utils.callbacks_factory import CloseThread, OpenThread
-from bozenka.instances.telegram.utils.filters import UserHasPermissions, BotHasPermissions
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard, close_thread_keyboard, open_thread_keyboard
+from bozenka.features.main import BasicFeature
+from bozenka.instances.telegram.utils.callbacks_factory import CloseThread, OpenThread, DeleteMenu
+from bozenka.instances.telegram.filters import UserHasPermissions, BotHasPermissions
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard
from bozenka.instances.telegram.utils.simpler import SolutionSimpler
+# Close / Open thread commands related keyboards
+def telegram_close_thread_keyboard(user_id: int) -> InlineKeyboardMarkup:
+ """
+ Generate menu for /close command
+ :param user_id: User_if of member, who closed thread
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[
+ [InlineKeyboardButton(text="Окрыть обсуждение 🛠️", callback_data=OpenThread(user_id=user_id).pack())],
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())]
+ ])
+ return kb
+
+
+def telegram_open_thread_keyboard(user_id: int) -> InlineKeyboardMarkup:
+ """
+ Generate menu for /open command
+ :param user_id: User_if of member, who opened thread
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[
+ [InlineKeyboardButton(text="Закрыть обсуждение 🛠️", callback_data=CloseThread(user_id=user_id).pack())],
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())]
+ ])
+ return kb
+
+
class Threads(BasicFeature):
"""
A class of topics / threads related commands
@@ -25,7 +52,7 @@ class Threads(BasicFeature):
"""
config = await SolutionSimpler.close_topic(msg=msg)
await msg.answer(config[0],
- reply_markup=close_thread_keyboard(user_id=msg.from_user.id)
+ reply_markup=telegram_close_thread_keyboard(user_id=msg.from_user.id)
if config[1] else delete_keyboard(msg.from_user.id))
async def telegram_reopen_topic_cmd_handler(msg: Message) -> None:
@@ -36,7 +63,7 @@ class Threads(BasicFeature):
"""
config = await SolutionSimpler.open_topic(msg=msg)
await msg.answer(config[0],
- reply_markup=open_thread_keyboard(user_id=msg.from_user.id)
+ reply_markup=telegram_open_thread_keyboard(user_id=msg.from_user.id)
if config[1] else delete_keyboard(msg.from_user.id))
async def telegram_close_general_topic_cmd_handler(msg: Message) -> None:
@@ -47,7 +74,7 @@ class Threads(BasicFeature):
"""
config = await SolutionSimpler.close_general_topic(msg=msg)
await msg.answer(config[0],
- reply_markup=close_thread_keyboard(user_id=msg.from_user.id)
+ reply_markup=telegram_close_thread_keyboard(user_id=msg.from_user.id)
if config[1] else delete_keyboard(msg.from_user.id))
async def telegram_reopen_general_topic_cmd(msg: Message) -> None:
@@ -58,7 +85,7 @@ class Threads(BasicFeature):
"""
config = await SolutionSimpler.open_general_topic(msg=msg)
await msg.answer(config[0],
- reply_markup=open_thread_keyboard(user_id=msg.from_user.id)
+ reply_markup=telegram_open_thread_keyboard(user_id=msg.from_user.id)
if config[1] else delete_keyboard(msg.from_user.id))
async def telegram_hide_general_topic_cmd_handler(msg: Message) -> None:
@@ -94,7 +121,7 @@ class Threads(BasicFeature):
config = await SolutionSimpler.close_topic(msg=call.message, call=call)
await call.message.edit_text(
config[0],
- reply_markup=close_thread_keyboard(user_id=call.from_user.id) if config[1] else
+ reply_markup=telegram_close_thread_keyboard(user_id=call.from_user.id) if config[1] else
delete_keyboard(admin_id=call.from_user.id)
)
@@ -111,7 +138,7 @@ class Threads(BasicFeature):
config = await SolutionSimpler.open_topic(msg=call.message, call=call)
await call.message.edit_text(
config[0],
- reply_markup=open_thread_keyboard(user_id=call.from_user.id) if config[1] else
+ reply_markup=telegram_open_thread_keyboard(user_id=call.from_user.id) if config[1] else
delete_keyboard(admin_id=call.from_user.id)
)
diff --git a/bozenka/features/basic/setup.py b/bozenka/features/basic/setup.py
index 43ac28d..0da0696 100644
--- a/bozenka/features/basic/setup.py
+++ b/bozenka/features/basic/setup.py
@@ -1,16 +1,74 @@
from aiogram import F
from aiogram.enums import ChatType
from aiogram.filters import Command
-from aiogram.types import Message, CallbackQuery
+from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
+from aiogram.utils.keyboard import InlineKeyboardBuilder
from sqlalchemy import Update
from sqlalchemy.ext.asyncio import async_sessionmaker
from bozenka.database.tables.telegram import get_chat_config_value, TelegramChatSettings
-from bozenka.features import BasicFeature
+from bozenka.features.main import BasicFeature
+from bozenka.instances.customizable_features_list import categorized_customizable_features, text_transcription
from bozenka.instances.telegram.utils.callbacks_factory import SetupAction, SetupFeature, SetupCategory
-from bozenka.instances.telegram.utils.filters import IsOwner
-from bozenka.instances.telegram.utils.keyboards import setup_keyboard, setup_category_keyboard, setup_feature_keyboard
-from bozenka.instances.telegram.utils.simpler import list_of_features
+from bozenka.instances.telegram.filters import IsOwner
+
+
+# Setup related keyboards
+def setup_keyboard() -> InlineKeyboardMarkup:
+ """
+ Generate keyboard for /setup command
+ :return:
+ """
+ kb = InlineKeyboardBuilder()
+
+ for category in categorized_customizable_features:
+ kb.row(InlineKeyboardButton(text=text_transcription[category],
+ callback_data=SetupCategory(category_name=category).pack()))
+
+ return kb.as_markup()
+
+
+def setup_category_keyboard(category: str) -> InlineKeyboardMarkup:
+ """
+ Generate keyboard for one of categories
+ :param category:
+ :return:
+ """
+ kb = InlineKeyboardBuilder()
+ for setting in categorized_customizable_features[category]:
+ kb.row(InlineKeyboardButton(text=setting.name,
+ callback_data=SetupFeature(
+ feature_index=categorized_customizable_features[category].index(setting),
+ feature_category=category
+ ).pack()))
+ return kb.as_markup()
+
+
+async def setup_feature_keyboard(category: str, index: int, is_enabled: bool) -> InlineKeyboardMarkup:
+ """
+ Generate keyboard for enabling or disabling
+ on of features
+ :param is_enabled:
+ :param category:
+ :param index:
+
+ :return:
+ """
+
+ from aiogram.types import InlineKeyboardButton
+ kb = InlineKeyboardMarkup(inline_keyboard=[[
+ InlineKeyboardButton(text="Выключить ❌", callback_data=SetupAction(action="disable",
+ feature_category=category,
+ feature_index=index).pack())
+ if is_enabled else
+ InlineKeyboardButton(text="Включить ✅", callback_data=SetupAction(action="enable",
+ feature_category=category,
+ feature_index=index).pack())
+ ], [
+ InlineKeyboardButton(text="Вернуться 🔙", callback_data=SetupAction(action="back",
+ feature_category=category,
+ feature_index=index).pack())]])
+ return kb
class Setup(BasicFeature):
@@ -25,58 +83,59 @@ class Setup(BasicFeature):
:param msg: Telegram message object
:return: Nothing
"""
- await msg.answer("Привет владелец чата 👋\n"
+ await msg.answer("Привет владелец чата 👋\n\n"
"Настрой меня - бота так, как тебе удобно, и я буду помогать тебе в чате с определенными функциями.\n"
"Используй меню настроек ниже, чтобы указать, какие функции, которые я умею, должен выполнять.",
reply_markup=setup_keyboard())
- async def telegram_setup_categories_handler(call: CallbackQuery, callback_data: SetupCategory | SetupAction):
+ async def telegram_setup_categories_handler(call: CallbackQuery, callback_data: SetupCategory | SetupAction) -> None:
"""
Query, what shows list of features to enable.
- :param call:
- :param callback_data:
- :return:
+ :param call: CallbackQuery class
+ :param callback_data: SetupCategory or SetupAction
+ :return: None
"""
- await call.message.edit_text("Выберите настройку, которую хотите изменить",
+ await call.message.edit_text(f"{text_transcription[callback_data.category_name]}\n\n"
+ f"Выберите функцию, которые вы хотите настроить в данной категории у бота.",
reply_markup=setup_category_keyboard(category=callback_data.category_name))
- async def telegram_setup_edit_feature_handler(call: CallbackQuery, callback_data: SetupFeature, session_maker: async_sessionmaker):
+ async def telegram_setup_edit_feature_handler(call: CallbackQuery, callback_data: SetupFeature, session_maker: async_sessionmaker) -> None:
"""
Query, what shows menu to enable / disable feature
- :param call:
- :param callback_data:
- :param session_maker:
- :return:
+ :param call: CallbackQuery class
+ :param callback_data: SetupFeature class
+ :param session_maker: AsyncSessionMaker SqlAlchemy object
+ :return: None
"""
is_enabled = await get_chat_config_value(
chat_id=call.message.chat.id,
session=session_maker,
- setting=list_of_features[callback_data.feature_category][callback_data.feature_index]
+ setting=categorized_customizable_features[callback_data.feature_category][callback_data.feature_index]
)
await call.message.edit_text(
- list_of_features[callback_data.feature_category][callback_data.feature_index].description,
+ categorized_customizable_features[callback_data.feature_category][callback_data.feature_index].telegram_setting_description,
reply_markup=await setup_feature_keyboard(category=callback_data.feature_category,
index=callback_data.feature_index,
is_enabled=is_enabled))
- async def telegram_features_edit_handler(call: CallbackQuery, callback_data: SetupAction, session_maker: async_sessionmaker):
+ async def telegram_features_edit_handler(call: CallbackQuery, callback_data: SetupAction, session_maker: async_sessionmaker) -> None:
"""
Query, what shows menu to enable / disable feature
after editing
- :param call:
- :param callback_data:
- :param session_maker:
- :return:
+ :param call: CallbackQuery class
+ :param callback_data: SetupAction class
+ :param session_maker: AsyncSessionMaker SqlAlchemy object
+ :return: None
"""
async with session_maker() as session:
async with session.begin():
await session.execute(Update(TelegramChatSettings)
.values(
- {list_of_features[callback_data.category_name][callback_data.feature_index].settings_name: callback_data.action == "enable"})
+ {categorized_customizable_features[callback_data.category_name][callback_data.feature_index].telegram_setting_description: callback_data.action == "enable"})
.where(TelegramChatSettings.chat_id == call.message.chat.id))
await call.message.edit_text(
- list_of_features[callback_data.category_name][callback_data.feature_index].description,
+ categorized_customizable_features[callback_data.feature_category][callback_data.feature_index].telegram_setting_description,
reply_markup=await setup_feature_keyboard(category=callback_data.category_name,
index=callback_data.afeature_index,
is_enabled=callback_data.action == "enable"))
diff --git a/bozenka/features/basic/start.py b/bozenka/features/basic/start.py
index 3194b91..8404995 100644
--- a/bozenka/features/basic/start.py
+++ b/bozenka/features/basic/start.py
@@ -4,12 +4,11 @@ from aiogram.filters import Command
from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
-from bozenka.features import BasicFeature
+from bozenka.features.main import BasicFeature
+from bozenka.instances.customizable_features_list import categorized_customizable_features, text_transcription
from bozenka.instances.telegram.utils.callbacks_factory import HelpCategory, HelpBackCategory, HelpFeature, HelpBack
-from bozenka.instances.telegram.utils.keyboards import help_category_keyboard, help_keyboard, \
- help_feature_keyboard, gpt_categories_keyboard
-from bozenka.instances.telegram.utils.simpler import list_of_features
-from bozenka.instances.version import build, is_updated
+from bozenka.features.user.text_generation import gpt_categories_keyboard
+from bozenka.instances.current_version import build, is_updated
telegram_main_menu = InlineKeyboardMarkup(
inline_keyboard=[
@@ -23,6 +22,51 @@ telegram_main_menu = InlineKeyboardMarkup(
)
+# Help related keyboards
+def main_help_keyboard() -> InlineKeyboardMarkup:
+ """
+ Generate keyboard for /help command
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardBuilder()
+ for category in categorized_customizable_features:
+ kb.row(InlineKeyboardButton(text=text_transcription[category],
+ callback_data=HelpCategory(category_name=category).pack()))
+
+ return kb.as_markup()
+
+
+def help_category_keyboard(category: str) -> InlineKeyboardMarkup:
+ """
+ Generate keyboard for one of categories
+ :param category: Category name
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardBuilder()
+ for setting in categorized_customizable_features[category]:
+ kb.row(InlineKeyboardButton(text=setting.telegram_setting_name,
+ callback_data=HelpFeature(
+ feature_index=categorized_customizable_features[category].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: Category name
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[
+ [InlineKeyboardButton(text="🔙 Назад к списку функций",
+ callback_data=HelpBackCategory(category_name=category).pack())]
+ ])
+ return kb
+
+
class Start(BasicFeature):
"""
A class of /start command
@@ -42,7 +86,7 @@ class Start(BasicFeature):
:return: None
"""
await call.message.edit_text("Выберите категорию, по которой нужна помощь:",
- reply_markup=help_keyboard())
+ reply_markup=main_help_keyboard())
await call.answer()
@staticmethod
@@ -66,7 +110,7 @@ class Start(BasicFeature):
:return: None
"""
await call.message.edit_text(
- list_of_features[callback_data.feature_category][callback_data.feature_index].description,
+ categorized_customizable_features[callback_data.feature_category][callback_data.feature_index]. telegram_setting_description,
reply_markup=help_feature_keyboard(category=callback_data.feature_category))
await call.answer()
@@ -78,7 +122,7 @@ class Start(BasicFeature):
:return: None
"""
await call.message.edit_text("Выберите категорию функций, по которой вам нужна помощь 🤖",
- reply_markup=help_keyboard())
+ reply_markup=main_help_keyboard())
await call.answer()
@staticmethod
diff --git a/bozenka/features/main.py b/bozenka/features/main.py
new file mode 100644
index 0000000..0729daa
--- /dev/null
+++ b/bozenka/features/main.py
@@ -0,0 +1,27 @@
+class BasicFeature:
+ """
+ A classic class of lineral (basic)
+ feature of bozenka. IN FUTURE!
+ :param telegram_setting_in_list: Does feature shows in /setup list
+ """
+ telegram_setting_in_list: bool = False # Does feature shows in /setup list
+ telegram_setting_name: str | None = None # Setting title in /setup command
+ telegram_setting_description: str | None = None # Setting description in /setup command
+ telegram_db_name = None # Name of TelegramChatSettings column will be affected
+ telegram_category: str | None = None # Telegram category name, current
+ # Telegram commands list of feature
+ telegram_commands: dict[str: str] = {
+ #
+ # Format is "CommandNameHere": "Command description is here"
+ #
+ "example": "Its an example"
+ }
+ telegram_cmd_avaible = True # Does this feature have a telegram commands
+
+ # All handlers to register automaticly by bozenka
+ telegram_message_handlers = [
+ # Format is [Handler, [Filters]]
+ ]
+ telegram_callback_handlers = [
+ # Format is [Handler, [Filters]]
+ ]
diff --git a/bozenka/features/user/image_generation.py b/bozenka/features/user/image_generation.py
index a93f70e..ecc5007 100644
--- a/bozenka/features/user/image_generation.py
+++ b/bozenka/features/user/image_generation.py
@@ -4,18 +4,65 @@ from typing import Callable
from aiogram import Dispatcher
from aiogram.filters import CommandObject, Command
from aiogram.fsm.context import FSMContext
-from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery, FSInputFile
+from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery, FSInputFile, InlineKeyboardButton
+from aiogram.utils.keyboard import InlineKeyboardBuilder
from sqlalchemy.ext.asyncio import async_sessionmaker
from bozenka.database.tables.telegram import TelegramChatSettings
-from bozenka.features import BasicFeature
+from bozenka.features.main import BasicFeature
+from bozenka.generative import image_generative_size, image_generative_categories
from bozenka.generative.kadinsky import kadinsky_gen
-from bozenka.instances.telegram.utils.callbacks_factory import ImageGenerationCategory, ImageGeneration
-from bozenka.instances.telegram.utils.keyboards import image_resolution_keyboard, delete_keyboard, \
- image_generation_keyboard, image_response_keyboard
+from bozenka.instances.telegram.utils.callbacks_factory import ImageGenerationCategory, ImageGeneration, DeleteMenu, \
+ GptStop
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard
from bozenka.instances.telegram.utils.simpler import GeneratingImages
+def telegram_image_response_keyboard(user_id: int) -> InlineKeyboardMarkup:
+ """
+ Generating menu for image
+ :param user_id: User_id of called user
+ :return: InlineKeyboardMarkup
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())],
+ [InlineKeyboardButton(text="Хватит 🚫", callback_data=GptStop(user_id=str(user_id)).pack())]
+ ])
+ return kb
+
+
+def telegram_image_resolution_keyboard(user_id: int, category: str) -> InlineKeyboardMarkup:
+ """
+ Create keyboard with list of resolution to generate image
+ :param category: Category name
+ :param user_id: User_id of called user
+ :return: InlineKeyboardMarkup
+ """
+ builder = InlineKeyboardBuilder()
+ for size in image_generative_size:
+ builder.row(InlineKeyboardButton(text=size,
+ callback_data=ImageGeneration(
+ user_id=user_id,
+ category=category,
+ size=size
+ ).pack()))
+ return builder.as_markup()
+
+
+def telegram_image_generation_categories_keyboard(user_id: int) -> InlineKeyboardMarkup:
+ """
+ Create keyboard with list of image generation librarioes avaible in the bozenka
+ :param user_id: User_id of called user
+ :return: InlineKeyboardMarkup
+ """
+ builder = InlineKeyboardBuilder()
+ for category in image_generative_categories:
+ builder.row(InlineKeyboardButton(text=category,
+ callback_data=ImageGenerationCategory(user_id=user_id,
+ category=category).pack()))
+ return builder.as_markup()
+
+
class ImageGeneratrion(BasicFeature):
"""
A classic class of lineral (basic)
@@ -38,8 +85,8 @@ class ImageGeneratrion(BasicFeature):
await state.update_data(set_category=callback_data.category)
await state.set_state(GeneratingImages.set_size)
await call.message.edit_text("Пожалуста, выберите размер изображения 🖼",
- reply_markup=image_resolution_keyboard(user_id=call.from_user.id,
- category=callback_data.category))
+ reply_markup=telegram_image_resolution_keyboard(user_id=call.from_user.id,
+ category=callback_data.category))
async def telegram_end_generation_handler(call: CallbackQuery, callback_data: ImageGeneration,
state: FSMContext) -> None:
@@ -81,7 +128,7 @@ class ImageGeneratrion(BasicFeature):
if await state.get_state():
return
await msg.answer("Пожалуста, выберите сервис / модель для генерации изображений",
- reply_markup=image_generation_keyboard(user_id=msg.from_user.id))
+ reply_markup=telegram_image_generation_categories_keyboard(user_id=msg.from_user.id))
async def telegram_kadinsky_generating_handler(msg: Message, state: FSMContext) -> None:
"""
@@ -110,13 +157,13 @@ class ImageGeneratrion(BasicFeature):
photo = FSInputFile(path)
await msg.answer_photo(photo=photo,
caption=msg.text,
- reply_markup=image_response_keyboard(user_id=msg.from_user.id))
+ reply_markup=telegram_image_response_keyboard(user_id=msg.from_user.id))
await message.delete()
else:
await message.edit_text("Простите, произошла ошибка 😔\n"
"Убедитесь, что севрера kadinsky работают и ваш промт не является неподобающим и неприемлимым\n"
"Если это продолжается, пожалуйста используйте /cancel",
- reply_markup=image_response_keyboard(user_id=msg.from_user.id))
+ reply_markup=telegram_image_response_keyboard(user_id=msg.from_user.id))
except Exception as ex:
logging.log(msg=f"Get an exception for generating answer={ex}",
diff --git a/bozenka/features/user/text_generation.py b/bozenka/features/user/text_generation.py
index 332c8c1..ee41015 100644
--- a/bozenka/features/user/text_generation.py
+++ b/bozenka/features/user/text_generation.py
@@ -1,26 +1,284 @@
import logging
+from typing import Any
import g4f
from aiogram import F
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
-from aiogram.types import Message, CallbackQuery
+from aiogram.types import Message, CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
+from aiogram.utils.keyboard import InlineKeyboardBuilder
from gpt4all import GPT4All
from bozenka.database.tables.telegram import TelegramChatSettings
-from bozenka.features import BasicFeature
+from bozenka.features.main import BasicFeature
+from bozenka.generative import text_generative_categories
from bozenka.generative.gpt4all import model_path, check
-from bozenka.generative.gpt4free import generate_gpt4free_providers
+from bozenka.generative.gpt4free import generate_gpt4free_providers, generate_gpt4free_models
from bozenka.instances.telegram.utils.callbacks_factory import Gpt4FreeProvsModelPage, Gpt4FreeProviderPage, \
Gpt4AllSelect, Gpt4AllModel, GptCategory, Gpt4freeResult, \
Gpt4FreeProvider, GptBackMenu, Gpt4FreeModel, Gpt4FreeCategory, Gpt4FreeModelPage, GptStop
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard, \
- text_response_keyboard, gpt_categories_keyboard, \
- gpt4free_models_by_provider_keyboard, gpt4free_providers_keyboard, gpt4all_model_menu, generate_gpt4all_page, \
- gpt4free_categories_keyboard, gpt4free_models_keyboard
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard
from bozenka.instances.telegram.utils.simpler import AnsweringGPT4Free, AnsweringGpt4All
+
+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 text_generative_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 text_response_keyboard(user_id: int) -> InlineKeyboardMarkup:
+ """
+ Generating menu for response from GPT
+ :param user_id:
+ :return:
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[
+ [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())],
+ [InlineKeyboardButton(text="Завершить диалог 🚫", callback_data=GptStop(user_id=str(user_id)).pack())]
+ ])
+ return kb
+
+
+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="g4fcategory").pack())],
+ [InlineKeyboardButton(text="Спасибо, не надо ❌",
+ callback_data=GptStop(user_id=str(user_id)).pack())]])
+ return generated_page
+
+
+def gpt4free_categories_keyboard(user_id: int) -> InlineKeyboardMarkup:
+ """
+ Menu of categories in Gpt4Free (Providers / Models)
+ :param user_id:
+ :return:
+ """
+ print("!231234")
+ kb = InlineKeyboardMarkup(inline_keyboard=[[
+ InlineKeyboardButton(text="По моделям 🤖",
+ callback_data=Gpt4FreeCategory(category="models", user_id=user_id).pack())
+ ], [
+ InlineKeyboardButton(text="По провайдерам 🤖",
+ callback_data=Gpt4FreeCategory(category="providers", user_id=user_id).pack())
+ ]])
+ return kb
+
+
+def gpt4free_models_keyboard(user_id: int, page: int) -> InlineKeyboardMarkup:
+ """
+ Generating list of GPT4FREE models, can be used to generate text.
+ :param user_id:
+ :param page:
+ :return:
+ """
+ builder = InlineKeyboardBuilder()
+ full_list = g4f.ModelUtils.convert.keys()
+ models = items_list_generator(page=page, list_of_items=full_list, count_of_items=4)
+ pages = [len(full_list) // 4 - 1 if page - 1 == -1 else page - 1,
+ 0 if page + 1 >= len(full_list) // 4 else page + 1]
+
+ for model in models:
+ builder.row(InlineKeyboardButton(text=model,
+ callback_data=Gpt4FreeModel(user_id=user_id, model=model).pack()))
+ builder.row(
+ # First page button
+ InlineKeyboardButton(text=str(len(full_list) // 4 if page == 0 else "1"),
+ callback_data=Gpt4FreeModelPage(
+ page=str(len(full_list) // 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], ).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]).pack()),
+ # Last page button
+ InlineKeyboardButton(text=str(len(full_list) // 4 if page != 0 else "1"),
+ callback_data=Gpt4FreeModelPage(
+ page=str(len(full_list) // 4 - 1) if page != 0 else "1",
+ user_id=user_id).pack(), ))
+ builder.row(InlineKeyboardButton(text="🔙 Вернуться",
+ callback_data=GptBackMenu(user_id=user_id, back_to="g4fcategory").pack()))
+ builder.row(InlineKeyboardButton(text="Спасибо, не надо ❌",
+ callback_data=GptStop(user_id=str(user_id)).pack()))
+ return builder.as_markup()
+
+
+def gpt4free_models_by_provider_keyboard(user_id: int, provider: str, 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:
+ :return:
+ """
+ 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=Gpt4FreeProvsModelPage(
+ page=str(len(models[provider]) // 4 - 1 if page == 0 else "1"),
+ user_id=user_id,
+ provider=provider).pack(),
+ ),
+ # Page back button
+ InlineKeyboardButton(text="⬅️",
+ callback_data=Gpt4FreeProvsModelPage(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=Gpt4FreeProvsModelPage(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=Gpt4FreeProvsModelPage(
+ 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), index=str(models.index(model))).pack())
+ )
+ builder.row(InlineKeyboardButton(text="🔙 Вернуться к списку",
+ callback_data=GptBackMenu(user_id=user_id, back_to="g4fcategory").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, 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
+
+
+
+
class TextGeneratrion(BasicFeature):
"""
A class, what have inside all handlers / functions
diff --git a/bozenka/features/user/welcome.py b/bozenka/features/user/welcome.py
index 9dbcfbe..facfa60 100644
--- a/bozenka/features/user/welcome.py
+++ b/bozenka/features/user/welcome.py
@@ -6,9 +6,7 @@ from aiogram.types import Message, CallbackQuery
from sqlalchemy.ext.asyncio import async_sessionmaker
from bozenka.database.tables.telegram import TelegramChatSettings
-from bozenka.features import BasicFeature
-from bozenka.instances.telegram.utils.callbacks_factory import PinMsg, UnpinMsg
-from bozenka.instances.telegram.utils.keyboards import unpin_msg_keyboard, delete_keyboard, pin_msg_keyboard
+from bozenka.features.main import BasicFeature
from bozenka.instances.telegram.utils.simpler import SolutionSimpler
diff --git a/bozenka/generative/__init__.py b/bozenka/generative/__init__.py
index f69fa20..4bd1f7d 100644
--- a/bozenka/generative/__init__.py
+++ b/bozenka/generative/__init__.py
@@ -1,14 +1,6 @@
import dataclasses
-@dataclasses
-class QueryPosition:
- """
- Class of Query to generate something
- with models
- """
- data: dict
- instance: str
# List of text generative categories, what we support
text_generative_categories = [
diff --git a/bozenka/instances/__init__.py b/bozenka/instances/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bozenka/instances/basic_features_list.py b/bozenka/instances/basic_features_list.py
new file mode 100644
index 0000000..e70b04a
--- /dev/null
+++ b/bozenka/instances/basic_features_list.py
@@ -0,0 +1,6 @@
+from bozenka.features import Setup, Start
+
+basic_features = [
+ Setup,
+ Start
+]
diff --git a/bozenka/instances/version.py b/bozenka/instances/current_version.py
similarity index 100%
rename from bozenka/instances/version.py
rename to bozenka/instances/current_version.py
diff --git a/bozenka/instances/customizable_features_list.py b/bozenka/instances/customizable_features_list.py
new file mode 100644
index 0000000..d83d7f5
--- /dev/null
+++ b/bozenka/instances/customizable_features_list.py
@@ -0,0 +1,30 @@
+import bozenka.features.admin
+from bozenka.features import *
+from bozenka.features.admin import *
+
+customizable_features = [
+ # Admin related category
+ Moderation,
+ Invite,
+ Pins,
+ Threads,
+ ChatInformation,
+ # User related category
+ ImageGeneratrion,
+ TextGeneratrion,
+ Welcome,
+]
+
+text_transcription = {
+ "user": "Пользователи 👤",
+ "admin": "Администраторы 👮♂"
+}
+
+categorized_customizable_features = {}
+
+for feature in customizable_features:
+ if feature.telegram_setting_in_list:
+ if feature.telegram_category in categorized_customizable_features.keys():
+ categorized_customizable_features[feature.telegram_category].append(feature)
+ else:
+ categorized_customizable_features[feature.telegram_category] = [feature]
diff --git a/bozenka/instances/features_list.py b/bozenka/instances/features_list.py
deleted file mode 100644
index 57b66e0..0000000
--- a/bozenka/instances/features_list.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from bozenka.features import *
-
-features_list = [
- # Admin related category
- Moderation,
- Invite,
- Pins,
- Threads,
- ChatInformation,
- # User related category
- ImageGeneratrion,
- TextGeneratrion,
- Welcome,
- # Basic Functions
- Setup,
- Start
-]
-
-customizable_features = {}
-
-for feature in features_list:
- if feature.telegram_setting_in_list:
- if feature.telegram_category in customizable_features.keys():
- customizable_features[feature.telegram_category].append(feature)
- else:
- customizable_features[feature.telegram_category] = [feature]
diff --git a/bozenka/instances/telegram/__init__.py b/bozenka/instances/telegram/__init__.py
index 56b5c84..e510a49 100644
--- a/bozenka/instances/telegram/__init__.py
+++ b/bozenka/instances/telegram/__init__.py
@@ -5,13 +5,12 @@ from aiogram import Dispatcher, Bot
from aiogram.types import BotCommand
from sqlalchemy.ext.asyncio import async_sessionmaker
-from bozenka.features import BasicFeature
-from bozenka.instances.features_list import features_list
-from bozenka.instances.telegram.utils.simpler import list_of_commands
+from bozenka.instances.basic_features_list import basic_features
+from bozenka.instances.customizable_features_list import customizable_features
from bozenka.instances.telegram.queries import *
-async def register_all_features(list_of_features: list[BasicFeature], dispatcher: Dispatcher, bot: Bot) -> None:
+async def register_all_features(list_of_features: list, dispatcher: Dispatcher, bot: Bot) -> None:
"""
Registers all features / handlers avaible in bozenka
:param list_of_features: List of features
@@ -34,10 +33,6 @@ async def register_all_features(list_of_features: list[BasicFeature], dispatcher
await bot.set_my_commands(cmd_list)
- # Registering other handlers
- await dispatcher.callback_query.register(delete_callback_handler, DeleteMenu.filter())
- await dispatcher.callback_query.register(hide_menu_handler, HideMenu.filter())
-
async def launch_telegram_instance(session_maker: async_sessionmaker) -> None:
"""
@@ -51,7 +46,15 @@ async def launch_telegram_instance(session_maker: async_sessionmaker) -> None:
dp = Dispatcher()
+ # Registering other handlers
+ dp.callback_query.register(delete_callback_handler, DeleteMenu.filter())
+ dp.callback_query.register(hide_menu_handler, HideMenu.filter())
+
await dp.start_polling(bot,
session_maker=session_maker, # Pass your async_sessionmaker here, you can do dependency injection
- on_startup=[await register_all_features(list_of_features=features_list, dispatcher=dp, bot=bot)]
+ on_startup=[
+ await register_all_features(list_of_features=customizable_features, dispatcher=dp, bot=bot),
+ await register_all_features(list_of_features=basic_features, dispatcher=dp, bot=bot)
+
+ ]
)
diff --git a/bozenka/instances/telegram/utils/filters/__init__.py b/bozenka/instances/telegram/filters/__init__.py
similarity index 100%
rename from bozenka/instances/telegram/utils/filters/__init__.py
rename to bozenka/instances/telegram/filters/__init__.py
diff --git a/bozenka/instances/telegram/utils/filters/chat_setting.py b/bozenka/instances/telegram/filters/chat_setting.py
similarity index 53%
rename from bozenka/instances/telegram/utils/filters/chat_setting.py
rename to bozenka/instances/telegram/filters/chat_setting.py
index 3bd0dba..eb44b3b 100644
--- a/bozenka/instances/telegram/utils/filters/chat_setting.py
+++ b/bozenka/instances/telegram/filters/chat_setting.py
@@ -3,7 +3,6 @@ from aiogram.types import Message
from sqlalchemy.ext.asyncio import async_sessionmaker
from bozenka.database.tables.telegram import get_chat_configuration, get_chat_config_value
-from bozenka.instances.telegram.utils.simpler import list_of_features
class IsSettingEnabled(Filter):
@@ -11,17 +10,16 @@ class IsSettingEnabled(Filter):
Check, does chat have enabled required feature
"""
- def __init__(self, setting: str) -> None:
+ def __init__(self, setting) -> None:
self.setting = setting
async def __call__(self, msg: Message, session_maker: async_sessionmaker) -> bool:
- setting_object = None
- for key in list_of_features.items():
- for feature in list_of_features[key]:
- if feature.setting_name == self.setting:
- setting_object = feature
- else:
- continue
+ """
+ Working after calling this filter
+ :param msg: Message telegram boject
+ :param session_maker: AsyncSessionMaker SqlAlchemy object
+ :return: Is config enabled
+ """
- return await get_chat_config_value(chat_id=msg.chat.id, session=session_maker, setting=setting_object)
+ return await get_chat_config_value(chat_id=msg.chat.id, session=session_maker, setting=self.setting)
diff --git a/bozenka/instances/telegram/utils/filters/permissions.py b/bozenka/instances/telegram/filters/permissions.py
similarity index 85%
rename from bozenka/instances/telegram/utils/filters/permissions.py
rename to bozenka/instances/telegram/filters/permissions.py
index 100a196..1261ae5 100644
--- a/bozenka/instances/telegram/utils/filters/permissions.py
+++ b/bozenka/instances/telegram/filters/permissions.py
@@ -3,8 +3,9 @@ from typing import Any
from aiogram.filters import Filter
from aiogram.methods import GetChatMember
from aiogram.types import Message, ChatPermissions, CallbackQuery
-from aiogram.enums import ChatMemberStatus
-from bozenka.instances.telegram.utils.simpler import ru_cmds
+from aiogram.enums import ChatMemberStatus, ChatType
+
+from bozenka.instances.telegram.utils.keyboards import delete_keyboard
class UserHasPermissions(Filter):
@@ -149,14 +150,29 @@ class IsAdminFilter(Filter):
"""
user = await msg.chat.get_member(msg.from_user.id)
bot = await msg.chat.get_member(msg.bot.id)
+
+ if msg.chat.type == ChatType.PRIVATE:
+ return False
+
if ChatMemberStatus.ADMINISTRATOR != user.status and ChatMemberStatus.CREATOR != user.status:
if bot.status != ChatMemberStatus.ADMINISTRATOR:
await msg.reply("Ошибка ❌\n"
- "У вас нет прав на использование этой комманды. У меня нет прав на использование 🚫")
+ "У вас нет прав на использование этой комманды. \n"
+ "У меня нет прав для осуществления этой комманды 🚫",
+ reply_markup=delete_keyboard())
+ return False
else:
await msg.reply("Ошибка ❌\n"
- "У вас нет прав на использование этой комманды 🚫")
+ "У вас нет прав на использование этой комманды 🚫",
+ reply_markup=delete_keyboard())
+ return False
+
+ if bot.status != ChatMemberStatus.ADMINISTRATOR:
+ await msg.reply("Ошибка ❌\n"
+ "У меня нет прав для осуществления этой комманды 🚫",
+ reply_markup=delete_keyboard())
return False
+
if ChatMemberStatus.CREATOR == user.status:
return True
return ChatMemberStatus.ADMINISTRATOR == user.status or ChatMemberStatus.CREATOR == user.status
diff --git a/bozenka/instances/telegram/utils/middleware/__init__.py b/bozenka/instances/telegram/middleware/__init__.py
similarity index 74%
rename from bozenka/instances/telegram/utils/middleware/__init__.py
rename to bozenka/instances/telegram/middleware/__init__.py
index 4b6f273..8341dac 100644
--- a/bozenka/instances/telegram/utils/middleware/__init__.py
+++ b/bozenka/instances/telegram/middleware/__init__.py
@@ -1,9 +1,6 @@
import logging
-from aiogram import Router, Dispatcher
-
-from bozenka.instances.telegram.utils.middleware.antiflood import MessageThrottlingMiddleware, \
- CallbackThrottlingMiddleware, CounterMiddleware
+from aiogram import Dispatcher
def register_middlewares(dp: Dispatcher) -> None:
diff --git a/bozenka/instances/telegram/utils/middleware/antiflood.py b/bozenka/instances/telegram/middleware/antiflood.py
similarity index 100%
rename from bozenka/instances/telegram/utils/middleware/antiflood.py
rename to bozenka/instances/telegram/middleware/antiflood.py
diff --git a/bozenka/instances/telegram/utils/middleware/retry.py b/bozenka/instances/telegram/middleware/retry.py
similarity index 100%
rename from bozenka/instances/telegram/utils/middleware/retry.py
rename to bozenka/instances/telegram/middleware/retry.py
diff --git a/bozenka/instances/telegram/utils/__init__.py b/bozenka/instances/telegram/utils/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bozenka/instances/telegram/utils/delete.py b/bozenka/instances/telegram/utils/delete.py
new file mode 100644
index 0000000..74658f9
--- /dev/null
+++ b/bozenka/instances/telegram/utils/delete.py
@@ -0,0 +1,16 @@
+from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
+
+from bozenka.instances.telegram.utils.callbacks_factory import *
+
+
+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: User_id of user to work with this
+ :return: None
+ """
+ kb = InlineKeyboardMarkup(inline_keyboard=[[
+ InlineKeyboardButton(text="Спасибо, удали сообщение ✅", callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())
+ ]])
+ return kb
diff --git a/bozenka/instances/telegram/utils/keyboards/__init__.py b/bozenka/instances/telegram/utils/keyboards/__init__.py
deleted file mode 100644
index 2453fe9..0000000
--- a/bozenka/instances/telegram/utils/keyboards/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .inline import *
diff --git a/bozenka/instances/telegram/utils/keyboards/inline.py b/bozenka/instances/telegram/utils/keyboards/inline.py
deleted file mode 100644
index 336ef1a..0000000
--- a/bozenka/instances/telegram/utils/keyboards/inline.py
+++ /dev/null
@@ -1,615 +0,0 @@
-import g4f
-import gpt4all
-
-from typing import Any
-
-from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, Message
-from aiogram.utils.keyboard import InlineKeyboardBuilder
-from gpt4all import GPT4All
-from sqlalchemy.ext.asyncio import async_sessionmaker
-
-from bozenka.database.tables.telegram import get_chat_config_value
-from bozenka.instances.features_list import customizable_features
-from bozenka.instances.telegram.utils.callbacks_factory import *
-from bozenka.instances.telegram.utils.simpler.lists_of_content import generate_list_of_features
-from bozenka.generative.gpt4free import generate_gpt4free_models, generate_gpt4free_providers
-from bozenka.generative import text_generative_categories, image_generative_categories, image_generative_size
-
-"""
-File, contains inline keyboard & menus and their work.
-Right now only on Russian language, multi-language planning soon.
-"""
-
-
-def start_keyboard() -> InlineKeyboardMarkup:
- """
- Generate keyboard for /start command
- """
- kb = InlineKeyboardMarkup(
- inline_keyboard=[
- [InlineKeyboardButton(text="Добавить в ваш групповой чат 🔌", callback_data="addtochat")],
- [InlineKeyboardButton(text="Информация об функционале бота 🔨", callback_data="functional")],
- [InlineKeyboardButton(text="О данном проекте ℹ️", callback_data="aboutdevs")],
- [InlineKeyboardButton(text="О данном запущенном экзепляре ℹ️", callback_data="aboutbot")],
- [InlineKeyboardButton(text="Начать диалог с текстовым ИИ 🤖", callback_data="dialogai")],
- [InlineKeyboardButton(text="Начать генерировать изображения 🖼", callback_data="dialogimage")],
- ]
- )
- return kb
-
-
-# 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())],
- [InlineKeyboardButton(text="Вернуться 🔙", callback_data="back")]
- ])
- 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(category_name=category).pack())]
- ])
- return kb
-
-
-# Setup related keyboards
-def setup_keyboard() -> InlineKeyboardMarkup:
- """
- Generate keyboard for /setup command
- :return:
- """
- kb = InlineKeyboardBuilder()
- translations = {
- "admin": "Администраторы 👮♂",
- "user": "Пользователи 👤"
- }
-
- for category in customizable_features:
- kb.row(InlineKeyboardButton(text=translations[category],
- callback_data=SetupCategory(category_name=category).pack()))
-
- return kb.as_markup()
-
-
-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()
-
-
-async def setup_feature_keyboard(category: str, index: int, is_enabled: bool) -> InlineKeyboardMarkup:
- """
- Generate keyboard for enabling or disabling
- on of features
- :param is_enabled:
- :param category:
- :param index:
-
- :return:
- """
-
- kb = InlineKeyboardMarkup(inline_keyboard=[[
- InlineKeyboardButton(text="Выключить ❌", callback_data=SetupAction(action="disable",
- feature_category=category,
- feature_index=index).pack())
- if is_enabled else
- InlineKeyboardButton(text="Включить ✅", callback_data=SetupAction(action="enable",
- feature_category=category,
- feature_index=index).pack())
- ], [
- InlineKeyboardButton(text="Вернуться 🔙", callback_data=SetupAction(action="back",
- feature_category=category,
- feature_index=index).pack())]])
- return kb
-
-
-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=DeleteMenu(user_id_clicked=str(admin_id)).pack())
- ]])
- return kb
-
-
-def image_resolution_keyboard(user_id: int, category: str) -> InlineKeyboardMarkup:
- """
- Create keyboard with list of resolution to generate image
- :param user_id:
- :param category:
- :return:
- """
- builder = InlineKeyboardBuilder()
- for size in image_generative_size:
- builder.row(InlineKeyboardButton(text=size,
- callback_data=ImageGeneration(
- user_id=user_id,
- category=category,
- size=size
- ).pack()))
- return builder.as_markup()
-
-
-def image_generation_keyboard(user_id: int) -> InlineKeyboardMarkup:
- """
- Create keyboard with list of image generation librarioes avaible in the bot
- :param user_id:
- :return:
- """
- builder = InlineKeyboardBuilder()
- for category in image_generative_categories:
- builder.row(InlineKeyboardButton(text=category,
- callback_data=ImageGenerationCategory(user_id=user_id,
- category=category).pack()))
- return builder.as_markup()
-
-
-# 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 text_generative_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="g4fcategory").pack())],
- [InlineKeyboardButton(text="Спасибо, не надо ❌",
- callback_data=GptStop(user_id=str(user_id)).pack())]])
- return generated_page
-
-
-def gpt4free_categories_keyboard(user_id: int) -> InlineKeyboardMarkup:
- """
- Menu of categories in Gpt4Free (Providers / Models)
- :param user_id:
- :return:
- """
- print("!231234")
- kb = InlineKeyboardMarkup(inline_keyboard=[[
- InlineKeyboardButton(text="По моделям 🤖",
- callback_data=Gpt4FreeCategory(category="models", user_id=user_id).pack())
- ], [
- InlineKeyboardButton(text="По провайдерам 🤖",
- callback_data=Gpt4FreeCategory(category="providers", user_id=user_id).pack())
- ]])
- return kb
-
-
-def gpt4free_models_keyboard(user_id: int, page: int) -> InlineKeyboardMarkup:
- """
- Generating list of GPT4FREE models, can be used to generate text.
- :param user_id:
- :param page:
- :return:
- """
- builder = InlineKeyboardBuilder()
- full_list = g4f.ModelUtils.convert.keys()
- models = items_list_generator(page=page, list_of_items=full_list, count_of_items=4)
- pages = [len(full_list) // 4 - 1 if page - 1 == -1 else page - 1,
- 0 if page + 1 >= len(full_list) // 4 else page + 1]
-
- for model in models:
- builder.row(InlineKeyboardButton(text=model,
- callback_data=Gpt4FreeModel(user_id=user_id, model=model).pack()))
- builder.row(
- # First page button
- InlineKeyboardButton(text=str(len(full_list) // 4 if page == 0 else "1"),
- callback_data=Gpt4FreeModelPage(
- page=str(len(full_list) // 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], ).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]).pack()),
- # Last page button
- InlineKeyboardButton(text=str(len(full_list) // 4 if page != 0 else "1"),
- callback_data=Gpt4FreeModelPage(
- page=str(len(full_list) // 4 - 1) if page != 0 else "1",
- user_id=user_id).pack(), ))
- builder.row(InlineKeyboardButton(text="🔙 Вернуться",
- callback_data=GptBackMenu(user_id=user_id, back_to="g4fcategory").pack()))
- builder.row(InlineKeyboardButton(text="Спасибо, не надо ❌",
- callback_data=GptStop(user_id=str(user_id)).pack()))
- return builder.as_markup()
-
-
-def gpt4free_models_by_provider_keyboard(user_id: int, provider: str, 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:
- :return:
- """
- 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=Gpt4FreeProvsModelPage(
- page=str(len(models[provider]) // 4 - 1 if page == 0 else "1"),
- user_id=user_id,
- provider=provider).pack(),
- ),
- # Page back button
- InlineKeyboardButton(text="⬅️",
- callback_data=Gpt4FreeProvsModelPage(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=Gpt4FreeProvsModelPage(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=Gpt4FreeProvsModelPage(
- 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), index=str(models.index(model))).pack())
- )
- builder.row(InlineKeyboardButton(text="🔙 Вернуться к списку",
- callback_data=GptBackMenu(user_id=user_id, back_to="g4fcategory").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, 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 text_response_keyboard(user_id: int) -> InlineKeyboardMarkup:
- """
- Generating menu for response from GPT
- :param user_id:
- :return:
- """
- kb = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(user_id_clicked=str(user_id)).pack())],
- [InlineKeyboardButton(text="Завершить диалог 🚫", callback_data=GptStop(user_id=str(user_id)).pack())]
- ])
- return kb
-
-
-def image_response_keyboard(user_id: int) -> InlineKeyboardMarkup:
- """
- Generating menu for image
- :param user_id:
- :return:
- """
- kb = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text="Спасибо ✅", callback_data=DeleteMenu(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=DeleteMenu(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=DeleteMenu(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, mute_id: int) -> InlineKeyboardMarkup:
- """
- Generating menu for /mute command.
- :param admin_id:
- :param mute_id:
- :return:
- """
- kb = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text="Спасибо ✅",
- callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())],
- [InlineKeyboardButton(text="Размутить 🛠️",
- callback_data=UnmuteData(user_id_unmute=mute_id, user_id_clicked=admin_id).pack())]])
- return kb
-
-
-def unmute_keyboard(admin_id: int, unmute_id: int) -> InlineKeyboardMarkup:
- """
- Generating menu for /unmute command.
- :param admin_id:
- :param unmute_id:
- :return:
- """
- kb = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text="Спасибо ✅",
- callback_data=DeleteMenu(user_id_clicked=str(admin_id)).pack())],
- [InlineKeyboardButton(text="Замутить 🛠️",
- callback_data=MuteData(user_id_mute=unmute_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=DeleteMenu(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=DeleteMenu(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=DeleteMenu(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=DeleteMenu(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=DeleteMenu(user_id_clicked=str(user_id)).pack())]
- ])
- return kb
-
-
-about_keyboard = InlineKeyboardBuilder()
-about_keyboard.button(
- text="Bozo Development", url="https://t.me/BozoDevelopment"
-)
diff --git a/bozenka/instances/telegram/utils/simpler/lists_of_content.py b/bozenka/instances/telegram/utils/simpler/lists_of_content.py
deleted file mode 100644
index 69e4598..0000000
--- a/bozenka/instances/telegram/utils/simpler/lists_of_content.py
+++ /dev/null
@@ -1,301 +0,0 @@
-from dataclasses import dataclass
-from typing import List, Any
-
-import g4f
-from g4f import Provider
-from g4f.Provider import RetryProvider
-from varname import nameof
-
-from bozenka.database.tables.telegram import TelegramChatSettings
-
-
-@dataclass
-class BaseFeature:
- """
- Basic class of Feature.
- Have inside desription, name, callback name,
- """
- name: str
- description: str
- callback_name: str
- settings_name: str
- db_name: Any
-
-
-@dataclass
-class BaseCategory:
- """
- Basic class of Feature category
- Have inside category name, callbackname
- """
- name: str
- callback_name: str
-
-
-# List of categories, avaible in bot
-list_of_categories = [
- BaseCategory(name="Администраторы 👮♂", callback_name="Admins"),
- BaseCategory(name="Пользователи 👤", callback_name="Members"),
- BaseCategory(name="В разработке 👨💻", callback_name="Devs")
-]
-
-# List of features, avaible in bot
-list_of_features = {
- "Admins": [
- BaseFeature(
- name="Закреп 📌",
- description="Закреп📌"
- "\nДанная функция включает команды:"
- "/pin - закрепляет сообщение\n"
- "/unpin - открепляет сообщение\n"
- "/unpin_all - открепляет все сообщения, которые видит бот
\n"
- "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота.",
- callback_name="pins",
- settings_name="pins",
- db_name=TelegramChatSettings.pins
- ),
- BaseFeature(
- name="Модерация чата 🕵️",
- description="Модерация чата🕵️\nДанная настройка включает следущие комманды:"
- "\n/ban [время блокировки] [причина блокировки] - блокировка пользователя"
- "\n/unban - разблокировка пользователя\n"
- "/mute [время мута] [причина мута] - мут пользователя\n"
- "/unmute - Размут пользователя
\n"
- "Время обозначается как:"
- "1h - один час, "
- "1d - один день, "
- "1m - одна минута, "
- "1s - одна секунда
\n"
- "Для того, "
- "чтобы выполнить одну из комманд по отношению к пользователю, "
- "ответьте на сообщение пользователя и используйте команду\n"
- "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота.",
- callback_name="moderation",
- settings_name="moderation",
- db_name=TelegramChatSettings.moderation
- ),
- BaseFeature(
- name="Работа с Форумом 💬",
- description="Работа с Форумом💬\nДанная настройка включает следущие комманды:\n"
- "/open - открывают тему форума\n"
- "/close - закрывают тему форума\n"
- "/open_general - открывают основную тему форума\n"
- "/close_general - закрывает основную тему форума\n"
- "/hide_general - прячет основную тему форума\n"
- "/show_general - показывает основную тему форума
\n"
- "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота. Также должен быть"
- "включен форум",
- callback_name="topics",
- settings_name="topics",
- db_name=TelegramChatSettings.topics
- ),
- BaseFeature(
- name="Приглашения в Чат ✉",
- description="Генератор приглашения в Чат ✉\n"
- "Разрешает использование комманды /invite
в чате, для созданния приглашений.\n"
- "Для исполнения требует соответсвующих прав от пользователя и их наличие у бота.",
- callback_name="invites",
- settings_name="invite_generator",
- db_name=TelegramChatSettings.invite_generator
- ),
- BaseFeature(
- name="Результаты в лс ✉",
- description="Результаты в личных сообщениях ✉\n"
- "Отправляет все результаты команд модерации в личные сообщения пользователя\n"
- "Никаких особых прав у бота не требует.",
- callback_name="results_in_dm",
- settings_name="results_in_dm",
- db_name=TelegramChatSettings.results_in_dm
- ),
- BaseFeature(
- name="Оповещение об ограничении 🗯",
- description="Оповещение об ограничении 🗯\n"
- "Отправляет оповещение пользователю об его муте, бане\n"
- "Никаких особых прав у бота не требует.",
- callback_name="restrict_notification",
- settings_name="restrict_notification",
- db_name=TelegramChatSettings.restrict_notification
- )
- ],
- "Members": [
- BaseFeature(
- name="Приветсвенные сообщения 👋",
- description="Приветсвенные сообщения 👋"
- "\nПриветсвенные сообщения новым и ушедшим пользователям.",
- callback_name="welcome",
- settings_name="welcome_messages",
- db_name=TelegramChatSettings.welcome_messages
- ),
- BaseFeature(
- name="Оповещение о муте 📬",
- description="Оповещение о муте 📬"
- "\nОповещает пользователя в личных сообщениях, что тот был: замучен, размучен, забанен, разбанен",
- callback_name="notify",
- settings_name="restrict_notification",
- db_name=TelegramChatSettings.restrict_notification
- )
- ],
- "Devs": [
- BaseFeature(
- name="Функция Привет 👋",
- description="Функция `Привет` 👋"
- "\nБот будет отвечать на комманды "
- "/hi, /hello, /privet и т.п., отвечая приветсвием на сообщение пользователя.",
- callback_name="hi",
- settings_name="hi_command",
- db_name=TelegramChatSettings.hi_command
- ),
- BaseFeature(
- name="ИИ ЧатБот 🤖",
- description="ИИ ЧатБот 🤖"
- "\nЕсть поддержка:\n"
- "- Моделей Gpt4All\n"
- "- Провайдеров Gpt4Free и моделей\n"
- "Для использования:\n"
- "/conversations
"
- "\nНаходится в разработке, планируется в будущем. Следите за обновлениями 😘",
- callback_name="gtm",
- settings_name="gpt_conversations",
- db_name=TelegramChatSettings.text_generation
- ),
- BaseFeature(
- name="Генерация изображений 📸",
- description="Генерация изображений 🤖"
- "\nНаходится в разработке, планируется в будущем. Следите за обновлениями 😘",
- callback_name="gpm",
- settings_name="123",
- db_name=TelegramChatSettings.image_generation
- )
- ]
-
-}
-
-
-def generate_list_of_features(category: str) -> list[BaseFeature]:
- """
- Generates list of features avaible at some category
- made for future auto translate
- :param category:
- :return:
- """
- return list_of_features[category]
-
-
-ru_cmds = {
- # /info command translation
- "info": "Информация об чате с названием nameofchathere"
- "descr\n"
- "Является chattype isforum requiredinvite\n"
- "Скрытые участники ishiddenmembers, isprotected",
- "chat_types": {"group": "группой", "supergroup": "cупер группой"},
- "forum_type": {True: "и форумом,", False: ", не является форумом,", None: ", не является форумом,"},
- "required_invite": {True: "требуется одобрение заявки на вступление", False: "заявка не требуется.",
- None: "заявка не требуется."},
- "hidden_members": {True: "присуствуют", False: "отсуствуют", None: "отсуствуют"},
- "isprotected": {True: "пересылать сообщения из группы можно.", False: "пересылать сообщения из группы нельзя.",
- None: "пересылать сообщения из группы можно."},
- # /hi command translation
- "hi": "Привет, user 👋",
- "user": "пользователь",
- # /invite command translation
- "invite_generation": " Держите ваше приглашение в чат, user 👋",
- "sir": "сэр",
- # Ban cases
- "ban_1": "Удача ✅\n"
- "Пользователь banned был заблокирован пользователем admin.\n"
- "По причине ban_reason, до даты ban_time",
- "ban_2": "Удача ✅\n"
- "Пользователь banned был заблокирован пользователем admin.\n"
- "По причине ban_reason.",
- "ban_3": "Удача ✅\n"
- "Пользователь banned был заблокирован пользователем admin.",
- "ban_4": "Удача ✅\n"
- "Пользователь banned был заблокирован пользователем admin, до даты ban_time.\n",
- "ban_success": "Успешно заблокирован ✅",
- # Unban cases
- "unban_1": "Удача ✅\n"
- "Пользователь unbanned был разблокирован пользователем admin.\n"
- "По причине reason.",
- "unban_2": "Удача ✅\n"
- "Пользователь unbanned был разблокирован пользователем admin.",
- "unban_3": "Ошибка ❌\n"
- "Этот пользователь не находится в бане.",
- "unban_success": "Успешно разблокирован ✅",
- # Work with topic
- "topic_closed": "Удача ✅\n"
- "Пользователь user закрыл данное обсуждение.",
- "open_topic": "Удача ✅\n"
- "Пользователь user открыл данное обсуждение.",
- "close_general": "Удача ✅\n"
- "Пользователь user закрыл основное обсуждение",
- "open_general": "Удача ✅\n"
- "Пользователь user открыл основное обсуждение",
- "hide_general": "Удача ✅\n"
- "Пользователь user скрыл основное обсуждение",
- "show_general": "Удача ✅\n"
- f"Пользователь user раскрыл основное обсуждение",
- "topic_renamed": "Удача ✅\n"
- f"Пользователь user переименовал обсуждение originalthreadname
",
- # GPT cases
- "generate_answer": "Пожалуйста подождите, ответ генерируется ⏰",
- "select_provider": "Выберите пожалуйста одного из провайдеров 👨💻",
- "select_provider_message": "Выберите пожалуйста одного из провайдеров 👨💻",
- "help_notification": "Это текущая странница 📃",
- "select_provider_page": "Пожалуйста, выберите одного из провайдеров 👨💻\n"
- "Ваша текущая страница это pagecount📄",
- "moved_page": "Перенесли на страницу pagecount📄",
- "finish_gpt4all_message": "Удача ✅\n"
- "Вы теперь можете спокойно вести диалог 🤖\n"
- "Чтобы прекратить общение, используйте /cancel",
- "finish_gptfree_message": "Удача ✅\n"
- "Вы теперь можете спокойно вести диалог 🤖\n"
- "Вы выбрали модель modelname
👾, от провайдера providername
👨💻\n"
- "Чтобы прекратить общение, используйте /cancel ",
- "finish_gpt": "Вы теперь можете спокойно вести диалог 🤖",
- "select_model_message": "Выберите пожалуйста модель ИИ 👾",
- "select_model": "Выберите пожалуйста модель ИИ 👾",
- # No Permission translation
- "no_perms": "Ошибка ❌"
- "У вас нет прав на использование этой комманды 🚫",
- # After adding bot into group message text
- "after_adding": "Здраствуйте администраторы чата 👋\n"
- "Я - бозенька, мультифункциональный бот, разрабатываемый Bozo Developement\n"
- "Выдайте мне полные права администратора для моей полной работы."
- "Чтобы настроить функционал, используйте /setup или кнопку под сообщением",
- # Success
- "success": "Удача ✅"
-
-}
-
-list_of_commands = {
- # Main commands
- ("start", "Command to start work with bozenka the bot"),
- ('setup', 'Command to setup bozenka features in chat'),
- # Moderation commands
- ("ban", "Command to ban user in chat"),
- ('unban', 'Command to unban user in chat'),
- ('mute', 'Command to mute user in chat'),
- ('unmute', 'Command to unmute user in chat'),
- # Work with pins
- ('pin', 'Pin fast any message in chat'),
- ('unpin', 'Unpin fast any message in chat'),
- # Close / open topics
- ('close', 'Close fast topic (not general) in chat'),
- ('open', 'Open fast topic (not general) in chat'),
- ('hide_general', 'Hide general topic in chat'),
- ('show_general', 'Show general topic in chat'),
- ("close_general", 'Closes general topic in chat'),
- ("open_general", 'Opens general topic in chat'),
- # AI related
- ('conversation', 'Starts conversation with text generative ai'),
- ('imagine', 'Starts conversation with image generative ai'),
- # Basic features
- ('invite', 'Generates invite into current chat'),
- ('about', 'Sends information about bozenka'),
- ('hi', 'Sends test welcome message'),
- ('info', 'Get information about chat')
-}
-
-translations = {
- "ru": ru_cmds,
-}
--
2.30.2
From 402c4c9c18efa0b8672ea8dfddc627a6cb2bdc7a Mon Sep 17 00:00:00 2001
From: kittyneverdies <85691197+KittyNeverDies@users.noreply.github.com>
Date: Sun, 11 Feb 2024 22:12:54 +0300
Subject: [PATCH 09/13] Workflow is back
---
.github/workflows/start.yml | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 .github/workflows/start.yml
diff --git a/.github/workflows/start.yml b/.github/workflows/start.yml
new file mode 100644
index 0000000..488fb44
--- /dev/null
+++ b/.github/workflows/start.yml
@@ -0,0 +1,24 @@
+# This is a basic workflow to help you get started with Actions
+
+name: CI
+
+# Controls when the workflow will run
+on:
+ # Triggers the workflow on push or pull request events but only for the "main" branch
+ push:
+ branches: [ "telegram", "main", "discord", "matrix" ]
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+ # This workflow contains a single job called "build"
+ telegram_notification:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Github Telegram Notifier
+ uses: EverythingSuckz/github-telegram-notify@v1.1.2
+ with:
+ bot_token: '${{ secrets.BOT_TOKEN }}'
+ chat_id: '${{ secrets.CHAT_ID }}'
+
+
+
--
2.30.2
From 71b33ef6660fc79215b495759f977e1750a0731f Mon Sep 17 00:00:00 2001
From: kittyneverdies <85691197+KittyNeverDies@users.noreply.github.com>
Date: Tue, 13 Feb 2024 21:56:17 +0300
Subject: [PATCH 10/13] Fixing source code
---
bozenka/features/admin/information.py | 2 +-
bozenka/features/admin/invite_generation.py | 1 -
bozenka/features/admin/moderation.py | 2 +-
bozenka/features/admin/msg_pins.py | 2 +-
bozenka/features/admin/topics.py | 2 +-
bozenka/features/user/image_generation.py | 2 +-
bozenka/features/user/text_generation.py | 2 +-
bozenka/instances/telegram/__init__.py | 12 +++++++++---
bozenka/instances/telegram/filters/permissions.py | 2 +-
bozenka/instances/telegram/utils/simpler/__init__.py | 4 ----
10 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/bozenka/features/admin/information.py b/bozenka/features/admin/information.py
index 059fe9a..ffc5e5e 100644
--- a/bozenka/features/admin/information.py
+++ b/bozenka/features/admin/information.py
@@ -4,7 +4,7 @@ from aiogram.filters import Command
from aiogram.types import Message
from bozenka.features.main import BasicFeature
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
+from bozenka.instances.telegram.utils.delete import delete_keyboard
class ChatInformation(BasicFeature):
diff --git a/bozenka/features/admin/invite_generation.py b/bozenka/features/admin/invite_generation.py
index 53c6989..b72f61f 100644
--- a/bozenka/features/admin/invite_generation.py
+++ b/bozenka/features/admin/invite_generation.py
@@ -28,7 +28,6 @@ def invite_telegram_keyboard(invite_link: str, admin_id: int, chat_name: str) ->
return kb
-
class Invite(BasicFeature):
"""
A class with information about invite feature
diff --git a/bozenka/features/admin/moderation.py b/bozenka/features/admin/moderation.py
index 5b11c90..b3ca93f 100644
--- a/bozenka/features/admin/moderation.py
+++ b/bozenka/features/admin/moderation.py
@@ -10,7 +10,7 @@ from bozenka.database.tables.telegram import get_chat_config_value, TelegramChat
from bozenka.features.main import BasicFeature
from bozenka.instances.telegram.utils.callbacks_factory import UnbanData, BanData, UnmuteData, MuteData, DeleteMenu
from bozenka.instances.telegram.filters import IsAdminFilter, BotHasPermissions, UserHasPermissions
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
+from bozenka.instances.telegram.utils.delete import delete_keyboard
from bozenka.instances.telegram.utils.simpler import SolutionSimpler
diff --git a/bozenka/features/admin/msg_pins.py b/bozenka/features/admin/msg_pins.py
index a2b8ace..25d345f 100644
--- a/bozenka/features/admin/msg_pins.py
+++ b/bozenka/features/admin/msg_pins.py
@@ -7,7 +7,7 @@ from bozenka.database.tables.telegram import TelegramChatSettings
from bozenka.features.main import BasicFeature
from bozenka.instances.telegram.utils.callbacks_factory import PinMsg, UnpinMsg, DeleteMenu
from bozenka.instances.telegram.filters import UserHasPermissions, BotHasPermissions, IsAdminFilter
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
+from bozenka.instances.telegram.utils.delete import delete_keyboard
from bozenka.instances.telegram.utils.simpler import SolutionSimpler
diff --git a/bozenka/features/admin/topics.py b/bozenka/features/admin/topics.py
index e1311ef..0ada18e 100644
--- a/bozenka/features/admin/topics.py
+++ b/bozenka/features/admin/topics.py
@@ -7,7 +7,7 @@ from bozenka.database.tables.telegram import TelegramChatSettings
from bozenka.features.main import BasicFeature
from bozenka.instances.telegram.utils.callbacks_factory import CloseThread, OpenThread, DeleteMenu
from bozenka.instances.telegram.filters import UserHasPermissions, BotHasPermissions
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
+from bozenka.instances.telegram.utils.delete import delete_keyboard
from bozenka.instances.telegram.utils.simpler import SolutionSimpler
diff --git a/bozenka/features/user/image_generation.py b/bozenka/features/user/image_generation.py
index ecc5007..5dff3b9 100644
--- a/bozenka/features/user/image_generation.py
+++ b/bozenka/features/user/image_generation.py
@@ -14,7 +14,7 @@ from bozenka.generative import image_generative_size, image_generative_categorie
from bozenka.generative.kadinsky import kadinsky_gen
from bozenka.instances.telegram.utils.callbacks_factory import ImageGenerationCategory, ImageGeneration, DeleteMenu, \
GptStop
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
+from bozenka.instances.telegram.utils.delete import delete_keyboard
from bozenka.instances.telegram.utils.simpler import GeneratingImages
diff --git a/bozenka/features/user/text_generation.py b/bozenka/features/user/text_generation.py
index ee41015..44019ab 100644
--- a/bozenka/features/user/text_generation.py
+++ b/bozenka/features/user/text_generation.py
@@ -17,7 +17,7 @@ from bozenka.generative.gpt4free import generate_gpt4free_providers, generate_gp
from bozenka.instances.telegram.utils.callbacks_factory import Gpt4FreeProvsModelPage, Gpt4FreeProviderPage, \
Gpt4AllSelect, Gpt4AllModel, GptCategory, Gpt4freeResult, \
Gpt4FreeProvider, GptBackMenu, Gpt4FreeModel, Gpt4FreeCategory, Gpt4FreeModelPage, GptStop
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
+from bozenka.instances.telegram.utils.delete import delete_keyboard
from bozenka.instances.telegram.utils.simpler import AnsweringGPT4Free, AnsweringGpt4All
diff --git a/bozenka/instances/telegram/__init__.py b/bozenka/instances/telegram/__init__.py
index e510a49..c0aa434 100644
--- a/bozenka/instances/telegram/__init__.py
+++ b/bozenka/instances/telegram/__init__.py
@@ -31,7 +31,12 @@ async def register_all_features(list_of_features: list, dispatcher: Dispatcher,
for callback_query_handler in feature.telegram_callback_handlers:
dispatcher.callback_query.register(callback_query_handler[0], *callback_query_handler[1])
- await bot.set_my_commands(cmd_list)
+ if not (commands := await bot.get_my_commands()):
+ await bot.set_my_commands(cmd_list)
+ else:
+ for cmd in cmd_list:
+ commands.append(cmd)
+ await bot.set_my_commands(commands)
async def launch_telegram_instance(session_maker: async_sessionmaker) -> None:
@@ -46,6 +51,8 @@ async def launch_telegram_instance(session_maker: async_sessionmaker) -> None:
dp = Dispatcher()
+ await bot.delete_my_commands()
+
# Registering other handlers
dp.callback_query.register(delete_callback_handler, DeleteMenu.filter())
dp.callback_query.register(hide_menu_handler, HideMenu.filter())
@@ -56,5 +63,4 @@ async def launch_telegram_instance(session_maker: async_sessionmaker) -> None:
await register_all_features(list_of_features=customizable_features, dispatcher=dp, bot=bot),
await register_all_features(list_of_features=basic_features, dispatcher=dp, bot=bot)
- ]
- )
+ ])
diff --git a/bozenka/instances/telegram/filters/permissions.py b/bozenka/instances/telegram/filters/permissions.py
index 1261ae5..edb9767 100644
--- a/bozenka/instances/telegram/filters/permissions.py
+++ b/bozenka/instances/telegram/filters/permissions.py
@@ -5,7 +5,7 @@ from aiogram.methods import GetChatMember
from aiogram.types import Message, ChatPermissions, CallbackQuery
from aiogram.enums import ChatMemberStatus, ChatType
-from bozenka.instances.telegram.utils.keyboards import delete_keyboard
+from bozenka.instances.telegram.utils.delete import delete_keyboard
class UserHasPermissions(Filter):
diff --git a/bozenka/instances/telegram/utils/simpler/__init__.py b/bozenka/instances/telegram/utils/simpler/__init__.py
index 0b5517c..4ce3ddc 100644
--- a/bozenka/instances/telegram/utils/simpler/__init__.py
+++ b/bozenka/instances/telegram/utils/simpler/__init__.py
@@ -1,6 +1,2 @@
from .solution_simpler import SolutionSimpler
-from .lists_of_content import *
from .fsm_states import *
-
-
-
--
2.30.2
From 3bc579d6122292054396aa6e6835f12f5a2526f7 Mon Sep 17 00:00:00 2001
From: kittyneverdies <85691197+KittyNeverDies@users.noreply.github.com>
Date: Wed, 14 Feb 2024 21:24:13 +0300
Subject: [PATCH 11/13] Fixed all code
---
bozenka/features/basic/start.py | 7 +++---
bozenka/features/user/image_generation.py | 13 +++++++-----
bozenka/features/user/text_generation.py | 26 +++++++++++------------
bozenka/generative/gpt4all/__init__.py | 3 +--
4 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/bozenka/features/basic/start.py b/bozenka/features/basic/start.py
index 8404995..85485c0 100644
--- a/bozenka/features/basic/start.py
+++ b/bozenka/features/basic/start.py
@@ -7,7 +7,7 @@ from aiogram.utils.keyboard import InlineKeyboardBuilder
from bozenka.features.main import BasicFeature
from bozenka.instances.customizable_features_list import categorized_customizable_features, text_transcription
from bozenka.instances.telegram.utils.callbacks_factory import HelpCategory, HelpBackCategory, HelpFeature, HelpBack
-from bozenka.features.user.text_generation import gpt_categories_keyboard
+from bozenka.features.user.text_generation import telegram_text_categories_keyboard
from bozenka.instances.current_version import build, is_updated
telegram_main_menu = InlineKeyboardMarkup(
@@ -197,7 +197,7 @@ class Start(BasicFeature):
:return: Nothing
"""
await call.message.edit_text("Пожалуста, выберите сервиc / библиотеку, через которую вы будете общаться",
- reply_markup=gpt_categories_keyboard
+ reply_markup=telegram_text_categories_keyboard
(user_id=call.from_user.id))
@staticmethod
@@ -239,7 +239,7 @@ class Start(BasicFeature):
"""
await msg.answer("""
Привет 👋
-Я - бозенька, бот с открытым исходным кодом, который поможет тебе в различных задачах.
+Я - групповой чат-бот с открытым исходным кодом, который поможет тебе в различных задачах.
Вот что ты можешь сделать с помощью меню:
• Добавить в чат: добавляет меня в групповой чат, чтобы я мог выполнять свои функции внутри него.
@@ -250,7 +250,6 @@ class Start(BasicFeature):
• Генерация изображений: позволяет сгенерировать изображения на основе заданных параметров и промта
Вот нужные ссылки обо мне:
-• Канал с новостями об разработке
• Исходный код на Github
Чтобы воспользоваться какой-либо функцией, просто нажми на соответствующую кнопку ниже.
diff --git a/bozenka/features/user/image_generation.py b/bozenka/features/user/image_generation.py
index 5dff3b9..0272853 100644
--- a/bozenka/features/user/image_generation.py
+++ b/bozenka/features/user/image_generation.py
@@ -1,7 +1,7 @@
import logging
from typing import Callable
-from aiogram import Dispatcher
+from aiogram import Dispatcher, F
from aiogram.filters import CommandObject, Command
from aiogram.fsm.context import FSMContext
from aiogram.types import InlineKeyboardMarkup, Message, CallbackQuery, FSInputFile, InlineKeyboardButton
@@ -68,8 +68,6 @@ class ImageGeneratrion(BasicFeature):
A classic class of lineral (basic)
feature of bozenka. IN FUTURE!
"""
- cmd_description: str = "Your description of command"
-
async def telegram_select_image_size_handler(call: CallbackQuery, callback_data: ImageGenerationCategory,
state: FSMContext) -> None:
"""
@@ -118,7 +116,7 @@ class ImageGeneratrion(BasicFeature):
"Подождите пожалуйста, мы уже генерируем изображение для вас, подождите, когда мы ответим на ваш передыдущий вопрос",
reply_markup=delete_keyboard(admin_id=msg.from_user.id))
- async def telegram_imagine_handler(msg: Message, state: FSMContext) -> None:
+ async def telegram_imagine_handler(msg: Message | CallbackQuery, state: FSMContext) -> None:
"""
/imagine command handler, start menu
:param msg: Message telegram object
@@ -127,6 +125,10 @@ class ImageGeneratrion(BasicFeature):
"""
if await state.get_state():
return
+
+ if type(msg) == CallbackQuery:
+ msg = msg.message
+
await msg.answer("Пожалуста, выберите сервис / модель для генерации изображений",
reply_markup=telegram_image_generation_categories_keyboard(user_id=msg.from_user.id))
@@ -194,5 +196,6 @@ class ImageGeneratrion(BasicFeature):
]
telegram_callback_handlers = [
[telegram_select_image_size_handler, [ImageGenerationCategory.filter()]],
- [telegram_end_generation_handler, [ImageGeneration.filter()]]
+ [telegram_end_generation_handler, [ImageGeneration.filter()]],
+ [telegram_imagine_handler, [F.data == "dialogimage"]]
]
diff --git a/bozenka/features/user/text_generation.py b/bozenka/features/user/text_generation.py
index 44019ab..e17618a 100644
--- a/bozenka/features/user/text_generation.py
+++ b/bozenka/features/user/text_generation.py
@@ -11,9 +11,10 @@ from gpt4all import GPT4All
from bozenka.database.tables.telegram import TelegramChatSettings
from bozenka.features.main import BasicFeature
-from bozenka.generative import text_generative_categories
+from bozenka.generative import text2text_generatiove_libraries
from bozenka.generative.gpt4all import model_path, check
from bozenka.generative.gpt4free import generate_gpt4free_providers, generate_gpt4free_models
+from bozenka.instances.telegram.utils.callbacks_factory import DeleteMenu
from bozenka.instances.telegram.utils.callbacks_factory import Gpt4FreeProvsModelPage, Gpt4FreeProviderPage, \
Gpt4AllSelect, Gpt4AllModel, GptCategory, Gpt4freeResult, \
Gpt4FreeProvider, GptBackMenu, Gpt4FreeModel, Gpt4FreeCategory, Gpt4FreeModelPage, GptStop
@@ -21,15 +22,14 @@ from bozenka.instances.telegram.utils.delete import delete_keyboard
from bozenka.instances.telegram.utils.simpler import AnsweringGPT4Free, AnsweringGpt4All
-
-def gpt_categories_keyboard(user_id: int) -> InlineKeyboardMarkup:
+def telegram_text_categories_keyboard(user_id: int) -> InlineKeyboardMarkup:
"""
Create list keyboard list of gpt libraries, available in the bot
- :param user_id:
+ :param user_id: User_id of user
:return: InlineKeyboardMarkup
"""
builder = InlineKeyboardBuilder()
- for category in text_generative_categories:
+ for category in text2text_generatiove_libraries:
builder.row(InlineKeyboardButton(text=category,
callback_data=GptCategory(user_id=str(user_id), category=category).pack()))
return builder.as_markup()
@@ -39,7 +39,7 @@ def gpt_categories_keyboard(user_id: int) -> InlineKeyboardMarkup:
def items_list_generator(page: int, list_of_items, count_of_items: int) -> list[Any]:
"""
Generate page, made for backend
- :param page:
+ :param page: Number of page
:param list_of_items:
:param count_of_items:
"""
@@ -65,7 +65,7 @@ def text_response_keyboard(user_id: int) -> InlineKeyboardMarkup:
return kb
-def gpt4free_providers_keyboard(user_id: int, page: int) -> InlineKeyboardMarkup:
+def telegram_gpt4free_providers_keyboard(user_id: int, page: int) -> InlineKeyboardMarkup:
"""
Generate page of gpt providers, can be used by user.
:param user_id:
@@ -307,7 +307,7 @@ class TextGeneratrion(BasicFeature):
if await state.get_state():
return
await msg.answer("Пожалуста, выберите сервис для ИИ.",
- reply_markup=gpt_categories_keyboard
+ reply_markup=telegram_text_categories_keyboard
(user_id=msg.from_user.id))
async def telegram_cancel_cmd_handler(msg: Message, state: FSMContext) -> None:
@@ -396,7 +396,7 @@ class TextGeneratrion(BasicFeature):
if call.from_user.id != callback_data.user_id or await state.get_state():
return
await call.message.edit_text("Пожалуста, выберите сервис для ИИ.",
- reply_markup=gpt_categories_keyboard(user_id=call.from_user.id))
+ reply_markup=telegram_text_categories_keyboard(user_id=call.from_user.id))
async def telegram_g4f_providers_handlers(call: CallbackQuery, callback_data: Gpt4FreeCategory,
state: FSMContext) -> None:
@@ -417,7 +417,7 @@ class TextGeneratrion(BasicFeature):
await state.set_state(AnsweringGPT4Free.set_provider)
await call.message.edit_text("Выберите пожалуйста одного из провайдеров 👨💻",
- reply_markup=gpt4free_providers_keyboard(user_id=call.from_user.id, page=0))
+ reply_markup=telegram_gpt4free_providers_keyboard(user_id=call.from_user.id, page=0))
async def telegram_g4f_models_handler(call: CallbackQuery, callback_data: GptCategory, state: FSMContext) -> None:
"""
@@ -517,7 +517,7 @@ class TextGeneratrion(BasicFeature):
await state.set_state(AnsweringGPT4Free.set_provider)
await call.message.edit_text("Выберите пожалуйста одного из провайдеров 👨💻",
- reply_markup=gpt4free_providers_keyboard(page=0, user_id=callback_data.user_id))
+ reply_markup=telegram_gpt4free_providers_keyboard(page=0, user_id=callback_data.user_id))
await call.answer("Выберите пожалуйста одного из провайдеров 👨💻")
async def telegram_g4f_by_provider_models(call: CallbackQuery, callback_data: Gpt4FreeProvider,
@@ -608,8 +608,8 @@ class TextGeneratrion(BasicFeature):
logging.log(msg=f"Changed page to {str(callback_data.page + 1)} user_id={call.from_user.id}",
level=logging.INFO)
await call.message.edit_text(call.message.text,
- reply_markup=gpt4free_providers_keyboard(user_id=callback_data.user_id,
- page=callback_data.page))
+ reply_markup=telegram_gpt4free_providers_keyboard(user_id=callback_data.user_id,
+ page=callback_data.page))
await call.answer(f"Вы перелистнули на страницу {callback_data.page + 1}📄")
# G4A telegram handlers section
diff --git a/bozenka/generative/gpt4all/__init__.py b/bozenka/generative/gpt4all/__init__.py
index 0aa5da9..4420033 100644
--- a/bozenka/generative/gpt4all/__init__.py
+++ b/bozenka/generative/gpt4all/__init__.py
@@ -4,14 +4,13 @@ import pathlib
model_path = os.getcwd() + "\\model\\"
-
def check(model_filename: str) -> bool:
"""
Checking & downloading our gpt4all models
Returns True if it's already downloaded
Returns False if it's not downloaded
:param model_filename: File name of gpt4all model
- :return:
+ :return: Does it exist
"""
print(os.path.exists("models\\" + model_filename))
return os.path.exists("models\\" + model_filename)
--
2.30.2
From d784c57df419d51ee3816498c6f15ffe3aeb14c5 Mon Sep 17 00:00:00 2001
From: kittyneverdies catofeyev
Date: Wed, 14 Feb 2024 18:39:56 +0000
Subject: [PATCH 12/13] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B8=D1=82?=
=?UTF-8?q?=D1=8C=20README.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 61 -------------------------------------------------------
1 file changed, 61 deletions(-)
delete mode 100644 README.md
diff --git a/README.md b/README.md
deleted file mode 100644
index 6e0f2af..0000000
--- a/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-[![CodeFactor](https://www.codefactor.io/repository/github/kittyneverdies/bozenka/badge)](https://www.codefactor.io/repository/github/kittyneverdies/bozenka)
-
-[Telegram Channel](https://t.me/bozodevelopment/)
-
-
-
-
-Telegram Instance
-
-### Features of Telegram instance
-
-- [ ] Group
- - [ ] Administration
- - [x] Ban & Unban commands
- - [x] Mute & Unmute commands
- - [x] Pin & Unpin & Unpin all commands
- - [ ] Bad words & Spam filter
- - [ ] Setup command (Going to release)
- - [x] Welcome message to administrators after adding bot to chat.
- - [x] Work with inline keyboard
- - [x] Work with telegram topics
- - [x] Close & Open Topics
- - [x] Hide general topic
- - [x] Rename topics
- - [x] Work with inline keyboard
- - [x] Users
- - [x] Show information about chat (/info)
- - [x] Welcome messages
- - [x] Generating invites
- - [x] Start command menu (/start)
-- [ ] Fun
- - [ ] GPT based text generation
- - [x] Gpt4All
- - [x] Gpt4Free
- - [ ] RWKV
- - [ ] H20
- - [x] Work with inline keyboard
- - [ ] Using tutorial.
- - [x] Threads and Topic of dialog support (Already by new aiogram)
- - [ ] Image generation
- - [ ] Using tutorial
- - [ ] Inline generation
- - [x] Imagine command + inline keyboard support
-- [x] Code
- - [x] Logging support
- - [x] Features descriptions
- - [x] Custom Filters
- - [x] Middlewares
- - [x] Database
-
-
-### This part of project made with
-
-- [Aiogram python library](https://github.com/aiogram/aiogram) and with their community support.
-- [GPT4Free](https://github.com/xtekky/gpt4free), [Gpt4All](https://github.com/nomic-ai/gpt4all), [SqlAlchemy](https://github.com/sqlalchemy/sqlalchemy/) python libraries
-- With our love & your support <3
-
--
2.30.2
From a6e6d1617eac599f011fb77700865583f11b0d76 Mon Sep 17 00:00:00 2001
From: kittyneverdies catofeyev
Date: Wed, 14 Feb 2024 18:55:52 +0000
Subject: [PATCH 13/13] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B8=D1=82?=
=?UTF-8?q?=D1=8C=20.github/workflows/start.yml?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/start.yml | 24 ------------------------
1 file changed, 24 deletions(-)
delete mode 100644 .github/workflows/start.yml
diff --git a/.github/workflows/start.yml b/.github/workflows/start.yml
deleted file mode 100644
index 488fb44..0000000
--- a/.github/workflows/start.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
-name: CI
-
-# Controls when the workflow will run
-on:
- # Triggers the workflow on push or pull request events but only for the "main" branch
- push:
- branches: [ "telegram", "main", "discord", "matrix" ]
-
-# A workflow run is made up of one or more jobs that can run sequentially or in parallel
-jobs:
- # This workflow contains a single job called "build"
- telegram_notification:
- runs-on: ubuntu-latest
- steps:
- - name: Github Telegram Notifier
- uses: EverythingSuckz/github-telegram-notify@v1.1.2
- with:
- bot_token: '${{ secrets.BOT_TOKEN }}'
- chat_id: '${{ secrets.CHAT_ID }}'
-
-
-
--
2.30.2