Compare commits
No commits in common. "e78d34e3cb9128c52732ecc78438eb2fa07a152d" and "89f17d53d85c4d155fad3e5cbd86fcd3f8b3cfa7" have entirely different histories.
e78d34e3cb
...
89f17d53d8
1
.env
1
.env
@ -1 +0,0 @@
|
|||||||
DISCORD_TOKEN=MTI4ODA4NTM0OTQxNDk5ODAyNw.Gk3VXx.ZevANnkcdoxtv-Wi8RCMXVa6RczHbUsmhByV3g
|
|
||||||
31
bot.py
31
bot.py
@ -5,8 +5,6 @@ import threading
|
|||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands import CommandNotFound
|
|
||||||
from discord.ext.commands import CommandNotFound
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
from commands import ALL_COMMANDS
|
from commands import ALL_COMMANDS
|
||||||
@ -30,20 +28,6 @@ async def on_ready():
|
|||||||
print(f" Загружен: {cog}")
|
print(f" Загружен: {cog}")
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
|
||||||
async def on_command_error(ctx, error):
|
|
||||||
if isinstance(error, CommandNotFound):
|
|
||||||
return
|
|
||||||
print(f"Ошибка команды: {error}")
|
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
|
||||||
async def on_command_error(ctx, error):
|
|
||||||
if isinstance(error, CommandNotFound):
|
|
||||||
return
|
|
||||||
print(f"Ошибка команды: {error}")
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(name="msg")
|
@bot.command(name="msg")
|
||||||
async def msg(ctx, *, text: str):
|
async def msg(ctx, *, text: str):
|
||||||
"""Повторяет текст после !msg"""
|
"""Повторяет текст после !msg"""
|
||||||
@ -57,13 +41,19 @@ def console_input():
|
|||||||
if cmd == "stop":
|
if cmd == "stop":
|
||||||
print("\nОстановка бота...")
|
print("\nОстановка бота...")
|
||||||
stop_event.set()
|
stop_event.set()
|
||||||
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result()
|
try:
|
||||||
|
bot.loop.stop()
|
||||||
|
except (AttributeError, RuntimeError):
|
||||||
|
pass
|
||||||
break
|
break
|
||||||
elif cmd:
|
elif cmd:
|
||||||
print(f"Неизвестная команда: {cmd}")
|
print(f"Неизвестная команда: {cmd}")
|
||||||
except EOFError:
|
except EOFError:
|
||||||
stop_event.set()
|
stop_event.set()
|
||||||
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result()
|
try:
|
||||||
|
bot.loop.stop()
|
||||||
|
except (AttributeError, RuntimeError):
|
||||||
|
pass
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
@ -81,6 +71,9 @@ if __name__ == "__main__":
|
|||||||
bot.run(token)
|
bot.run(token)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("\nОстановка бота...")
|
print("\nОстановка бота...")
|
||||||
|
try:
|
||||||
|
bot.loop.stop()
|
||||||
|
except (AttributeError, RuntimeError):
|
||||||
|
pass
|
||||||
stop_event.set()
|
stop_event.set()
|
||||||
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result()
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -7,74 +7,81 @@ class Pogoda(commands.Cog):
|
|||||||
"""Команда !pogoda — прогноз погоды для Магнитогорска"""
|
"""Команда !pogoda — прогноз погоды для Магнитогорска"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.api_url = "https://wttr.in/Magnitogorsk?format=j1&lang=ru"
|
self.api_url = "https://api.open-meteo.com/v1/forecast"
|
||||||
|
self.lat = 53.41
|
||||||
|
self.lon = 59.06
|
||||||
|
|
||||||
@commands.command(name="pogoda")
|
@commands.command(name="pogoda")
|
||||||
async def pogoda(self, ctx):
|
async def pogoda(self, ctx):
|
||||||
|
params = {
|
||||||
|
"latitude": self.lat,
|
||||||
|
"longitude": self.lon,
|
||||||
|
"current": "temperature_2m,weather_code,relative_humidity_2m,wind_speed_10m,pressure_msl",
|
||||||
|
"timezone": "Asia/Yekaterinburg",
|
||||||
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.get(self.api_url, timeout=10)
|
response = requests.get(self.api_url, params=params, timeout=10)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
data = response.json()
|
data = response.json()
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
await ctx.send(f"Ошибка при получении данных: {e}")
|
await ctx.send(f"Ошибка при получении данных: {e}")
|
||||||
return
|
return
|
||||||
|
|
||||||
current = data.get("current_condition", [{}])[0]
|
current = data.get("current", {})
|
||||||
if not current:
|
if not current:
|
||||||
await ctx.send("Не удалось получить данные о погоде.")
|
await ctx.send("Не удалось получить данные о погоде.")
|
||||||
return
|
return
|
||||||
|
|
||||||
temp = current.get("temp_C", "—")
|
temp = current.get("temperature_2m", "—")
|
||||||
feels_like = current.get("FeelsLikeC", "—")
|
weather_code = current.get("weather_code", "—")
|
||||||
description = self._translate_weather(current.get("weatherDesc", [{}])[0].get("value", "—"))
|
humidity = current.get("relative_humidity_2m", "—")
|
||||||
humidity = current.get("humidity", "—")
|
wind = current.get("wind_speed_10m", "—")
|
||||||
wind_kmh = current.get("windspeedKmph", "—")
|
pressure = current.get("pressure_msl", "—")
|
||||||
wind = round(int(wind_kmh) / 3.6, 1) if wind_kmh != "—" else "—"
|
|
||||||
pressure_mb = current.get("pressure", "—")
|
|
||||||
|
|
||||||
pressure_mm = self._pressure_to_mmhg(pressure_mb)
|
description = self._get_weather_description(weather_code)
|
||||||
|
pressure_mm = self._pressure_to_mmhg(pressure)
|
||||||
|
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
f"[TEMP] Температура: {temp}°C (ощущается как {feels_like}°C)\n"
|
f"🌡 Температура: {temp}°C\n"
|
||||||
f"[DESC] Описание: {description}\n"
|
f"📝 Описание: {description}\n"
|
||||||
f"[HUMID] Влажность: {humidity}%\n"
|
f"💧 Влажность: {humidity}%\n"
|
||||||
f"[WIND] Ветер: {wind} м/с\n"
|
f"💨 Ветер: {wind} км/ч\n"
|
||||||
f"[PRESS] Давление: {pressure_mm} мм рт. ст."
|
f"🌍 Давление: {pressure_mm} мм рт. ст."
|
||||||
)
|
)
|
||||||
|
|
||||||
def _translate_weather(self, en):
|
def _get_weather_description(self, code):
|
||||||
mapping = {
|
descriptions = {
|
||||||
"Sunny": "Ясно",
|
0: "Ясно",
|
||||||
"Clear": "Ясно",
|
1: "Преимущественно ясно",
|
||||||
"Partly cloudy": "Переменная облачность",
|
2: "Переменная облачность",
|
||||||
"Cloudy": "Облачно",
|
3: "Пасмурно",
|
||||||
"Overcast": "Пасмурно",
|
45: "Туман",
|
||||||
"Mist": "Туман",
|
48: "Изморозь",
|
||||||
"Fog": "Туман",
|
51: "Лёгкая морось",
|
||||||
"Patchy rain nearby": "Местами дождь",
|
53: "Морось",
|
||||||
"Light rain": "Небольшой дождь",
|
55: "Сильная морось",
|
||||||
"Moderate rain": "Умеренный дождь",
|
61: "Небольшой дождь",
|
||||||
"Heavy rain": "Сильный дождь",
|
63: "Дождь",
|
||||||
"Patchy snow nearby": "Местами снег",
|
65: "Сильный дождь",
|
||||||
"Light snow": "Небольшой снег",
|
66: "Ледяной дождь",
|
||||||
"Heavy snow": "Сильный снег",
|
67: "Сильный ледяной дождь",
|
||||||
"Patchy sleet nearby": "Местами слякоть",
|
71: "Небольшой снег",
|
||||||
"Blowing snow": "Метель",
|
73: "Снег",
|
||||||
"Thundery outbreaks in nearby": "Гроза вблизи",
|
75: "Сильный снег",
|
||||||
"Moderate or heavy snow in area": "Снег",
|
77: "Снежная крупа",
|
||||||
"Moderate or heavy rain in area": "Дождь",
|
80: "Небольшой ливень",
|
||||||
"Moderate or heavy freezing rain in area": "Ледяной дождь",
|
81: "Ливень",
|
||||||
"Moderate or heavy sleet in area": "Слякоть",
|
82: "Сильный ливень",
|
||||||
"Ice pellets": "Ледяные кристаллы",
|
85: "Небольшой снегопад",
|
||||||
"Haze": "Дымка",
|
86: "Сильный снегопад",
|
||||||
"Foggy": "Туманно",
|
95: "Гроза",
|
||||||
|
96: "Гроза с градом",
|
||||||
|
99: "Сильная гроза с градом",
|
||||||
}
|
}
|
||||||
for key, value in mapping.items():
|
return descriptions.get(code, "Неизвестно")
|
||||||
if key.lower() in en.lower():
|
|
||||||
return value
|
|
||||||
return en
|
|
||||||
|
|
||||||
def _pressure_to_mmhg(self, mb):
|
def _pressure_to_mmhg(self, hpa):
|
||||||
if mb == "—":
|
if hpa == "—":
|
||||||
return "—"
|
return "—"
|
||||||
return round(int(mb) * 0.750062, 1)
|
return round(hpa * 0.750062, 1)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user