fediverse: публикация в GoToSocial (@vesti@dedinit.ru) из publisher-service

- gotosocial.py: клиент GtS (httpx): post_status (markdown), upload_media v2, verify_credentials, delete_status
- config.py: gt_social_url/token/visibility/format/channels
- channels.py: fediverse-каналы (VESTI_GTS_CHANNELS, префикс gt:), gt: уходит только в fediverse
- main.py: _publish_gotosocial + healthz-блок gotosocial + dry_run; status_id (ULID) в ответе
- .env.example: GT_SOCIAL_* и VESTI_GTS_CHANNELS
- STATUS.md/WALKTHROUGH.md: fediverse-раздел, хронология
- openspec: change gotosocial-publisher (proposal/design/tasks/specs), validate чисто
This commit is contained in:
kpa39l
2026-09-13 20:19:52 +00:00
parent 71fd48aa06
commit bf176cc02b
12 changed files with 677 additions and 16 deletions
+24 -4
View File
@@ -1,12 +1,32 @@
# Разбор списка каналов из конфигурации.
# Разбор списков каналов из конфигурации.
# Два независимых списка:
# VESTI_BOT_CHANNELS — Telegram-каналы (@dedinit_vesti, ...)
# VESTI_GTS_CHANNELS — fediverse-каналы GoToSocial (@kpa39l@dedinit.ru, ...)
# Деление по типу канала: алгоритм НЕ угадывает по виду строки (надёжнее конфиг).
from .config import settings
def resolve_channels(channels: list[str] | None) -> list[str]:
"""Итоговый список каналов для публикации.
"""Итоговый список Telegram-каналов для публикации.
channels из запроса (MAY переопределять) -> иначе VESTI_BOT_CHANNELS (конфиг).
Каналы с префиксом 'gt:' — это fediverse (GoToSocial), НЕ Telegram: отбрасываются.
"""
if channels:
return list(dict.fromkeys([c.strip() for c in channels if c.strip()]))
return list(settings.channels)
tg = [c.strip() for c in channels if c.strip() and not c.strip().startswith("gt:")]
return list(dict.fromkeys(tg))
return list(settings.channels)
def resolve_gotosocial_channels(channels: list[str] | None) -> list[str]:
"""Итоговый список GoToSocial-каналов (fediverse).
В запросе fediverse-каналы передаются ПРЕФИКСОМ gt: (например gt:@kpa39l@dedinit.ru),
чтобы не смешивать с Telegram-каналами. Если в запросе их нет — берётся
VESTI_GTS_CHANNELS из конфига.
"""
if channels:
gts = [c[3:].strip() for c in channels if c.strip().startswith("gt:")]
if gts:
return list(dict.fromkeys(gts))
return list(settings.gt_social_channels)