diff --git a/ISSUES.md b/ISSUES.md index 3ea6ad4..a337401 100644 --- a/ISSUES.md +++ b/ISSUES.md @@ -81,7 +81,7 @@ - [ ] **Отсутствует `pyproject.toml`** — проект использует `requirements.txt` + `requirements-dev.txt` без единого файла конфигурации. Рекомендуется `pyproject.toml` с `[project]`, настройками ruff и pytest -- [ ] **`commands/news.py` — дублирование кода для статей и постов** — блоки обработки `articles` и `posts` почти идентичны (проверка `None`, форматирование, fallback). Вынести в вспомогательную функцию +- [x] ~~**`commands/news.py` — дублирование кода для статей и постов**~~ — вынесено в `_format_feed_section()` (`commands/news.py`) - [x] ~~**Город захардкожен в `API_URL_WEATHER`**~~ — вынесен в `WEATHER_CITY` env-переменную, шаблон `"Погода: {city}:"` (`utils/pogoda.py`, `.env.example`) diff --git a/commands/news.py b/commands/news.py index eaaf5ab..9fe5ace 100644 --- a/commands/news.py +++ b/commands/news.py @@ -1,5 +1,7 @@ import asyncio import logging +from typing import Optional + from discord.ext import commands from utils.news import ( fetch_rss, @@ -12,6 +14,29 @@ from utils.news import ( logger = logging.getLogger(__name__) +def _format_feed_section( + data: Optional[list[dict]], + author: str, + label_warning: str, + label_info: str, + msg_error: str, + msg_empty: str, + title: str, + link: str, +) -> str: + """Форматировать один RSS-раздел (статьи или посты).""" + if data is None: + logger.warning( + "%s: !nw — не удалось получить %s (API вернул None)", author, label_warning + ) + return msg_error + elif data: + return "\n".join(format_articles(data, title, link)) + else: + logger.info("%s: !nw — %s нет в RSS", author, label_info) + return msg_empty + + class News(commands.Cog): """Команда !news — свежие статьи и новости по AI с Habr""" @@ -23,41 +48,28 @@ class News(commands.Cog): fetch_rss(RSS_URL_POSTS), ) - parts: list[str] = [] - - # --- Статьи --- - if articles is None: - logger.warning( - "%s: !nw — не удалось получить статьи (API вернул None)", ctx.author - ) - parts.append("Не удалось получить статьи.") - elif articles: - articles_text = format_articles( + parts: list[str] = [ + _format_feed_section( articles, + str(ctx.author), + "статьи", + "статей", + "Не удалось получить статьи.", + "Статей пока нет.", "Лучшие статьи за сутки / Искусственный интеллект / Хабr", "https://habr.com/ru/hubs/artificial_intelligence/articles/top/daily/", - ) - parts.append("\n".join(articles_text)) - else: - logger.info("%s: !nw — статей нет в RSS", ctx.author) - parts.append("Статей пока нет.") - - # --- Посты --- - if posts is None: - logger.warning( - "%s: !nw — не удалось получить посты (API вернул None)", ctx.author - ) - parts.append("\nНе удалось получить новости.") - elif posts: - posts_text = format_articles( + ), + _format_feed_section( posts, + str(ctx.author), + "посты", + "постов", + "Не удалось получить новости.", + "Новостей пока нет.", "Лучшие новости за сутки / Искусственный интеллект / Хабr", "https://habr.com/ru/hubs/artificial_intelligence/news/top/daily/", - ) - parts.append("\n" + "\n".join(posts_text)) - else: - logger.info("%s: !nw — постов нет в RSS", ctx.author) - parts.append("\nНовостей пока нет.") + ), + ] message = truncate_message("\n".join(parts)) await ctx.send(message)