62 Commits

Author SHA1 Message Date
deadzilla
1a6b7043ad fix: применить ruff format к 7 файлам
ruff format --check падает на 7 файлах (не 5 как было указано).
Изменения — чистое форматирование: line wrapping, trailing commas, blank lines.
Никаких логических изменений.

Файлы: bot.py, tests/test_commands_news.py, tests/test_commands_pg.py,
tests/test_fetch_weather.py, tests/test_help_command.py,
tests/test_morning_runner.py, utils/pogoda.py
2026-07-22 21:58:55 +05:00
deadzilla
f7df0f4900 feat(weather): кэширование погоды с TTL 1 час
- fetch_weather кэширует результат на 3600 сек (WEATHER_CACHE_TTL)
- Провал запроса тоже кэшируется — не долбит API повторно
- bypass_cache=True для форсирования свежего запроса
- clear_weather_cache() для сброса кэша
- asyncio.Lock для thread-safety
- 5 новых тестов (cache hit, bypass, failure cache, clear, TTL expiry)
2026-07-21 00:08:09 +05:00
deadzilla
b8b1801f23 fix(weather): исправлены баги в погодном функционале
- JSONDecodeError теперь ловится в fetch_weather (был краш при невалидном JSON от API)
- Порывы ветра больше не теряются при отсутствии base wind (gust fallback)
- Устранено дублирование 'м/с' при порывах + отсутствии направления ветра
- Переименован windspeedKmph → wind_speed_mps (ключ хранил м/с, а не км/ч)
- Обновлены тесты, добавлены 6 новых (gust-only, no-duplication, JSONDecodeError)
2026-07-20 23:56:07 +05:00
deadzilla
48e64c2bc8 Replace wttr.in/Open-Meteo with Yandex Weather API
- Switch from wttr.in + Open-Meteo fallback to Yandex Weather API
- Add YANDEX_WEATHER_API_KEY to .env and config validation
- Enrich weather output: wind gusts, wind direction (Russian)
- Pressure now in mmHg directly from Yandex (no conversion needed)
- Update rate limiter: weather_limiter + open_meteo_limiter → yandex_weather_limiter
- Remove dead code: API_URL_WEATHER, fetch_open_meteo, translate_weather
- Update all tests (271 passed)
2026-07-20 23:31:11 +05:00
deadzilla
bb9e50fb05 Убраны приватные атрибуты с объекта discord.py Bot: START_TIME вынесен на уровень модуля, _scheduler удалён (не использовался) 2026-07-14 22:46:57 +05:00
deadzilla
29313530f3 Удалены избыточные @pytest.mark.asyncio (asyncio_mode = auto в pytest.ini) 2026-07-14 22:41:10 +05:00
deadzilla
3888c3cd01 fetch_cat() передаёт x-api-key при наличии CAT_API_KEY в окружении 2026-07-14 22:27:30 +05:00
deadzilla
0d5d8dbe7b Удалён лишний __init__ в Pg; API_URL_WEATHER используется напрямую 2026-07-14 22:23:38 +05:00
deadzilla
bb9f291623 Scheduler.__init__ больше не создаёт task синхронно; start() стал async-методом 2026-07-14 22:20:45 +05:00
deadzilla
1ab3205333 fix: format_articles(None) возвращает graceful fallback вместо TypeError 2026-07-12 00:11:54 +05:00
deadzilla
f825be866b chore: удалена закомментированная устаревшая строка теста pressure_to_mmhg(0) 2026-07-12 00:09:21 +05:00
deadzilla
5eb4184d63 refactor: RateLimiter принимает _time_func для детерминированных тестов без зависимости от реального времени 2026-07-12 00:08:13 +05:00
deadzilla
d94b9c16ab fix: translate_weather обрезает пробелы перед проверкой на пустоту 2026-07-12 00:02:13 +05:00
deadzilla
efee713301 fix: TextHelpCommand показывает standalone-команды (без cog) если они не hidden 2026-07-11 23:59:41 +05:00
deadzilla
b22b02d65e fix: _parse_date валидирует формат даты через regex вместо возврата мусора 2026-07-11 23:55:18 +05:00
deadzilla
048b9a3a91 fix: format_weather_data_for_console заменяет None на эм-дэш вместо вывода 'None' в текст 2026-07-11 23:50:05 +05:00
deadzilla
cef53197b1 feat: !morning — заменить embed на plain text, кот отдельным сообщением
- Переименован format_weather_for_embed -> format_weather_for_message
- Убран markdown жирный (**text**) из заголовков погоды и статей
- Утренний дайджест отправляется как обычное текстовое сообщение
- Котик отправляется отдельным сообщением перед дайджестом
- Truncation через truncate_message (лимит 2000 символов)
- Обновлены тесты: проверка 2 send() вместо embed
2026-07-09 13:28:39 +05:00
deadzilla
bc843abc63 Добавлены тесты для Cat, News, Morning когов, TextHelpCommand и truncate-функций (282 теста, все проходят) 2026-07-09 13:07:09 +05:00
deadzilla
d0a4f45e68 feat: удалить команду !hp вместе с тестами 2026-07-09 09:35:49 +05:00
deadzilla
48ed9aa07b fix: !hp теперь показывает правильные описания команд
Проблема: cmd.__doc__ возвращал docstring класса Command из discord.py
(одинаковый для всех команд), а не docstring callback-функции.

