deadzilla 2188a7d3fd feat: упростить вывод команды !hp, добавить тесты
- Убран discord.Embed в пользу простого текста без timestamp ошибки
- Добавлены разделители = вокруг заголовка
- Создан tests/test_help_discord.py с 2 тестами для Discord команды
- Создан tests/test_help_console.py с 2 тестами для консольной команды
- Закрыто: AttributeError 'Message' object has no attribute 'timestamp'
2026-06-02 23:14:37 +05:00

Discord Bot

Discord-бот для Магнитогорска. Команды погоды, новостей, котиков и утреннего дайджеста.

📖 Документация

Основной документ проекта — AGENTS.md. Содержит детальные инструкции по архитектуре, командам и работе с ботом.

Установка

pip install -r requirements.txt

Запуск

python bot.py

Введите номер команды в терминале или !команда в Discord.

Настройка

  1. Скопируйте .env.example в .env:

    cp .env.example .env
    
  2. Вставьте токен бота в .env:

    DISCORD_TOKEN=ваш_токен
    

Токен получите на Discord Developer Portal.

Команды Discord

Команда Описание
!pg Прогноз погоды для Магнитогорска
!nw Топ-5 свежих статей по AI с Habr
!hp Список всех команд бота с описанием
!morning Погода + топ-5 статей + топ-5 новостей + котик (утренний дайджест)
!cat Случайный котик
!msg <текст> Повторить текст в чате

Команды терминала

Номер Команда Описание
1 news Топ-5 статей + топ-5 новостей с Habr
2 pogoda Прогноз погоды для Магнитогорска
3 morning Погода + топ-5 статей + топ-5 новостей + котик
4 cat Вывести URL случайного котика
0 stop Остановка бота

Архитектура

bot.py                  # Точка входа, инициализация бота, console_input()
commands/               # Discord команды (cogs)
  __init__.py           # ALL_COMMANDS — явные импорты
  pg.py                 # !pg — погода с retry + fallback
  news.py               # !nw — новости с Habr
  cat.py                # !cat — случайный котик
  morning.py            # !morning — утренний дайджест
  help.py               # !hp — список команд
console_commands/       # Консольные команды
  __init__.py           # ALL_CONSOLE_COMMANDS — явные импорты
  stop.py               # stop — остановка бота
  news.py               # news — новости с Habr
  pogoda.py             # pogoda — погода в терминале
  morning.py            # morning — утренний дайджест в терминале
  cat.py                # cat — вывод URL котика
utils/                  # Утилиты (API-клиенты, конвертации)
  pogoda.py             # fetch_weather(), fetch_open_meteo(), wmo_to_russian(), translate_weather(), pressure_to_mmhg(), format_weather_data_for_console()
  news.py               # fetch_rss(), format_articles(), truncate_title(), parse_date()
  cat.py                # fetch_cat()
tests/                  # pytest-тесты
  test_pogoda.py        # translate_weather, pressure_to_mmhg, wmo_to_russian, format_weather_data_for_console
  test_fetch_cat.py     # fetch_cat
  test_fetch_rss.py     # fetch_rss
  test_fetch_weather.py # fetch_weather, fetch_open_meteo
  test_format_articles.py # truncate_title, parse_date, format_articles
  test_commands_pg.py   # Pg cog
  test_bot.py           # инициализация бота
  test_morning_runner.py# тесты morning runner-а
  test_help_discord.py  # команда !hp — проверка формата вывода и контента (2 теста)
  test_help_console.py  # консольная help — проверка списка команд (2 теста)
ISSUES.md               # Задачи и баг-трекер проекта
pytest.ini              # Конфигурация pytest

Добавление Discord команды

  1. Создать файл commands/имя.py с классом, наследующим commands.Cog
  2. Добавить импорт в commands/__init__.py
  3. Добавить класс в ALL_COMMANDS

Добавление консольной команды

  1. Создать файл console_commands/имя.py с функцией func(stop_event, bot)
  2. Добавить импорт в console_commands/__init__.py
  3. Добавить функцию в ALL_CONSOLE_COMMANDS

Запуск тестов

python -m pytest tests/ -v

