Refactor: add commands/, console_commands/, !pogoda command
This commit is contained in:
parent
83fc714b8e
commit
89f17d53d8
22
AGENTS.md
22
AGENTS.md
@ -1,7 +1,7 @@
|
||||
# AGENTS.md
|
||||
|
||||
## Проект
|
||||
Discord-бот на Python (discord.py). Команда `!msg <текст>` повторяет текст.
|
||||
Discord-бот на Python (discord.py). Команды: `!msg` (повтор текста), `!pogoda` (прогноз погоды для Магнитогорска).
|
||||
|
||||
## Запуск
|
||||
```
|
||||
@ -16,3 +16,23 @@ python bot.py
|
||||
|
||||
## Конвенции
|
||||
Используй TODO-списки для каждого запроса с несколькими шагами.
|
||||
|
||||
## Архитектура
|
||||
```
|
||||
commands/ # Discord команды (cogs)
|
||||
__init__.py # ALL_COMMANDS — явные импорты
|
||||
pogoda.py # !pogoda
|
||||
console_commands/ # Консольные команды
|
||||
__init__.py # ALL_CONSOLE_COMMANDS — явные импорты
|
||||
stop.py # stop
|
||||
```
|
||||
|
||||
**Добавление Discord команды:**
|
||||
1. Создать файл `commands/имя.py` с классом, наследующим `commands.Cog`
|
||||
2. Добавить импорт в `commands/__init__.py`
|
||||
3. Добавить класс в `ALL_COMMANDS`
|
||||
|
||||
**Добавление консольной команды:**
|
||||
1. Создать файл `console_commands/имя.py` с функцией
|
||||
2. Добавить импорт в `console_commands/__init__.py`
|
||||
3. Добавить функцию в `ALL_CONSOLE_COMMANDS`
|
||||
|
||||
23
bot.py
23
bot.py
@ -7,6 +7,8 @@ import discord
|
||||
from discord.ext import commands
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from commands import ALL_COMMANDS
|
||||
|
||||
load_dotenv()
|
||||
|
||||
intents = discord.Intents.default()
|
||||
@ -19,6 +21,11 @@ stop_event = threading.Event()
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
print(f"Бот вошёл как {bot.user}")
|
||||
for cog_class in ALL_COMMANDS:
|
||||
cog = cog_class()
|
||||
await bot.add_cog(cog)
|
||||
for cog in bot.cogs:
|
||||
print(f" Загружен: {cog}")
|
||||
|
||||
|
||||
@bot.command(name="msg")
|
||||
@ -34,13 +41,19 @@ def console_input():
|
||||
if cmd == "stop":
|
||||
print("\nОстановка бота...")
|
||||
stop_event.set()
|
||||
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop)
|
||||
try:
|
||||
bot.loop.stop()
|
||||
except (AttributeError, RuntimeError):
|
||||
pass
|
||||
break
|
||||
elif cmd:
|
||||
print(f"Неизвестная команда: {cmd}")
|
||||
except EOFError:
|
||||
stop_event.set()
|
||||
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop)
|
||||
try:
|
||||
bot.loop.stop()
|
||||
except (AttributeError, RuntimeError):
|
||||
pass
|
||||
break
|
||||
|
||||
|
||||
@ -58,5 +71,9 @@ if __name__ == "__main__":
|
||||
bot.run(token)
|
||||
except KeyboardInterrupt:
|
||||
print("\nОстановка бота...")
|
||||
bot.loop.stop()
|
||||
try:
|
||||
bot.loop.stop()
|
||||
except (AttributeError, RuntimeError):
|
||||
pass
|
||||
stop_event.set()
|
||||
sys.exit(0)
|
||||
|
||||
3
commands/__init__.py
Normal file
3
commands/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from .pogoda import Pogoda
|
||||
|
||||
ALL_COMMANDS = [Pogoda]
|
||||
BIN
commands/__pycache__/__init__.cpython-314.pyc
Normal file
BIN
commands/__pycache__/__init__.cpython-314.pyc
Normal file
Binary file not shown.
BIN
commands/__pycache__/pogoda.cpython-314.pyc
Normal file
BIN
commands/__pycache__/pogoda.cpython-314.pyc
Normal file
Binary file not shown.
87
commands/pogoda.py
Normal file
87
commands/pogoda.py
Normal file
@ -0,0 +1,87 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import requests
|
||||
|
||||
|
||||
class Pogoda(commands.Cog):
|
||||
"""Команда !pogoda — прогноз погоды для Магнитогорска"""
|
||||
|
||||
def __init__(self):
|
||||
self.api_url = "https://api.open-meteo.com/v1/forecast"
|
||||
self.lat = 53.41
|
||||
self.lon = 59.06
|
||||
|
||||
@commands.command(name="pogoda")
|
||||
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:
|
||||
response = requests.get(self.api_url, params=params, timeout=10)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
except requests.RequestException as e:
|
||||
await ctx.send(f"Ошибка при получении данных: {e}")
|
||||
return
|
||||
|
||||
current = data.get("current", {})
|
||||
if not current:
|
||||
await ctx.send("Не удалось получить данные о погоде.")
|
||||
return
|
||||
|
||||
temp = current.get("temperature_2m", "—")
|
||||
weather_code = current.get("weather_code", "—")
|
||||
humidity = current.get("relative_humidity_2m", "—")
|
||||
wind = current.get("wind_speed_10m", "—")
|
||||
pressure = current.get("pressure_msl", "—")
|
||||
|
||||
description = self._get_weather_description(weather_code)
|
||||
pressure_mm = self._pressure_to_mmhg(pressure)
|
||||
|
||||
await ctx.send(
|
||||
f"🌡 Температура: {temp}°C\n"
|
||||
f"📝 Описание: {description}\n"
|
||||
f"💧 Влажность: {humidity}%\n"
|
||||
f"💨 Ветер: {wind} км/ч\n"
|
||||
f"🌍 Давление: {pressure_mm} мм рт. ст."
|
||||
)
|
||||
|
||||
def _get_weather_description(self, code):
|
||||
descriptions = {
|
||||
0: "Ясно",
|
||||
1: "Преимущественно ясно",
|
||||
2: "Переменная облачность",
|
||||
3: "Пасмурно",
|
||||
45: "Туман",
|
||||
48: "Изморозь",
|
||||
51: "Лёгкая морось",
|
||||
53: "Морось",
|
||||
55: "Сильная морось",
|
||||
61: "Небольшой дождь",
|
||||
63: "Дождь",
|
||||
65: "Сильный дождь",
|
||||
66: "Ледяной дождь",
|
||||
67: "Сильный ледяной дождь",
|
||||
71: "Небольшой снег",
|
||||
73: "Снег",
|
||||
75: "Сильный снег",
|
||||
77: "Снежная крупа",
|
||||
80: "Небольшой ливень",
|
||||
81: "Ливень",
|
||||
82: "Сильный ливень",
|
||||
85: "Небольшой снегопад",
|
||||
86: "Сильный снегопад",
|
||||
95: "Гроза",
|
||||
96: "Гроза с градом",
|
||||
99: "Сильная гроза с градом",
|
||||
}
|
||||
return descriptions.get(code, "Неизвестно")
|
||||
|
||||
def _pressure_to_mmhg(self, hpa):
|
||||
if hpa == "—":
|
||||
return "—"
|
||||
return round(hpa * 0.750062, 1)
|
||||
5
console_commands/__init__.py
Normal file
5
console_commands/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
from .stop import stop
|
||||
|
||||
ALL_CONSOLE_COMMANDS = {
|
||||
"stop": stop,
|
||||
}
|
||||
3
console_commands/stop.py
Normal file
3
console_commands/stop.py
Normal file
@ -0,0 +1,3 @@
|
||||
def stop(stop_event):
|
||||
"""Остановка бота"""
|
||||
pass
|
||||
@ -1,2 +1,3 @@
|
||||
discord.py>=2.3.2
|
||||
python-dotenv>=1.0.0
|
||||
requests>=2.31.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user