Переписал почти все тесты #16
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@@ -35,7 +35,8 @@ jobs:
|
||||
python -m black .
|
||||
echo "🔍 Checking that repo is already formatted (no diff after isort+black)..."
|
||||
git diff --exit-code || (
|
||||
echo "❌ Code style drift. Locally run: isort . && black . && git add -A && git commit -m 'style: isort + black'"
|
||||
echo "❌ Code style drift. From THIS repo root (telegram-helper-bot) run:"
|
||||
echo " python -m isort . && python -m black . && git add -A && git commit -m 'style: isort + black'"
|
||||
exit 1
|
||||
)
|
||||
|
||||
|
||||
@@ -11,9 +11,19 @@
|
||||
|
||||
from .async_db import AsyncBotDB
|
||||
from .base import DatabaseConnection
|
||||
from .models import (Admin, AudioListenRecord, AudioMessage, AudioModerate,
|
||||
BlacklistUser, MessageContentLink, Migration, PostContent,
|
||||
TelegramPost, User, UserMessage)
|
||||
from .models import (
|
||||
Admin,
|
||||
AudioListenRecord,
|
||||
AudioMessage,
|
||||
AudioModerate,
|
||||
BlacklistUser,
|
||||
MessageContentLink,
|
||||
Migration,
|
||||
PostContent,
|
||||
TelegramPost,
|
||||
User,
|
||||
UserMessage,
|
||||
)
|
||||
from .repository_factory import RepositoryFactory
|
||||
|
||||
# Для обратной совместимости экспортируем старый интерфейс
|
||||
|
||||
@@ -2,9 +2,17 @@ from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
import aiosqlite
|
||||
from database.models import (Admin, AudioMessage, BlacklistHistoryRecord,
|
||||
BlacklistUser, PostContent, TelegramPost, User,
|
||||
UserMessage)
|
||||
|
||||
from database.models import (
|
||||
Admin,
|
||||
AudioMessage,
|
||||
BlacklistHistoryRecord,
|
||||
BlacklistUser,
|
||||
PostContent,
|
||||
TelegramPost,
|
||||
User,
|
||||
UserMessage,
|
||||
)
|
||||
from database.repository_factory import RepositoryFactory
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
from typing import Optional
|
||||
|
||||
import aiosqlite
|
||||
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Репозиторий для работы с миграциями базы данных."""
|
||||
|
||||
import aiosqlite
|
||||
|
||||
from database.base import DatabaseConnection
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@ from typing import Optional
|
||||
|
||||
from database.repositories.admin_repository import AdminRepository
|
||||
from database.repositories.audio_repository import AudioRepository
|
||||
from database.repositories.blacklist_history_repository import \
|
||||
BlacklistHistoryRepository
|
||||
from database.repositories.blacklist_history_repository import (
|
||||
BlacklistHistoryRepository,
|
||||
)
|
||||
from database.repositories.blacklist_repository import BlacklistRepository
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
from database.repositories.migration_repository import MigrationRepository
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
from .admin_handlers import admin_router
|
||||
from .dependencies import AdminAccessMiddleware, BotDB, Settings
|
||||
from .exceptions import (AdminAccessDeniedError, AdminError, InvalidInputError,
|
||||
UserAlreadyBannedError, UserNotFoundError)
|
||||
from .exceptions import (
|
||||
AdminAccessDeniedError,
|
||||
AdminError,
|
||||
InvalidInputError,
|
||||
UserAlreadyBannedError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
from .services import AdminService, BannedUser, User
|
||||
from .utils import (escape_html, format_ban_confirmation, format_user_info,
|
||||
handle_admin_error, return_to_admin_menu)
|
||||
from .utils import (
|
||||
escape_html,
|
||||
format_ban_confirmation,
|
||||
format_user_info,
|
||||
handle_admin_error,
|
||||
return_to_admin_menu,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"admin_router",
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
from aiogram import F, Router, types
|
||||
from aiogram.filters import Command, MagicData, StateFilter
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
from helper_bot.filters.main import ChatTypeFilter
|
||||
from helper_bot.handlers.admin.dependencies import AdminAccessMiddleware
|
||||
from helper_bot.handlers.admin.exceptions import (InvalidInputError,
|
||||
UserAlreadyBannedError)
|
||||
from helper_bot.handlers.admin.exceptions import (
|
||||
InvalidInputError,
|
||||
UserAlreadyBannedError,
|
||||
)
|
||||
from helper_bot.handlers.admin.services import AdminService
|
||||
from helper_bot.handlers.admin.utils import (escape_html,
|
||||
format_ban_confirmation,
|
||||
format_user_info,
|
||||
handle_admin_error,
|
||||
return_to_admin_menu)
|
||||
from helper_bot.keyboards.keyboards import (create_keyboard_for_approve_ban,
|
||||
create_keyboard_for_ban_days,
|
||||
create_keyboard_for_ban_reason,
|
||||
create_keyboard_with_pagination,
|
||||
get_reply_keyboard_admin)
|
||||
from helper_bot.handlers.admin.utils import (
|
||||
escape_html,
|
||||
format_ban_confirmation,
|
||||
format_user_info,
|
||||
handle_admin_error,
|
||||
return_to_admin_menu,
|
||||
)
|
||||
from helper_bot.keyboards.keyboards import (
|
||||
create_keyboard_for_approve_ban,
|
||||
create_keyboard_for_ban_days,
|
||||
create_keyboard_for_ban_reason,
|
||||
create_keyboard_with_pagination,
|
||||
get_reply_keyboard_admin,
|
||||
)
|
||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import db_query_time, track_errors, track_time
|
||||
from logs.custom_logger import logger
|
||||
|
||||
@@ -7,6 +7,7 @@ except ImportError:
|
||||
|
||||
from aiogram import BaseMiddleware
|
||||
from aiogram.types import TelegramObject
|
||||
|
||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||
from helper_bot.utils.helper_func import check_access
|
||||
from logs.custom_logger import logger
|
||||
|
||||
@@ -6,15 +6,20 @@ from aiogram import F, Router, types
|
||||
from aiogram.filters import Command, MagicData
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import FSInputFile
|
||||
|
||||
from helper_bot.filters.main import ChatTypeFilter
|
||||
from helper_bot.middlewares.dependencies_middleware import \
|
||||
DependenciesMiddleware
|
||||
from helper_bot.middlewares.dependencies_middleware import DependenciesMiddleware
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import track_errors, track_time
|
||||
from helper_bot.utils.rate_limit_metrics import (
|
||||
get_rate_limit_metrics_summary, update_rate_limit_gauges)
|
||||
from helper_bot.utils.rate_limit_monitor import (get_rate_limit_summary,
|
||||
rate_limit_monitor)
|
||||
get_rate_limit_metrics_summary,
|
||||
update_rate_limit_gauges,
|
||||
)
|
||||
from helper_bot.utils.rate_limit_monitor import (
|
||||
get_rate_limit_summary,
|
||||
rate_limit_monitor,
|
||||
)
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
|
||||
from helper_bot.handlers.admin.exceptions import (InvalidInputError,
|
||||
UserAlreadyBannedError)
|
||||
from helper_bot.utils.helper_func import (add_days_to_date,
|
||||
get_banned_users_buttons,
|
||||
get_banned_users_list)
|
||||
from helper_bot.handlers.admin.exceptions import (
|
||||
InvalidInputError,
|
||||
UserAlreadyBannedError,
|
||||
)
|
||||
from helper_bot.utils.helper_func import (
|
||||
add_days_to_date,
|
||||
get_banned_users_buttons,
|
||||
get_banned_users_list,
|
||||
)
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import track_errors, track_time
|
||||
from logs.custom_logger import logger
|
||||
|
||||
@@ -3,6 +3,7 @@ from typing import Optional
|
||||
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
from helper_bot.handlers.admin.exceptions import AdminError
|
||||
from helper_bot.keyboards.keyboards import get_reply_keyboard_admin
|
||||
from logs.custom_logger import logger
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
from .callback_handlers import callback_router
|
||||
from .constants import (CALLBACK_BAN, CALLBACK_DECLINE, CALLBACK_PAGE,
|
||||
CALLBACK_PUBLISH, CALLBACK_RETURN, CALLBACK_UNLOCK)
|
||||
from .exceptions import (BanError, PostNotFoundError, PublishError,
|
||||
UserBlockedBotError, UserNotFoundError)
|
||||
from .constants import (
|
||||
CALLBACK_BAN,
|
||||
CALLBACK_DECLINE,
|
||||
CALLBACK_PAGE,
|
||||
CALLBACK_PUBLISH,
|
||||
CALLBACK_RETURN,
|
||||
CALLBACK_UNLOCK,
|
||||
)
|
||||
from .exceptions import (
|
||||
BanError,
|
||||
PostNotFoundError,
|
||||
PublishError,
|
||||
UserBlockedBotError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
from .services import BanService, PostPublishService
|
||||
|
||||
__all__ = [
|
||||
|
||||
@@ -7,28 +7,49 @@ from aiogram import F, Router
|
||||
from aiogram.filters import MagicData
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import CallbackQuery
|
||||
|
||||
from helper_bot.handlers.admin.utils import format_user_info
|
||||
from helper_bot.handlers.voice.constants import CALLBACK_DELETE, CALLBACK_SAVE
|
||||
from helper_bot.handlers.voice.services import AudioFileService
|
||||
from helper_bot.keyboards.keyboards import (create_keyboard_for_ban_reason,
|
||||
create_keyboard_with_pagination,
|
||||
get_reply_keyboard_admin)
|
||||
from helper_bot.keyboards.keyboards import (
|
||||
create_keyboard_for_ban_reason,
|
||||
create_keyboard_with_pagination,
|
||||
get_reply_keyboard_admin,
|
||||
)
|
||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||
from helper_bot.utils.helper_func import (get_banned_users_buttons,
|
||||
get_banned_users_list)
|
||||
from helper_bot.utils.helper_func import get_banned_users_buttons, get_banned_users_list
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import (db_query_time, track_errors,
|
||||
track_file_operations, track_time)
|
||||
from helper_bot.utils.metrics import (
|
||||
db_query_time,
|
||||
track_errors,
|
||||
track_file_operations,
|
||||
track_time,
|
||||
)
|
||||
from logs.custom_logger import logger
|
||||
|
||||
from .constants import (CALLBACK_BAN, CALLBACK_DECLINE, CALLBACK_PAGE,
|
||||
CALLBACK_PUBLISH, CALLBACK_RETURN, CALLBACK_UNLOCK,
|
||||
ERROR_BOT_BLOCKED, MESSAGE_DECLINED, MESSAGE_ERROR,
|
||||
MESSAGE_PUBLISHED, MESSAGE_USER_BANNED,
|
||||
MESSAGE_USER_UNLOCKED)
|
||||
from .constants import (
|
||||
CALLBACK_BAN,
|
||||
CALLBACK_DECLINE,
|
||||
CALLBACK_PAGE,
|
||||
CALLBACK_PUBLISH,
|
||||
CALLBACK_RETURN,
|
||||
CALLBACK_UNLOCK,
|
||||
ERROR_BOT_BLOCKED,
|
||||
MESSAGE_DECLINED,
|
||||
MESSAGE_ERROR,
|
||||
MESSAGE_PUBLISHED,
|
||||
MESSAGE_USER_BANNED,
|
||||
MESSAGE_USER_UNLOCKED,
|
||||
)
|
||||
from .dependency_factory import get_ban_service, get_post_publish_service
|
||||
from .exceptions import (BanError, PostNotFoundError, PublishError,
|
||||
UserBlockedBotError, UserNotFoundError)
|
||||
from .exceptions import (
|
||||
BanError,
|
||||
PostNotFoundError,
|
||||
PublishError,
|
||||
UserBlockedBotError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
|
||||
callback_router = Router()
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ from typing import Callable
|
||||
from aiogram import Bot
|
||||
from aiogram.client.default import DefaultBotProperties
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||
|
||||
from .services import BanService, PostPublishService
|
||||
|
||||
@@ -4,28 +4,49 @@ from typing import Any, Dict
|
||||
|
||||
from aiogram import Bot, types
|
||||
from aiogram.types import CallbackQuery
|
||||
|
||||
from helper_bot.keyboards.keyboards import create_keyboard_for_ban_reason
|
||||
from helper_bot.utils.helper_func import (delete_user_blacklist,
|
||||
get_text_message, send_audio_message,
|
||||
send_media_group_to_channel,
|
||||
send_photo_message,
|
||||
send_text_message,
|
||||
send_video_message,
|
||||
send_video_note_message,
|
||||
send_voice_message)
|
||||
from helper_bot.utils.helper_func import (
|
||||
delete_user_blacklist,
|
||||
get_text_message,
|
||||
send_audio_message,
|
||||
send_media_group_to_channel,
|
||||
send_photo_message,
|
||||
send_text_message,
|
||||
send_video_message,
|
||||
send_video_note_message,
|
||||
send_voice_message,
|
||||
)
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import (db_query_time, track_errors,
|
||||
track_media_processing, track_time)
|
||||
from helper_bot.utils.metrics import (
|
||||
db_query_time,
|
||||
track_errors,
|
||||
track_media_processing,
|
||||
track_time,
|
||||
)
|
||||
from logs.custom_logger import logger
|
||||
|
||||
from .constants import (CONTENT_TYPE_AUDIO, CONTENT_TYPE_MEDIA_GROUP,
|
||||
CONTENT_TYPE_PHOTO, CONTENT_TYPE_TEXT,
|
||||
CONTENT_TYPE_VIDEO, CONTENT_TYPE_VIDEO_NOTE,
|
||||
CONTENT_TYPE_VOICE, ERROR_BOT_BLOCKED,
|
||||
MESSAGE_POST_DECLINED, MESSAGE_POST_PUBLISHED,
|
||||
MESSAGE_USER_BANNED_SPAM)
|
||||
from .exceptions import (BanError, PostNotFoundError, PublishError,
|
||||
UserBlockedBotError, UserNotFoundError)
|
||||
from .constants import (
|
||||
CONTENT_TYPE_AUDIO,
|
||||
CONTENT_TYPE_MEDIA_GROUP,
|
||||
CONTENT_TYPE_PHOTO,
|
||||
CONTENT_TYPE_TEXT,
|
||||
CONTENT_TYPE_VIDEO,
|
||||
CONTENT_TYPE_VIDEO_NOTE,
|
||||
CONTENT_TYPE_VOICE,
|
||||
ERROR_BOT_BLOCKED,
|
||||
MESSAGE_POST_DECLINED,
|
||||
MESSAGE_POST_PUBLISHED,
|
||||
MESSAGE_USER_BANNED_SPAM,
|
||||
)
|
||||
from .exceptions import (
|
||||
BanError,
|
||||
PostNotFoundError,
|
||||
PublishError,
|
||||
UserBlockedBotError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
|
||||
|
||||
class PostPublishService:
|
||||
|
||||
@@ -6,6 +6,7 @@ from .constants import ERROR_MESSAGES, FSM_STATES
|
||||
from .decorators import error_handler
|
||||
from .exceptions import NoReplyToMessageError, UserNotFoundError
|
||||
from .group_handlers import GroupHandlers, create_group_handlers, group_router
|
||||
|
||||
# Local imports - services
|
||||
from .services import AdminReplyService, DatabaseProtocol
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from typing import Any, Callable
|
||||
|
||||
# Third-party imports
|
||||
from aiogram import types
|
||||
|
||||
# Local imports
|
||||
from logs.custom_logger import logger
|
||||
|
||||
@@ -24,8 +25,9 @@ def error_handler(func: Callable[..., Any]) -> Callable[..., Any]:
|
||||
(arg for arg in args if isinstance(arg, types.Message)), None
|
||||
)
|
||||
if message and hasattr(message, "bot"):
|
||||
from helper_bot.utils.base_dependency_factory import \
|
||||
get_global_instance
|
||||
from helper_bot.utils.base_dependency_factory import (
|
||||
get_global_instance,
|
||||
)
|
||||
|
||||
bdf = get_global_instance()
|
||||
important_logs = bdf.settings["Telegram"]["important_logs"]
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
# Third-party imports
|
||||
from aiogram import Router, types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
# Local imports - filters
|
||||
from database.async_db import AsyncBotDB
|
||||
from helper_bot.filters.main import ChatTypeFilter
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import metrics, track_errors, track_time
|
||||
|
||||
# Local imports - utilities
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
@@ -5,8 +5,10 @@ from typing import Optional, Protocol
|
||||
|
||||
# Third-party imports
|
||||
from aiogram import types
|
||||
|
||||
# Local imports
|
||||
from helper_bot.utils.helper_func import send_text_message
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import db_query_time, track_errors, track_time
|
||||
from logs.custom_logger import logger
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
# Local imports - constants and utilities
|
||||
from .constants import BUTTON_TEXTS, ERROR_MESSAGES, FSM_STATES
|
||||
from .decorators import error_handler
|
||||
from .private_handlers import (PrivateHandlers, create_private_handlers,
|
||||
private_router)
|
||||
from .private_handlers import PrivateHandlers, create_private_handlers, private_router
|
||||
|
||||
# Local imports - services
|
||||
from .services import BotSettings, PostService, StickerService, UserService
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from typing import Any, Callable
|
||||
|
||||
# Third-party imports
|
||||
from aiogram import types
|
||||
|
||||
# Local imports
|
||||
from logs.custom_logger import logger
|
||||
|
||||
@@ -24,8 +25,9 @@ def error_handler(func: Callable[..., Any]) -> Callable[..., Any]:
|
||||
(arg for arg in args if isinstance(arg, types.Message)), None
|
||||
)
|
||||
if message and hasattr(message, "bot"):
|
||||
from helper_bot.utils.base_dependency_factory import \
|
||||
get_global_instance
|
||||
from helper_bot.utils.base_dependency_factory import (
|
||||
get_global_instance,
|
||||
)
|
||||
|
||||
bdf = get_global_instance()
|
||||
important_logs = bdf.settings["Telegram"]["important_logs"]
|
||||
|
||||
@@ -8,18 +8,23 @@ from datetime import datetime
|
||||
from aiogram import F, Router, types
|
||||
from aiogram.filters import Command, StateFilter
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
# Local imports - filters and middlewares
|
||||
from database.async_db import AsyncBotDB
|
||||
from helper_bot.filters.main import ChatTypeFilter
|
||||
|
||||
# Local imports - utilities
|
||||
from helper_bot.keyboards import (get_reply_keyboard,
|
||||
get_reply_keyboard_for_post)
|
||||
from helper_bot.keyboards import get_reply_keyboard, get_reply_keyboard_for_post
|
||||
from helper_bot.keyboards.keyboards import get_reply_keyboard_leave_chat
|
||||
from helper_bot.middlewares.album_middleware import AlbumMiddleware
|
||||
from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware
|
||||
from helper_bot.utils import messages
|
||||
from helper_bot.utils.helper_func import (check_user_emoji, get_first_name,
|
||||
update_user_info)
|
||||
from helper_bot.utils.helper_func import (
|
||||
check_user_emoji,
|
||||
get_first_name,
|
||||
update_user_info,
|
||||
)
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import db_query_time, track_errors, track_time
|
||||
|
||||
|
||||
@@ -12,19 +12,35 @@ from typing import Any, Callable, Dict, Protocol, Union
|
||||
# Third-party imports
|
||||
from aiogram import types
|
||||
from aiogram.types import FSInputFile
|
||||
|
||||
from database.models import TelegramPost, User
|
||||
from helper_bot.keyboards import get_reply_keyboard_for_post
|
||||
|
||||
# Local imports - utilities
|
||||
from helper_bot.utils.helper_func import (
|
||||
add_in_db_media, check_username_and_full_name, determine_anonymity,
|
||||
get_first_name, get_text_message, prepare_media_group_from_middlewares,
|
||||
send_audio_message, send_media_group_message_to_private_chat,
|
||||
send_photo_message, send_text_message, send_video_message,
|
||||
send_video_note_message, send_voice_message)
|
||||
add_in_db_media,
|
||||
check_username_and_full_name,
|
||||
determine_anonymity,
|
||||
get_first_name,
|
||||
get_text_message,
|
||||
prepare_media_group_from_middlewares,
|
||||
send_audio_message,
|
||||
send_media_group_message_to_private_chat,
|
||||
send_photo_message,
|
||||
send_text_message,
|
||||
send_video_message,
|
||||
send_video_note_message,
|
||||
send_voice_message,
|
||||
)
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import (db_query_time, track_errors,
|
||||
track_file_operations,
|
||||
track_media_processing, track_time)
|
||||
from helper_bot.utils.metrics import (
|
||||
db_query_time,
|
||||
track_errors,
|
||||
track_file_operations,
|
||||
track_media_processing,
|
||||
track_time,
|
||||
)
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
|
||||
@@ -7,16 +7,24 @@ from pathlib import Path
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from aiogram.types import FSInputFile
|
||||
from helper_bot.handlers.voice.constants import (MESSAGE_DELAY_1,
|
||||
MESSAGE_DELAY_2,
|
||||
MESSAGE_DELAY_3,
|
||||
MESSAGE_DELAY_4, STICK_DIR,
|
||||
STICK_PATTERN, STICKER_DELAY,
|
||||
VOICE_USERS_DIR)
|
||||
from helper_bot.handlers.voice.exceptions import (AudioProcessingError,
|
||||
DatabaseError,
|
||||
FileOperationError,
|
||||
VoiceMessageError)
|
||||
|
||||
from helper_bot.handlers.voice.constants import (
|
||||
MESSAGE_DELAY_1,
|
||||
MESSAGE_DELAY_2,
|
||||
MESSAGE_DELAY_3,
|
||||
MESSAGE_DELAY_4,
|
||||
STICK_DIR,
|
||||
STICK_PATTERN,
|
||||
STICKER_DELAY,
|
||||
VOICE_USERS_DIR,
|
||||
)
|
||||
from helper_bot.handlers.voice.exceptions import (
|
||||
AudioProcessingError,
|
||||
DatabaseError,
|
||||
FileOperationError,
|
||||
VoiceMessageError,
|
||||
)
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import db_query_time, track_errors, track_time
|
||||
from logs.custom_logger import logger
|
||||
|
||||
@@ -6,25 +6,38 @@ from aiogram import F, Router, types
|
||||
from aiogram.filters import Command, MagicData, StateFilter
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import FSInputFile
|
||||
|
||||
from helper_bot.filters.main import ChatTypeFilter
|
||||
from helper_bot.handlers.private.constants import BUTTON_TEXTS, FSM_STATES
|
||||
from helper_bot.handlers.voice.constants import *
|
||||
from helper_bot.handlers.voice.services import VoiceBotService
|
||||
from helper_bot.handlers.voice.utils import (get_last_message_text,
|
||||
get_user_emoji_safe,
|
||||
validate_voice_message)
|
||||
from helper_bot.handlers.voice.utils import (
|
||||
get_last_message_text,
|
||||
get_user_emoji_safe,
|
||||
validate_voice_message,
|
||||
)
|
||||
from helper_bot.keyboards import get_reply_keyboard
|
||||
from helper_bot.keyboards.keyboards import (get_main_keyboard,
|
||||
get_reply_keyboard_for_voice)
|
||||
from helper_bot.keyboards.keyboards import (
|
||||
get_main_keyboard,
|
||||
get_reply_keyboard_for_voice,
|
||||
)
|
||||
from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware
|
||||
from helper_bot.middlewares.dependencies_middleware import \
|
||||
DependenciesMiddleware
|
||||
from helper_bot.middlewares.dependencies_middleware import DependenciesMiddleware
|
||||
from helper_bot.utils import messages
|
||||
from helper_bot.utils.helper_func import (check_user_emoji, get_first_name,
|
||||
send_voice_message, update_user_info)
|
||||
from helper_bot.utils.helper_func import (
|
||||
check_user_emoji,
|
||||
get_first_name,
|
||||
send_voice_message,
|
||||
update_user_info,
|
||||
)
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import (db_query_time, track_errors,
|
||||
track_file_operations, track_time)
|
||||
from helper_bot.utils.metrics import (
|
||||
db_query_time,
|
||||
track_errors,
|
||||
track_file_operations,
|
||||
track_time,
|
||||
)
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from aiogram import types
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder, ReplyKeyboardBuilder
|
||||
|
||||
# Local imports - metrics
|
||||
from helper_bot.utils.metrics import track_errors, track_time
|
||||
|
||||
|
||||
@@ -6,19 +6,20 @@ from aiogram import Bot, Dispatcher
|
||||
from aiogram.client.default import DefaultBotProperties
|
||||
from aiogram.fsm.storage.memory import MemoryStorage
|
||||
from aiogram.fsm.strategy import FSMStrategy
|
||||
|
||||
from helper_bot.handlers.admin import admin_router
|
||||
from helper_bot.handlers.callback import callback_router
|
||||
from helper_bot.handlers.group import group_router
|
||||
from helper_bot.handlers.private import private_router
|
||||
from helper_bot.handlers.voice import VoiceHandlers
|
||||
from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware
|
||||
from helper_bot.middlewares.dependencies_middleware import \
|
||||
DependenciesMiddleware
|
||||
from helper_bot.middlewares.metrics_middleware import (ErrorMetricsMiddleware,
|
||||
MetricsMiddleware)
|
||||
from helper_bot.middlewares.dependencies_middleware import DependenciesMiddleware
|
||||
from helper_bot.middlewares.metrics_middleware import (
|
||||
ErrorMetricsMiddleware,
|
||||
MetricsMiddleware,
|
||||
)
|
||||
from helper_bot.middlewares.rate_limit_middleware import RateLimitMiddleware
|
||||
from helper_bot.server_prometheus import (start_metrics_server,
|
||||
stop_metrics_server)
|
||||
from helper_bot.server_prometheus import start_metrics_server, stop_metrics_server
|
||||
|
||||
|
||||
async def start_bot_with_retry(
|
||||
|
||||
@@ -4,6 +4,7 @@ from typing import Any, Dict
|
||||
|
||||
from aiogram import BaseMiddleware, types
|
||||
from aiogram.types import CallbackQuery, Message, TelegramObject
|
||||
|
||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ from typing import Any, Dict
|
||||
|
||||
from aiogram import BaseMiddleware
|
||||
from aiogram.types import TelegramObject
|
||||
|
||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
@@ -16,16 +16,16 @@ from ..utils.metrics import metrics
|
||||
|
||||
# Import button command mapping
|
||||
try:
|
||||
from ..handlers.admin.constants import (ADMIN_BUTTON_COMMAND_MAPPING,
|
||||
ADMIN_COMMANDS)
|
||||
from ..handlers.admin.constants import ADMIN_BUTTON_COMMAND_MAPPING, ADMIN_COMMANDS
|
||||
from ..handlers.callback.constants import CALLBACK_COMMAND_MAPPING
|
||||
from ..handlers.private.constants import BUTTON_COMMAND_MAPPING
|
||||
from ..handlers.voice.constants import \
|
||||
BUTTON_COMMAND_MAPPING as VOICE_BUTTON_COMMAND_MAPPING
|
||||
from ..handlers.voice.constants import \
|
||||
CALLBACK_COMMAND_MAPPING as VOICE_CALLBACK_COMMAND_MAPPING
|
||||
from ..handlers.voice.constants import \
|
||||
COMMAND_MAPPING as VOICE_COMMAND_MAPPING
|
||||
from ..handlers.voice.constants import (
|
||||
BUTTON_COMMAND_MAPPING as VOICE_BUTTON_COMMAND_MAPPING,
|
||||
)
|
||||
from ..handlers.voice.constants import (
|
||||
CALLBACK_COMMAND_MAPPING as VOICE_CALLBACK_COMMAND_MAPPING,
|
||||
)
|
||||
from ..handlers.voice.constants import COMMAND_MAPPING as VOICE_COMMAND_MAPPING
|
||||
except ImportError:
|
||||
# Fallback if constants not available
|
||||
BUTTON_COMMAND_MAPPING = {}
|
||||
|
||||
@@ -6,8 +6,8 @@ from typing import Any, Awaitable, Callable, Dict, Union
|
||||
|
||||
from aiogram import BaseMiddleware
|
||||
from aiogram.exceptions import TelegramAPIError, TelegramRetryAfter
|
||||
from aiogram.types import (CallbackQuery, ChatMemberUpdated, InlineQuery,
|
||||
Message, Update)
|
||||
from aiogram.types import CallbackQuery, ChatMemberUpdated, InlineQuery, Message, Update
|
||||
|
||||
from helper_bot.utils.rate_limiter import telegram_rate_limiter
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
@@ -9,9 +9,14 @@
|
||||
|
||||
from .base import CombinedScore, ScoringResult, ScoringServiceProtocol
|
||||
from .deepseek_service import DeepSeekService
|
||||
from .exceptions import (DeepSeekAPIError, InsufficientExamplesError,
|
||||
ModelNotLoadedError, ScoringError, TextTooShortError,
|
||||
VectorStoreError)
|
||||
from .exceptions import (
|
||||
DeepSeekAPIError,
|
||||
InsufficientExamplesError,
|
||||
ModelNotLoadedError,
|
||||
ScoringError,
|
||||
TextTooShortError,
|
||||
VectorStoreError,
|
||||
)
|
||||
from .rag_client import RagApiClient
|
||||
from .scoring_manager import ScoringManager
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import json
|
||||
from typing import List, Optional
|
||||
|
||||
import httpx
|
||||
|
||||
from helper_bot.utils.metrics import track_errors, track_time
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ HTTP клиент для взаимодействия с внешним RAG се
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
import httpx
|
||||
|
||||
from helper_bot.utils.metrics import track_errors, track_time
|
||||
from logs.custom_logger import logger
|
||||
|
||||
from .base import ScoringResult
|
||||
from .exceptions import (InsufficientExamplesError, ScoringError,
|
||||
TextTooShortError)
|
||||
from .exceptions import InsufficientExamplesError, ScoringError, TextTooShortError
|
||||
|
||||
|
||||
class RagApiClient:
|
||||
|
||||
@@ -13,8 +13,7 @@ from logs.custom_logger import logger
|
||||
|
||||
from .base import CombinedScore, ScoringResult
|
||||
from .deepseek_service import DeepSeekService
|
||||
from .exceptions import (InsufficientExamplesError, ScoringError,
|
||||
TextTooShortError)
|
||||
from .exceptions import InsufficientExamplesError, ScoringError, TextTooShortError
|
||||
from .rag_client import RagApiClient
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from typing import Optional
|
||||
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
|
||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@ import os
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
from database.async_db import AsyncBotDB
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from database.async_db import AsyncBotDB
|
||||
from helper_bot.utils.s3_storage import S3StorageService
|
||||
from logs.custom_logger import logger
|
||||
|
||||
@@ -141,8 +142,11 @@ class BaseDependencyFactory:
|
||||
|
||||
Вызывается лениво при первом обращении к get_scoring_manager().
|
||||
"""
|
||||
from helper_bot.services.scoring import (DeepSeekService, RagApiClient,
|
||||
ScoringManager)
|
||||
from helper_bot.services.scoring import (
|
||||
DeepSeekService,
|
||||
RagApiClient,
|
||||
ScoringManager,
|
||||
)
|
||||
|
||||
scoring_config = self.settings["Scoring"]
|
||||
|
||||
|
||||
@@ -17,16 +17,29 @@ except ImportError:
|
||||
_emoji_lib_available = False
|
||||
|
||||
from aiogram import types
|
||||
from aiogram.types import (FSInputFile, InputMediaAudio, InputMediaDocument,
|
||||
InputMediaPhoto, InputMediaVideo)
|
||||
from aiogram.types import (
|
||||
FSInputFile,
|
||||
InputMediaAudio,
|
||||
InputMediaDocument,
|
||||
InputMediaPhoto,
|
||||
InputMediaVideo,
|
||||
)
|
||||
|
||||
from database.models import TelegramPost
|
||||
from helper_bot.utils.base_dependency_factory import (BaseDependencyFactory,
|
||||
get_global_instance)
|
||||
from helper_bot.utils.base_dependency_factory import (
|
||||
BaseDependencyFactory,
|
||||
get_global_instance,
|
||||
)
|
||||
from logs.custom_logger import logger
|
||||
|
||||
# Local imports - metrics
|
||||
from .metrics import (db_query_time, track_errors, track_file_operations,
|
||||
track_media_processing, track_time)
|
||||
from .metrics import (
|
||||
db_query_time,
|
||||
track_errors,
|
||||
track_file_operations,
|
||||
track_media_processing,
|
||||
track_time,
|
||||
)
|
||||
|
||||
bdf = get_global_instance()
|
||||
# TODO: поменять архитектуру и подключить правильный BotDB
|
||||
|
||||
@@ -10,8 +10,13 @@ from contextlib import asynccontextmanager
|
||||
from functools import wraps
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from prometheus_client import (CONTENT_TYPE_LATEST, Counter, Gauge, Histogram,
|
||||
generate_latest)
|
||||
from prometheus_client import (
|
||||
CONTENT_TYPE_LATEST,
|
||||
Counter,
|
||||
Gauge,
|
||||
Histogram,
|
||||
generate_latest,
|
||||
)
|
||||
from prometheus_client.core import CollectorRegistry
|
||||
|
||||
# Метрики rate limiter теперь создаются в основном классе
|
||||
|
||||
@@ -8,6 +8,7 @@ from dataclasses import dataclass
|
||||
from typing import Any, Callable, Dict, Optional
|
||||
|
||||
from aiogram.exceptions import TelegramAPIError, TelegramRetryAfter
|
||||
|
||||
from logs.custom_logger import logger
|
||||
|
||||
from .metrics import metrics
|
||||
@@ -187,8 +188,7 @@ class TelegramRateLimiter:
|
||||
|
||||
|
||||
# Глобальный экземпляр rate limiter
|
||||
from helper_bot.config.rate_limit_config import (RateLimitSettings,
|
||||
get_rate_limit_config)
|
||||
from helper_bot.config.rate_limit_config import RateLimitSettings, get_rate_limit_config
|
||||
|
||||
|
||||
def _create_rate_limit_config(settings: RateLimitSettings) -> RateLimitConfig:
|
||||
|
||||
@@ -8,6 +8,7 @@ from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import aioboto3
|
||||
|
||||
from logs.custom_logger import logger
|
||||
|
||||
|
||||
|
||||
@@ -68,8 +68,7 @@ async def main():
|
||||
|
||||
# Останавливаем планировщик метрик
|
||||
try:
|
||||
from helper_bot.utils.metrics_scheduler import \
|
||||
stop_metrics_scheduler
|
||||
from helper_bot.utils.metrics_scheduler import stop_metrics_scheduler
|
||||
|
||||
stop_metrics_scheduler()
|
||||
logger.info("Планировщик метрик остановлен")
|
||||
|
||||
@@ -13,10 +13,10 @@ if str(_project_root) not in sys.path:
|
||||
import pytest
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import Chat, Message, User
|
||||
from database.async_db import AsyncBotDB
|
||||
|
||||
# Импортируем моки в самом начале
|
||||
import tests.mocks
|
||||
from database.async_db import AsyncBotDB
|
||||
|
||||
# Настройка pytest-asyncio
|
||||
pytest_plugins = ("pytest_asyncio",)
|
||||
|
||||
@@ -3,6 +3,7 @@ import tempfile
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import UserMessage
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from datetime import datetime
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import MessageContentLink, PostContent, TelegramPost
|
||||
from database.repositories.post_repository import PostRepository
|
||||
|
||||
|
||||
@@ -5,8 +5,12 @@
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.handlers.admin.dependencies import (AdminAccessMiddleware,
|
||||
get_bot_db, get_settings)
|
||||
|
||||
from helper_bot.handlers.admin.dependencies import (
|
||||
AdminAccessMiddleware,
|
||||
get_bot_db,
|
||||
get_settings,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -7,16 +7,19 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from helper_bot.handlers.admin.admin_handlers import (admin_panel,
|
||||
cancel_ban_process,
|
||||
confirm_ban,
|
||||
get_banned_users,
|
||||
get_last_users,
|
||||
get_ml_stats,
|
||||
process_ban_duration,
|
||||
process_ban_reason,
|
||||
process_ban_target,
|
||||
start_ban_process)
|
||||
|
||||
from helper_bot.handlers.admin.admin_handlers import (
|
||||
admin_panel,
|
||||
cancel_ban_process,
|
||||
confirm_ban,
|
||||
get_banned_users,
|
||||
get_last_users,
|
||||
get_ml_stats,
|
||||
process_ban_duration,
|
||||
process_ban_reason,
|
||||
process_ban_target,
|
||||
start_ban_process,
|
||||
)
|
||||
from helper_bot.handlers.admin.services import User as AdminUser
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import Admin
|
||||
from database.repositories.admin_repository import AdminRepository
|
||||
|
||||
|
||||
@@ -5,12 +5,15 @@
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from helper_bot.handlers.admin.exceptions import AdminError
|
||||
from helper_bot.handlers.admin.utils import (escape_html,
|
||||
format_ban_confirmation,
|
||||
format_user_info,
|
||||
handle_admin_error,
|
||||
return_to_admin_menu)
|
||||
from helper_bot.handlers.admin.utils import (
|
||||
escape_html,
|
||||
format_ban_confirmation,
|
||||
format_user_info,
|
||||
handle_admin_error,
|
||||
return_to_admin_menu,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -6,8 +6,8 @@ import asyncio
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.middlewares.album_middleware import (AlbumGetter,
|
||||
AlbumMiddleware)
|
||||
|
||||
from helper_bot.middlewares.album_middleware import AlbumGetter, AlbumMiddleware
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from database.async_db import AsyncBotDB
|
||||
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, mock_open, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.exceptions import (DatabaseError,
|
||||
FileOperationError)
|
||||
|
||||
from helper_bot.handlers.voice.exceptions import DatabaseError, FileOperationError
|
||||
from helper_bot.handlers.voice.services import AudioFileService
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ from datetime import datetime, timezone
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import AudioListenRecord, AudioMessage, AudioModerate
|
||||
from database.repositories.audio_repository import AudioRepository
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ from datetime import datetime, timezone
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from database.repositories.audio_repository import AudioRepository
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from datetime import datetime, timedelta, timezone
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from helper_bot.utils.auto_unban_scheduler import AutoUnbanScheduler
|
||||
|
||||
|
||||
|
||||
@@ -3,8 +3,11 @@ from datetime import datetime, timedelta, timezone
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.utils.auto_unban_scheduler import (AutoUnbanScheduler,
|
||||
get_auto_unban_scheduler)
|
||||
|
||||
from helper_bot.utils.auto_unban_scheduler import (
|
||||
AutoUnbanScheduler,
|
||||
get_auto_unban_scheduler,
|
||||
)
|
||||
|
||||
|
||||
class TestAutoUnbanScheduler:
|
||||
|
||||
@@ -3,9 +3,11 @@ from datetime import datetime
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import BlacklistHistoryRecord
|
||||
from database.repositories.blacklist_history_repository import \
|
||||
BlacklistHistoryRepository
|
||||
from database.repositories.blacklist_history_repository import (
|
||||
BlacklistHistoryRepository,
|
||||
)
|
||||
|
||||
|
||||
class TestBlacklistHistoryRepository:
|
||||
|
||||
@@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
|
||||
from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import BlacklistUser
|
||||
from database.repositories.blacklist_repository import BlacklistRepository
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from helper_bot.handlers.callback.dependency_factory import (
|
||||
get_ban_service, get_post_publish_service)
|
||||
from helper_bot.handlers.callback.services import (BanService,
|
||||
PostPublishService)
|
||||
get_ban_service,
|
||||
get_post_publish_service,
|
||||
)
|
||||
from helper_bot.handlers.callback.services import BanService, PostPublishService
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -3,9 +3,15 @@ from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from helper_bot.handlers.callback.callback_handlers import (
|
||||
change_page, delete_voice_message, process_ban_user, process_unlock_user,
|
||||
return_to_main_menu, save_voice_message)
|
||||
change_page,
|
||||
delete_voice_message,
|
||||
process_ban_user,
|
||||
process_unlock_user,
|
||||
return_to_main_menu,
|
||||
save_voice_message,
|
||||
)
|
||||
from helper_bot.handlers.voice.constants import CALLBACK_DELETE, CALLBACK_SAVE
|
||||
|
||||
|
||||
|
||||
@@ -6,13 +6,15 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
|
||||
from helper_bot.handlers.callback.constants import CONTENT_TYPE_MEDIA_GROUP
|
||||
from helper_bot.handlers.callback.exceptions import (PostNotFoundError,
|
||||
PublishError,
|
||||
UserBlockedBotError,
|
||||
UserNotFoundError)
|
||||
from helper_bot.handlers.callback.services import (BanService,
|
||||
PostPublishService)
|
||||
from helper_bot.handlers.callback.exceptions import (
|
||||
PostNotFoundError,
|
||||
PublishError,
|
||||
UserBlockedBotError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
from helper_bot.handlers.callback.services import BanService, PostPublishService
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -6,10 +6,11 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from helper_bot.handlers.group.decorators import \
|
||||
error_handler as group_error_handler
|
||||
from helper_bot.handlers.private.decorators import \
|
||||
error_handler as private_error_handler
|
||||
|
||||
from helper_bot.handlers.group.decorators import error_handler as group_error_handler
|
||||
from helper_bot.handlers.private.decorators import (
|
||||
error_handler as private_error_handler,
|
||||
)
|
||||
|
||||
|
||||
class FakeMessage:
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from helper_bot.services.scoring.deepseek_service import DeepSeekService
|
||||
from helper_bot.services.scoring.exceptions import (DeepSeekAPIError,
|
||||
ScoringError,
|
||||
TextTooShortError)
|
||||
from helper_bot.services.scoring.exceptions import (
|
||||
DeepSeekAPIError,
|
||||
ScoringError,
|
||||
TextTooShortError,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.middlewares.dependencies_middleware import \
|
||||
DependenciesMiddleware
|
||||
|
||||
from helper_bot.middlewares.dependencies_middleware import DependenciesMiddleware
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -8,9 +8,13 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram import types
|
||||
|
||||
from helper_bot.utils.helper_func import (
|
||||
add_in_db_media, add_in_db_media_mediagroup, download_file,
|
||||
send_media_group_message_to_private_chat)
|
||||
add_in_db_media,
|
||||
add_in_db_media_mediagroup,
|
||||
download_file,
|
||||
send_media_group_message_to_private_chat,
|
||||
)
|
||||
|
||||
|
||||
class TestDownloadFile:
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram.types import (InlineKeyboardButton, InlineKeyboardMarkup,
|
||||
KeyboardButton, ReplyKeyboardMarkup)
|
||||
from aiogram.types import (
|
||||
InlineKeyboardButton,
|
||||
InlineKeyboardMarkup,
|
||||
KeyboardButton,
|
||||
ReplyKeyboardMarkup,
|
||||
)
|
||||
|
||||
from database.async_db import AsyncBotDB
|
||||
from helper_bot.filters.main import ChatTypeFilter
|
||||
from helper_bot.keyboards.keyboards import (create_keyboard_with_pagination,
|
||||
get_reply_keyboard,
|
||||
get_reply_keyboard_admin,
|
||||
get_reply_keyboard_for_post,
|
||||
get_reply_keyboard_leave_chat)
|
||||
from helper_bot.keyboards.keyboards import (
|
||||
create_keyboard_with_pagination,
|
||||
get_reply_keyboard,
|
||||
get_reply_keyboard_admin,
|
||||
get_reply_keyboard_for_post,
|
||||
get_reply_keyboard_leave_chat,
|
||||
)
|
||||
|
||||
|
||||
class TestKeyboards:
|
||||
|
||||
@@ -6,6 +6,7 @@ import asyncio
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from helper_bot.main import start_bot, start_bot_with_retry
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import UserMessage
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import tempfile
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import UserMessage
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
|
||||
|
||||
@@ -7,8 +7,12 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram.types import Message
|
||||
|
||||
from helper_bot.middlewares.metrics_middleware import (
|
||||
DatabaseMetricsMiddleware, ErrorMetricsMiddleware, MetricsMiddleware)
|
||||
DatabaseMetricsMiddleware,
|
||||
ErrorMetricsMiddleware,
|
||||
MetricsMiddleware,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -3,6 +3,7 @@ from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import MessageContentLink, PostContent, TelegramPost
|
||||
from database.repositories.post_repository import PostRepository
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import tempfile
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
|
||||
from database.models import MessageContentLink, PostContent, TelegramPost
|
||||
from database.repositories.post_repository import PostRepository
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram import types
|
||||
|
||||
from database.models import TelegramPost, User
|
||||
from helper_bot.handlers.private.services import BotSettings, PostService
|
||||
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.services.scoring.exceptions import (InsufficientExamplesError,
|
||||
ScoringError,
|
||||
TextTooShortError)
|
||||
|
||||
from helper_bot.services.scoring.exceptions import (
|
||||
InsufficientExamplesError,
|
||||
ScoringError,
|
||||
TextTooShortError,
|
||||
)
|
||||
from helper_bot.services.scoring.rag_client import RagApiClient
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram.types import CallbackQuery, Message, Update
|
||||
|
||||
from helper_bot.middlewares.rate_limit_middleware import RateLimitMiddleware
|
||||
|
||||
|
||||
|
||||
@@ -7,10 +7,13 @@ from collections import deque
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.utils.rate_limit_monitor import (RateLimitMonitor,
|
||||
RateLimitStats,
|
||||
get_rate_limit_summary,
|
||||
record_rate_limit_request)
|
||||
|
||||
from helper_bot.utils.rate_limit_monitor import (
|
||||
RateLimitMonitor,
|
||||
RateLimitStats,
|
||||
get_rate_limit_summary,
|
||||
record_rate_limit_request,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -7,15 +7,21 @@ import time
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.config.rate_limit_config import (RateLimitSettings,
|
||||
get_rate_limit_config)
|
||||
from helper_bot.utils.rate_limit_monitor import (RateLimitMonitor,
|
||||
RateLimitStats,
|
||||
record_rate_limit_request)
|
||||
from helper_bot.utils.rate_limiter import (ChatRateLimiter, GlobalRateLimiter,
|
||||
RateLimitConfig, RetryHandler,
|
||||
TelegramRateLimiter,
|
||||
send_with_rate_limit)
|
||||
|
||||
from helper_bot.config.rate_limit_config import RateLimitSettings, get_rate_limit_config
|
||||
from helper_bot.utils.rate_limit_monitor import (
|
||||
RateLimitMonitor,
|
||||
RateLimitStats,
|
||||
record_rate_limit_request,
|
||||
)
|
||||
from helper_bot.utils.rate_limiter import (
|
||||
ChatRateLimiter,
|
||||
GlobalRateLimiter,
|
||||
RateLimitConfig,
|
||||
RetryHandler,
|
||||
TelegramRateLimiter,
|
||||
send_with_rate_limit,
|
||||
)
|
||||
|
||||
|
||||
class TestRateLimitConfig:
|
||||
|
||||
@@ -3,9 +3,12 @@ from unittest.mock import AsyncMock, Mock, patch
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from helper_bot.handlers.admin.exceptions import (InvalidInputError,
|
||||
UserAlreadyBannedError,
|
||||
UserNotFoundError)
|
||||
|
||||
from helper_bot.handlers.admin.exceptions import (
|
||||
InvalidInputError,
|
||||
UserAlreadyBannedError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
from helper_bot.handlers.admin.services import AdminService, BannedUser, User
|
||||
|
||||
|
||||
|
||||
@@ -5,11 +5,16 @@ from unittest.mock import AsyncMock, MagicMock, Mock
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
from helper_bot.handlers.group.constants import ERROR_MESSAGES, FSM_STATES
|
||||
from helper_bot.handlers.group.exceptions import (NoReplyToMessageError,
|
||||
UserNotFoundError)
|
||||
from helper_bot.handlers.group.group_handlers import (GroupHandlers,
|
||||
create_group_handlers)
|
||||
from helper_bot.handlers.group.exceptions import (
|
||||
NoReplyToMessageError,
|
||||
UserNotFoundError,
|
||||
)
|
||||
from helper_bot.handlers.group.group_handlers import (
|
||||
GroupHandlers,
|
||||
create_group_handlers,
|
||||
)
|
||||
from helper_bot.handlers.group.services import AdminReplyService
|
||||
|
||||
|
||||
|
||||
@@ -5,9 +5,12 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
from helper_bot.handlers.private.constants import BUTTON_TEXTS, FSM_STATES
|
||||
from helper_bot.handlers.private.private_handlers import (
|
||||
PrivateHandlers, create_private_handlers)
|
||||
PrivateHandlers,
|
||||
create_private_handlers,
|
||||
)
|
||||
from helper_bot.handlers.private.services import BotSettings
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from pathlib import Path
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from helper_bot.utils.s3_storage import S3StorageService
|
||||
|
||||
|
||||
|
||||
@@ -6,11 +6,14 @@ import json
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
# Импорты для тестирования базовых классов
|
||||
from helper_bot.services.scoring.base import CombinedScore, ScoringResult
|
||||
from helper_bot.services.scoring.exceptions import (InsufficientExamplesError,
|
||||
ScoringError,
|
||||
TextTooShortError)
|
||||
from helper_bot.services.scoring.exceptions import (
|
||||
InsufficientExamplesError,
|
||||
ScoringError,
|
||||
TextTooShortError,
|
||||
)
|
||||
|
||||
|
||||
class TestScoringResult:
|
||||
@@ -134,6 +137,7 @@ class TestVectorStore:
|
||||
"""Создает VectorStore для тестов."""
|
||||
try:
|
||||
import numpy as np
|
||||
|
||||
from helper_bot.services.scoring.vector_store import VectorStore
|
||||
|
||||
return VectorStore(vector_dim=768, max_examples=100)
|
||||
@@ -220,8 +224,7 @@ class TestDeepSeekService:
|
||||
@pytest.fixture
|
||||
def deepseek_service(self):
|
||||
"""Создает DeepSeekService для тестов."""
|
||||
from helper_bot.services.scoring.deepseek_service import \
|
||||
DeepSeekService
|
||||
from helper_bot.services.scoring.deepseek_service import DeepSeekService
|
||||
|
||||
return DeepSeekService(
|
||||
api_key="test_key",
|
||||
@@ -231,8 +234,7 @@ class TestDeepSeekService:
|
||||
|
||||
def test_service_disabled_without_key(self):
|
||||
"""Тест отключения сервиса без API ключа."""
|
||||
from helper_bot.services.scoring.deepseek_service import \
|
||||
DeepSeekService
|
||||
from helper_bot.services.scoring.deepseek_service import DeepSeekService
|
||||
|
||||
service = DeepSeekService(api_key=None, enabled=True)
|
||||
|
||||
@@ -264,8 +266,7 @@ class TestDeepSeekService:
|
||||
@pytest.mark.asyncio
|
||||
async def test_calculate_score_disabled(self):
|
||||
"""Тест расчета скора при отключенном сервисе."""
|
||||
from helper_bot.services.scoring.deepseek_service import \
|
||||
DeepSeekService
|
||||
from helper_bot.services.scoring.deepseek_service import DeepSeekService
|
||||
|
||||
service = DeepSeekService(api_key=None, enabled=False)
|
||||
|
||||
|
||||
@@ -6,8 +6,12 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from aiohttp import web
|
||||
from helper_bot.server_prometheus import (MetricsServer, start_metrics_server,
|
||||
stop_metrics_server)
|
||||
|
||||
from helper_bot.server_prometheus import (
|
||||
MetricsServer,
|
||||
start_metrics_server,
|
||||
stop_metrics_server,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from helper_bot.middlewares.text_middleware import BulkTextMiddleware
|
||||
|
||||
|
||||
|
||||
@@ -2,21 +2,41 @@ import os
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import helper_bot.utils.messages as messages # Import for patching constants
|
||||
import pytest
|
||||
|
||||
import helper_bot.utils.messages as messages # Import for patching constants
|
||||
from database.async_db import AsyncBotDB
|
||||
from helper_bot.utils.base_dependency_factory import (BaseDependencyFactory,
|
||||
get_global_instance)
|
||||
from helper_bot.utils.base_dependency_factory import (
|
||||
BaseDependencyFactory,
|
||||
get_global_instance,
|
||||
)
|
||||
from helper_bot.utils.helper_func import (
|
||||
add_days_to_date, add_in_db_media, add_in_db_media_mediagroup,
|
||||
check_access, check_user_emoji, check_username_and_full_name,
|
||||
delete_user_blacklist, determine_anonymity, download_file,
|
||||
get_banned_users_buttons, get_banned_users_list, get_first_name,
|
||||
get_random_emoji, get_text_message, prepare_media_group_from_middlewares,
|
||||
safe_html_escape, send_audio_message,
|
||||
send_media_group_message_to_private_chat, send_media_group_to_channel,
|
||||
send_photo_message, send_text_message, send_video_message,
|
||||
send_video_note_message, send_voice_message, update_user_info)
|
||||
add_days_to_date,
|
||||
add_in_db_media,
|
||||
add_in_db_media_mediagroup,
|
||||
check_access,
|
||||
check_user_emoji,
|
||||
check_username_and_full_name,
|
||||
delete_user_blacklist,
|
||||
determine_anonymity,
|
||||
download_file,
|
||||
get_banned_users_buttons,
|
||||
get_banned_users_list,
|
||||
get_first_name,
|
||||
get_random_emoji,
|
||||
get_text_message,
|
||||
prepare_media_group_from_middlewares,
|
||||
safe_html_escape,
|
||||
send_audio_message,
|
||||
send_media_group_message_to_private_chat,
|
||||
send_media_group_to_channel,
|
||||
send_photo_message,
|
||||
send_text_message,
|
||||
send_video_message,
|
||||
send_video_note_message,
|
||||
send_voice_message,
|
||||
update_user_info,
|
||||
)
|
||||
from helper_bot.utils.messages import get_message
|
||||
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@ from pathlib import Path
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.exceptions import (AudioProcessingError,
|
||||
VoiceMessageError)
|
||||
|
||||
from helper_bot.handlers.voice.exceptions import AudioProcessingError, VoiceMessageError
|
||||
from helper_bot.handlers.voice.services import VoiceBotService
|
||||
from helper_bot.handlers.voice.utils import (get_last_message_text,
|
||||
get_user_emoji_safe,
|
||||
validate_voice_message)
|
||||
from helper_bot.handlers.voice.utils import (
|
||||
get_last_message_text,
|
||||
get_user_emoji_safe,
|
||||
validate_voice_message,
|
||||
)
|
||||
|
||||
|
||||
class TestVoiceBotService:
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.constants import (BTN_LISTEN, BTN_SPEAK,
|
||||
BUTTON_COMMAND_MAPPING,
|
||||
CALLBACK_COMMAND_MAPPING,
|
||||
CALLBACK_DELETE,
|
||||
CALLBACK_SAVE, CMD_EMOJI,
|
||||
CMD_HELP, CMD_REFRESH,
|
||||
CMD_RESTART, CMD_START,
|
||||
COMMAND_MAPPING,
|
||||
STATE_STANDUP_WRITE,
|
||||
STATE_START, VOICE_BOT_NAME)
|
||||
|
||||
from helper_bot.handlers.voice.constants import (
|
||||
BTN_LISTEN,
|
||||
BTN_SPEAK,
|
||||
BUTTON_COMMAND_MAPPING,
|
||||
CALLBACK_COMMAND_MAPPING,
|
||||
CALLBACK_DELETE,
|
||||
CALLBACK_SAVE,
|
||||
CMD_EMOJI,
|
||||
CMD_HELP,
|
||||
CMD_REFRESH,
|
||||
CMD_RESTART,
|
||||
CMD_START,
|
||||
COMMAND_MAPPING,
|
||||
STATE_STANDUP_WRITE,
|
||||
STATE_START,
|
||||
VOICE_BOT_NAME,
|
||||
)
|
||||
|
||||
|
||||
class TestVoiceConstants:
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.exceptions import (AudioProcessingError,
|
||||
VoiceBotError,
|
||||
VoiceMessageError)
|
||||
|
||||
from helper_bot.handlers.voice.exceptions import (
|
||||
AudioProcessingError,
|
||||
VoiceBotError,
|
||||
VoiceMessageError,
|
||||
)
|
||||
|
||||
|
||||
class TestVoiceExceptions:
|
||||
|
||||
@@ -3,8 +3,8 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from helper_bot.handlers.voice.constants import (STATE_STANDUP_WRITE,
|
||||
STATE_START)
|
||||
|
||||
from helper_bot.handlers.voice.constants import STATE_STANDUP_WRITE, STATE_START
|
||||
from helper_bot.handlers.voice.voice_handler import VoiceHandlers
|
||||
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ from pathlib import Path
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.exceptions import (AudioProcessingError,
|
||||
VoiceMessageError)
|
||||
|
||||
from helper_bot.handlers.voice.exceptions import AudioProcessingError, VoiceMessageError
|
||||
from helper_bot.handlers.voice.services import VoiceBotService
|
||||
|
||||
|
||||
|
||||
@@ -3,10 +3,14 @@ from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from helper_bot.handlers.voice.utils import (format_time_ago,
|
||||
get_last_message_text,
|
||||
get_user_emoji_safe, plural_time,
|
||||
validate_voice_message)
|
||||
|
||||
from helper_bot.handlers.voice.utils import (
|
||||
format_time_ago,
|
||||
get_last_message_text,
|
||||
get_user_emoji_safe,
|
||||
plural_time,
|
||||
validate_voice_message,
|
||||
)
|
||||
|
||||
|
||||
class TestVoiceUtils:
|
||||
|
||||
Reference in New Issue
Block a user