Files
vesti/openspec/changes/fix-media-mount/design.md
T
kpa39l ee2f8ac61a fix(publisher): медиа постов не публиковалось в Telegram — контейнер монтировал media/media вместо media
Причина: compose монтировал ../../media/media:/srv/publisher/media, а краулер
с 2026-09-12 качает файлы в media/<file> (новая раскладка). В контейнере
Path(media/<file>).exists() = False → медиа молча пропускалось, уходил только
текст (пост #1017).

Фикс: монтировать весь ../../media + _resolve_media() в publisher
(пробует media/<file>, media/media/<basename>). GoToSocial тоже.
Change fix-media-mount (skip_specs: багфикс), e2e: media_message_id задан,
тестовые сообщения удалены.
2026-09-14 18:29:54 +00:00

93 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Дизайн
### 1. docker-compose.yml — весь каталог media
Было:
```yaml
volumes:
- ../../media/media:/srv/publisher/media:ro
```
Стало:
```yaml
volumes:
# ВЕСЬ каталог медиа (не media/media): краулер с 2026-09-12 качает в
# media/<file>, старые лежали в media/media/<file>. Обе раскладки
# доступны в контейнере: /srv/publisher/media/<file> и
# /srv/publisher/media/media/<file>.
- ../../media:/srv/publisher/media:ro
```
### 2. main.py — резолвинг медиа-пути в контейнере
В `publish()` для Telegram-каналов заменить прямую проверку на устойчивый
поиск:
Было:
```python
if req.card.media and Path(req.card.media).exists():
media_msg = telegram.send_media(ch, req.card.media, caption=req.card.text[:1000])
res.media_message_id = media_msg
msg = telegram.send_message(ch, req.card.text)
res.message_id = msg
```
Стало — хелпер `_resolve_media(card.media)`:
```python
def _resolve_media(media: str | None) -> str | None:
"""Находит реальный путь медиа-файла в контейнере (CWD /srv/publisher).
Пробует варианты в порядке приоритета:
1. media как есть -> /srv/publisher/media/<file> (новая раскладка)
2. media/media/<basename> -> старая раскладка (media/media/<file>)
Возвращает существующий путь или None (медиа молча пропускается).
"""
if not media:
return None
base = Path(media).name
# card.media из веба — относительный 'media/<file>' → резолвится от CWD /srv/publisher
cands = [Path(media), Path("media") / base, Path("media/media") / base]
for c in cands:
try:
if c.exists() and c.is_file():
return str(c)
except OSError:
continue
return None
```
Использование:
```python
media_path = _resolve_media(req.card.media)
if media_path:
media_msg = telegram.send_media(ch, media_path, caption=req.card.text[:1000])
res.media_message_id = media_msg
msg = telegram.send_message(ch, req.card.text)
res.message_id = msg
else:
msg = telegram.send_message(ch, req.card.text)
res.message_id = msg
```
Для GoToSocial — тот же `_resolve_media` в `_publish_gotosocial`:
```python
media_ids = []
media_path = _resolve_media(card.media)
if media_path:
media_ids.append(gotosocial.upload_media(media_path))
```
### 3. Что НЕ меняем
- `publisher/card.py` — медиа-нормализация на стороне веба остаётся.
- БД, `media_path` — без миграций.
- `web/app.py`, `web/store.py` — без изменений.
## Порядок деплоя
1. Правки compose + main.py.
2. `docker compose -f services/publisher/docker-compose.yml up -d` (volume
изменился — контейнер пересоздастся).
3. Проверка: `docker exec vesti-publisher python -c "import os; print(os.path.exists('media/linux_education_2772.jpg'))"` → True.
4. e2e: publish поста (текст+медиа) в канал → `media_message_id` задан, затем
удалить тестовые сообщения (delete_message).