From 5c8456de967ef3832223496e8712ab32911a507f Mon Sep 17 00:00:00 2001 From: vrubel Date: Thu, 8 Jan 2026 19:05:41 +0300 Subject: [PATCH] Update .env.example with new admin bot token, modify Docker configuration for Instagram downloader to use host network mode, and enhance YouTube downloader with improved cookie validation and error handling for video downloads. --- .env.example | 2 +- instagram-downloader/docker-compose.yml | 8 +-- youtube-downloader/TROUBLESHOOTING.md | 78 +++++++++++++++++++++++++ youtube-downloader/app.py | 61 ++++++++++++++++++- 4 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 youtube-downloader/TROUBLESHOOTING.md diff --git a/.env.example b/.env.example index 1c33000..18b1f52 100644 --- a/.env.example +++ b/.env.example @@ -19,5 +19,5 @@ TIKTOK_DOWNLOADER_URL=http://localhost:5559 # Admin Bot Configuration -ADMIN_BOT_TOKEN=8575250350:AAHte7xaQFS3FvoKyul9tl5DTFzEkT7ZQTs +ADMIN_BOT_TOKEN=8128669173:AAGEEBuBwDm36jChqcFB31P3_VP4-EzK5aM # Chat ID будет автоматически сохранен при первом использовании админ бота (команда /stat) diff --git a/instagram-downloader/docker-compose.yml b/instagram-downloader/docker-compose.yml index 91c0092..50e9d9b 100644 --- a/instagram-downloader/docker-compose.yml +++ b/instagram-downloader/docker-compose.yml @@ -3,17 +3,11 @@ services: build: . container_name: instagram_downloader_service restart: unless-stopped - ports: - - "5556:5556" volumes: - ./downloads:/app/downloads - ./instagram_cookies.txt:/app/instagram_cookies.txt environment: - INSTAGRAM_COOKIES_FILE=/app/instagram_cookies.txt - PORT=5556 - dns: - - 8.8.8.8 - - 8.8.4.4 - extra_hosts: - - "host.docker.internal:host-gateway" + network_mode: host diff --git a/youtube-downloader/TROUBLESHOOTING.md b/youtube-downloader/TROUBLESHOOTING.md new file mode 100644 index 0000000..fcf60c3 --- /dev/null +++ b/youtube-downloader/TROUBLESHOOTING.md @@ -0,0 +1,78 @@ +# Устранение проблем с YouTube Downloader + +## Ошибка 500 при скачивании + +### Диагностика + +1. **Проверьте статус сервиса:** + ```bash + curl http://localhost:5557/health | python3 -m json.tool + ``` + + Должен вернуть: + ```json + { + "status": "ok", + "service": "youtube-downloader", + "cookies": { + "file": "/app/youtube_cookies.txt", + "status": "valid", + "valid": true + } + } + ``` + +2. **Проверьте логи:** + ```bash + docker logs youtube_downloader_service --tail=50 + ``` + +### Обновление куков + +Если куки устарели (статус `invalid` или `not_found`): + +1. **На сервере, где получаются куки:** + ```bash + cd youtube-downloader + ./get_youtube_cookies.sh + ``` + +2. **Скопируйте файл на продакшн хост:** + ```bash + # Если используется rsync/scp + scp youtube_cookies.txt user@production-host:/path/to/youtube-downloader/ + ``` + +3. **Перезапустите контейнер:** + ```bash + cd youtube-downloader + docker-compose restart + ``` + +### Частые проблемы + +1. **Куки устарели:** + - Обновите куки на сервере с Firefox + - Скопируйте файл на продакшн хост + - Перезапустите контейнер + +2. **Видео недоступно:** + - Проверьте, что видео не удалено + - Проверьте, что видео не приватное + - Для 18+ видео нужны валидные куки + +3. **Проблемы с сетью:** + - Проверьте доступность YouTube + - Проверьте firewall/прокси настройки + +## Проверка работы + +После обновления куков проверьте: +```bash +curl -X POST http://localhost:5557/download/stream \ + -H "Content-Type: application/json" \ + -d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}' \ + --output test_video.mp4 +``` + +Если скачивание успешно - проблема решена. diff --git a/youtube-downloader/app.py b/youtube-downloader/app.py index 964026d..adfa2ba 100644 --- a/youtube-downloader/app.py +++ b/youtube-downloader/app.py @@ -182,8 +182,16 @@ def download_youtube_video(url: str, max_retries: int = 3) -> Path: logger.info(f"YouTube: попытка {attempt + 1}/{max_retries}, стратегия: {strategy['name']}") # Получаем информацию о видео - with yt_dlp.YoutubeDL(strategy['opts'].copy()) as ydl: - info = ydl.extract_info(url, download=False) + try: + with yt_dlp.YoutubeDL(strategy['opts'].copy()) as ydl: + info = ydl.extract_info(url, download=False) + except Exception as info_error: + error_str = str(info_error).lower() + logger.warning(f"YouTube: ошибка при получении информации о видео: {str(info_error)[:200]}") + # Если ошибка связана с куками - пробуем следующую стратегию + if any(keyword in error_str for keyword in ['bot', 'sign in', 'cookies', 'private', 'unavailable']): + continue + raise video_title = info.get('title', 'video') if info else 'video' logger.info(f"YouTube: получена информация о видео: {video_title}") @@ -260,7 +268,28 @@ def download_youtube_video(url: str, max_retries: int = 3) -> Path: @app.route('/health', methods=['GET']) def health(): """Health check endpoint""" - return jsonify({'status': 'ok', 'service': 'youtube-downloader'}), 200 + cookies_file = os.getenv('YOUTUBE_COOKIES_FILE', 'youtube_cookies.txt') + cookies_file_path = Path(cookies_file) + cookies_status = 'not_found' + cookies_valid = False + + if cookies_file_path.exists(): + cookies_status = 'found' + cookies_valid = _is_valid_cookies_file(cookies_file_path) + if cookies_valid: + cookies_status = 'valid' + else: + cookies_status = 'invalid' + + return jsonify({ + 'status': 'ok', + 'service': 'youtube-downloader', + 'cookies': { + 'file': str(cookies_file_path), + 'status': cookies_status, + 'valid': cookies_valid + } + }), 200 @app.route('/download/stream', methods=['POST']) @@ -308,7 +337,10 @@ def download_stream(): except Exception as e: error_str = str(e) + import traceback + error_traceback = traceback.format_exc() logger.error(f"Ошибка при скачивании: {error_str}") + logger.error(f"Traceback: {error_traceback}") # Улучшаем сообщение об ошибке error_msg = error_str @@ -318,6 +350,14 @@ def download_stream(): "💡 Совет: YouTube требует авторизацию для этого видео (18+, приватное и т.д.). " "Попробуйте открыть видео в браузере, авторизоваться, затем повторить запрос." ) + elif 'unable to download' in error_str.lower() or 'http error' in error_str.lower(): + error_msg = ( + f"{error_str}\n\n" + "💡 Возможные причины:\n" + "1. Видео недоступно или удалено\n" + "2. Проблемы с сетью или доступом к YouTube\n" + "3. Куки устарели - обновите файл youtube_cookies.txt" + ) return jsonify({'error': error_msg}), 500 @@ -325,6 +365,21 @@ def download_stream(): if __name__ == '__main__': port = int(os.getenv('PORT', 5000)) # Внутренний порт контейнера host = os.getenv('HOST', '0.0.0.0') + + # Проверяем куки при старте + cookies_file = os.getenv('YOUTUBE_COOKIES_FILE', 'youtube_cookies.txt') + cookies_file_path = Path(cookies_file) + if cookies_file_path.exists(): + cookies_valid = _is_valid_cookies_file(cookies_file_path) + if cookies_valid: + logger.info(f"YouTube: файл куков найден и валиден: {cookies_file_path}") + else: + logger.warning(f"YouTube: файл куков найден, но не валиден: {cookies_file_path}") + logger.warning("YouTube: сервис будет работать, но может потребоваться обновление куков") + else: + logger.warning(f"YouTube: файл куков не найден: {cookies_file_path}") + logger.warning("YouTube: сервис будет работать без куков (может не работать для 18+ и приватных видео)") + logger.info(f"Запуск YouTube Downloader сервиса на {host}:{port}") app.run(host=host, port=port, debug=False)