feat(ru): full Russia/offline support (#RF)
- Add lib/download_helper.sh: proxy detection, GitHub mirrors, offline cache, tarball fallback - Rewrite install_nfqws.sh: offline bundle support, bol-van/zapret via git clone + tarball + mirror fallback - Rewrite sync_from_upstream.sh: proxy aware, --offline flag, graceful degradation - Add prepare_offline_bundle.sh: create tar.gz with sources + lists + fake bins on machine WITH internet - Add .env.example: GITHUB_PROXY, HTTPS_PROXY configuration - Update install.sh: check GitHub reachability, suggest proxy/offline, --offline flag - Update README: Russia section at top, Offline section, VPN/proxy examples, .env guide
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
#!/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[@]}"
|
||||
}
|
||||
Reference in New Issue
Block a user