diff --git a/main.py b/main.py index 667c01a..0047cbc 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,7 @@ from aiogram import Bot, Dispatcher from tgbot.data.config import BOT_TOKEN, scheduler, get_admins from tgbot.middlewares import register_all_middlwares from tgbot.routers import register_all_routers -from tgbot.services.api_session import RequestsSession +from tgbot.services.api_session import AsyncSession from tgbot.services.api_sqlite import create_dbx from tgbot.utils.misc.bot_commands import set_commands from tgbot.utils.misc.bot_logging import bot_logger @@ -20,15 +20,15 @@ colorama.init() # Запуск шедулеров async def scheduler_start(bot): - scheduler.add_job(autobackup, "cron", hour=00, args=(bot,)) # Автобэкап в 12:00 - scheduler.add_job(autobackup, "cron", hour=12, args=(bot,)) # Автобэкап в 00:00 + scheduler.add_job(autobackup, "cron", hour=00, args=(bot,)) # Ежедневный Автобэкап в 00:00 + scheduler.add_job(autobackup, "cron", hour=12, args=(bot,)) # Ежедневный Автобэкап в 12:00 # Запуск бота и функций async def main(): scheduler.start() # Запуск Шедулера - dp = Dispatcher() # Создание Диспетчера - rSession = RequestsSession() # Асинхронные Запросы + dp = Dispatcher() # Образ Диспетчера + aSession = AsyncSession() # Пул асинхронной сессии запросов bot = Bot(token=BOT_TOKEN, parse_mode="HTML") # Образ Бота register_all_middlwares(dp) # Регистрация всех мидлварей @@ -48,9 +48,9 @@ async def main(): await bot.delete_webhook() await bot.get_updates(offset=-1) - await dp.start_polling(bot, allowed_updates=dp.resolve_used_update_types(), rSession=rSession) + await dp.start_polling(bot, allowed_updates=dp.resolve_used_update_types(), aSession=aSession) finally: - await rSession.close() + await aSession.close() await bot.session.close() diff --git a/tgbot/data/config.py b/tgbot/data/config.py index 870600e..117b39e 100644 --- a/tgbot/data/config.py +++ b/tgbot/data/config.py @@ -3,15 +3,19 @@ import configparser from apscheduler.schedulers.asyncio import AsyncIOScheduler -scheduler = AsyncIOScheduler() +# Токен бота +BOT_TOKEN = configparser.ConfigParser() +BOT_TOKEN.read("settings.ini") +BOT_TOKEN = BOT_TOKEN['settings']['token'].strip().replace(' ', '') -read_config = configparser.ConfigParser() -read_config.read("settings.ini") - -BOT_TOKEN = read_config['settings']['token'].strip().replace(' ', '') # Токен бота +# Пути к файлам PATH_DATABASE = "tgbot/data/database.db" # Путь к БД PATH_LOGS = "tgbot/data/logs.log" # Путь к Логам +# Образы и конфиги +scheduler = AsyncIOScheduler() # Образ шедулера +start_status = True # Оповещение админам при запуске бота (True или False) + # Получение администраторов бота def get_admins(): diff --git a/tgbot/middlewares/__init__.py b/tgbot/middlewares/__init__.py index b1561ea..636f5ae 100644 --- a/tgbot/middlewares/__init__.py +++ b/tgbot/middlewares/__init__.py @@ -5,6 +5,7 @@ from tgbot.middlewares.exists_user import ExistsUserMiddleware from tgbot.middlewares.throttling import ThrottlingMiddleware +# Регистрация всех миддлварей def register_all_middlwares(dp: Dispatcher): dp.callback_query.outer_middleware(ExistsUserMiddleware()) dp.message.outer_middleware(ExistsUserMiddleware()) diff --git a/tgbot/middlewares/exists_user.py b/tgbot/middlewares/exists_user.py index 7d55a17..27d7abd 100644 --- a/tgbot/middlewares/exists_user.py +++ b/tgbot/middlewares/exists_user.py @@ -16,15 +16,15 @@ class ExistsUserMiddleware(BaseMiddleware): user_id = this_user.id user_login = this_user.username user_name = clear_html(this_user.first_name) - user_fullname = clear_html(this_user.first_name) user_surname = clear_html(this_user.last_name) + user_fullname = clear_html(this_user.first_name) user_language = this_user.language_code - if user_language != "ru": user_language = "en" if user_login is None: user_login = "" if user_name is None: user_name = "" - if user_fullname is None: user_fullname = "" if user_surname is None: user_surname = "" + if user_fullname is None: user_fullname = "" + if user_language != "ru": user_language = "en" if len(user_surname) >= 1: user_fullname += f" {user_surname}" diff --git a/tgbot/routers/__init__.py b/tgbot/routers/__init__.py index b89c403..eb67939 100644 --- a/tgbot/routers/__init__.py +++ b/tgbot/routers/__init__.py @@ -7,7 +7,7 @@ from tgbot.routers.user import user_menu from tgbot.utils.misc.bot_filters import IsAdmin -# Регистрация роутеров +# Регистрация всех роутеров def register_all_routers(dp: Dispatcher): # Подключение фильтров main_errors.router.message.filter(F.chat.type == "private") @@ -18,7 +18,7 @@ def register_all_routers(dp: Dispatcher): admin_menu.router.message.filter(F.chat.type == "private", IsAdmin()) - # Инициализация обязательных роутеров + # Подключение обязательных роутеров dp.include_router(main_errors.router) dp.include_router(main_start.router) @@ -26,5 +26,5 @@ def register_all_routers(dp: Dispatcher): dp.include_router(user_menu.router) # Юзер хендлер dp.include_router(admin_menu.router) # Админ хендлер - # Инициализация обязательных роутеров + # Подключение обязательных роутеров dp.include_router(main_missed.router) diff --git a/tgbot/routers/admin/admin_menu.py b/tgbot/routers/admin/admin_menu.py index 011716f..2a3636a 100644 --- a/tgbot/routers/admin/admin_menu.py +++ b/tgbot/routers/admin/admin_menu.py @@ -2,19 +2,18 @@ from aiogram import Router, Bot from aiogram.types import FSInputFile, Message -from tgbot.data.config import PATH_DATABASE, PATH_LOGS from tgbot.data.config import PATH_DATABASE, PATH_LOGS from tgbot.keyboards.inline_misc import admin_inl from tgbot.keyboards.reply_misc import admin_rep from tgbot.utils.const_functions import get_date -from tgbot.utils.misc.bot_models import FSM, RS +from tgbot.utils.misc.bot_models import FSM, AS router = Router() # Кнопка - Admin Inline @router.message(text="Admin Inline") -async def admin_button_inline(message: Message, bot: Bot, state: FSM, rSession: RS, my_user): +async def admin_button_inline(message: Message, bot: Bot, state: FSM, aSession: AS, my_user): await state.clear() await message.answer("Click Button - Admin Inline", reply_markup=admin_inl) @@ -22,7 +21,7 @@ async def admin_button_inline(message: Message, bot: Bot, state: FSM, rSession: # Кнопка - Admin Reply @router.message(text="Admin Reply") -async def admin_button_reply(message: Message, bot: Bot, state: FSM, rSession: RS, my_user): +async def admin_button_reply(message: Message, bot: Bot, state: FSM, aSession: AS, my_user): await state.clear() await message.answer("Click Button - Admin Reply", reply_markup=admin_rep) @@ -30,7 +29,7 @@ async def admin_button_reply(message: Message, bot: Bot, state: FSM, rSession: R # Получение Базы Данных @router.message(commands=['db', 'database']) -async def admin_database(message: Message, bot: Bot, state: FSM, rSession: RS, my_user): +async def admin_database(message: Message, bot: Bot, state: FSM, aSession: AS, my_user): await state.clear() await message.answer_document(FSInputFile(PATH_DATABASE), @@ -40,7 +39,19 @@ async def admin_database(message: Message, bot: Bot, state: FSM, rSession: RS, m # Получение логов @router.message(commands=['log', 'logs']) -async def admin_log(message: Message, bot: Bot, state: FSM, rSession: RS, my_user): +async def admin_log(message: Message, bot: Bot, state: FSM, aSession: AS, my_user): await state.clear() await message.answer_document(FSInputFile(PATH_LOGS), caption=f"🕰 {get_date()}") + + +# Очистить логи +@router.message(text_contains=['log', '_', 'clean']) +@router.message(text_contains=['log', '_', 'clear']) +async def admin_log_clear(message: Message, bot: Bot, state: FSM, aSession: AS, my_user): + await state.clear() + + with open(PATH_LOGS, "w") as file: + file.write(f"{get_date()} | LOGS WAS CLEAR") + + await message.answer("🖨 Логи были успешно очищены") diff --git a/tgbot/routers/main_errors.py b/tgbot/routers/main_errors.py index b8ca250..593c9e1 100644 --- a/tgbot/routers/main_errors.py +++ b/tgbot/routers/main_errors.py @@ -13,9 +13,12 @@ router = Router() @router.errors() async def processing_errors(update: Update, exception: TelegramAPIError, bot: Bot): print(f"-Exception | {exception}") - await send_admins(bot, f"❌ Ошибка\n\n" - f"Exception: {exception}\n\n" - f"Update: {update.dict()}") + await send_admins( + bot, + f"❌ Ошибка\n\n" + f"Exception: {exception}\n\n" + f"Update: {update.dict()}" + ) bot_logger.exception( f"Exception: {exception}\n" diff --git a/tgbot/routers/main_missed.py b/tgbot/routers/main_missed.py index 84f15e6..52516c2 100644 --- a/tgbot/routers/main_missed.py +++ b/tgbot/routers/main_missed.py @@ -10,7 +10,7 @@ router = Router() # Колбэк с удалением сообщения @router.callback_query(text="close_this") -async def processing_callback_remove(call: CallbackQuery, state: FSM): +async def processing_callback_close(call: CallbackQuery, state: FSM): await call.message.delete() diff --git a/tgbot/routers/main_start.py b/tgbot/routers/main_start.py index b917844..431d221 100644 --- a/tgbot/routers/main_start.py +++ b/tgbot/routers/main_start.py @@ -3,14 +3,14 @@ from aiogram import Router, Bot from aiogram.types import Message from tgbot.keyboards.reply_main import menu_frep -from tgbot.utils.misc.bot_models import FSM, RS +from tgbot.utils.misc.bot_models import FSM, AS router = Router() # Открытие главного меню @router.message(text_startswith=["⬅ Главное меню", "/start"]) -async def main_start(message: Message, bot: Bot, state: FSM, rSession: RS, my_user): +async def main_start(message: Message, bot: Bot, state: FSM, aSession: AS, my_user): await state.clear() await message.answer("🔸 Бот готов к использованию.\n" diff --git a/tgbot/routers/user/user_menu.py b/tgbot/routers/user/user_menu.py index fd066f5..68c0473 100644 --- a/tgbot/routers/user/user_menu.py +++ b/tgbot/routers/user/user_menu.py @@ -5,14 +5,14 @@ from aiogram.types import Message from tgbot.keyboards.inline_main import menu_finl from tgbot.keyboards.inline_misc import user_inl from tgbot.keyboards.reply_misc import user_rep -from tgbot.utils.misc.bot_models import FSM, RS +from tgbot.utils.misc.bot_models import FSM, AS router = Router() # Кнопка - User Inline @router.message(text="User Inline") -async def user_button_inline(message: Message, bot: Bot, state: FSM, rSession: RS, my_user): +async def user_button_inline(message: Message, bot: Bot, state: FSM, aSession: AS, my_user): await state.clear() await message.answer("Click Button - User Inline", reply_markup=user_inl) @@ -20,7 +20,7 @@ async def user_button_inline(message: Message, bot: Bot, state: FSM, rSession: R # Кнопка - User Reply @router.message(text="User Reply") -async def user_button_reply(message: Message, bot: Bot, state: FSM, rSession: RS, my_user): +async def user_button_reply(message: Message, bot: Bot, state: FSM, aSession: AS, my_user): await state.clear() await message.answer("Click Button - User Reply", reply_markup=user_rep) @@ -28,7 +28,7 @@ async def user_button_reply(message: Message, bot: Bot, state: FSM, rSession: RS # Команда - /inline @router.message(commands="inline") -async def user_command_inline(message: Message, bot: Bot, state: FSM, rSession: RS, my_user): +async def user_command_inline(message: Message, bot: Bot, state: FSM, aSession: AS, my_user): await state.clear() await message.answer("Click command - /inline", reply_markup=menu_finl(message.from_user.id)) diff --git a/tgbot/services/api_session.py b/tgbot/services/api_session.py index b58fd0b..0218d8c 100644 --- a/tgbot/services/api_session.py +++ b/tgbot/services/api_session.py @@ -5,7 +5,7 @@ import aiohttp # Асинхронная сессия для запросов -class RequestsSession: +class AsyncSession: def __init__(self) -> None: self._session: Optional[aiohttp.ClientSession] = None diff --git a/tgbot/services/api_sqlite.py b/tgbot/services/api_sqlite.py index 1ca9993..c72aaf1 100644 --- a/tgbot/services/api_sqlite.py +++ b/tgbot/services/api_sqlite.py @@ -51,7 +51,6 @@ def add_userx(user_id, user_login, user_name, user_surname, user_fullname): "(user_id, user_login, user_name, user_surname, user_fullname, user_date, user_unix) " "VALUES (?, ?, ?, ?, ?, ?, ?)", [user_id, user_login, user_name, user_surname, user_fullname, get_date(), get_unix()]) - con.commit() # Получение пользователя @@ -88,7 +87,6 @@ def update_userx(user_id, **kwargs): sql, parameters = update_format_with_args(sql, kwargs) parameters.append(user_id) con.execute(sql + "WHERE user_id = ?", parameters) - con.commit() # Удаление пользователя @@ -98,7 +96,6 @@ def delete_userx(**kwargs): sql = "DELETE FROM storage_users" sql, parameters = update_format_args(sql, kwargs) con.execute(sql, parameters) - con.commit() ######################################## СОЗДАНИЕ БАЗЫ ДАННЫХ ###################################### @@ -121,5 +118,3 @@ def create_dbx(): "user_date TIMESTAMP," "user_unix INTEGER)") print("DB was not found(1/1) | Creating...") - - con.commit() diff --git a/tgbot/utils/const_functions.py b/tgbot/utils/const_functions.py index 0bbde7f..f2676eb 100644 --- a/tgbot/utils/const_functions.py +++ b/tgbot/utils/const_functions.py @@ -70,6 +70,23 @@ async def smart_send(bot: Bot, message: types.Message, user_id, text_add=None, r ######################################## ПРОЧЕЕ ######################################## +# Удаление отступов у текста +def ded(get_text: str): + if get_text is not None: + split_text = get_text.split("\n") + if split_text[0] == "": split_text.pop(0) + if split_text[-1] == "": split_text.pop(-1) + save_text = [] + + for text in split_text: + while text.startswith(" "): + text = text[1:] + + save_text.append(text) + get_text = "\n".join(save_text) + + return get_text + # Очистка HTML тэгов def clear_html(get_text: str): if get_text is not None: diff --git a/tgbot/utils/misc/bot_filters.py b/tgbot/utils/misc/bot_filters.py index 271c37e..2d64ca7 100644 --- a/tgbot/utils/misc/bot_filters.py +++ b/tgbot/utils/misc/bot_filters.py @@ -1,5 +1,5 @@ # - *- coding: utf- 8 - *- -from aiogram.dispatcher.filters import BaseFilter +from aiogram.filters import BaseFilter from aiogram.types import Message from tgbot.data.config import get_admins diff --git a/tgbot/utils/misc/bot_models.py b/tgbot/utils/misc/bot_models.py index 235705d..624da26 100644 --- a/tgbot/utils/misc/bot_models.py +++ b/tgbot/utils/misc/bot_models.py @@ -1,10 +1,7 @@ # - *- coding: utf- 8 - *- -from textwrap import dedent +from aiogram.fsm.context import FSMContext -from aiogram.dispatcher.fsm.context import FSMContext +from tgbot.services.api_session import AsyncSession -from tgbot.services.api_session import RequestsSession - -ded = dedent FSM = FSMContext -RS = RequestsSession +AS = AsyncSession diff --git a/tgbot/utils/misc_functions.py b/tgbot/utils/misc_functions.py index 3eef745..06f1d28 100644 --- a/tgbot/utils/misc_functions.py +++ b/tgbot/utils/misc_functions.py @@ -2,13 +2,13 @@ from aiogram import Bot from aiogram.types import FSInputFile -from tgbot.data.config import get_admins, PATH_DATABASE +from tgbot.data.config import get_admins, PATH_DATABASE, start_status from tgbot.utils.const_functions import get_date, send_admins # Выполнение функции после запуска бота (рассылка админам о запуске бота) async def startup_notify(bot: Bot): - if len(get_admins()) >= 1: + if len(get_admins()) >= 1 and start_status: await send_admins(bot, "✅ Бот был запущен")