From 3bb01751c34f37f33dee63b4f85314ef14d413d9 Mon Sep 17 00:00:00 2001 From: Verum Date: Sat, 22 Feb 2025 11:10:16 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A2=D1=80=D0=B5=D1=82=D1=8C=D1=8F=20=D1=87?= =?UTF-8?q?=D0=B0=D1=81=D1=82=D1=8C:=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=87?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BotCode/__init__.py | 13 +++-- BotCode/inline/__init__.py | 2 +- BotCode/routers/__init__.py | 18 ++++++- BotCode/routers/commands/__init__.py | 16 ++++++ BotCode/routers/commands/list_commands.py | 32 ++++++++++++ BotCode/routers/commands/user_cmd/__init__.py | 19 +++++++ BotCode/routers/commands/user_cmd/help_cmd.py | 12 +++++ .../routers/commands/user_cmd/start_cmd.py | 13 +++++ .../commands/user_cmd/user_cmd_class.py | 51 +++++++++++++++++++ BotCode/routers/common/__init__.py | 13 +++++ BotCode/routers/common/messages.py | 15 ++++++ BotLibrary/analytics/type_msg.py | 5 ++ BotLibrary/loggers/__init__.py | 1 + BotLibrary/loggers/logs.py | 17 +------ BotLibrary/loggers/msg_logger.py | 19 +++++++ BotLibrary/system/__init__.py | 1 + BotLibrary/system/directory.py | 26 ++++++++++ BotLibrary/timer/start_time.py | 9 ++-- ProjectsFiles/configs/config.py | 20 +++++++- main.py | 6 +++ 20 files changed, 280 insertions(+), 28 deletions(-) create mode 100644 BotCode/routers/commands/__init__.py create mode 100644 BotCode/routers/commands/list_commands.py create mode 100644 BotCode/routers/commands/user_cmd/__init__.py create mode 100644 BotCode/routers/commands/user_cmd/help_cmd.py create mode 100644 BotCode/routers/commands/user_cmd/start_cmd.py create mode 100644 BotCode/routers/commands/user_cmd/user_cmd_class.py create mode 100644 BotCode/routers/common/__init__.py create mode 100644 BotCode/routers/common/messages.py create mode 100644 BotLibrary/loggers/msg_logger.py create mode 100644 BotLibrary/system/directory.py diff --git a/BotCode/__init__.py b/BotCode/__init__.py index fe24e97..3cb87d2 100644 --- a/BotCode/__init__.py +++ b/BotCode/__init__.py @@ -1,6 +1,11 @@ # BotCode/__init__.py -# Инициализация пакета BotCode, для создания кода проекта +# Инициализация пакета BotCode, для работы с главными частями кода -# Экспортирование модулей во внешние слои проекта -from .keyboards import * -from .routers import * +from aiogram import Router +from .routers import router as all_routers + +# Объявление главного роутера +router = Router(name="main_router") + +# Список подключаемых роутеров сверху-вниз +router.include_routers(all_routers) diff --git a/BotCode/inline/__init__.py b/BotCode/inline/__init__.py index 37bdd9e..21df62e 100644 --- a/BotCode/inline/__init__.py +++ b/BotCode/inline/__init__.py @@ -1,4 +1,4 @@ # BotCode/inline/__init__.py -# Инициализация модуля inline, для основных роутеров +# Инициализация модуля inline, для создания inline-команд # Экспортирование модулей во внешние слои проекта diff --git a/BotCode/routers/__init__.py b/BotCode/routers/__init__.py index 46fe7ba..8d330c6 100644 --- a/BotCode/routers/__init__.py +++ b/BotCode/routers/__init__.py @@ -1,4 +1,18 @@ # BotCode/routers/__init__.py -# Инициализация модуля routers, для основных роутеров +# Инициализация пакета routers, для работы с асинхронными обработчиками -# Экспортирование модулей во внешние слои проекта +from aiogram import Router +from .commands import router as commands_head_router +from .common import router as common_head_router + +# Объявление главного роутера и настройка экспорта модулей +__all__ = ("router",) +router = Router(name="all_routers") + + +# Список подключаемых роутеров сверху-вниз +router.include_routers( + commands_head_router, +) + +router.include_routers(common_head_router) diff --git a/BotCode/routers/commands/__init__.py b/BotCode/routers/commands/__init__.py new file mode 100644 index 0000000..970dd94 --- /dev/null +++ b/BotCode/routers/commands/__init__.py @@ -0,0 +1,16 @@ +# BotCode/routers/commands/__init__.py +# Инициализация модуля commands, для основных команд бота + +from aiogram import Router +from .user_cmd import router as user_cmd_router + + +# Объявление роутера и настройка экспорта модулей +__all__ = ("router",) +router = Router(name="commands_head_router") + + +# Список подключаемых роутеров сверху-вниз +router.include_routers( + user_cmd_router, +) \ No newline at end of file diff --git a/BotCode/routers/commands/list_commands.py b/BotCode/routers/commands/list_commands.py new file mode 100644 index 0000000..8554092 --- /dev/null +++ b/BotCode/routers/commands/list_commands.py @@ -0,0 +1,32 @@ +# BotCode/routers/commands/list_commands.py +# Создание списка команд для бота + +from aiogram import Router, types +from aiogram.filters import Command +from BotLibrary import * + +from .user_cmd.start_cmd import start_cmd +from .user_cmd.help_cmd import help_cmd + +# Создание роутера и настройка экспорта модулей +__all__ = ("router", "set_commands") +router = Router(name="list_cmd_routers") + +# Список ключевых слов для команды "setcommands" +secret_keywords = ["setcommands", "setcommand", "ыуесщььфтвы", "ыуесщььфтв", + "setcmd", "setcmds", "ыуесьв",] + + +# Хэндлер на команду /setcommands для использования в чате +@router.message( + #F.from_user.id.func(lambda user_id: str(user_id) in DataID.important.keys()), + Command(*secret_keywords, prefix=BotVar.prefix, ignore_case=True)) +@router.message( + #F.from_user.id.func(lambda user_id: str(user_id) in DataID.important.keys()), + F.text.lower().in_(secret_keywords)) +async def set_commands(): + bot_commands = [ + types.BotCommand(command=start_cmd.name, description=start_cmd.description), + types.BotCommand(command=help_cmd.name, description=help_cmd.description), + ] + await bot.set_my_commands(bot_commands) \ No newline at end of file diff --git a/BotCode/routers/commands/user_cmd/__init__.py b/BotCode/routers/commands/user_cmd/__init__.py new file mode 100644 index 0000000..0d84088 --- /dev/null +++ b/BotCode/routers/commands/user_cmd/__init__.py @@ -0,0 +1,19 @@ +# BotCode/routers/commands/user_cmd/__init__.py +# Инициализация модуля user_cmd, для пользовательских команд бота + +# Экспортирование модулей во внешние слои проекта +from aiogram import Router +from .start_cmd import start_cmd +from .help_cmd import help_cmd + +# Объявление роутера и настройка экспорта модулей +__all__ = ("router",) +router = Router(name="user_cmd_router") + + +# Список подключаемых роутеров сверху-вниз +router.include_routers( + help_cmd.router, +) + +router.include_routers(start_cmd.router) diff --git a/BotCode/routers/commands/user_cmd/help_cmd.py b/BotCode/routers/commands/user_cmd/help_cmd.py new file mode 100644 index 0000000..a5373b6 --- /dev/null +++ b/BotCode/routers/commands/user_cmd/help_cmd.py @@ -0,0 +1,12 @@ +# BotCode/routers/commands/user_cmd/help_cmd.py +# Работа с командой /help, для вывода помощи пользователю + +from .user_cmd_class import CommandHandler + +# Создание команды /help с нужными параметрами +help_cmd = CommandHandler( + name="help", + description="Получить помощь", + keywords=["help", "info", "помощь", "инфо", "информация", "рудз", "штащ", "byaj", "gjvjom", "byajhvfwbz"], + text_msg="Привет! Это команда помощи. Тут ты можешь узнать, как пользоваться ботом.", +) diff --git a/BotCode/routers/commands/user_cmd/start_cmd.py b/BotCode/routers/commands/user_cmd/start_cmd.py new file mode 100644 index 0000000..f9789e1 --- /dev/null +++ b/BotCode/routers/commands/user_cmd/start_cmd.py @@ -0,0 +1,13 @@ +# BotCode/routers/commands/user_cmd/start_cmd.py +# # Работа с командой /start, для запуска бота + +from .user_cmd_class import CommandHandler + +# Создание команды /start с нужными параметрами +start_cmd = CommandHandler( + name="start", + description="Запустить бота", + keywords=["start", "старт", "запуск", "пуск", "on", "вкл", "с", "s", "ы", + "ыефке", "cnfhn", "pfgecr", "gecr", "щт", "drk", "restart", "куыефке"], + text_msg="Старт!", +) diff --git a/BotCode/routers/commands/user_cmd/user_cmd_class.py b/BotCode/routers/commands/user_cmd/user_cmd_class.py new file mode 100644 index 0000000..d576970 --- /dev/null +++ b/BotCode/routers/commands/user_cmd/user_cmd_class.py @@ -0,0 +1,51 @@ +# BotCode/routers/commands/user_cmd_class.py +# Класс-шаблон для создания новых команд + +from aiogram import Router, types +from aiogram.filters import Command +from BotLibrary import * + +# Класс-шаблон для команд +class CommandHandler: + def __init__(self, name: str, description: str, + keywords: list, text_msg: str, + keyboard=None, prefix = BotVar.prefix, + ignore_case = True, + ): + """ + Универсальный обработчик команд для бота. + + :param name: Имя команды (например, "help"). + :param description: Описание команды. + :param keywords: Список ключевых слов, которые активируют команду. + :param text_msg: Текст сообщения, который отправляется пользователю. + :param keyboard: Клавиатура, если требуется. + """ + self.router = Router(name=f"{name}_router") + self.name = name + self.log_type = name.capitalize() + self.description = description + self.keywords = keywords + self.text_msg = text_msg + self.keyboard = keyboard + + # Привязываем хэндлер к роутеру + self.router.message( + Command(*keywords, prefix=prefix, ignore_case=ignore_case) + )(self.handler) + self.router.message(F.text.lower().in_(keywords))(self.handler) + + + async def handler(self, message: types.Message): + """Основной хэндлер команды.""" + user = f"@{message.from_user.username or message.from_user.id}" + try: + logger.bind(log_type=self.name.capitalize(), user=user).info(f"использовал(а) команду /{self.name}") + await message.reply( + text=self.text_msg, + reply_markup=self.keyboard() if self.keyboard else None, + ) + + # Проверка на ошибку + except Exception as e: + logger.bind(log_type=self.name.capitalize(), user=user).error(f"Ошибка команды: {e}") diff --git a/BotCode/routers/common/__init__.py b/BotCode/routers/common/__init__.py new file mode 100644 index 0000000..c4174c8 --- /dev/null +++ b/BotCode/routers/common/__init__.py @@ -0,0 +1,13 @@ +# BotCode/routers/common/__init__.py +# Инициализация пакета common, для работы со всеми сообщениями + +from aiogram import Router +from .messages import router as common_messages_router + + +# Объявление роутера и настройка экспорта модулей +__all__ = ("router",) +router = Router(name="common_head_router") + +# Идет самым последним, если другие роутеры не сработали +router.include_router(common_messages_router) \ No newline at end of file diff --git a/BotCode/routers/common/messages.py b/BotCode/routers/common/messages.py new file mode 100644 index 0000000..82482f5 --- /dev/null +++ b/BotCode/routers/common/messages.py @@ -0,0 +1,15 @@ +# BotCode/routers/common/messages.py +# Обработчик всех сообщений + +from aiogram import Router, types +from BotLibrary import * + +# Настройка экспорта модулей и роутера +__all__ = ("router",) +router = Router(name="common_msg_router") + + +# Хэндлер на все сообщения и записывает данные +@router.message() +async def handle_all_messages(message: types.Message): + await logger_msg(message) diff --git a/BotLibrary/analytics/type_msg.py b/BotLibrary/analytics/type_msg.py index 42dc661..748d101 100644 --- a/BotLibrary/analytics/type_msg.py +++ b/BotLibrary/analytics/type_msg.py @@ -3,6 +3,11 @@ from aiogram.types import ContentType +# Настройка экспорта из модуля +__all__ = ("types_message",) + + +# Функция определения типа сообщения def types_message(message): # Словарь для соответствия типов сообщений content_types = { diff --git a/BotLibrary/loggers/__init__.py b/BotLibrary/loggers/__init__.py index fe0f819..97afec3 100644 --- a/BotLibrary/loggers/__init__.py +++ b/BotLibrary/loggers/__init__.py @@ -3,4 +3,5 @@ # Экспортирование модулей во внешние слои проекта from .logs import * +from .msg_logger import * from .start_info_out import * diff --git a/BotLibrary/loggers/logs.py b/BotLibrary/loggers/logs.py index dbb28a8..2786765 100644 --- a/BotLibrary/loggers/logs.py +++ b/BotLibrary/loggers/logs.py @@ -3,7 +3,7 @@ import sys from loguru import logger -from ProjectsFiles.configs.config import BotLogs +from ProjectsFiles import BotLogs # Создание обычного логгера + логгер в файл async def setup_logger(): @@ -36,18 +36,3 @@ async def setup_logger(): diagnose=True, level="ERROR", filter=lambda record: record["level"].name == "ERROR")""" - - -# Создание функции логирования на обычные сообщения -async def common_msg_logginger(message, - name : str = "Пользователь", - message_type : str = "Медиа", - log_type : str = "Message"): - if BotLogs.permission_msg: - # Проверка на наличие текста и его типа - if message.text is None: - logger.bind(log_type=log_type, user=f"@{message.from_user.username}").info( - f"Получено сообщение из ({name}) : {message_type}") - else: - logger.bind(log_type=log_type, user=f"@{message.from_user.username}").info( - f"Получено сообщение из ({name}) : {message.text}") diff --git a/BotLibrary/loggers/msg_logger.py b/BotLibrary/loggers/msg_logger.py new file mode 100644 index 0000000..9dafc78 --- /dev/null +++ b/BotLibrary/loggers/msg_logger.py @@ -0,0 +1,19 @@ +# BotLibrary/loggers/msg_logger.py +# Логгер для всех не обработанных сообщений + +from .logs import logger +from ProjectsFiles import BotLogs +from ..analytics.type_msg import types_message + +# Настройка экспорта из модуля +__all__ = ("logger_msg",) + +# Создание функции логирования на обычные сообщения +async def logger_msg(message, log_type : str = "Message"): + user = f"@{message.from_user.username or message.from_user.id}" + if BotLogs.permission: + # Проверка на наличие текста и его типа + if message.text is None: + logger.bind(log_type=log_type, user=user).info(f"Получено сообщение из ({message.chat.id}) : {types_message(message)}") + else: + logger.bind(log_type=log_type, user=user).info(f"Получено сообщение из ({message.chat.id}) : {message.text}") diff --git a/BotLibrary/system/__init__.py b/BotLibrary/system/__init__.py index 3deb7e3..f52d45e 100644 --- a/BotLibrary/system/__init__.py +++ b/BotLibrary/system/__init__.py @@ -4,3 +4,4 @@ # Экспортирование модулей во внешние слои проекта from .bots import * from .bot_edit import * +from .directory import * diff --git a/BotLibrary/system/directory.py b/BotLibrary/system/directory.py new file mode 100644 index 0000000..2836e7a --- /dev/null +++ b/BotLibrary/system/directory.py @@ -0,0 +1,26 @@ +# BotLibrary/system/directory.py +# Создание пустых директорий при первом запуске + +import os +from ProjectsFiles import ProjectPath, TypeDirectory + +# Настройка экспорта из модуля +__all__ = ("create_directories", "setup_directories") + +# Функция создания пустых директорий +async def create_directories(base_directory, subdirectories): + # Создание директорий и файлов в каждой из них + for subdirectory in subdirectories: + directory_path = os.path.join(base_directory, subdirectory) + + # Проверка, существует ли директория, если нет - создаём + if not os.path.exists(directory_path): + os.makedirs(directory_path) + + +# Начальная установка пустых директорий +async def setup_directories(): + await create_directories(ProjectPath.personal_media, TypeDirectory.media_directories) + # await create_directories(ProjectPath.received_media, TypeDirectory.media_directories) + # await create_directories(ProjectPath.bot_files, TypeDirectory.avatar_directories) + # await create_directories(ProjectPath.msg, TypeDirectory.msg_directories) \ No newline at end of file diff --git a/BotLibrary/timer/start_time.py b/BotLibrary/timer/start_time.py index d41be7b..dad11c6 100644 --- a/BotLibrary/timer/start_time.py +++ b/BotLibrary/timer/start_time.py @@ -3,9 +3,14 @@ import pytz from datetime import datetime +from tzlocal import get_localzone from apscheduler.schedulers.asyncio import AsyncIOScheduler from ProjectsFiles import BotVar +# Создание планировщика +scheduler = AsyncIOScheduler(timezone=get_localzone().key) + + # Функция получение времени по Московскому времени def get_moscow_time(): moscow_tz = pytz.timezone('Europe/Moscow') @@ -17,7 +22,3 @@ def get_moscow_time(): def get_host_time(): host_time = datetime.now() return host_time.strftime(BotVar.time_format) - - -# Создание планировщика -scheduler = AsyncIOScheduler(timezone=get_moscow_time()) diff --git a/ProjectsFiles/configs/config.py b/ProjectsFiles/configs/config.py index 9b78296..d756815 100644 --- a/ProjectsFiles/configs/config.py +++ b/ProjectsFiles/configs/config.py @@ -8,7 +8,7 @@ class Permissions: logging = True # Вывод логов в консоль (True) logging_to_file = False # Вывод логов в файл (True) - msg_logging = False # Логирование сообщений (В разработке) + msg_logging = False # Логирование сообщений в консоль (В разработке) start_info_console = True # Вывод информации о боте в начале (True) @@ -48,10 +48,28 @@ class BotVar: prefix = ('$', '!', '.', '%', '&', ':', '|', '+', '-', '/', '~', '?') +# Класс для хранения типов директорий +class TypeDirectory: + # Типы сообщений и список директорий для создания + private_msg = "Личные" + group_msg = "Группы" + + # Названия директорий-хранилищ + avatar = "Avatar" + photo = "Photo" + video = "Video" + videonote = "VideoNote" + gif = "GIF" + files = "Document" + voice = "Voice" + media_directories = [avatar, photo, video, videonote, gif, files, voice] + # Класс создания директорий проекта class ProjectPath: BotLogs = "BotLogs" + personal_media = "ProjectsFiles/media" + # Настройки логирования бота class BotLogs: diff --git a/main.py b/main.py index 435449a..aaf771d 100644 --- a/main.py +++ b/main.py @@ -3,6 +3,8 @@ import asyncio from BotLibrary import * +from BotCode import router as main_router + # Запуск основного кода async def main(): @@ -11,7 +13,11 @@ async def main(): await bot_get_info() logger.bind(log_type="AEP", user="@Console").info(f"Начало запуска бота @{BotInfo.username}...") + # Создание пустых директорий + await setup_directories() + # Подключение главного маршрутизатора + dp.include_router(main_router) # Нужно ли удалить веб-хук if Permissions.delete_webhook: