типо да
This commit is contained in:
5
bot/utils/__init__.py
Normal file
5
bot/utils/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from .interesting_facts import *
|
||||
from .usernames import *
|
||||
from .pagination import *
|
||||
from .type_message import *
|
||||
from .argument import *
|
||||
59
bot/utils/argument.py
Normal file
59
bot/utils/argument.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
from configs import BotSettings
|
||||
|
||||
__all__ = ("is_command", "find_argument")
|
||||
|
||||
|
||||
def is_command(message: Optional[str]) -> bool:
|
||||
"""
|
||||
Проверяет, является ли сообщение командой.
|
||||
|
||||
Сообщение считается командой, если:
|
||||
1. Оно не пустое;
|
||||
2. Начинается с префикса команды, указанного в настройках.
|
||||
|
||||
Args:
|
||||
message (Optional[str]): Входное сообщение.
|
||||
|
||||
Returns:
|
||||
bool: True, если сообщение является командой, иначе False.
|
||||
|
||||
Пример:
|
||||
>>> is_command("/start")
|
||||
True
|
||||
>>> is_command("hello")
|
||||
False
|
||||
"""
|
||||
if not message:
|
||||
return False
|
||||
return message.strip().startswith(BotSettings.PREFIX)
|
||||
|
||||
|
||||
def find_argument(message: Optional[str]) -> Optional[str]:
|
||||
"""
|
||||
Извлекает аргумент команды из сообщения.
|
||||
|
||||
Аргументом считается текст после первой команды и пробела.
|
||||
Если аргумента нет — возвращает None.
|
||||
|
||||
Args:
|
||||
message (Optional[str]): Входное сообщение.
|
||||
|
||||
Returns:
|
||||
Optional[str]: Аргумент команды или None, если его нет.
|
||||
|
||||
Пример:
|
||||
>>> find_argument("/start referrer")
|
||||
'referrer'
|
||||
>>> find_argument("/start")
|
||||
None
|
||||
>>> find_argument("hello")
|
||||
None
|
||||
"""
|
||||
if not is_command(message):
|
||||
return None
|
||||
|
||||
parts = message.strip().split(maxsplit=1)
|
||||
return parts[1] if len(parts) > 1 else None
|
||||
54
bot/utils/interesting_facts.py
Normal file
54
bot/utils/interesting_facts.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from random import choice
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
from configs.config import Lists
|
||||
|
||||
__all__ = ("interesting_fact", "get_best_response",)
|
||||
|
||||
def interesting_fact(mode: str = "факт", lists: Optional[list[str]] = None) -> str:
|
||||
"""
|
||||
Возвращает случайный факт, анекдот или цитату, в зависимости от режима.
|
||||
|
||||
:param mode: строка, определяющая тип контента ("факт", "анекдот", "цитата").
|
||||
:param lists: необязательный список строк, из которого можно выбирать вручную.
|
||||
:return: случайный элемент из соответствующего списка.
|
||||
"""
|
||||
if lists is not None:
|
||||
return choice(lists)
|
||||
|
||||
mode = mode.lower()
|
||||
|
||||
if mode == "анекдот":
|
||||
source: list[str] = Lists.jokes
|
||||
elif mode == "цитата":
|
||||
source: list[str] = Lists.quotes
|
||||
else:
|
||||
source: list[str] = Lists.facts
|
||||
|
||||
return choice(source)
|
||||
|
||||
|
||||
def get_best_response(
|
||||
user_text: str,
|
||||
responses: Dict[str, Dict[str, List[str]]],
|
||||
random_phrases: List[str],
|
||||
) -> str:
|
||||
"""
|
||||
Подбирает наиболее подходящий ответ на сообщение пользователя.
|
||||
Сначала ищет ключевые слова и их синонимы, если совпадений нет — выдаёт случайную фразу.
|
||||
|
||||
:param user_text: текст сообщения пользователя
|
||||
:param responses: словарь с ключевыми словами и ответами
|
||||
:param random_phrases: список случайных фраз, если совпадений нет
|
||||
:return: строка с ответом
|
||||
"""
|
||||
normalized_text: str = user_text.lower()
|
||||
|
||||
# Перебор ключевых слов в словаре
|
||||
for _, data in responses.items():
|
||||
for keyword in data["keywords"]:
|
||||
if keyword in normalized_text:
|
||||
return choice(data["answers"])
|
||||
|
||||
# Если совпадений нет — выдаём случайную фразу
|
||||
return choice(random_phrases)
|
||||
28
bot/utils/pagination.py
Normal file
28
bot/utils/pagination.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from aiogram.types import InlineKeyboardButton
|
||||
|
||||
# Настройка экспорта в модули
|
||||
__all__ = ('pagination_btn',)
|
||||
|
||||
def pagination_btn(action: str,
|
||||
page: int = 0,
|
||||
total_posts: int = 0,
|
||||
bt_page: int = 5) -> list[InlineKeyboardButton]:
|
||||
"""
|
||||
Создает кнопки для пагинации.
|
||||
|
||||
:param action: Действие в котором нужна пангинация.
|
||||
:param page: Номер начальной страницы, по умолчанию 0.
|
||||
:param total_posts: Количество постов.
|
||||
:param bt_page: Количество кнопок на одной странице.
|
||||
:return: Готовый лист списка инлайн-кнопок.
|
||||
"""
|
||||
navigation_buttons: list[InlineKeyboardButton] = []
|
||||
if page > 0:
|
||||
navigation_buttons.append(InlineKeyboardButton(
|
||||
text="←", callback_data=f"{action}_page_{page - 1}"
|
||||
))
|
||||
if (page + 1) * bt_page < total_posts:
|
||||
navigation_buttons.append(InlineKeyboardButton(
|
||||
text="→", callback_data=f"{action}_page_{page + 1}"
|
||||
))
|
||||
return navigation_buttons
|
||||
18
bot/utils/random_lists.py
Normal file
18
bot/utils/random_lists.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from random import choice
|
||||
|
||||
def get_best_response(user_text: str) -> str:
|
||||
"""
|
||||
Подбирает наиболее подходящий ответ на сообщение пользователя.
|
||||
Сначала ищет ключевые слова и их синонимы, если совпадений нет — выдаёт случайную фразу.
|
||||
|
||||
:param user_text: текст сообщения пользователя
|
||||
:return: строка с ответом
|
||||
"""
|
||||
normalized_text: str = user_text.lower()
|
||||
|
||||
for _, data in RESPONSES.items():
|
||||
for keyword in data["keywords"]:
|
||||
if keyword in normalized_text:
|
||||
return choice(data["answers"])
|
||||
|
||||
return choice(RANDOM_PHRASES)
|
||||
85
bot/utils/type_message.py
Normal file
85
bot/utils/type_message.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from typing import Final
|
||||
|
||||
from aiogram.types import Message
|
||||
|
||||
# Настройка экспорта
|
||||
__all__ = ("CHAT_TYPES", "CONTENT_TYPE_RU", "type_chat", "type_msg")
|
||||
|
||||
|
||||
# Словарь сопоставлений "chat_type -> русское название"
|
||||
CHAT_TYPES: Final[dict[str, str]] = {
|
||||
"private": "Личный",
|
||||
"group": "Группа",
|
||||
"supergroup": "Группа",
|
||||
"channel": "Канал",
|
||||
}
|
||||
|
||||
# Словарь сопоставлений "content_type -> русское название"
|
||||
CONTENT_TYPE_RU: Final[dict[str, str]] = {
|
||||
"text": "Текст",
|
||||
"animation": "Гиф",
|
||||
"audio": "Аудио",
|
||||
"document": "Файл",
|
||||
"photo": "Фото",
|
||||
"sticker": "Стикер",
|
||||
"video": "Видео",
|
||||
"video_note": "Видеосообщение",
|
||||
"voice": "Голосовое сообщение",
|
||||
"contact": "Контакт",
|
||||
"dice": "Кубик",
|
||||
"game": "Игра",
|
||||
"poll": "Опрос",
|
||||
"venue": "Место",
|
||||
"location": "Локация",
|
||||
"new_chat_members": "Новые участники чата",
|
||||
"left_chat_member": "Участник вышел",
|
||||
"new_chat_title": "Новое название чата",
|
||||
"new_chat_photo": "Новая картинка чата",
|
||||
"delete_chat_photo": "Удалена картинка чата",
|
||||
"group_chat_created": "Создана группа",
|
||||
"supergroup_chat_created": "Создана супергруппа",
|
||||
"channel_chat_created": "Создан канал",
|
||||
"message_auto_delete_timer_changed": "Изменён автоудалитель",
|
||||
"migrate_to_chat_id": "Группа → супергруппа",
|
||||
"migrate_from_chat_id": "Супергруппа → группа",
|
||||
"pinned_message": "Закреплённое сообщение",
|
||||
"invoice": "Счёт",
|
||||
"successful_payment": "Успешный платёж",
|
||||
"connected_website": "Подключённый сайт",
|
||||
"passport_data": "Данные Telegram Passport",
|
||||
"proximity_alert_triggered": "Алерт о приближении",
|
||||
"video_chat_scheduled": "Запланированный видеочат",
|
||||
"video_chat_started": "Видеочат начался",
|
||||
"video_chat_ended": "Видеочат завершён",
|
||||
"video_chat_participants_invited": "Приглашены участники видеочата",
|
||||
"web_app_data": "Данные из веб-приложения",
|
||||
"forum_topic_created": "Создана тема форума",
|
||||
"forum_topic_edited": "Изменена тема форума",
|
||||
"forum_topic_closed": "Тема форума закрыта",
|
||||
"forum_topic_reopened": "Тема форума открыта",
|
||||
"general_forum_topic_hidden": "Общая тема скрыта",
|
||||
"general_forum_topic_unhidden": "Общая тема снова отображается",
|
||||
"giveaway_created": "Создан розыгрыш",
|
||||
"giveaway": "Розыгрыш",
|
||||
"giveaway_completed": "Розыгрыш завершён",
|
||||
"message_reaction": "Реакция на сообщение",
|
||||
}
|
||||
|
||||
|
||||
def type_msg(message: Message) -> str:
|
||||
"""
|
||||
Определяет и возвращает тип сообщения на русском языке.
|
||||
|
||||
:param message: объект Message от aiogram
|
||||
:return: строка с типом сообщения
|
||||
"""
|
||||
return CONTENT_TYPE_RU.get(message.content_type, f"Неизвестный тип ({message.content_type})")
|
||||
|
||||
def type_chat(message: Message) -> str:
|
||||
"""
|
||||
Преобразует информацию о чате в его тип на русском языке.
|
||||
|
||||
:param message: Объект сообщения из aiogram, содержащий информацию о чате.
|
||||
:return: Тип чата строкой.
|
||||
"""
|
||||
return CHAT_TYPES.get(message.chat.type, f"Неизвестный тип чата {message.chat.type}")
|
||||
21
bot/utils/usernames.py
Normal file
21
bot/utils/usernames.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from aiogram.types import Message
|
||||
|
||||
# Настройка экспорта в модули
|
||||
__all__ = ('username', )
|
||||
|
||||
# Функция получения юзера или ID пользователя
|
||||
def username(message: Message) -> str:
|
||||
"""
|
||||
Возвращает юзернейм пользователя из сообщения, или ID, если юзернейм не указан.
|
||||
|
||||
:param message: Объект сообщения из aiogram.
|
||||
:return: Строка с юзернеймом пользователя или его ID.
|
||||
:raises ValueError: Если в сообщении отсутствует информация о пользователе.
|
||||
"""
|
||||
try:
|
||||
if message.from_user:
|
||||
return f"@{message.from_user.username}" if message.from_user.username else f"@{message.from_user.id}"
|
||||
raise ValueError("Информация о пользователе отсутствует в сообщении.")
|
||||
|
||||
except ValueError as e:
|
||||
raise e # Перебрасываем ошибку выше для дальнейшей обработки
|
||||
Reference in New Issue
Block a user