Files

3.5 KiB
Raw Permalink Blame History

Дизайн

1. docker-compose.yml — весь каталог media

Было:

    volumes:
      - ../../media/media:/srv/publisher/media:ro

Стало:

    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-каналов заменить прямую проверку на устойчивый поиск:

Было:

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):

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

Использование:

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:

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).