Решение:
- Использовать cmd.help вместо cmd.__doc__ для получения описания
- Скрыть !hp из списка через hidden=True
- Пропускать hidden-команды и команды без описания
- Обновить тесты под новый интерфейс
2026-07-09 09:18:48 +05:00
deadzilla
7ade3147cf форматирование: применён ruff format ко всем файлам проекта (21 файл) 2026-07-08 00:44:22 +05:00
deadzilla
4b61909ebc исправлено: убраны неиспользуемые импорты и переменные из tests/test_morning_runner.py 2026-07-08 00:40:08 +05:00
deadzilla
4e816d5998 исправлено: перемещён import contextlib в начало файла 2026-07-08 00:39:43 +05:00
deadzilla
b21237b042 исправлено: убран неиспользуемый import requests из tests/test_integration.py 2026-07-08 00:39:27 +05:00
deadzilla
0fa467d40e исправлено: переименована неоднозначная переменная l в line 2026-07-08 00:39:12 +05:00
deadzilla
a1b72ecbcf исправлено: убрана неиспользуемая переменная mock_fallback в test_fetch_open_meteo_ssl_error 2026-07-08 00:38:59 +05:00
deadzilla
00ec2eac0e исправлено: убран неиспользуемый import pytest из tests/test_fetch_rss.py 2026-07-08 00:38:16 +05:00
deadzilla
ab0039661a исправлено: убраны неиспользуемые импорты json и pytest из tests/test_fetch_cat.py 2026-07-08 00:37:35 +05:00
deadzilla
5a2ff483a1 исправлено: убраны неиспользуемые импорты pytest и patch из tests/test_commands_status.py 2026-07-08 00:37:16 +05:00
deadzilla
cd25d63f5b исправлено: убран неиспользуемый import pytest из tests/test_commands_stats.py 2026-07-08 00:37:04 +05:00
deadzilla
a063abcd17 Добавлены интеграционные тесты: загрузка когов, команды !cat и !stats, утилиты (9 тестов, итого 239) 2026-07-08 00:27:56 +05:00
deadzilla
a8d2bdb579 Исправление: вынес import из тел функций тестов наверх модулей (35 вхождений) 2026-07-08 00:15:34 +05:00
deadzilla
beae42fdc8 Исправление: добавил -> None ко всем 140 test-функциям 2026-07-08 00:10:27 +05:00
deadzilla
41102a9d3d Исправление: убрал утечку корутин Scheduler в тестах — mock _start_scheduler вместо create_task 2026-07-07 23:32:46 +05:00
deadzilla
ec0cee6c68 Исправление: удаление эмодзи из сообщений и логов morning_runner 2026-07-07 23:08:58 +05:00
deadzilla
5a11fb2b5d Исправление: замена signal handler на on_shutdown (устранён race condition event loop) 2026-07-07 22:51:23 +05:00
deadzilla
6e2a092548 fix: H5 — 50 тестов asyncio.run() заменены на async def
- test_fetch_cat.py: 10 тестов (def → async def, asyncio.run → await)
- test_fetch_rss.py: 21 тест (def → async def, asyncio.run → await)
- test_fetch_weather.py: 19 тест (def → async def, asyncio.run → await)
- Удалён лишний import asyncio из тестовых файлов
- Больше не создаётся новый event loop на каждый тест
- RateLimiter (asyncio.Lock) теперь корректно работает в одном loop

230 тестов проходят.
2026-07-07 21:52:18 +05:00
deadzilla
ea0d50df4f fix: H3 — pressure_to_mmhg(0) возвращает 0.0 вместо '—'
- Заменён 'not mb' на 'mb is None or mb == ""' (0 — валидное значение)
- Обновлён тест test_pressure_zero: ожидание 0.0 вместо '—'

230 тестов проходят.
2026-07-07 21:44:48 +05:00
deadzilla
3aebda1114 fix: H2 — translate_weather сортировка ключей по убыванию длины
- Заменён dict на _WEATHER_MAPPING (list of tuples, отсортирован по длине ключей)
- Длинные фразы проверяются первыми, исключая ложные подстроочные совпадения
- "Moderate or heavy rain at times" теперь корректно -> "Дождь" вместо "Сильный дождь"
- Обновлены тесты: test_translate_known и test_translate_longer_key_priority

230 тестов проходят.
2026-07-07 21:28:29 +05:00
deadzilla
5d9c33a12c fix: H1 — IndexError в format_weather_data_for_console при пустом current_condition
- Защита от пустого списка [] и пустого dict [{}] в current_condition
- Возврат None вместо краша, команда !pg показывает fallback-сообщение
- Обновлён тест test_pg_empty_current_condition (graceful fallback вместо IndexError)