Структура тестов

Файл Что тестирует Кол-во
test_pogoda.py translate_weather(), pressure_to_mmhg(), wmo_to_russian(), format_weather_data_for_console() 93
test_fetch_cat.py fetch_cat() 10
test_fetch_rss.py fetch_rss() 20
test_fetch_weather.py fetch_weather(), fetch_open_meteo() 20
test_format_articles.py truncate_title(), parse_date(), format_articles() 24
test_commands_pg.py Pg cog, команда !pg 13
test_bot.py инициализация бота 7
test_morning_runner.py morning runner-а 68

Итого: 262 теста (4 новых для help).

API и внешние сервисы

Погода (!pg, !morning)

  • Основной: wttr.in/Magnitogorsk (бесплатный, без ключа)
  • Fallback: api.open-meteo.com (бесплатный, без ключа)
  • Retry: 3 попытки с экспоненциальной задержкой при SSL/Connection/Timeout ошибках
  • Fallback срабатывает автоматически при неуспешных попытках
  • WMO weather codes → русский перевод в wmo_to_russian()

Конвертации

  • Давление: hPa → мм рт. ст. (* 0.750062)
  • Ветер: км/ч → м/с (/ 3.6)
  • Погодные описания: английский → русский (translate_weather())

Новости (!nw, !morning)

  • Articles: https://habr.com/ru/rss/hubs/artificial_intelligence/articles/top/daily/?fl=ru
  • News: https://habr.com/ru/rss/hubs/artificial_intelligence/news/top/daily/?fl=ru
  • Парсинг RSS 2.0 и Atom форматов
  • Извлечение ссылок из <guid isPermaLink="true"> и авторов из <dc:creator>
  • Формат вывода: заголовок → дата → ссылка

Котики (!cat, !morning)

  • API: https://api.thecatapi.com/v1/images/search
  • Картинка встраивается в Discord Embed

Структура данных погоды

Команда !pg возвращает:

Температура: X°C (ощущается как Y°C)
Описание: Z
Влажность: X%
Ветер: X м/с
Давление: X мм рт. ст.

Формат дат

Даты форматируются как дд.мм.гггг через datetime.strptime с форматом %a, %d %b %Y %H:%M:%S %z.

Конфигурация

Переменная Описание Где взять
DISCORD_TOKEN Токен бота Discord Developer Portal
MORNING_TIME Время запуска утреннего дайджеста .env (формат ЧЧ:ММ, по умолчанию 07:00)
MORNING_CHANNEL_ID ID канала для утреннего дайджеста Правый клик по каналу → Копировать ID

Зависимости

discord.py>=2.3.2
python-dotenv>=1.0.0
requests>=2.31.0
pytest>=7.4.0
pytest-asyncio>=0.21.0

Безопасность

  • .env в .gitignore — токен никогда не должен попадать в репозиторий
  • Используйте .env.example как шаблон

Формат новостей

Каждая новость выводится в формате:

Заголовок статьи
   дд.мм.гггг   https://habr.com/ru/articles/...

Заголовки обрезаются до 60 символов с суффиксом ....

Ссылки отображаются без <> и https:// префикса для предотвращения embed-превью в Discord.

Основные функции утилит

utils/pogoda.py

Функция Описание
fetch_weather() Основная функция получения погоды с wttr.in
fetch_open_meteo() Fallback при ошибках основного API
wmo_to_russian() Перевод WMO кодов погоды в русское описание
translate_weather() Перевод погодных описаний на русский язык
pressure_to_mmhg() Конвертация давления из hPa в мм рт. ст.
format_weather_data_for_console() Форматирование данных погоды для вывода в консоль

utils/news.py

Функция Описание
fetch_rss() Получение RSS ленты (статьи или новости)
parse_date() Парсинг даты из RSS
truncate_title() Обрезка заголовка до заданной длины
format_articles() Форматирование списка статей для вывода

utils/cat.py

Функция Описание
fetch_cat() Получение URL случайного котика
Description
Бот анонсер начала дня. Погода + новости + отельный команды.
Readme 546 KiB
Languages
Python 99.4%
Dockerfile 0.6%