diff --git a/.gitignore b/.gitignore
index 98e7c69..64038af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,6 @@ BotFiles/
# Игнорирование базы данных пользователя
MySQL/user_data.db
MySQL/user_data.json
+
+# Файл подсчета строк
+project_count_line.py
diff --git a/.idea/PRIMOWORLD.iml b/.idea/PRIMOWORLD.iml
index 66cc0a4..bd5aef4 100644
--- a/.idea/PRIMOWORLD.iml
+++ b/.idea/PRIMOWORLD.iml
@@ -13,6 +13,7 @@
+
diff --git a/BotCode/routers/commands/cmd_class/user_cmd_class.py b/BotCode/routers/commands/cmd_class/user_cmd_class.py
index eecbbd1..70efdd9 100644
--- a/BotCode/routers/commands/cmd_class/user_cmd_class.py
+++ b/BotCode/routers/commands/cmd_class/user_cmd_class.py
@@ -43,7 +43,7 @@ class CommandHandler:
async def handler(self, message: types.Message):
"""Основной хэндлер команды."""
try:
- Logs.info(log_type=self.name.capitalize(), text=f"использовал(а) команду /{self.name}")
+ Logs.info(log_type=self.name.capitalize(), user=username(message), text=f"использовал(а) команду /{self.name}")
await message.reply(
text=self.text_msg,
reply_markup=self.keyboard() if self.keyboard else None,
@@ -51,4 +51,4 @@ class CommandHandler:
# Проверка на ошибку
except Exception as e:
- Logs.error(log_type=self.name.capitalize(), user=message.from_user.username, text=f"Ошибка команды: {e}")
+ Logs.error(log_type=self.name.capitalize(), user=username(message), text=f"Ошибка команды: {e}")
diff --git a/BotLibrary/loggers/custom_loggers.py b/BotLibrary/loggers/custom_loggers.py
index 232a690..7c95b96 100644
--- a/BotLibrary/loggers/custom_loggers.py
+++ b/BotLibrary/loggers/custom_loggers.py
@@ -13,7 +13,7 @@ class Logs:
"""Класс для логирования с разными уровнями через loguru."""
@staticmethod
- def debug(text: str = "Логирование!", log_type: str = "Logs", user: str = "Console", message: Message = None) -> None:
+ def debug(text: str = "Логирование!", log_type: str = "Logs", user: str = "@Console", message: Message = None) -> None:
"""
Логирует сообщение на уровне DEBUG.
@@ -27,7 +27,7 @@ class Logs:
logger.bind(log_type=log_type, user=user).debug(text)
@staticmethod
- def info(text: str = "Логирование!", log_type: str = "Logs", user: str = "Console", message: Message = None) -> None:
+ def info(text: str = "Логирование!", log_type: str = "Logs", user: str = "@Console", message: Message = None) -> None:
"""
Логирует сообщение на уровне INFO.
@@ -41,7 +41,7 @@ class Logs:
logger.bind(log_type=log_type, user=user).info(text)
@staticmethod
- def warning(text: str = "Логирование!", log_type: str = "Logs", user: str = "Console", message: Message = None) -> None:
+ def warning(text: str = "Логирование!", log_type: str = "Logs", user: str = "@Console", message: Message = None) -> None:
"""
Логирует сообщение на уровне WARNING.
@@ -55,7 +55,7 @@ class Logs:
logger.bind(log_type=log_type, user=user).warning(text)
@staticmethod
- def error(text: str = "Логирование!", log_type: str = "Logs", user: str = "Console", message: Message = None) -> None:
+ def error(text: str = "Логирование!", log_type: str = "Logs", user: str = "@Console", message: Message = None) -> None:
"""
Логирует сообщение на уровне ERROR.
diff --git a/Documentation/FIX_LIST.md b/Documentation/FIX_LIST.md
new file mode 100644
index 0000000..0c1b216
--- /dev/null
+++ b/Documentation/FIX_LIST.md
@@ -0,0 +1,51 @@
+## Что нужно исправить:
+
+---
+
+- [X] Сделать НОВОЕ логгирование
+
+ ~~- [ ] Создать новые классы логгеров~~
+ - [X] Переделать везде на новые логгеры
+ - [X] Создать логгеры на ошибки
+
+
+- [ ] Определение типа сообщения
+ - [X] Закреп
+ - [ ] Добавление\Уход участника
+ - [ ] Прочие системные уведомления
+
+
+- [X] Починить скачивание документов и файлов [Возможно-частично!]
+ - [ ] Улучшить качество изображений аватарок чата
+
+
+- [ ] ~~Сделать красивый GUI работы~~
+ [Боту нужнее новое логирование, пока отменить GUI]
+
+
+- [ ] Определение юзернейма по id (Для работы команд администрации)
+
+
+- [ ] Доделать команды администрирования (бан, кик, мут, админ+, админ-)
+
+
+- [ ] Починить батники для работы с обновами (Авто-обновления проекта)
+
+
+- [ ] Исправить остальные проблемы
+ - [X] Прокомментировать каждый файл
+ - [ ] Сделать нормальную инструкцию
+ - [ ] Проверить все файлы и улучшить их
+ - [ ] Иное.
+---
+
+- [ ] Сделать проверку на ошибки в edit_bot? (Там также добавлена команда set_commands)
+
+
+---
+
+07.02.2025
+- [ ] Сделать проверку на личные сообщения
+- [ ] Починить start_time и отображение времени
+- [ ] Модуль день рождение
+- [ ] FSM
\ No newline at end of file
diff --git a/Documentation/README.md b/Documentation/README.md
new file mode 100644
index 0000000..62927ab
--- /dev/null
+++ b/Documentation/README.md
@@ -0,0 +1,74 @@
+## PRIMO_aiogram_bot
+
+---
+## Приветствие
+
+Здравствуй, **дорогой пользователь**!
+Меня зовут *Лейн*, я думаю, мы вряд ли с Вами знакомы,
+но это и неважно.
+
+Этот проект нужен для того, чтобы каждый мог
+создать своего *бота* на основе **Aiogram**.
+Этот **шаблон** позволит Вам получить все возможные функции: от создания *клавиатур*,
+до *логгеров* или *машины состояний*.
+
+---
+## Навигация:
+
+- ### [Приветствие](#Приветствие)
+- ### [Первый запуск бота](#Запуск)
+- ### [Его возможности](#Возможности)
+- ### [Прочее](#Прочее)
+- ### [Задачи:](#Задачи)
+- ### [Прощание](#Прощание)
+
+---
+## Запуск
+
+Так что, давайте поговорим немного о самом проекте.
+Для начала, проект, что Вы получили с **GitHub**, имеет небольшую особенность
+для Windows-пользователей, а именно файл **project.bat**.
+Активировав этот файл через *консоль* с помощью команды:
+**start project**.
+Вы сможете установить локальное окружение, обновить библиотеки и запустить бота. Вам
+не понадобиться думать и настраивать бота. Все, что Вам необходимо - это иметь
+установленным **Python 3.13** и **GIT**. После этого он автоматически:
+
+- создаст локальное окружение
+- установит все необходимые библиотеки
+- создаст локальный **GIT** репозиторий
+- запустит сам **main.py** (*основной файл бота*)
+
+---
+## Возможности
+
+Поэтому, Вы уже получите возможность пользоваться системой **GIT**. Также из плюсов можно
+выделить многое другое, например:
+- Работа с репозиториями и системой GIT
+- Удобное логирование с помощью loguru
+- Проверка на ошибки и удобный вывод их в окно консоли
+- Работа с базами данных (в разработке)
+- И т.д...
+
+
+---
+## Задачи:
+
+- Сделать адекватную базу данных
+- Сделать проверки на ошибки, и не правильный тип данных,
+а главное, чтобы это логгировалось консолью
+- Сделать отдельный логгер под ошибки в файл
+- Скачивание аватарок каналов + доделать для чатов
+- Доделать команды /ban, /kik, /mute
+- И т.д.
+
+---
+## Прощание
+
+Я очень рад, что Вы пользуетесь этим проектом, надеюсь,
+что в дальнейшем буду улучшать его все дальше и дальше.
+Удачи Вам, и ,конечно же...
+
+***Вперед за Истиной, Дорогой Друг!***
+
+- **Verum.**
diff --git a/SQLite3/list_ids.json b/SQLite3/list_ids.json
new file mode 100644
index 0000000..67a513a
--- /dev/null
+++ b/SQLite3/list_ids.json
@@ -0,0 +1,35 @@
+{
+ "ban_list_ids": {
+ "6666666666666": "Забанненый"
+ },
+ "important_adm_ids": {
+ "6751720805": "Лейн",
+ "7051557370": "Рикси",
+ "1570652377": "Риша",
+ "1398573474": "Финаки",
+ "1851081467": "Финик",
+ "929782381": "Хиде",
+ "6714237814": "Слешик",
+ "1686743480": "Полина",
+ "1184519857": "Катаз"
+ },
+ "important_groups_ids": {
+ "1087968824": "GroupAnonymousBot",
+ "-1002442589033": "Любовники Сергея",
+ "-1002124483077": "Труба_Сквад",
+ "-1002123850090": "Тест_Чат",
+ "-1001552311087": "Все_Будет_Хорошо"
+ },
+ "important_users_list_ids": {
+ "7145369362": "Артур",
+ "1219440132": "Данил",
+ "1443833264": "Виктор",
+ "5424384921": "Олег",
+ "556943853": "Ваня",
+ "1295708467": "Степан"
+ },
+ "important_channel_ids": {
+ "10000000000000": "Канал1",
+ "20000000000000": "Канал2"
+ }
+}
diff --git a/Test/GUI/__init__.py b/Test/GUI/__init__.py
new file mode 100644
index 0000000..732d5ec
--- /dev/null
+++ b/Test/GUI/__init__.py
@@ -0,0 +1,4 @@
+# GUI/__init__.py
+# Инициализация пакета GUI, для работы с графическим интерфейсом
+
+from .console import *
diff --git a/Test/GUI/console.py b/Test/GUI/console.py
new file mode 100644
index 0000000..f06444b
--- /dev/null
+++ b/Test/GUI/console.py
@@ -0,0 +1,167 @@
+from tkinter import PhotoImage
+import customtkinter as ctk # модуль для создания стилизованных интерфейсов
+from PIL import Image, ImageTk
+from BotLibrary import * # импорт настроек бота (например, имени, фамилии, и имени пользователя)
+
+# Создание роутера и настройка экспорта
+__all__ = ("App", )
+command_text = "GUI"
+
+
+# Настройка внешнего вида интерфейса
+ctk.set_appearance_mode("System") # Установка режима внешнего вида: "System", "Dark" или "Light"
+ctk.set_default_color_theme("blue") # Установка цветовой темы: "blue", "green", "dark-blue"
+
+
+# Класс приложения, наследующий от customtkinter.CTk
+class App(ctk.CTk):
+ def __init__(self):
+ super().__init__() # Инициализация базового класса
+
+ # Настройка главного окна
+ self.title(f"{BotInfo.first_name} {BotInfo.last_name} - @{BotInfo.username}") # Заголовок окна
+ self.geometry(f"{700}x{580}") # Размер окна (ширина x высота)
+
+ # Настройка сетки (разметка окна на ячейки)
+ self.grid_columnconfigure(0, weight=1) # Установка растяжения для 1-го столбца (боковая панель)
+ self.grid_columnconfigure(1, weight=9) # Установка растяжения для 2-го столбца (содержимое вкладок)
+ self.grid_rowconfigure((0, 1), weight=1) # Установка растяжения для первых трех строк
+
+ # Создание боковой панели
+ self.sidebar_frame = ctk.CTkFrame(self, width=100, corner_radius=0) # Рамка боковой панели с уменьшенной шириной
+ self.sidebar_frame.grid(row=0, column=0, rowspan=4, sticky="nsew") # Расположение в сетке
+ self.sidebar_frame.grid_rowconfigure(4, weight=1) # Установка растяжения для 4-й строки
+
+ # Логотип на боковой панели
+ self.logo_label = ctk.CTkLabel(self.sidebar_frame, text=BotInfo.username,
+ font=ctk.CTkFont(size=16, weight="bold")) # Метка с текстом
+ self.logo_label.grid(row=0, column=0, padx=10, pady=(20, 10)) # Расположение метки в сетке
+
+ # Кнопки на боковой панели
+ self.sidebar_button_1 = ctk.CTkButton(self.sidebar_frame, text="Консоль",
+ command=self.switch_tab_console,
+ font=ctk.CTkFont(size=14))
+ self.sidebar_button_1.grid(row=1, column=0, padx=10, pady=10) # Первая кнопка
+ self.sidebar_button_2 = ctk.CTkButton(self.sidebar_frame, text="База данных",
+ command=self.switch_tab_database,
+ font=ctk.CTkFont(size=14))
+ self.sidebar_button_2.grid(row=2, column=0, padx=10, pady=10) # Вторая кнопка
+ self.sidebar_button_3 = ctk.CTkButton(self.sidebar_frame, text="Иное",
+ command=self.switch_tab_other,
+ font=ctk.CTkFont(size=14))
+ self.sidebar_button_3.grid(row=3, column=0, padx=10, pady=10) # Третья кнопка
+
+ # Новые кнопки "Запуск" и "Выключение"
+ self.start_button = ctk.CTkButton(self.sidebar_frame, text="Запуск", command=self.start_button_click,
+ font=ctk.CTkFont(size=14))
+ self.start_button.grid(row=5, column=0, padx=10, pady=10) # Кнопка "Запуск"
+
+ self.stop_button = ctk.CTkButton(self.sidebar_frame, text="Выключение",
+ command=self.stop_button_click,
+ font=ctk.CTkFont(size=14))
+ self.stop_button.grid(row=6, column=0, padx=10, pady=10) # Кнопка "Выключение"
+
+ # Элементы управления режимами и масштабированием интерфейса
+ self.appearance_mode_label = ctk.CTkLabel(self.sidebar_frame, text="Тема UI", anchor="w",
+ font=ctk.CTkFont(size=12))
+ self.appearance_mode_label.grid(row=7, column=0, padx=10, pady=(10, 0)) # Метка для выбора темы
+ self.appearance_mode_optionemenu = ctk.CTkOptionMenu(
+ self.sidebar_frame, values=["Светлая", "Темная", "Система"], command=self.change_appearance_mode_event
+ ) # Меню выбора темы
+ self.appearance_mode_optionemenu.grid(row=8, column=0, padx=10, pady=(10, 10)) # Расположение меню
+
+ self.scaling_label = ctk.CTkLabel(self.sidebar_frame, text="Масштабирование",
+ anchor="w", font=ctk.CTkFont(size=12)) # Метка для масштабирования
+ self.scaling_label.grid(row=9, column=0, padx=10, pady=(10, 0)) # Расположение метки
+ self.scaling_optionemenu = ctk.CTkOptionMenu(
+ self.sidebar_frame, values=["80%", "90%", "100%", "110%", "120%"], command=self.change_scaling_event
+ ) # Меню выбора масштаба
+ self.scaling_optionemenu.grid(row=10, column=0, padx=10, pady=(10, 20)) # Расположение меню
+
+ # Создание вкладок
+ self.tabview = ctk.CTkTabview(self, width=250) # Виджет вкладок
+ self.tabview.grid(row=0, column=1, rowspan=3, columnspan=2, padx=(20, 0), pady=(20, 0),
+ sticky="nsew") # Растягиваем на все пустое пространство
+ self.tabview.add("Консоль") # Первая вкладка
+ self.tabview.add("База данных") # Вторая вкладка
+ self.tabview.add("Иное") # Третья вкладка
+
+ # Вкладка "Консоль" с текстовым полем
+ self.textbox_tab_1 = ctk.CTkTextbox(self.tabview.tab("Консоль"))
+ self.textbox_tab_1.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
+ self.textbox_tab_1.insert("0.0", "Текст в Textbox на вкладке Консоль\n\n")
+
+ # Вкладка "База данных" с текстовым полем
+ self.textbox_tab_2 = ctk.CTkTextbox(self.tabview.tab("База данных"))
+ self.textbox_tab_2.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
+ self.textbox_tab_2.insert("0.0", "Текст в Textbox на вкладке База данных\n\n")
+
+ # Вкладка "Иное" с текстовым полем
+ self.textbox_tab_3 = ctk.CTkTextbox(self.tabview.tab("Иное"))
+ self.textbox_tab_3.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
+ self.textbox_tab_3.insert("0.0", "Текст в Textbox на вкладке Иное\n\n")
+
+ # Растягиваем строки и столбцы вкладок
+ self.tabview.grid_rowconfigure(0, weight=1) # Растягиваем строку, где находится текстовое поле
+ self.tabview.grid_columnconfigure(0, weight=1) # Растягиваем столбец, где находится текстовое поле
+
+ # Убедитесь, что в каждой из вкладок разрешено растяжение:
+ self.tabview.tab("Консоль").grid_rowconfigure(0, weight=1)
+ self.tabview.tab("База данных").grid_rowconfigure(0, weight=1)
+ self.tabview.tab("Иное").grid_rowconfigure(0, weight=1)
+
+ self.tabview.tab("Консоль").grid_columnconfigure(0, weight=1)
+ self.tabview.tab("База данных").grid_columnconfigure(0, weight=1)
+ self.tabview.tab("Иное").grid_columnconfigure(0, weight=1)
+
+ # Настройка элементов
+ self.appearance_mode_optionemenu.set("Темная") # Режим отображения установлен на "Dark"
+ self.scaling_optionemenu.set("100%") # Масштаб интерфейса установлен на 100%
+
+ self.update() # Принудительное обновление окна после создания
+
+ def change_appearance_mode_event(self, new_appearance_mode: str):
+ # Метод для изменения режима отображения интерфейса
+ if new_appearance_mode == "Светлая":
+ ctk.set_appearance_mode("Light")
+ elif new_appearance_mode == "Темная":
+ ctk.set_appearance_mode("Dark")
+ elif new_appearance_mode == "Система":
+ ctk.set_appearance_mode("System")
+
+ def change_scaling_event(self, new_scaling: str):
+ # Метод для изменения масштаба интерфейса
+ new_scaling_float = int(new_scaling.replace("%", "")) / 100
+ # Преобразование процента масштаба в дробное число
+ ctk.set_widget_scaling(new_scaling_float)
+ # Применение нового масштаба ко всем виджетам
+
+ def switch_tab_console(self):
+ # Переключение на вкладку "Консоль"
+ self.tabview.grid(row=0, column=1, rowspan=3, columnspan=2, padx=(20, 0), pady=(20, 0), sticky="nsew")
+ self.tabview.set("Консоль")
+
+ def switch_tab_database(self):
+ # Переключение на вкладку "База данных"
+ # Для возвращения вкладок
+ self.tabview.grid(row=0, column=1, rowspan=3, columnspan=2, padx=(20, 0), pady=(20, 0), sticky="nsew")
+ self.tabview.set("База данных")
+
+ def switch_tab_other(self):
+ # Переключение на вкладку "Иное"
+ self.tabview.grid(row=0, column=1, rowspan=3, columnspan=2, padx=(20, 0), pady=(20, 0), sticky="nsew")
+ self.tabview.set("Иное")
+
+ def start_button_click(self):
+ # Обработчик для кнопки "Запуск"
+ print("Запуск")
+
+ def stop_button_click(self):
+ # Обработчик для кнопки "Выключение"
+ print("Выключение")
+
+
+# Начало кода и запуск GUI
+if __name__ == "__main__":
+ app = App()
+ app.mainloop()
diff --git a/Test/GUI/console_0.py b/Test/GUI/console_0.py
new file mode 100644
index 0000000..ce73298
--- /dev/null
+++ b/Test/GUI/console_0.py
@@ -0,0 +1,74 @@
+import sys
+import customtkinter as ctk
+import asyncio
+import threading
+
+# Ваши настройки и модули
+from BotLibrary import *
+from BotCode.routers import router as main_router
+from BotCode.routers import set_commands
+
+
+# Класс для перенаправления стандартного вывода в текстовое поле
+class Logger:
+ def __init__(self, text_widget):
+ self.text_widget = text_widget
+
+ def write(self, message):
+ self.text_widget.insert("end", message)
+ self.text_widget.see("end") # Прокрутка к последнему сообщению
+
+ def flush(self):
+ pass
+
+
+# Основная функция для запуска бота
+async def main_bot():
+ just_fix_windows_console() # Подключение ANSI в Windows CMD
+ dp.include_router(main_router) # Подключение главного роутера
+
+ await set_all() # Установка настроек бота
+ await set_commands() # Установка команд бота
+ await bot_get_info() # Получение информации о боте
+
+ # Логирование в консоль и текстовое поле
+ logger.add(sys.stderr, colorize=True, format=logs_text, level="INFO")
+ logger.info(f"Начало запуска бота @{BotInfo.username}...")
+
+ bot_info_out() # Включение опроса бота
+ await dp.start_polling(bot) # Запуск бота
+
+
+# Класс графического интерфейса
+class BotConsoleWindow(ctk.CTk):
+ def __init__(self):
+ super().__init__()
+
+ # Настройка окна
+ self.title("Bot Console")
+ self.geometry("800x600")
+
+ # Создание текстового поля для логов
+ self.log_text = ctk.CTkTextbox(self, wrap="word", width=780, height=500)
+ self.log_text.pack(padx=10, pady=10)
+
+ # Перенаправление вывода в текстовое поле
+ sys.stdout = Logger(self.log_text)
+ sys.stderr = Logger(self.log_text)
+
+ # Кнопка запуска бота
+ self.start_button = ctk.CTkButton(self, text="Запустить бота", command=self.start_bot)
+ self.start_button.pack(pady=10)
+
+ def start_bot(self):
+ self.start_button.configure(state="disabled") # Отключить кнопку
+ threading.Thread(target=self.run_bot, daemon=True).start()
+
+ def run_bot(self):
+ asyncio.run(main_bot())
+ self.start_button.configure(state="normal") # Включить кнопку после завершения
+
+
+if __name__ == "__main__":
+ app = BotConsoleWindow()
+ app.mainloop()
diff --git a/Test/__init__.py b/Test/__init__.py
new file mode 100644
index 0000000..b37c6a3
--- /dev/null
+++ b/Test/__init__.py
@@ -0,0 +1,12 @@
+# Test/__init__.py
+# Инициализация пакета Test, для работы с тестированием (в разработке)
+
+# Импортируем библиотеки для экспорта
+from aiogram import Router
+from .commands import *
+from .GUI import *
+from .old_files import *
+
+
+# Создание роутера "test_router"
+router = Router(name="test_router")
diff --git a/Documentation/ReadMe.md b/Test/commands/__init__.py
similarity index 100%
rename from Documentation/ReadMe.md
rename to Test/commands/__init__.py
diff --git a/Test/commands/ban_cmd.py b/Test/commands/ban_cmd.py
new file mode 100644
index 0000000..c022f72
--- /dev/null
+++ b/Test/commands/ban_cmd.py
@@ -0,0 +1,63 @@
+# BotCode/routers/commands/admin_cmd/ban_cmd.py
+# Работа с админ-командой /ban, для блокировки пользователей (в разработке)
+# Проверка на наличие блокировки пользователя в боте
+
+
+from aiogram import Router, types
+from aiogram.filters import Command
+from BotLibrary import *
+
+# Создание роутера и настройка экспорта
+__all__ = ("router", "banned_user", "ban_user_by_username",)
+router = Router(name="ban_router")
+command_text = "BAN"
+
+
+# Функция проверки блокировки пользователя в боте
+@router.message(lambda message: message.from_user.id in ListId.ban_list_id)
+async def banned_user(message: types_msg.Message):
+ try:
+ # Вывод сообщения пользователю
+ chat_id = await find_chat_id(message)
+ text = (f"{TextDecorator.RED}Получено сообщение от забанненго пользователя"
+ f" из ({chat_id}) : {message.text}{TextDecorator.RESET_DECORATOR}")
+ await message.answer(f"Вы были забаннены в боте @{BotInfo.username}!")
+
+ # Активация логгера
+ await cmd_logginger(message, command_text, text)
+
+ return text
+
+ # Проверка на ошибку и ее логирование
+ except Exception as e:
+ text_error = await error_cmd_logginger(message, command_text, e)
+ return text_error
+
+
+# Обработчик команды /ban
+@router.message(Command("ban", "ифт", "бан", ",fy", prefix=BotEdit.prefixs, ignore_case=True))
+async def ban_user_by_username(message: types_msg.Message):
+ try:
+ text = f"использовал(а) команду /{command_text.lower()}"
+
+ # Получаем аргументы команды
+ args = message.get_args() # Вернет все, что идет после /ban
+
+ # Проверка на наличие аргумента
+ if not args:
+ text = f"Пожалуйста, укажите ID или имя пользователя для бана. Пример: /ban 123456"
+ await message.reply(text)
+ return text
+
+ # Вывод сообщения пользователю
+ await message.reply(text=f"Вы попытались забанить, обидно да?")
+
+ # Активация логгера
+ await cmd_logginger(message, command_text, text)
+
+ return text
+
+ # Проверка на ошибку и ее логирование
+ except Exception as e:
+ text_error = await error_cmd_logginger(message, command_text, e)
+ return text_error
diff --git a/Test/commands/download_channel_avatar.py b/Test/commands/download_channel_avatar.py
new file mode 100644
index 0000000..d64d9ab
--- /dev/null
+++ b/Test/commands/download_channel_avatar.py
@@ -0,0 +1,63 @@
+# BotCode/routers/downloads/download_channel_avatar.py
+# Закачка аватарок канала (в разработке + сделать логирование!!!)
+
+import requests
+from aiogram import Router
+from aiogram.types import Message
+from BotLibrary import *
+
+# Создание роутера и настройка экспорта
+__all__ = ("router", "download_channel_avatar",)
+router = Router(name="avatar_channel_router")
+type_messages = "AvatarChannel"
+
+
+# Функция для скачивания аватарки канала
+@router.message(lambda message: message.chat.type == 'channel')
+async def download_channel_avatar(message: Message):
+ try:
+ # Логирование для получения сообщения из канала
+ logger.bind(custom_variable=type_messages, user_var=f"{message.chat.id}").info(f"Получено сообщение из канала ID {message.chat.id}: {message.text}")
+
+ # Получаем информацию о чате канала
+ chat_info = await bot.get_chat(message.chat.id) # message.chat.id для получения ID канала
+
+ # Логирование полученной информации
+ logger.bind(custom_variable=type_messages, user_var=f"{chat_info.id}").info(f"Информация о канале: {chat_info.title}")
+
+ # Проверка наличия аватара
+ if not chat_info.photo:
+ text_error = f"Канал с ID {message.chat.id} не имеет аватара."
+ logger.error(text_error)
+ return text_error
+
+ # Получаем file_id для фото (используем big_file_id для лучшего качества)
+ file_info = await bot.get_file(chat_info.photo.big_file_id)
+
+ # Строим URL для скачивания файла
+ file_url = f"https://api.telegram.org/file/bot{bot.token}/{file_info.file_path}"
+
+ # Формируем имя и путь для сохранения фото
+ save_dir = f"{ImportantPath.channel_avatar}/{message.chat.id}"
+ os.makedirs(save_dir, exist_ok=True)
+ file_name = file_info.file_path.split("/")[-1] # Имя файла (например, "abc.jpg")
+ save_path = os.path.join(save_dir, file_name)
+
+ # Скачиваем аватар
+ response = requests.get(file_url)
+ if response.status_code == 200:
+ with open(save_path, "wb") as file:
+ file.write(response.content)
+ text = f"Фото аватара канала с ID {message.chat.id} успешно скачано и сохранено как {save_path}"
+ logger.info(text)
+ return text
+
+ else:
+ text_error = f"Не удалось скачать аватар канала с ID {message.chat.id}. Статус: {response.status_code}"
+ logger.bind(custom_variable=type_messages, user_var=f"{message.chat.id}").error(text_error)
+ return text_error
+
+ except Exception as e:
+ text_error = f"Ошибка при скачивании фото аватара канала с ID {message.chat.id}: {e}"
+ logger.bind(custom_variable=type_messages, user_var=f"{message.chat.id}").error(text_error)
+ return text_error
diff --git a/Test/commands/find_username.py b/Test/commands/find_username.py
new file mode 100644
index 0000000..7733ca5
--- /dev/null
+++ b/Test/commands/find_username.py
@@ -0,0 +1,25 @@
+# BotLibrary/analitics/find_username.py
+# Нахождение юзернейма пользователя по id (в разработке)
+
+from loguru import logger
+from BotLibrary.library.bots import bot
+
+# Настройка экспорта
+__all__ = ("get_user_id_by_username",)
+type_messages = "ID_USERNAME"
+
+
+# Получение ID пользователя по юзернейму (в разработке)
+async def get_user_id_by_username(chat_id, username):
+ try:
+ user = await bot.get_chat_member_by_username(chat_id, username)
+ if user:
+ return user.user.id
+ else:
+ return None
+
+ # Проверка на ошибку и ее логирование (в разработке)
+ except Exception as e:
+ text_error = f"Ошибка при получении ID пользователя: {e}"
+ logger.bind(custom_variable="IDS", user_var=type_messages).error(text_error)
+ return text_error
diff --git a/Test/commands/send_to_user.py b/Test/commands/send_to_user.py
new file mode 100644
index 0000000..9eb0b2f
--- /dev/null
+++ b/Test/commands/send_to_user.py
@@ -0,0 +1,65 @@
+# BotCode/routers/commands/admin_cmd/send_to_user.py
+# Работа с админ-командой /send, для отправки конкретного сообщения пользователю (в разработке)
+
+from aiogram import Router, types, F
+from aiogram.filters import Command
+from BotLibrary import *
+
+# Создание роутера и настройка экспорта
+__all__ = ("router", "send_message",)
+router = Router(name="send_router")
+command_text = "Send"
+
+
+# Обработчик команды /send для отправки сообщения определенному пользователю (в разработке)
+@router.message(F.from_user.id.in_(ListId.important),
+ Command("send", "отправить", "отправ", "s", "ыутв", "jnghfdbnm", "jnghfd",
+ prefix=BotEdit.prefixs, ignore_case=True))
+async def send_message(message: types_msg.Message):
+ try:
+ if message.chat.id in ListId.adm_list_id:
+ text = f"использовал(а) команду /{command_text.lower()}"
+
+ # Разбиваем сообщение на аргументы
+ args = message.text.split()
+
+ # Проверка на правильность команды /send
+ if len(args) < 3:
+ texts = "Некорректный формат команды. Используйте: /send <текст>"
+ await message.reply(texts)
+ return texts
+
+ # Получаем user_id и текст сообщения
+ user_id = int(args[1])
+ text_send = ' '.join(args[2:])
+
+ # Отправляем сообщение пользователю
+ await bot.send_message(chat_id=user_id, text=text_send)
+
+ # Логирование
+ user_id = find_imp_id(user_id)
+ await cmd_logginger(message, command_text, text)
+
+ # Логирование и отчет об отправке
+ await message.reply(f"Сообщение успешно отправлено пользователю с ID {user_id}")
+ return text
+
+ # Проверка на ошибку и ее логирование
+ except Exception as e:
+ text_error = await error_cmd_logginger(message, command_text, e)
+ return text_error
+
+ # Проверка заблокирован ли бот для пользователя
+ # except exceptions.BotBlocked:
+ # await message.answer("Пользователь заблокировал бота")
+ # except aiogram.utils.exceptions.ChatNotFound:
+ # await message.answer("Чат с пользователем не найден")
+ # except exceptions.RetryAfter as e:
+ # await asyncio.sleep(e.timeout)
+ # return await send_message(message)
+ # except exceptions.UserDeactivated:
+ # await message.answer("Пользователь деактивирован")
+ # except exceptions.TelegramAPIError:
+ # await message.answer("Произошла ошибка при отправке сообщения")
+ # except:
+ # return
diff --git a/Test/old_files/__init__.py b/Test/old_files/__init__.py
new file mode 100644
index 0000000..492dcdc
--- /dev/null
+++ b/Test/old_files/__init__.py
@@ -0,0 +1,22 @@
+# BotCode/routers/old_files/__init__.py
+# Инициализация старого пакета old_files, для хранения старых функций
+
+from aiogram import Router
+from .media_func import router as media_old_router
+from .regular_handlers import router as regular_router
+
+
+# Объявление роутера и настройка экспорта
+__all__ = ("router",)
+router = Router(name="old_files_router")
+
+
+# Список подключаемых роутеров сверху-вниз
+router.include_routers(
+ regular_router,
+ media_old_router,
+)
+
+
+# Список подключаемых роутеров сверху-вниз
+router.include_routers()
diff --git a/Test/old_files/media_func.py b/Test/old_files/media_func.py
new file mode 100644
index 0000000..ac76469
--- /dev/null
+++ b/Test/old_files/media_func.py
@@ -0,0 +1,55 @@
+# BotCode/routers/old_files/media_func.py
+# Некоторые функции для работы с медиа-сообщениями
+
+from re import Match
+from aiogram import Router, F, types
+from magic_filter import RegexpMode
+from BotLibrary import *
+
+# Настройка экспорта модулей и роутера
+__all__ = ("router",)
+router = Router(name="media_func")
+
+
+# @router.message(F.photo, ~F.caption)
+async def handle_photo_wo_caption(message: types_msg.Message):
+ caption = f"Простите, я не могу это увидеть. Вы можете описать что это?"
+ await message.reply_photo(
+ photo=message.photo[-1].file_id,
+ caption=caption,
+ )
+ return caption
+
+
+# @router.message(F.photo, F.caption.contains("please"))
+async def handle_photo_with_please_caption(message: types_msg.Message):
+ text = f"Простите, я не могу это увидеть."
+ await message.reply(text)
+ return text
+
+
+# @router.message(any_media_filter, ~F.caption)
+async def handle_any_media_wo_caption(message: types_msg.Message):
+ if message.document:
+ await message.reply_document(
+ document=message.document.file_id,
+ )
+ return f"Перессылка документа"
+
+ elif message.video:
+ await message.reply_video(
+ video=message.video.file_id,
+ )
+ return f"Перессылка видео"
+
+ else:
+ text = f"Я не могу это увидеть."
+ await message.reply(text)
+ return text
+
+
+# @router.message(any_media_filter, F.caption)
+async def handle_any_media_w_caption(message: types_msg.Message):
+ text = f"Что-то на медиа. Твой текст: {message.caption!r}"
+ await message.reply(text)
+ return text
diff --git a/Test/old_files/regular_handlers.py b/Test/old_files/regular_handlers.py
new file mode 100644
index 0000000..f51394e
--- /dev/null
+++ b/Test/old_files/regular_handlers.py
@@ -0,0 +1,29 @@
+# BotCode/routers/old_files/regular_handlers.py
+# Регулярная функция, выдает тебе сообщение на код при сообщении с числами
+
+from aiogram import F, types, Router
+from magic_filter import RegexpMode
+from re import Match
+
+from BotLibrary import logginger
+import configs
+
+# Настройка экспорта модулей и роутера
+__all__ = ("router",)
+router = Router(name="regular_handlers")
+
+
+# Хэндлер на циферный код (регулярная функция)
+@router.message(
+ F.from_user.id.in_(configs.ListId.adm_list_id),
+ F.text.regexp(r"(\d+)", mode=RegexpMode.MATCH).as_("code"),
+)
+async def handle_code(message: types.Message, code: Match[str]):
+ # Вывод сообщения
+ text = f"Ваш код: {code.group()}"
+ await message.reply(text)
+
+ # Включение логирования в файл
+ await logginger(message)
+
+ return text