#!/bin/bash # download_helper.sh - Универсальный загрузчик с fallback для РФ # Поддерживает: HTTPS_PROXY, зеркала GitHub, локальные кэши, raw.githubusercontent.com SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)" CACHE_DIR="$SCRIPT_DIR/.cache" mkdir -p "$CACHE_DIR" # Read proxy from environment or .env file load_proxy() { if [[ -f "$SCRIPT_DIR/.env" ]]; then source "$SCRIPT_DIR/.env" fi # Priority: runtime env > .env > system env if [[ -n "${GITHUB_PROXY:-}" ]]; then HTTPS_PROXY="$GITHUB_PROXY" fi if [[ -n "${HTTPS_PROXY:-}" ]]; then export HTTPS_PROXY="$HTTPS_PROXY" fi if [[ -n "${HTTP_PROXY:-}" ]]; then export HTTP_PROXY="$HTTP_PROXY" fi } # Detect available download tool detect_curl() { local cmd="curl -sfL --max-time 15 --retry 2" if [[ -n "${HTTPS_PROXY:-}" ]]; then cmd="curl -sfL --max-time 15 --retry 2 --proxy '$HTTPS_PROXY'" fi echo "$cmd" } # Try downloading multiple sources, use cache, log failures download_with_fallback() { local output="$1" shift local sources=("$@") local curl_cmd curl_cmd=$(detect_curl) load_proxy # Try local cache first local cache_file="$CACHE_DIR/$(echo "$output" | tr '/\\' '_')" if [[ -f "$cache_file" ]] && [[ -s "$cache_file" ]]; then echo "[OK] Using cached: $(basename "$cache_file")" cp "$cache_file" "$output" return 0 fi # Try each source local success=0 for src in "${sources[@]}"; do echo "[*] Trying: $src" if $curl_cmd "$src" -o "$output.tmp" 2>/dev/null; then if [[ -s "$output.tmp" ]]; then mv "$output.tmp" "$output" cp "$output" "$cache_file" echo "[OK] Downloaded from: $src" success=1 break fi fi rm -f "$output.tmp" done if [[ "$success" -eq 0 ]]; then echo "[FAIL] All download sources exhausted." return 1 fi } # Download GitHub repository as tarball (faster than clone for read-only) clone_repo_fallback() { local repo="$1" # e.g., Flowseal/zapret-discord-youtube local branch="${2:-main}" local output_dir="$3" local curl_cmd curl_cmd=$(detect_curl) # Try git clone with proxy local git_env="" if [[ -n "${HTTPS_PROXY:-}" ]]; then git_env="GIT_SSL_NO_VERIFY=1" fi # Try direct git clone if GIT_SSL_NO_VERIFY=1 git clone --depth=1 --single-branch --branch "$branch" "https://github.com/$repo.git" "$output_dir" 2>/dev/null; then echo "[OK] git clone success" return 0 fi # Try tarball download (often works when git blocked) local tarball="/tmp/repo-$$.tar.gz" echo "[*] Trying tarball download..." if $curl_cmd "https://api.github.com/repos/$repo/tarball/$branch" -o "$tarball" 2>/dev/null; then if [[ -s "$tarball" ]]; then mkdir -p "$output_dir" tar -xzf "$tarball" -C "$output_dir" --strip-components=1 rm -f "$tarball" echo "[OK] Downloaded tarball" return 0 fi fi rm -f "$tarball" # Try ZIP download local zipfile="/tmp/repo-$$.zip" echo "[*] Trying ZIP download..." if $curl_cmd "https://api.github.com/repos/$repo/zipball/$branch" -o "$zipfile" 2>/dev/null; then if [[ -s "$zipfile" ]]; then mkdir -p "$output_dir" unzip -q "$zipfile" -d "/tmp/repo-$$-extract" mv "/tmp/repo-$$-extract"/*/ "$output_dir" 2>/dev/null || true rm -rf "$zipfile" "/tmp/repo-$$-extract" echo "[OK] Downloaded ZIP" return 0 fi fi rm -f "$zipfile" # Try mirror: gitea / gitlab / codeberg local mirrors=( "https://ghproxy.com/https://github.com/$repo.git" "https://hub.fastgit.xyz/$repo.git" ) for mirror in "${mirrors[@]}"; do echo "[*] Trying mirror: $mirror" if GIT_SSL_NO_VERIFY=1 git clone --depth=1 --single-branch --branch "$branch" "$mirror" "$output_dir" 2>/dev/null; then echo "[OK] Clone from mirror" return 0 fi rm -rf "$output_dir" done echo "[FAIL] Cannot clone repository. Check proxy or use prepare_offline_bundle.sh" return 1 } # Generic file download from remote with mirrors download_file_fallback() { local output="$1" local primary_url="$2" local mirrors=( "https://ghproxy.com/$primary_url" "https://raw.fastgit.xyz/${primary_url#https://raw.githubusercontent.com/}" ) local all_sources=("$primary_url" "${mirrors[@]}") download_with_fallback "$output" "${all_sources[@]}" }