Proto-to-Prod
This commit is contained in:
parent
82a8a6a21a
commit
5cabc31d37
63 changed files with 3783 additions and 602 deletions
49
bin/build-artists
Executable file
49
bin/build-artists
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
MANIFEST="${MANIFEST:-$REPO_ROOT/content/audio.yaml}"
|
||||
OUT="${OUT:-$REPO_ROOT/web/src/lib/artists.json}"
|
||||
|
||||
for tool in yq jq; do
|
||||
if ! command -v "$tool" >/dev/null; then
|
||||
echo "error: $tool not in PATH (try: nix develop)" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
yq -o=json '.' "$MANIFEST" | jq '
|
||||
def render_artist:
|
||||
. as $a |
|
||||
{
|
||||
id: $a.id,
|
||||
name: $a.name,
|
||||
slug: $a.slug,
|
||||
description: ($a.description // "" | rtrimstr("\n")),
|
||||
images: [
|
||||
($a.images // []) | to_entries[] |
|
||||
("/images/" + $a.slug + "-" + ((.key + 1) | tostring) + ".webp")
|
||||
],
|
||||
shows: [
|
||||
$a.shows[] | . as $s | {
|
||||
caption: $s.caption,
|
||||
slug: $s.slug,
|
||||
sides: [
|
||||
$s.sides[] | {
|
||||
id: .id,
|
||||
label: .label,
|
||||
audio: ("/audio/" + $a.slug + "-" + $s.slug + "-" + .id + ".opus")
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
{
|
||||
exhibit: .exhibit,
|
||||
artists: [ .artists[] | render_artist ]
|
||||
}
|
||||
' > "$OUT.tmp"
|
||||
|
||||
mv "$OUT.tmp" "$OUT"
|
||||
echo "wrote $OUT ($(jq '.artists | length' "$OUT") artists)"
|
||||
95
bin/build-audio
Executable file
95
bin/build-audio
Executable file
|
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/env bash
|
||||
# Sides are encoded individually — no concatenation. Idempotent: a side is
|
||||
# skipped if its output is newer than its source.
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
MANIFEST="${MANIFEST:-$REPO_ROOT/content/audio.yaml}"
|
||||
RAW_DIR="${RAW_DIR:-$REPO_ROOT/content/audio}"
|
||||
OUT_DIR="${OUT_DIR:-$REPO_ROOT/web/static/audio}"
|
||||
|
||||
for tool in yq ffmpeg; do
|
||||
if ! command -v "$tool" >/dev/null; then
|
||||
echo "error: $tool not in PATH (try: nix develop)" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ! -f "$MANIFEST" ]]; then
|
||||
echo "error: manifest not found: $MANIFEST" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
DEFAULT_BITRATE=$(yq -r '.defaults.bitrate // "64k"' "$MANIFEST")
|
||||
DEFAULT_CHANNELS=$(yq -r '.defaults.channels // "2"' "$MANIFEST")
|
||||
DEFAULT_RATE=$(yq -r '.defaults.sample_rate // "48000"' "$MANIFEST")
|
||||
|
||||
encoded=0
|
||||
skipped=0
|
||||
missing=0
|
||||
failed=0
|
||||
|
||||
NUM_ARTISTS=$(yq '.artists | length' "$MANIFEST")
|
||||
|
||||
for ((a=0; a<NUM_ARTISTS; a++)); do
|
||||
ARTIST_SLUG=$(yq -r ".artists[$a].slug" "$MANIFEST")
|
||||
NUM_SHOWS=$(yq ".artists[$a].shows | length" "$MANIFEST")
|
||||
|
||||
for ((s=0; s<NUM_SHOWS; s++)); do
|
||||
SHOW_SLUG=$(yq -r ".artists[$a].shows[$s].slug" "$MANIFEST")
|
||||
NUM_SIDES=$(yq ".artists[$a].shows[$s].sides | length" "$MANIFEST")
|
||||
|
||||
for ((sd=0; sd<NUM_SIDES; sd++)); do
|
||||
SIDE_ID=$(yq -r ".artists[$a].shows[$s].sides[$sd].id" "$MANIFEST")
|
||||
SOURCE=$(yq -r ".artists[$a].shows[$s].sides[$sd].source" "$MANIFEST")
|
||||
BITRATE=$(yq -r ".artists[$a].shows[$s].sides[$sd].bitrate // \"$DEFAULT_BITRATE\"" "$MANIFEST")
|
||||
CHANNELS=$(yq -r ".artists[$a].shows[$s].sides[$sd].channels // \"$DEFAULT_CHANNELS\"" "$MANIFEST")
|
||||
RATE=$(yq -r ".artists[$a].shows[$s].sides[$sd].sample_rate // \"$DEFAULT_RATE\"" "$MANIFEST")
|
||||
|
||||
SRC_PATH="$RAW_DIR/$SOURCE"
|
||||
OUT_NAME="${ARTIST_SLUG}-${SHOW_SLUG}-${SIDE_ID}.opus"
|
||||
OUT_PATH="$OUT_DIR/$OUT_NAME"
|
||||
|
||||
if [[ ! -f "$SRC_PATH" ]]; then
|
||||
printf ' %-50s SKIP (source not present)\n' "$OUT_NAME"
|
||||
missing=$((missing + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ -f "$OUT_PATH" ]]; then
|
||||
src_mt=$(stat -c %Y "$SRC_PATH")
|
||||
out_mt=$(stat -c %Y "$OUT_PATH")
|
||||
if (( out_mt > src_mt )); then
|
||||
printf ' %-50s up to date\n' "$OUT_NAME"
|
||||
skipped=$((skipped + 1))
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
printf ' %-50s encoding ...\n' "$OUT_NAME"
|
||||
|
||||
if ffmpeg \
|
||||
-i "$SRC_PATH" \
|
||||
-c:a libopus -b:a "$BITRATE" -ac "$CHANNELS" -ar "$RATE" \
|
||||
-application audio -vbr on -compression_level 10 \
|
||||
-y "$OUT_PATH" \
|
||||
-hide_banner -loglevel warning -nostdin </dev/null; then
|
||||
size=$(du -h "$OUT_PATH" | cut -f1)
|
||||
printf ' %-50s done (%s)\n' "$OUT_NAME" "$size"
|
||||
encoded=$((encoded + 1))
|
||||
else
|
||||
printf ' %-50s FAILED\n' "$OUT_NAME" >&2
|
||||
failed=$((failed + 1))
|
||||
fi
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
printf '\n%d encoded · %d up-to-date · %d missing sources · %d failed\n' \
|
||||
"$encoded" "$skipped" "$missing" "$failed"
|
||||
|
||||
if (( failed > 0 )); then
|
||||
exit 1
|
||||
fi
|
||||
76
bin/build-images
Executable file
76
bin/build-images
Executable file
|
|
@ -0,0 +1,76 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
MANIFEST="${MANIFEST:-$REPO_ROOT/content/audio.yaml}"
|
||||
SRC_DIR="${SRC_DIR:-$REPO_ROOT/content/images}"
|
||||
OUT_DIR="${OUT_DIR:-$REPO_ROOT/web/static/images}"
|
||||
MAX_SIZE="${MAX_SIZE:-1200}"
|
||||
QUALITY="${QUALITY:-80}"
|
||||
|
||||
for tool in yq magick; do
|
||||
if ! command -v "$tool" >/dev/null; then
|
||||
echo "error: $tool not in PATH (try: nix develop)" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
encoded=0
|
||||
skipped=0
|
||||
missing=0
|
||||
failed=0
|
||||
|
||||
NUM_ARTISTS=$(yq '.artists | length' "$MANIFEST")
|
||||
|
||||
for ((a=0; a<NUM_ARTISTS; a++)); do
|
||||
ARTIST_SLUG=$(yq -r ".artists[$a].slug" "$MANIFEST")
|
||||
NUM_IMAGES=$(yq ".artists[$a].images | length // 0" "$MANIFEST")
|
||||
|
||||
for ((i=0; i<NUM_IMAGES; i++)); do
|
||||
SRC_NAME=$(yq -r ".artists[$a].images[$i]" "$MANIFEST")
|
||||
SRC_PATH="$SRC_DIR/$SRC_NAME"
|
||||
OUT_NAME="${ARTIST_SLUG}-$((i + 1)).webp"
|
||||
OUT_PATH="$OUT_DIR/$OUT_NAME"
|
||||
|
||||
if [[ ! -f "$SRC_PATH" ]]; then
|
||||
printf ' %-45s SKIP (source not found)\n' "$OUT_NAME"
|
||||
missing=$((missing + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ -f "$OUT_PATH" ]]; then
|
||||
src_mt=$(stat -c %Y "$SRC_PATH")
|
||||
out_mt=$(stat -c %Y "$OUT_PATH")
|
||||
if (( out_mt > src_mt )); then
|
||||
printf ' %-45s up to date\n' "$OUT_NAME"
|
||||
skipped=$((skipped + 1))
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
printf ' %-45s converting ...\n' "$OUT_NAME"
|
||||
|
||||
if magick "$SRC_PATH" \
|
||||
-auto-orient \
|
||||
-strip \
|
||||
-resize "${MAX_SIZE}x${MAX_SIZE}>" \
|
||||
-quality "$QUALITY" \
|
||||
"$OUT_PATH"; then
|
||||
size=$(du -h "$OUT_PATH" | cut -f1)
|
||||
printf ' %-45s done (%s)\n' "$OUT_NAME" "$size"
|
||||
encoded=$((encoded + 1))
|
||||
else
|
||||
printf ' %-45s FAILED\n' "$OUT_NAME" >&2
|
||||
failed=$((failed + 1))
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
printf '\n%d converted · %d up-to-date · %d missing sources · %d failed\n' \
|
||||
"$encoded" "$skipped" "$missing" "$failed"
|
||||
|
||||
if (( failed > 0 )); then
|
||||
exit 1
|
||||
fi
|
||||
39
bin/pull-audio
Executable file
39
bin/pull-audio
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copy concert WAV files from the curator's Dropbox folder into content/audio/,
|
||||
# stripping the ` Brianna` suffix that the source files carry.
|
||||
# Idempotent: skips files that already exist at the destination.
|
||||
set -euo pipefail
|
||||
|
||||
SRC_DIR="${SRC_DIR:-$HOME/Dropbox/File requests/Mill Run Audio}"
|
||||
DEST_DIR="${DEST_DIR:-$(cd "$(dirname "$0")/.." && pwd)/content/audio}"
|
||||
|
||||
if [[ ! -d "$SRC_DIR" ]]; then
|
||||
echo "error: source directory not found: $SRC_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$DEST_DIR"
|
||||
|
||||
count=0
|
||||
copied=0
|
||||
skipped=0
|
||||
|
||||
shopt -s nullglob
|
||||
for src in "$SRC_DIR"/*.wav; do
|
||||
count=$((count + 1))
|
||||
name=$(basename "$src")
|
||||
# Strip trailing " Brianna.wav" → ".wav"
|
||||
dest_name="${name% Brianna.wav}.wav"
|
||||
dest="$DEST_DIR/$dest_name"
|
||||
|
||||
if [[ -f "$dest" ]] && [[ $(stat -c %s "$src") -eq $(stat -c %s "$dest") ]]; then
|
||||
skipped=$((skipped + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
printf ' [%2d] %s\n' "$count" "$dest_name"
|
||||
cp -- "$src" "$dest"
|
||||
copied=$((copied + 1))
|
||||
done
|
||||
|
||||
printf '\n%d total · %d copied · %d skipped (already present)\n' "$count" "$copied" "$skipped"
|
||||
Loading…
Add table
Add a link
Reference in a new issue