diff --git a/youtube-downloader/app.py b/youtube-downloader/app.py index 04b6179..964026d 100644 --- a/youtube-downloader/app.py +++ b/youtube-downloader/app.py @@ -4,6 +4,7 @@ YouTube Video Downloader Service """ import os import logging +import time from pathlib import Path from flask import Flask, request, jsonify from flask_cors import CORS @@ -33,195 +34,227 @@ def _safe_filename(title: str) -> str: def _is_valid_cookies_file(cookies_path: Path) -> bool: - """Проверяет, что файл cookies существует и содержит данные (не только заголовки)""" + """Проверяет, что файл cookies существует и содержит валидные YouTube-куки""" if not cookies_path.exists(): return False try: with open(cookies_path, 'r', encoding='utf-8', errors='ignore') as f: - lines = [line.strip() for line in f.readlines() if line.strip() and not line.strip().startswith('#')] - # Проверяем, что есть хотя бы одна строка с данными cookie - return len(lines) > 0 + content = f.read() + + # Простая проверка: есть ли YouTube-куки в файле + has_youtube_domain = '.youtube.com' in content or 'youtube.com' in content + + if not has_youtube_domain: + logger.warning("YouTube: в файле cookies нет YouTube-куков") + return False + + # Проверяем строки с данными (не комментарии) + lines = [line.strip() for line in content.split('\n') if line.strip() and not line.strip().startswith('#')] + + if len(lines) == 0: + return False + + # Проверяем наличие YouTube-куков и важных параметров + youtube_cookies_count = 0 + important_cookies_count = 0 + current_time = int(time.time()) + + for line in lines: + # Формат Netscape cookie: domain, flag, path, secure, expiration, name, value + # Разделяем по табуляции, но учитываем что значения могут содержать табы + parts = line.split('\t') + if len(parts) >= 7: # Должно быть минимум 7 полей + domain = parts[0].strip() + expiration = parts[4].strip() + cookie_name = parts[5].strip() if len(parts) > 5 else '' + + # Проверяем домен + if '.youtube.com' in domain or domain == 'youtube.com': + youtube_cookies_count += 1 + + # Проверяем срок действия (0 означает сессионный куки, это нормально) + is_valid = True + if expiration != '0': + try: + exp_time = int(expiration) + if exp_time < current_time: + is_valid = False + logger.debug(f"YouTube: просроченный куки {cookie_name} (истек: {exp_time})") + except (ValueError, OverflowError): + pass + + # Проверяем наличие важных куков + if is_valid and any(important in cookie_name for important in ['VISITOR_INFO1_LIVE', '__Secure-3PSID', 'PREF', '__Secure-YNID', 'YSC']): + important_cookies_count += 1 + + if youtube_cookies_count > 0: + if important_cookies_count > 0: + logger.debug(f"YouTube: найдены валидные куки ({youtube_cookies_count} YouTube-куков, {important_cookies_count} важных)") + else: + logger.warning(f"YouTube: найдены YouTube-куки ({youtube_cookies_count}), но нет важных параметров") + return True + else: + logger.warning("YouTube: в файле cookies нет валидных YouTube-куков") + return False + except Exception as e: logger.warning(f"Ошибка при проверке файла cookies: {e}") return False def download_youtube_video(url: str, max_retries: int = 3) -> Path: - """Скачивает видео с YouTube - используем cookies для обхода блокировок""" + """ + Скачивает видео с YouTube с умной стратегией использования куков: + 1. Сначала пробуем БЕЗ куков (работает в большинстве случаев) + 2. Если нужны куки (18+, приватные, проверка на бота) - пробуем файл куков + 3. Если файл не работает - пробуем автоматически из браузера (если доступен) + """ cookies_file = os.getenv('YOUTUBE_COOKIES_FILE', 'youtube_cookies.txt') cookies_file_path = Path(cookies_file) - cookies_valid = _is_valid_cookies_file(cookies_file_path) - if not cookies_valid: - logger.warning(f"YouTube: файл cookies не найден или невалиден ({cookies_file_path}). " - f"Работаем без cookies. Для лучшей работы рекомендуется обновить cookies через скрипт get_youtube_cookies.sh") + # Проверяем наличие валидного файла куков (но не используем сразу) + cookies_file_valid = _is_valid_cookies_file(cookies_file_path) user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' + # Определяем, это Shorts или обычное видео + is_shorts = '/shorts/' in url + player_clients = ['android', 'ios', 'web'] if is_shorts else ['android', 'web'] + + def create_ydl_opts(use_cookies_from_file: bool = False, use_browser_cookies: str = None): + """Создает опции для yt-dlp""" + opts = { + 'quiet': False, + 'no_warnings': False, + 'user_agent': user_agent, + 'socket_timeout': 60, + 'extractor_args': { + 'youtube': { + 'player_client': player_clients, + 'player_skip': ['webpage'], + }, + }, + 'http_headers': { + 'User-Agent': user_agent, + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', + 'Accept-Language': 'en-us,en;q=0.5', + 'Accept-Encoding': 'gzip, deflate', + 'Connection': 'keep-alive', + }, + } + + if use_browser_cookies: + # Автоматически получаем куки из браузера (не нужен файл) + opts['cookiesfrombrowser'] = (use_browser_cookies,) + logger.info(f"YouTube: используем автоматические куки из браузера {use_browser_cookies}") + elif use_cookies_from_file and cookies_file_valid: + opts['cookiefile'] = str(cookies_file_path.absolute()) + logger.info(f"YouTube: используем куки из файла {cookies_file_path.absolute()}") + else: + logger.info(f"YouTube: работаем БЕЗ куков (в большинстве случаев это работает)") + + return opts + + # Стратегии попыток: без куков -> файл куков -> браузер куки + strategies = [ + {'name': 'без куков', 'opts': create_ydl_opts(use_cookies_from_file=False)}, + ] + + if cookies_file_valid: + strategies.append({ + 'name': 'куки из файла', + 'opts': create_ydl_opts(use_cookies_from_file=True) + }) + + # Добавляем стратегии с браузерами (в Docker обычно нет браузеров, но пробуем) + # yt-dlp автоматически обработает ошибку, если браузер недоступен + for browser in ['firefox', 'chrome', 'chromium']: + strategies.append({ + 'name': f'куки из браузера {browser}', + 'opts': create_ydl_opts(use_browser_cookies=browser) + }) + last_error = None for attempt in range(max_retries): - try: - # Определяем, это Shorts или обычное видео - is_shorts = '/shorts/' in url - - # Базовые настройки для получения информации - # Для Shorts используем более надежные клиенты - player_clients = ['android', 'ios', 'web'] if is_shorts else ['android', 'web'] - - ydl_opts_info = { - 'quiet': False, - 'no_warnings': False, - 'user_agent': user_agent, - 'socket_timeout': 60, - 'extractor_args': { - 'youtube': { - 'player_client': player_clients, - 'player_skip': ['webpage'], - }, - }, - 'http_headers': { - 'User-Agent': user_agent, - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', - 'Accept-Language': 'en-us,en;q=0.5', - 'Accept-Encoding': 'gzip, deflate', - 'Connection': 'keep-alive', - }, - } - - # Если есть валидный файл с cookies, используем его - if cookies_valid: - ydl_opts_info['cookiefile'] = str(cookies_file_path.absolute()) - logger.info(f"YouTube: используем cookies из {cookies_file_path.absolute()} (попытка {attempt + 1})") - else: - logger.info(f"YouTube: работаем без cookies (попытка {attempt + 1})") - - # Пробуем получить информацию о видео - info = None + for strategy in strategies: try: - with yt_dlp.YoutubeDL(ydl_opts_info) as ydl: + 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) - except Exception as info_error: - # Если не получилось с cookies, пробуем без них - if cookies_valid and ('cookies' in str(info_error).lower() or 'bot' in str(info_error).lower()): - logger.warning("YouTube: не удалось получить информацию с cookies, пробуем без них") - ydl_opts_info.pop('cookiefile', None) - with yt_dlp.YoutubeDL(ydl_opts_info) as ydl: - info = ydl.extract_info(url, download=False) - cookies_valid = False # Отключаем cookies для скачивания тоже - else: - raise - video_title = info.get('title', 'video') if info else 'video' - logger.info(f"YouTube: получена информация о видео: {video_title}") - - # Настройки для скачивания с более гибким форматом - # Пробуем разные варианты форматов, если один не работает - format_options = [ - 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', # Предпочтительный - 'best[ext=mp4]/best', # Простой fallback - 'bestvideo+bestaudio/best', # Без ограничения по расширению - 'best', # Самый простой вариант - ] - - download_success = False - for format_option in format_options: - ydl_opts_download = { - 'format': format_option, - 'outtmpl': _safe_filename(video_title), - 'quiet': False, - 'no_warnings': False, - 'user_agent': user_agent, - 'socket_timeout': 60, - 'extractor_args': { - 'youtube': { - 'player_client': ['android', 'ios', 'web'] if is_shorts else ['android', 'web'], - 'player_skip': ['webpage'], - }, - }, - 'http_headers': { - 'User-Agent': user_agent, - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', - 'Accept-Language': 'en-us,en;q=0.5', - 'Accept-Encoding': 'gzip, deflate', - 'Connection': 'keep-alive', - }, - } + video_title = info.get('title', 'video') if info else 'video' + logger.info(f"YouTube: получена информация о видео: {video_title}") - # Если есть валидный файл с cookies, используем его для скачивания - use_cookies_this_attempt = cookies_valid - if use_cookies_this_attempt: - ydl_opts_download['cookiefile'] = str(cookies_file_path.absolute()) + # Настройки для скачивания с более гибким форматом + format_options = [ + 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', + 'best[ext=mp4]/best', + 'bestvideo+bestaudio/best', + 'best', + ] - logger.info(f"YouTube: начинаем скачивание (попытка {attempt + 1}/{max_retries}, Shorts: {is_shorts}, формат: {format_option}, cookies: {use_cookies_this_attempt})") - - try: - with yt_dlp.YoutubeDL(ydl_opts_download) as ydl: - ydl.download([url]) - download_success = True - break - except Exception as download_error: - error_str = str(download_error) - # Если ошибка с cookies, пробуем без них - if use_cookies_this_attempt and ('cookies' in error_str.lower() or 'bot' in error_str.lower() or 'sign in' in error_str.lower()): - logger.warning(f"YouTube: ошибка с cookies для формата {format_option}, пробуем без cookies...") - ydl_opts_download.pop('cookiefile', None) - try: - with yt_dlp.YoutubeDL(ydl_opts_download) as ydl: - ydl.download([url]) - download_success = True - cookies_valid = False # Отключаем cookies для следующих попыток - break - except Exception: - # Если и без cookies не получилось, пробуем следующий формат - logger.warning(f"YouTube: не удалось скачать без cookies, пробуем следующий формат...") + # Используем ту же стратегию куков для скачивания + for format_option in format_options: + download_opts = strategy['opts'].copy() + download_opts.update({ + 'format': format_option, + 'outtmpl': _safe_filename(video_title), + }) + + logger.info(f"YouTube: скачивание (формат: {format_option}, стратегия: {strategy['name']})") + + try: + with yt_dlp.YoutubeDL(download_opts) as ydl: + ydl.download([url]) + + # Находим скачанный файл + downloaded_files = list(DOWNLOADS_DIR.glob('*')) + if downloaded_files: + downloaded_files.sort(key=lambda x: x.stat().st_mtime, reverse=True) + logger.info(f"YouTube: успешно скачано стратегией '{strategy['name']}'") + return downloaded_files[0] + else: + raise Exception("Файл не был найден после скачивания") + + except Exception as download_error: + error_str = str(download_error).lower() + + # Если ошибка "bot" или "sign in" - пробуем следующую стратегию + if any(keyword in error_str for keyword in ['bot', 'sign in', 'cookies']): + logger.warning(f"YouTube: ошибка с куками для формата {format_option}, пробуем следующую стратегию...") + break # Переходим к следующей стратегии + + # Если ошибка формата - пробуем следующий формат + if 'format is not available' in error_str or 'requested format' in error_str: + logger.warning(f"YouTube: формат {format_option} недоступен, пробуем следующий...") continue - # Если ошибка формата, пробуем следующий формат - elif 'format is not available' in error_str.lower() or 'requested format' in error_str.lower(): - logger.warning(f"YouTube: формат {format_option} недоступен, пробуем следующий...") + + # Другая ошибка - логируем и пробуем следующий формат + logger.warning(f"YouTube: ошибка формата {format_option}: {str(download_error)[:100]}") continue - else: - # Другая ошибка - пробуем следующий формат - logger.warning(f"YouTube: ошибка при скачивании формата {format_option}: {error_str[:100]}, пробуем следующий...") - continue - - if not download_success: - raise Exception("Не удалось скачать видео ни с одним из доступных форматов") - - # Находим скачанный файл - downloaded_files = list(DOWNLOADS_DIR.glob('*')) - if downloaded_files: - downloaded_files.sort(key=lambda x: x.stat().st_mtime, reverse=True) - return downloaded_files[0] - else: - raise Exception("Файл не был найден после скачивания") - except Exception as e: - last_error = e - error_str = str(e) - logger.warning(f"YouTube: попытка {attempt + 1}/{max_retries} не удалась: {error_str}") - - # Если ошибка связана с форматом, пробуем другие настройки - if 'format is not available' in error_str.lower() or 'requested format' in error_str.lower(): - logger.warning("YouTube: проблема с форматом, пробуем другие настройки на следующей попытке") - # На следующей попытке попробуем другие player_client - if attempt < max_retries - 1: - import time - time.sleep((attempt + 1) * 2) + # Если все форматы не подошли для этой стратегии, пробуем следующую + continue + + except Exception as e: + error_str = str(e).lower() + logger.warning(f"YouTube: стратегия '{strategy['name']}' не сработала: {str(e)[:100]}") + + # Если ошибка "bot" или "sign in" - пробуем следующую стратегию + if any(keyword in error_str for keyword in ['bot', 'sign in', 'cookies']): continue - - # Если ошибка связана с cookies и они были использованы, попробуем без cookies на следующей попытке - if 'cookies' in error_str.lower() or 'bot' in error_str.lower() or 'sign in' in error_str.lower(): - if cookies_valid and attempt == 0: - logger.warning("YouTube: ошибка с cookies, попробуем обновить cookies или работать без них") - # На следующей попытке попробуем без cookies - cookies_valid = False - - if attempt < max_retries - 1: - import time - time.sleep((attempt + 1) * 2) + + # Для других ошибок - пробуем следующую стратегию или следующую попытку + last_error = e + + # Если все стратегии не сработали, делаем паузу перед следующей попыткой + if attempt < max_retries - 1: + time.sleep((attempt + 1) * 2) - raise last_error or Exception("Неизвестная ошибка при скачивании с YouTube") + raise last_error or Exception("Не удалось скачать видео ни с одной стратегией") @app.route('/health', methods=['GET']) @@ -277,17 +310,14 @@ def download_stream(): error_str = str(e) logger.error(f"Ошибка при скачивании: {error_str}") - # Улучшаем сообщение об ошибке, если проблема с cookies + # Улучшаем сообщение об ошибке + error_msg = error_str if 'cookies' in error_str.lower() or 'bot' in error_str.lower() or 'sign in' in error_str.lower(): error_msg = ( f"{error_str}\n\n" - "💡 Совет: Cookies устарели или недействительны. " - "Обновите cookies, запустив скрипт:\n" - " ./youtube-downloader/get_youtube_cookies.sh\n" - "Затем перезапустите сервис." + "💡 Совет: YouTube требует авторизацию для этого видео (18+, приватное и т.д.). " + "Попробуйте открыть видео в браузере, авторизоваться, затем повторить запрос." ) - else: - error_msg = error_str return jsonify({'error': error_msg}), 500 diff --git a/youtube-downloader/get_youtube_cookies.sh b/youtube-downloader/get_youtube_cookies.sh index 8859b0f..43346c0 100755 --- a/youtube-downloader/get_youtube_cookies.sh +++ b/youtube-downloader/get_youtube_cookies.sh @@ -1,106 +1,218 @@ #!/bin/bash # Скрипт для получения cookies YouTube через yt-dlp из Firefox +# Предназначен для запуска на Ubuntu 24.04 с авторизованным Firefox +# Результат копируется через cron на серверы со службами скачивания SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" COOKIES_FILE="$SCRIPT_DIR/youtube_cookies.txt" BROWSER="firefox" +TEMP_FILE="${COOKIES_FILE}.tmp" -# Если запущено с sudo, используем HOME реального пользователя +# Определяем HOME пользователя (работает для sudo и обычного запуска) if [ -n "$SUDO_USER" ]; then REAL_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6) export HOME="$REAL_HOME" - echo "⚠️ Обнаружен sudo, использую домашнюю директорию пользователя: $HOME" +elif [ -z "$HOME" ] || [ "$HOME" = "/root" ]; then + # Если HOME не установлен или это root, пытаемся найти реального пользователя + REAL_USER=$(whoami) + if [ "$REAL_USER" != "root" ]; then + export HOME=$(getent passwd "$REAL_USER" | cut -d: -f6) + fi fi -echo "Получение cookies YouTube из Firefox..." -echo "Файл cookies будет сохранен в: $COOKIES_FILE" +# Проверка для cron: если запущен без терминала, меньше вывода +if [ -t 0 ]; then + VERBOSE=1 +else + VERBOSE=0 +fi + +if [ "$VERBOSE" = "1" ]; then + echo "Получение cookies YouTube из Firefox..." + echo "Файл cookies будет сохранен в: $COOKIES_FILE" +fi # Проверяем наличие yt-dlp if ! command -v yt-dlp &> /dev/null; then - echo "" - echo "❌ yt-dlp не найден в системе" - echo "" - echo "Установите yt-dlp одним из способов:" - echo "" - echo "1. Через pacman (Arch Linux):" - echo " sudo pacman -S yt-dlp" - echo "" - echo "2. Через pip:" - echo " pip install yt-dlp" - echo " или" - echo " pip3 install yt-dlp" - echo "" - echo "3. Через pipx (рекомендуется):" - echo " pipx install yt-dlp" - echo "" + echo "ERROR: yt-dlp не найден в системе" >&2 + echo "Установите: sudo apt install yt-dlp (Ubuntu) или pip install yt-dlp" >&2 exit 1 fi -echo "Получаю cookies..." +if [ "$VERBOSE" = "1" ]; then + echo "Получаю cookies..." +fi -# Используем простой способ: извлекаем cookies из браузера и сохраняем в файл -# Используем конкретное короткое видео (не плейлист, не главную страницу) -# Таймаут 10 секунд +# Удаляем старый временный файл +rm -f "$TEMP_FILE" + +# Извлекаем cookies из браузера и сохраняем во временный файл +# Используем главную страницу YouTube для получения всех необходимых куков # --no-download - не скачивать видео # --skip-download - пропустить скачивание -# --flat-playlist - не извлекать информацию о видео в плейлистах -# Перенаправляем весь вывод, чтобы не видеть процесс скачивания -timeout 10 yt-dlp \ - --cookies-from-browser "$BROWSER" \ - --cookies "$COOKIES_FILE" \ - --no-download \ - --skip-download \ - --flat-playlist \ - --quiet \ - "https://www.youtube.com/watch?v=jNQXAC9IVRw" > /dev/null 2>&1 || true +if [ "$VERBOSE" = "1" ]; then + yt-dlp \ + --cookies-from-browser "$BROWSER" \ + --cookies "$TEMP_FILE" \ + --no-download \ + --skip-download \ + "https://www.youtube.com" > /dev/null 2>&1 +else + yt-dlp \ + --cookies-from-browser "$BROWSER" \ + --cookies "$TEMP_FILE" \ + --no-download \ + --skip-download \ + --quiet \ + "https://www.youtube.com" > /dev/null 2>&1 +fi EXIT_CODE=$? -# Не важно, какой код возврата - главное проверить, создался ли файл cookies -# yt-dlp может вернуть ошибку, но cookies все равно сохранить - -if [ -f "$COOKIES_FILE" ]; then - # Проверяем, что файл содержит данные (не только заголовки) - COOKIE_LINES=$(grep -v '^#' "$COOKIES_FILE" | grep -v '^$' | wc -l) +# Функция проверки валидности куков +check_cookies() { + local file="$1" + local current_time=$(date +%s) - if [ "$COOKIE_LINES" -gt 0 ]; then + # Проверяем существование файла + if [ ! -f "$file" ]; then + return 1 + fi + + # Проверяем, что файл содержит данные (не только заголовки) + local cookie_lines=$(grep -v '^#' "$file" | grep -v '^$' | wc -l) + if [ "$cookie_lines" -eq 0 ]; then + return 1 + fi + + # Проверяем наличие YouTube-куков + local youtube_cookies=$(grep -E '\.youtube\.com|youtube\.com' "$file" | grep -v '^#' | wc -l) + if [ "$youtube_cookies" -eq 0 ]; then + return 1 + fi + + # Проверяем срок действия куков (должен быть хотя бы один не просроченный) + local valid_cookies=0 + local expired_cookies=0 + + # Используем awk для более надежного парсинга + while IFS=$'\t' read -r domain flag path secure expiration name value; do + # Пропускаем комментарии и пустые строки + [[ "$domain" =~ ^#.*$ ]] && continue + [[ -z "$domain" ]] && continue + + # Проверяем только YouTube-куки + if [[ "$domain" =~ youtube\.com ]]; then + if [ "$expiration" = "0" ] || [ -z "$expiration" ]; then + # Сессионные куки (expiration=0) считаем валидными + valid_cookies=$((valid_cookies + 1)) + else + # Проверяем срок действия + if [ "$expiration" -gt "$current_time" ] 2>/dev/null; then + valid_cookies=$((valid_cookies + 1)) + else + expired_cookies=$((expired_cookies + 1)) + fi + fi + fi + done < "$file" + + # Должен быть хотя бы один валидный YouTube-куки + if [ "$valid_cookies" -eq 0 ]; then + return 1 + fi + + # Если есть просроченные куки, выводим предупреждение, но не считаем критичным + if [ "$expired_cookies" -gt 0 ] && [ "$VERBOSE" = "1" ]; then + echo "⚠️ Предупреждение: найдено $expired_cookies просроченных YouTube-куков" >&2 + fi + + return 0 +} + +# Проверяем результат +if [ -f "$TEMP_FILE" ] && check_cookies "$TEMP_FILE"; then + # Куки валидны, переносим во временный файл в финальный + mv "$TEMP_FILE" "$COOKIES_FILE" + + # Собираем статистику для вывода + COOKIE_LINES=$(grep -v '^#' "$COOKIES_FILE" | grep -v '^$' | wc -l) + YOUTUBE_COOKIES=$(grep -E '\.youtube\.com|youtube\.com' "$COOKIES_FILE" | grep -v '^#' | wc -l) + IMPORTANT_COOKIES=$(grep -E 'VISITOR_INFO1_LIVE|__Secure-3PSID|PREF|__Secure-YNID' "$COOKIES_FILE" | grep -v '^#' | wc -l) + + if [ "$VERBOSE" = "1" ]; then echo "" echo "✅ Cookies успешно сохранены в $COOKIES_FILE" - echo " Найдено строк с cookies: $COOKIE_LINES" + echo " Всего строк с cookies: $COOKIE_LINES" + echo " YouTube-куков: $YOUTUBE_COOKIES" + echo " Важных куков: $IMPORTANT_COOKIES" echo "" - echo "Теперь перезапустите youtube-downloader:" - echo " docker compose -f youtube-downloader/docker-compose.yml restart" - echo "" - echo "Или перезапустите все сервисы:" - echo " ./stop_all.sh && ./start_all.sh" + echo "Файл готов к копированию на серверы через cron" else - echo "" - echo "❌ Ошибка: файл cookies создан, но не содержит данных" - rm -f "$COOKIES_FILE" - exit 1 + # Минимальный вывод для cron (можно логировать в файл) + echo "$(date '+%Y-%m-%d %H:%M:%S') - YouTube cookies updated: $YOUTUBE_COOKIES cookies, $IMPORTANT_COOKIES important" fi + + exit 0 else - echo "" - echo "❌ Ошибка: файл cookies не был создан" - echo "" - echo "Возможные причины:" - echo "1. Firefox не найден или недоступен" - echo "2. Проблемы с правами доступа к файлу cookies браузера" - echo "3. Cookies не найдены в браузере" - echo "" - echo "Проверка:" - if [ -n "$SUDO_USER" ]; then - REAL_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6) - FIREFOX_DIR="$REAL_HOME/.mozilla/firefox" + # Очищаем временный файл при ошибке + rm -f "$TEMP_FILE" + + if [ "$VERBOSE" = "1" ]; then + echo "" + echo "❌ Ошибка: не удалось получить валидные YouTube-куки" + echo "" + echo "Возможные причины:" + echo "1. В Firefox нет куков для YouTube" + echo "2. Откройте YouTube в Firefox и войдите в аккаунт" + echo "3. Все куки просрочены - обновите их в браузере" + echo "" else - FIREFOX_DIR="$HOME/.mozilla/firefox" + echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: Failed to get valid YouTube cookies" >&2 fi - if [ -d "$FIREFOX_DIR" ]; then - echo " ✓ Директория Firefox найдена: $FIREFOX_DIR" + + if [ ! -f "$COOKIES_FILE" ]; then + # Если файла не было, это критичная ошибка + exit 1 else - echo " ✗ Директория Firefox не найдена: $FIREFOX_DIR" - echo " Попробуйте запустить скрипт БЕЗ sudo: ./get_youtube_cookies.sh" + # Если файл был, просто оставляем старый (лучше работать со старыми куками чем без них) + if [ "$VERBOSE" = "1" ]; then + echo "⚠️ Оставляю существующий файл cookies без изменений" + fi + exit 0 + fi +fi + +if [ ! -f "$TEMP_FILE" ] && [ ! -f "$COOKIES_FILE" ]; then + if [ "$VERBOSE" = "1" ]; then + echo "" + echo "❌ Ошибка: файл cookies не был создан" + echo "" + echo "Возможные причины:" + echo "1. Firefox не найден или недоступен" + echo "2. Проблемы с правами доступа к файлу cookies браузера" + echo "3. Cookies не найдены в браузере" + echo "" + echo "Проверка:" + FIREFOX_DIR="$HOME/.mozilla/firefox" + if [ -d "$FIREFOX_DIR" ]; then + echo " ✓ Директория Firefox найдена: $FIREFOX_DIR" + else + echo " ✗ Директория Firefox не найдена: $FIREFOX_DIR" + echo " Убедитесь что Firefox установлен и вы авторизованы на YouTube" + fi + else + echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: Cookies file was not created" >&2 + fi + + # Если был старый файл, оставляем его + if [ -f "$COOKIES_FILE" ]; then + if [ "$VERBOSE" = "1" ]; then + echo "⚠️ Оставляю существующий файл cookies без изменений" + fi + exit 0 + else + exit 1 fi - exit 1 fi