Files
local-ai/kiwix_update.sh
T
Claude 199fd4069a Add kiwix_update.sh — auto-updater for ZIM files
Compares what's on disk against the mirror, downloads newer versions,
removes old ones, and restarts Kiwix if anything changed. Safe to cron.

https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
2026-03-21 20:05:27 +00:00

131 lines
5.2 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# Kiwix ZIM Auto-Updater
# Checks each ZIM for a newer version on the mirror, downloads it, removes old.
# Safe to run as a cron job — only acts when a newer version exists.
# Usage: bash kiwix_update.sh
# Cron example (monthly): 0 3 1 * * /bin/bash /path/to/kiwix_update.sh
# =============================================================================
KIWIX_DIR="$HOME/docker/ai-stack/kiwix"
MIRROR="https://ftp.fau.de/kiwix/zim"
MIRROR2="https://download.kiwix.org/zim"
LOG="$HOME/docker/ai-stack/logs/kiwix-update.log"
mkdir -p "$KIWIX_DIR" "$(dirname "$LOG")"
G='\033[0;32m'; Y='\033[1;33m'; C='\033[0;36m'; R='\033[0;31m'; N='\033[0m'
ok() { echo -e "${G}[OK]${N} $1" | tee -a "$LOG"; }
inf() { echo -e "${C}[..]${N} $1" | tee -a "$LOG"; }
wrn() { echo -e "${Y}[!!]${N} $1" | tee -a "$LOG"; }
err() { echo -e "${R}[XX]${N} $1" | tee -a "$LOG"; }
echo "" | tee -a "$LOG"
echo "=== Kiwix Update Check: $(date) ===" | tee -a "$LOG"
echo "" | tee -a "$LOG"
# Find latest filename on mirror
latest_zim() {
local base_url="$1"
local pattern="$2"
curl -s "$base_url/" | \
grep -oP "${pattern}_[\d-]+\.zim" | \
sort -u | tail -1
}
# Find what's currently on disk matching a pattern
current_zim() {
local pattern="$1"
ls "$KIWIX_DIR"/${pattern}_*.zim 2>/dev/null | sort | tail -1 | xargs basename 2>/dev/null
}
# Check and update one ZIM
# Usage: check_update "category" "pattern" "description" ["mirror"]
UPDATED=0
check_update() {
local category="$1"
local pattern="$2"
local description="$3"
local mirror="${4:-$MIRROR}"
inf "Checking $description..."
local latest
latest=$(latest_zim "$mirror/$category" "$pattern")
if [[ -z "$latest" ]]; then
wrn "$description: could not find latest on mirror — skipping"
return
fi
local current
current=$(current_zim "$pattern")
if [[ -z "$current" ]]; then
inf "$description: not downloaded yet — skipping (run kiwix_download.sh first)"
return
fi
if [[ "$latest" == "$current" ]]; then
ok "$description: up to date ($current)"
return
fi
echo ""
inf "$description: update available"
inf " Current: $current"
inf " Latest: $latest"
local url="$mirror/$category/$latest"
local dest="$KIWIX_DIR/$latest"
local old="$KIWIX_DIR/$current"
inf " Downloading $latest..."
if wget -q --show-progress -c "$url" -O "$dest" >> "$LOG" 2>&1; then
ok " Download complete — removing old file"
rm -f "$old"
UPDATED=$((UPDATED + 1))
else
err " Download failed — keeping old file"
rm -f "$dest"
fi
echo ""
}
# ── Check each ZIM ─────────────────────────────────────────────────────────
check_update "wikipedia" "wikipedia_en_all_nopic" "Wikipedia"
check_update "wiktionary" "wiktionary_en_all_nopic" "Wiktionary"
check_update "wikiquote" "wikiquote_en_all_nopic" "Wikiquote"
check_update "wikisource" "wikisource_en_all_nopic" "Wikisource"
check_update "wikibooks" "wikibooks_en_all_nopic" "Wikibooks"
check_update "wikivoyage" "wikivoyage_en_all_nopic" "Wikivoyage"
check_update "wikiversity" "wikiversity_en_all_nopic" "Wikiversity"
check_update "wikinews" "wikinews_en_all_nopic" "WikiNews"
check_update "vikidia" "vikidia_en_all_nopic" "Vikidia"
check_update "stack_exchange" "stackoverflow.com_en_all" "Stack Overflow"
check_update "stack_exchange" "askubuntu.com_en_all" "Ask Ubuntu"
check_update "stack_exchange" "superuser.com_en_all" "Super User"
check_update "stack_exchange" "unix.stackexchange.com_en_all" "Unix & Linux SE"
check_update "stack_exchange" "serverfault.com_en_all" "Server Fault"
check_update "other" "archlinux_en_all_maxi" "Arch Wiki"
check_update "ted" "ted_mul_youth" "TED Talks"
check_update "phet" "phet_en_all" "PhET Simulations"
check_update "devdocs" "devdocs_en_zig" "DevDocs"
check_update "freecodecamp" "freecodecamp_en_all" "FreeCodeCamp"
check_update "ifixit" "ifixit_en_all" "iFixit"
check_update "libretexts" "libretexts.org_en_workforce" "LibreTexts"
check_update "gutenberg" "gutenberg_en_all" "Project Gutenberg" "$MIRROR2"
# ── Restart Kiwix if anything changed ─────────────────────────────────────
echo ""
if [[ $UPDATED -gt 0 ]]; then
ok "$UPDATED ZIM(s) updated — restarting Kiwix container"
docker compose -f "$HOME/docker/ai-stack/docker-compose.yml" restart kiwix >> "$LOG" 2>&1 \
&& ok "Kiwix restarted" \
|| wrn "Could not restart Kiwix — do it manually: docker compose restart kiwix"
else
ok "All ZIMs are up to date — no restart needed"
fi
echo ""
echo "=== Update check complete: $(date) ===" | tee -a "$LOG"
echo ""