Initial commit: UMB Telegram Bot

This commit is contained in:
Галингер Р.С.
2026-07-07 18:30:17 +07:00
commit 76e5701eba
31 changed files with 2524 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
import logging
from datetime import datetime
import aiohttp
from aiohttp_socks import ProxyConnector, ProxyType
from config import API_WEATHER, PROXY_ENABLED, PROXY_URL
from bot.bot import bot
logger = logging.getLogger(__name__)
def get_wind_direction(deg: float) -> str:
if deg >= 337.5 or deg < 22.5:
return "Север"
if deg < 67.5:
return "Северо-восток"
if deg < 112.5:
return "Восток"
if deg < 157.5:
return "Юго-восток"
if deg < 202.5:
return "Юг"
if deg < 247.5:
return "Юго-запад"
if deg < 292.5:
return "Запад"
return "Северо-запад"
def _get_connector():
if PROXY_ENABLED and PROXY_URL:
parsed = PROXY_URL.replace("socks5://", "").replace("socks5h://", "")
if "@" in parsed:
auth, host_port = parsed.split("@", 1)
username, password = auth.split(":", 1)
else:
username = None
password = None
host_port = parsed
host, port = host_port.rsplit(":", 1)
port = int(port)
return ProxyConnector(
proxy_type=ProxyType.SOCKS5,
host=host,
port=port,
username=username,
password=password,
)
return None
async def get_weather(message) -> None:
if len(message.text.split(maxsplit=1)) == 1:
await bot.send_message(message.chat.id, "Пожалуйста, укажите город.")
return
city = message.text.split(maxsplit=1)[1].strip()
url = "https://api.openweathermap.org/data/2.5/weather"
params = {"q": city, "appid": API_WEATHER, "units": "metric", "lang": "ru"}
timeout = aiohttp.ClientTimeout(total=30, sock_connect=15, sock_read=15)
connector = _get_connector()
try:
async with aiohttp.ClientSession(timeout=timeout, connector=connector) as session:
async with session.get(url, params=params) as response:
if response.status == 404:
await bot.send_message(message.chat.id, "Город не найден. Пожалуйста, уточните запрос.")
return
response.raise_for_status()
weather_data = await response.json()
weather_description = weather_data["weather"][0]["description"]
temperature = weather_data["main"]["temp"]
feels_like = weather_data["main"]["feels_like"]
temp_min = weather_data["main"]["temp_min"]
temp_max = weather_data["main"]["temp_max"]
humidity = weather_data["main"]["humidity"]
pressure = int(weather_data["main"]["pressure"] / 1.333)
wind_speed = weather_data["wind"]["speed"]
wind_deg = weather_data["wind"].get("deg", 0)
wind_direction = get_wind_direction(wind_deg)
rain_1h = weather_data.get("rain", {}).get("1h", 0)
clouds_all = weather_data["clouds"]["all"]
visibility = weather_data.get("visibility", 0)
sunrise_time = datetime.fromtimestamp(weather_data["sys"]["sunrise"]).strftime("%H:%M")
sunset_time = datetime.fromtimestamp(weather_data["sys"]["sunset"]).strftime("%H:%M")
weather_message = (
f"Погода в городе {city}:\n\n"
f"Описание: {weather_description}\n"
f"Температура: {temperature}°C (ощущается как {feels_like}°C)\n"
f"Минимальная температура: {temp_min}°C\n"
f"Максимальная температура: {temp_max}°C\n"
f"Влажность: {humidity}%\n"
f"Давление: {pressure} мм рт.ст\n"
f"Скорость ветра: {wind_speed} м/с, направление: {wind_direction}\n"
f"Осадки за последний час: {rain_1h} мм\n"
f"Облачность: {clouds_all}%\n"
f"Видимость: {visibility} м\n"
f"Восход: {sunrise_time}, закат: {sunset_time}"
)
await bot.send_message(message.chat.id, weather_message, parse_mode=None)
except aiohttp.ClientResponseError as exc:
logger.error("HTTP ошибка погоды: %s", exc)
await bot.send_message(message.chat.id, "При получении данных произошла ошибка, попробуйте еще раз.")
except aiohttp.ClientError as exc:
logger.error("Ошибка запроса погоды: %s", exc)
await bot.send_message(message.chat.id, "Не удалось связаться с погодным сервисом.")
except Exception as exc:
logger.exception("Неожиданная ошибка погоды: %s", exc)
await bot.send_message(message.chat.id, "Произошла ошибка при обработке погоды.")
finally:
if connector:
await connector.close()