fix(downloaders): Deno runtime, свежий yt-dlp, честный health-check, смоук-тест
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 2m36s
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 2m36s
Возрастные YouTube-видео не скачивались: с cookies yt-dlp отбрасывает клиент
android и остаётся web, которому нужно решить n-challenge, а в образе стоял
Node 20 при требуемом минимуме 22 ("JS runtimes: node-20.19.2 (unsupported)").
Ставим Deno — рекомендованный yt-dlp рантайм и один статический бинарник.
Instagram падал с "empty media response" одинаково с cookies и без них —
дело было не в сессии, а в устаревшем экстракторе: слой pip был закеширован
на yt-dlp 2026.06.09. Поднимаем нижнюю границу до 2026.7.4.
/cookies/check помечал проблемой с cookies ЛЮБОЙ сбой, из-за чего на поломку
JS-рантайма прилетел алерт про протухшие cookies и увёл разбор не туда.
Теперь ответ содержит status: ok | cookies_invalid | extraction_failed |
no_cookies, и админ-бот шлёт разные сообщения. Разбор ответа в bot.py
сохраняет совместимость со старым форматом без поля status.
Добавлен smoke_test.py — гоняет реальные ссылки (включая обе регрессии выше)
через запущенные сервисы и печатает таблицу. Запускать после каждой правки.
Схема получения cookies переведена с крона на разовый ручной экспорт:
cookies-cron/ -> cookies/, удалены скрипты с анти-паттерном
`--cookies-from-browser BROWSER --cookies FILE`, который wiki yt-dlp прямо
запрещает и который сам ломал YouTube-сессию ротацией. Ключевые cookies живут
около года, поэтому обновление по расписанию не нужно — триггером служит алерт
health-check. deliver_cookies.sh только доставляет файлы по scp.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
5092d882e5
commit
d597a5e1c5
19 changed files with 373 additions and 733 deletions
|
|
@ -206,12 +206,24 @@ INSTAGRAM_COOKIE_TEST_URL = os.getenv(
|
|||
)
|
||||
|
||||
|
||||
# Маркеры, по которым сбой однозначно относится к cookies/авторизации.
|
||||
# Всё остальное считаем поломкой извлечения (версия yt-dlp, изменения на стороне
|
||||
# Instagram) и про cookies ничего не утверждаем — иначе мониторинг уводит
|
||||
# диагностику не туда: например, "empty media response" воспроизводится и без cookies.
|
||||
INSTAGRAM_COOKIE_INVALID_MARKERS = (
|
||||
'login required',
|
||||
'locked behind the login page',
|
||||
'rate-limit reached',
|
||||
)
|
||||
|
||||
|
||||
@app.route('/cookies/check', methods=['POST'])
|
||||
def cookies_check():
|
||||
"""Проверяет, рабочие ли сейчас Instagram cookies (для проактивного мониторинга)."""
|
||||
cookies_file = Path(os.getenv('INSTAGRAM_COOKIES_FILE', 'instagram_cookies.txt'))
|
||||
if not cookies_file.exists():
|
||||
return jsonify({'cookies_present': False, 'cookies_valid': None,
|
||||
'status': 'no_cookies',
|
||||
'detail': 'cookies file missing'}), 200
|
||||
|
||||
ydl_opts = {
|
||||
|
|
@ -224,10 +236,16 @@ def cookies_check():
|
|||
try:
|
||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||
ydl.extract_info(INSTAGRAM_COOKIE_TEST_URL, download=False)
|
||||
return jsonify({'cookies_present': True, 'cookies_valid': True, 'detail': ''}), 200
|
||||
return jsonify({'cookies_present': True, 'cookies_valid': True,
|
||||
'status': 'ok', 'detail': ''}), 200
|
||||
except Exception as e:
|
||||
return jsonify({'cookies_present': True, 'cookies_valid': False,
|
||||
'detail': str(e)[-500:]}), 200
|
||||
err = str(e)
|
||||
detail = err[-500:]
|
||||
if any(marker in err.lower() for marker in INSTAGRAM_COOKIE_INVALID_MARKERS):
|
||||
return jsonify({'cookies_present': True, 'cookies_valid': False,
|
||||
'status': 'cookies_invalid', 'detail': detail}), 200
|
||||
return jsonify({'cookies_present': True, 'cookies_valid': None,
|
||||
'status': 'extraction_failed', 'detail': detail}), 200
|
||||
|
||||
|
||||
@app.route('/download/stream', methods=['POST'])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue