Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
52 lines
2.8 KiB
Bash
Executable File
52 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Mirrors the live 2021 site (a Create React App build) into archive/2021/ so it can be served
|
|
# frozen at old.lucaswinther.info (deploy/compose.old-site.yml). Idempotent: files already
|
|
# present are skipped; delete archive/2021 (or pass --force) to refetch. Files that 404 are
|
|
# skipped with a warning; any other failure aborts.
|
|
# Usage: scripts/archive-old-site.sh [--force]
|
|
set -euo pipefail
|
|
base=${OLD_SITE_URL:-https://lucaswinther.info}
|
|
base=${base%/}
|
|
dest="$(cd "$(dirname "$0")/.." && pwd)/archive/2021"
|
|
force=0; [ "${1:-}" = "--force" ] && force=1
|
|
mkdir -p "$dest"
|
|
fetched=0 skipped=0 missing=0
|
|
|
|
# fetch <url-path> [local-path]: path is as in the URL (already encoded); local-path is decoded.
|
|
fetch() {
|
|
local urlpath=$1 local_path=${2:-$(bun -e 'process.stdout.write(decodeURIComponent(process.argv[1]))' "$1")}
|
|
local out="$dest/${local_path#/}" code
|
|
if [ -s "$out" ] && [ "$force" = 0 ]; then skipped=$((skipped + 1)); return 0; fi
|
|
mkdir -p "$(dirname "$out")"
|
|
code=$(curl -sS --fail --location --output "$out.part" --write-out '%{http_code}' "$base$urlpath" 2>/dev/null) || code=$?
|
|
if [ -f "$out.part" ] && [ "$code" = 200 ]; then
|
|
mv "$out.part" "$out"; fetched=$((fetched + 1)); echo "fetched $urlpath"
|
|
else
|
|
rm -f "$out.part"
|
|
# curl --fail exits 22 on HTTP >= 400; the 404 case is the expected one.
|
|
if [ "$code" = 22 ]; then echo "warning: $urlpath not found (404 or other HTTP error), skipped" >&2; missing=$((missing + 1))
|
|
else echo "error: fetching $urlpath failed (curl/http: $code)" >&2; exit 1; fi
|
|
fi
|
|
}
|
|
|
|
for f in index.html info.json favicon.ico logo192.png manifest.json; do
|
|
[ "$f" = index.html ] && fetch / index.html || fetch "/$f"
|
|
done
|
|
|
|
# Static bundles referenced by index.html, plus assets referenced from those bundles.
|
|
refs() { grep -ohE '/static/[A-Za-z0-9_./-]+\.(js|css|woff2?|ttf|svg|png|jpe?g|gif|webp|map)' "$@" 2>/dev/null | sort -u || true; }
|
|
for p in $(refs "$dest/index.html"); do fetch "$p"; done
|
|
for p in $(refs "$dest"/static/css/*.css "$dest"/static/js/*.js); do fetch "$p"; done
|
|
|
|
# Project images: /images/<title>.jpg for every entry in info.json.
|
|
while IFS= read -r title; do
|
|
fetch "/images/$(bun -e 'process.stdout.write(encodeURIComponent(process.argv[1]))' "$title").jpg"
|
|
done < <(bun -e 'for (const p of Object.values(await Bun.file(process.argv[1]).json())) if (p.title) console.log(p.title)' "$dest/info.json")
|
|
|
|
# Reports linked from the academics field.
|
|
while IFS= read -r url; do
|
|
fetch "/documents/${url##*/}"
|
|
done < <(bun -e 'for (const p of Object.values(await Bun.file(process.argv[1]).json())) if (/^https:\/\/lucaswinther\.info\/documents\//.test(p.academics ?? "")) console.log(p.academics)' "$dest/info.json")
|
|
|
|
echo "archive: $fetched fetched, $skipped already present, $missing skipped (not found) -> $dest"
|