230 тестов проходят.
2026-07-07 21:24:04 +05:00
deadzilla
900128fbd4 удаление консольных команд 2026-07-07 20:52:11 +05:00
deadzilla
cc2808fb40 fix: graceful shutdown — заменить bot.run() на async with + signal handlers (C2)
- Удалён dead code except KeyboardInterrupt (никогда не срабатывал в bot.run())
- Добавлен _signal_handler() для SIGINT/SIGTERM с остановкой scheduler и bot.close()
- Заменён bot.run(token) на asyncio.run(main()) с async with self.bot:
- Добавлен reconnect=True для устойчивости к разрывам gateway
- Тесты: string-matching заменены на поведенческие mock-тесты (5 тестов, все OK)
- Добавлен CODE_REVIEW.md с результатами ревью
2026-07-07 20:51:32 +05:00
deadzilla
8ee5ed669f Исправление планировщика morning: tasks.loop → asyncio.sleep
- Scheduler больше не опрашивает каждую секунду (tasks.loop мог пропустить
  момент срабатывания из-за неточности тайминга). Теперь спит ровно до
  целевого времени через asyncio.sleep, затем запускает morning и повторяет.
- Добавлено логирование ожидания и срабатывания расписания.
- Перенес инициализацию планировщика из on_ready в on_guild_available —
  гарантирует, что кэш гильдии загружен до запуска Scheduler.
- Обновлены тесты под новый Scheduler (asyncio.create_task вместо tasks.loop).
- README.md: исправлены пути admin.py → console_commands/admin.py для docker exec.
- docker-compose.yml: добавлены переменные LOG_LEVEL и rate-limit конфиги.
- console_commands/__init__.py: переименованы help → console_help,
  reload → reload_cogs (избежал конфликта с built-in и уточнил имена).
2026-06-16 22:10:40 +05:00
deadzilla
4027b7df6c feat: ротация логов по размеру (RotatingFileHandler, 5 МБ, 5 бэкапов) 2026-06-12 21:43:00 +05:00
deadzilla
9c7909bde5 fix: автоматическое создание директории logs при запуске бота 2026-06-12 21:11:23 +05:00
deadzilla
c37baafacc feat: добавлены консольные команды logs, reload, trigger morning
- console_commands/logs.py — чтение последних строк лога (tail -20)
- console_commands/reload.py — горячая перезагрузка всех cogs
- console_commands/trigger_morning.py — ручной запуск morning-дайджеста
- logs доступна через admin.py (docker exec) и интерактивный терминал
- reload и trigger morning доступны через интерактивный терминал
- сохранён bot._scheduler для доступа к планировщику
- обновлены __init__.py, admin.py, README.md, ISSUES.md
- добавлены тесты: test_console_logs.py (4), test_console_reload.py (2), test_console_trigger_morning.py (3)
- итого 243 теста
2026-06-12 18:03:47 +05:00
deadzilla
f4d267d254 fix: !stats исключает CategoryChannel из подсчёта каналов
guild.channels содержит все типы включая CategoryChannel.
Категории — это контейнеры для группировки, а не каналы.

Изменено:
  - commands/stats.py: filter по isinstance(CategoryChannel)
  - console_commands/stats.py: аналогичный фильтр
  - test_commands_stats.py: тест test_stats_excludes_categories
  - Итого: 234 теста
2026-06-12 17:01:53 +05:00
deadzilla
f2844f0453 fix: uptime читается с bot._start_time вместо Cog
Проблема: _start_time хранился в Status Cog, но консольная
команда искала его на объекте bot — всегда получала fallback
time.time() и показывала 0с.

Решение: _start_time устанавливается в BotRunner.__init__ на
объекте bot. Cog и console_command читают getattr(bot, '_start_time').

Изменено: bot.py, commands/status.py, console_commands/status.py,
tests/test_commands_status.py
2026-06-12 16:32:55 +05:00
deadzilla
91f34625a8 feat: команды !status и !stats
Добавлены Discord-команды:
  - !status — пинг к gateway, uptime, статус (embed)
  - !stats — серверы, каналы, пользователи (embed)

Добавлены консольные команды:
  - status — статус бота в терминале
  - stats — статистика серверов в терминале

Тесты:
  - test_commands_status.py (6 тестов)
  - test_commands_stats.py (4 теста)
  - всего: 233 теста

Обновления:
  - README.md — новые команды в таблицах и архитектуре
  - ISSUES.md — высокий приоритет закрыт
  - admin.py — hint на !status и !stats
2026-06-12 16:19:21 +05:00
deadzilla
12ed515cca feat: admin.py для управления ботом через docker exec
- Добавлен console_commands/admin.py — CLI-скрипт с командами
  pogoda, news, cat, morning, help
- Добавлен docstring к методу pg (отображается в !hp)
- Обновлён README.md: архитектура, администрирование в Docker, тесты
- Добавлены тесты test_admin.py (5 тестов)
- Итого тестов: 223
2026-06-12 16:06:35 +05:00