From a44e31066097f51ed56ddf784c3855fca8f02341 Mon Sep 17 00:00:00 2001 From: Verum Date: Thu, 5 Mar 2026 19:08:22 +0700 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D1=81=D1=82=D0=B5=D0=BD?= =?UTF-8?q?=D1=8C=D0=BA=D0=B8=D0=B9=20=D0=B1=D0=BE=D1=82=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=B2=D1=8B=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D1=81=D1=82=D0=B0=D1=82=D1=83=D1=81=D0=B0=20=D1=81=D0=B5?= =?UTF-8?q?=D1=80=D0=B2=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..51925de --- /dev/null +++ b/main.py @@ -0,0 +1,157 @@ +""" +Telegram-бот для отображения состояния системы. + +Функциональность: +- команда /start отправляет информацию о сервере +- отображаются CPU, RAM, диск, uptime и load average +- токен загружается из переменной окружения BOT_TOKEN или .env + +Зависимости: + pip install aiogram psutil python-dotenv +""" + +from __future__ import annotations + +import asyncio +import os +from datetime import datetime +from platform import uname, system +from typing import Final + +import psutil +from aiogram import Bot, Dispatcher +from aiogram.client.default import DefaultBotProperties +from aiogram.filters import CommandStart +from aiogram.types import Message +from dotenv import load_dotenv + + +# --------------------------------------------------------------------- +# Загрузка переменных окружения +# --------------------------------------------------------------------- + +load_dotenv() + +BOT_TOKEN: Final[str | None] = os.getenv("BOT_TOKEN") + +if BOT_TOKEN is None: + raise RuntimeError( + "Переменная окружения BOT_TOKEN не найдена.\n" + "Создайте файл .env и добавьте:\n" + "BOT_TOKEN=your_telegram_token" + ) + + +# --------------------------------------------------------------------- +# Инициализация Telegram-бота +# --------------------------------------------------------------------- + +bot: Bot = Bot( + token=BOT_TOKEN, + default=DefaultBotProperties(parse_mode="HTML"), +) + +dp: Dispatcher = Dispatcher() + + +# --------------------------------------------------------------------- +# Системная информация +# --------------------------------------------------------------------- + +def get_system_info() -> str: + """ + Собирает информацию о состоянии системы. + + Возвращает: + str: форматированная строка с информацией о системе + """ + + # Информация о системе + system_info = uname() + + # Время загрузки системы + boot_time_timestamp: float = psutil.boot_time() + boot_time: str = datetime.fromtimestamp( + boot_time_timestamp + ).strftime("%Y-%m-%d %H:%M:%S") + + # Память + memory = psutil.virtual_memory() + + # CPU + cpu_percent: float = psutil.cpu_percent(interval=1) + physical_cores: int | None = psutil.cpu_count(logical=False) + logical_cores: int | None = psutil.cpu_count(logical=True) + + # Определяем корневой диск + root_path: str = "C:\\" if system() == "Windows" else "/" + disk = psutil.disk_usage(root_path) + + # Load average (только UNIX) + load_str: str = "" + if hasattr(os, "getloadavg"): + load_avg = os.getloadavg() + load_str = ( + f"└ Load average: " + f"{load_avg[0]:.2f}, {load_avg[1]:.2f}, {load_avg[2]:.2f}\n" + ) + + # Формирование сообщения + info: str = f""" +🖥️ Состояние сервера + +OS: {system_info.system} {system_info.release} +Uptime: {boot_time} + +CPU: +├ Ядер: {physical_cores} (логических: {logical_cores}) +├ Загрузка: {cpu_percent}% +{load_str}RAM: +├ Всего: {memory.total / 1024 ** 3:.2f} GB +├ Используется: {memory.used / 1024 ** 3:.2f} GB +└ Свободно: {memory.available / 1024 ** 3:.2f} GB + +Диск ({root_path}): +├ Всего: {disk.total / 1024 ** 3:.2f} GB +├ Используется: {disk.used / 1024 ** 3:.2f} GB +└ Свободно: {disk.free / 1024 ** 3:.2f} GB +""".strip() + + return info + + +# --------------------------------------------------------------------- +# Обработчики +# --------------------------------------------------------------------- + +@dp.message(CommandStart()) +async def start_handler(message: Message) -> None: + """ + Обработчик команды /start. + + Отправляет пользователю текущее состояние системы. + """ + + system_info: str = get_system_info() + await message.answer(system_info) + + +# --------------------------------------------------------------------- +# Основной запуск +# --------------------------------------------------------------------- + +async def main() -> None: + """ + Основная функция запуска бота. + + Запускает polling и корректно завершает соединение. + """ + + try: + await dp.start_polling(bot) + finally: + await bot.session.close() + + +if __name__ == "__main__": + asyncio.run(main())