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:
2026-05-10 20:11:08 +04:00
parent 1bca276c7f
commit 2a6a358baf
7 changed files with 675 additions and 174 deletions
+154
View File
@@ -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[@]}"
}