Revise migrate-seasons.sh: ASTRO_YEAR=2025 only, move not symlink, quarantine bad clips
- Filter to ASTRO_YEAR=2025 (Winter 2025-26 onward); skip Autumn 2025 and earlier - Move files instead of creating symlinks - Quarantine clips matching Day<N>of92 (Spring clips from broken script with wrong 92-day movement total) to quarantine-old-scripts/ for review + deletion - Preserve clips with Dayof92 (no day number, old legacy format) — these are migrated normally since montage-mvt.sh re-adjusts speed regardless - Summary shows delete commands for temp files and quarantine folder https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
This commit is contained in:
+93
-58
@@ -1,24 +1,32 @@
|
||||
#!/bin/bash
|
||||
# migrate-seasons.sh — map old-format seasons clips to the new sky-cam directory
|
||||
# structure using season_info.py to correctly categorize each clip by date.
|
||||
# migrate-seasons.sh — move old-format seasons clips into the new sky-cam
|
||||
# directory structure for astronomical year 2025 only (Winter 2025-26 onward).
|
||||
#
|
||||
# The old system used different movement-boundary and naming conventions;
|
||||
# this script ignores the old labels and re-classifies every clip by its
|
||||
# YYYY-MM-DD filename prefix, placing it exactly where montage-mvt.sh expects.
|
||||
# Earlier years (Autumn 2025 / ASTRO_YEAR=2024 and before) are skipped.
|
||||
#
|
||||
# Two categories of old file:
|
||||
# MIGRATE — clips from the legacy script (filename has "Dayof<N>" with no
|
||||
# preceding digit, e.g. 2026-03-21_Mvt3-Dayof92-final.mp4)
|
||||
# → moved to the correct $MOVIES_DIR/<cam>/2025/<Season>/Mvt<N>/
|
||||
#
|
||||
# QUARANTINE — clips produced by the later broken script that recorded a
|
||||
# specific day number but used the wrong movement total
|
||||
# (filename has Day<digit>of92, e.g. 2026-04-10_Mvt1-Day21of92-final.mp4)
|
||||
# → moved to $MOVIES_DIR/<cam>/2025/quarantine-old-scripts/
|
||||
# Review and delete when you're done: rm -rf <quarantine dir>
|
||||
#
|
||||
# Usage:
|
||||
# ./migrate-seasons.sh [--dry-run] [OLD_ROOT]
|
||||
#
|
||||
# --dry-run print what would happen without creating any links
|
||||
# OLD_ROOT root of old movie archive (default: ~/drives/local-2tb/movies/sunrise)
|
||||
# --dry-run print what would happen without moving anything
|
||||
# OLD_ROOT root of old movie archive
|
||||
# (default: ~/drives/local-2tb/movies/sunrise)
|
||||
#
|
||||
# Output: symlinks in $MOVIES_DIR/<cam>/<ASTRO_YEAR>/<SEASON>/Mvt<N>/
|
||||
#
|
||||
# After running, trigger any completed movement montages manually:
|
||||
# ./montage-mvt.sh 2026-04-19 east # Spring Mvt1 (just completed)
|
||||
# ./montage-mvt.sh 2026-01-18 east # Winter Mvt1
|
||||
# ./montage-mvt.sh 2026-02-16 east # Winter Mvt2
|
||||
# ./montage-mvt.sh 2026-03-19 east # Winter Mvt3
|
||||
# After running, trigger montages for completed movements:
|
||||
# ./montage-mvt.sh 2026-04-19 east # Spring Mvt1 (~20/31 days)
|
||||
# ./montage-mvt.sh 2026-01-18 east # Winter Mvt1 (~18/29 days)
|
||||
# ./montage-mvt.sh 2026-02-16 east # Winter Mvt2 (~24/29 days)
|
||||
# ./montage-mvt.sh 2026-03-19 east # Winter Mvt3 (~20/31 days)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -36,60 +44,76 @@ for arg in "$@"; do
|
||||
done
|
||||
|
||||
CAM="$SUNRISE_CAM"
|
||||
NEW_ROOT="$MOVIES_DIR/$CAM"
|
||||
NEW_ROOT="$MOVIES_DIR/$CAM/2025"
|
||||
QUARANTINE="$NEW_ROOT/quarantine-old-scripts"
|
||||
|
||||
echo "Old archive : $OLD_ROOT"
|
||||
echo "New root : $NEW_ROOT"
|
||||
echo "Camera : $CAM"
|
||||
$DRY_RUN && echo "(DRY RUN — no files will be created)"
|
||||
echo "Old archive : $OLD_ROOT"
|
||||
echo "New root : $NEW_ROOT"
|
||||
echo "Quarantine : $QUARANTINE"
|
||||
echo "Camera : $CAM"
|
||||
$DRY_RUN && echo "(DRY RUN — no files will be moved)"
|
||||
echo ""
|
||||
|
||||
# Counters per movement
|
||||
declare -A LINKED SKIPPED ERRORS
|
||||
declare -A CNT_MIGRATE CNT_QUARANTINE CNT_SKIP
|
||||
|
||||
link_clip() {
|
||||
local src="$1" dst_dir="$2" key="$3"
|
||||
local dst="$dst_dir/$(basename "$src")"
|
||||
do_move() {
|
||||
local src="$1" dst="$2" label="$3" key="$4"
|
||||
local dst_dir
|
||||
dst_dir="$(dirname "$dst")"
|
||||
if [ -e "$dst" ]; then
|
||||
SKIPPED["$key"]=$(( ${SKIPPED["$key"]:-0} + 1 ))
|
||||
printf " EXISTS %-11s %s\n" "" "$(basename "$src")"
|
||||
CNT_SKIP["$key"]=$(( ${CNT_SKIP["$key"]:-0} + 1 ))
|
||||
return
|
||||
fi
|
||||
if $DRY_RUN; then
|
||||
echo " LINK $(basename "$src")"
|
||||
echo " -> $dst"
|
||||
printf " %-10s %s\n %13s-> %s/\n" \
|
||||
"$label" "$(basename "$src")" "" "$dst_dir"
|
||||
else
|
||||
mkdir -p "$dst_dir"
|
||||
ln -sf "$src" "$dst"
|
||||
mv "$src" "$dst"
|
||||
fi
|
||||
LINKED["$key"]=$(( ${LINKED["$key"]:-0} + 1 ))
|
||||
case "$label" in
|
||||
MIGRATE) CNT_MIGRATE["$key"]=$(( ${CNT_MIGRATE["$key"]:-0} + 1 )) ;;
|
||||
QUARANTINE) CNT_QUARANTINE["$key"]=$(( ${CNT_QUARANTINE["$key"]:-0} + 1 )) ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Returns true if filename has the bad pattern: Day<digit(s)>of92
|
||||
# (specific day number + wrong 92-day total from the broken Spring script)
|
||||
is_quarantine_candidate() {
|
||||
[[ "$1" =~ Day[0-9]+of92 ]]
|
||||
}
|
||||
|
||||
# Search the season subdirectories for old *-final.mp4 clips
|
||||
while IFS= read -r -d '' src; do
|
||||
fname="$(basename "$src")"
|
||||
|
||||
# Extract YYYY-MM-DD from filename prefix
|
||||
# Extract YYYY-MM-DD prefix
|
||||
date_str="${fname%%_*}"
|
||||
if [[ ! "$date_str" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
|
||||
echo "SKIP (no date): $fname"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Classify by date using the new system's season_info.py
|
||||
# Classify date using the new system's boundaries
|
||||
if ! info="$(python3 "$SCRIPT_DIR/season_info.py" "$date_str" 2>/dev/null)"; then
|
||||
echo "ERROR: season_info.py failed for $date_str ($fname)"
|
||||
echo "ERROR: season_info.py failed for $date_str — skipping $fname"
|
||||
continue
|
||||
fi
|
||||
eval "$info"
|
||||
# SEASON MVT_NUM DAY_OF_MVT DAYS_IN_MVT MVT_START MVT_END ASTRO_YEAR
|
||||
# Provides: SEASON MVT_NUM DAY_OF_MVT DAYS_IN_MVT ASTRO_YEAR ...
|
||||
|
||||
dst_dir="$NEW_ROOT/$ASTRO_YEAR/$SEASON/Mvt$MVT_NUM"
|
||||
key="${ASTRO_YEAR}/${SEASON}/Mvt${MVT_NUM}"
|
||||
# Skip everything outside the current astronomical year
|
||||
if [ "$ASTRO_YEAR" != "2025" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
$DRY_RUN && printf " %-12s %s Mvt%s Day %s/%s\n" \
|
||||
"$date_str" "$SEASON" "$MVT_NUM" "$DAY_OF_MVT" "$DAYS_IN_MVT"
|
||||
key="${SEASON}/Mvt${MVT_NUM}"
|
||||
|
||||
link_clip "$src" "$dst_dir" "$key"
|
||||
if is_quarantine_candidate "$fname"; then
|
||||
do_move "$src" "$QUARANTINE/$fname" "QUARANTINE" "$key"
|
||||
else
|
||||
do_move "$src" "$NEW_ROOT/$SEASON/Mvt$MVT_NUM/$fname" "MIGRATE" "$key"
|
||||
fi
|
||||
|
||||
done < <(find \
|
||||
"$OLD_ROOT/Spring" \
|
||||
@@ -98,29 +122,40 @@ done < <(find \
|
||||
-name "*-final.mp4" -print0 2>/dev/null | sort -z)
|
||||
|
||||
echo ""
|
||||
echo "=== Summary ==="
|
||||
printf "%-35s %8s %8s\n" "Movement" "Linked" "Skipped"
|
||||
printf "%-35s %8s %8s\n" "--------" "------" "-------"
|
||||
echo "=== Summary (ASTRO_YEAR=2025 only) ==="
|
||||
printf "%-22s %8s %11s %7s\n" "Movement" "Migrated" "Quarantined" "Skipped"
|
||||
printf "%-22s %8s %11s %7s\n" "--------" "--------" "-----------" "-------"
|
||||
|
||||
# Collect all movement keys from both arrays
|
||||
declare -A ALL_KEYS
|
||||
for k in "${!LINKED[@]}" "${!SKIPPED[@]}"; do ALL_KEYS["$k"]=1; done
|
||||
|
||||
for key in $(printf '%s\n' "${!ALL_KEYS[@]}" | sort); do
|
||||
linked=${LINKED["$key"]:-0}
|
||||
skipped=${SKIPPED["$key"]:-0}
|
||||
printf "%-35s %8d %8d\n" "$key" "$linked" "$skipped"
|
||||
for k in "${!CNT_MIGRATE[@]}" "${!CNT_QUARANTINE[@]}" "${!CNT_SKIP[@]}"; do
|
||||
ALL_KEYS["$k"]=1
|
||||
done
|
||||
|
||||
total_m=0 total_q=0
|
||||
for key in $(printf '%s\n' "${!ALL_KEYS[@]}" | sort); do
|
||||
m=${CNT_MIGRATE["$key"]:-0}
|
||||
q=${CNT_QUARANTINE["$key"]:-0}
|
||||
s=${CNT_SKIP["$key"]:-0}
|
||||
printf "%-22s %8d %11d %7d\n" "$key" "$m" "$q" "$s"
|
||||
total_m=$(( total_m + m ))
|
||||
total_q=$(( total_q + q ))
|
||||
done
|
||||
printf "%-22s %8d %11d\n" "TOTAL" "$total_m" "$total_q"
|
||||
|
||||
echo ""
|
||||
if $DRY_RUN; then
|
||||
echo "Re-run without --dry-run to create the symlinks."
|
||||
echo "Then trigger montages for completed movements:"
|
||||
else
|
||||
echo "Symlinks created. Trigger montages for completed movements:"
|
||||
echo "Re-run without --dry-run to move the files."
|
||||
echo ""
|
||||
fi
|
||||
echo " ./montage-mvt.sh 2026-04-19 $CAM # Spring Mvt1 (just completed, 30/31 days)"
|
||||
echo " ./montage-mvt.sh 2026-01-18 $CAM # Winter Mvt1 (~18/29 days)"
|
||||
echo " ./montage-mvt.sh 2026-02-16 $CAM # Winter Mvt2 (~24/29 days)"
|
||||
echo " ./montage-mvt.sh 2026-03-19 $CAM # Winter Mvt3 (~20/31 days)"
|
||||
echo " # Autumn Mvt1/Mvt3 migrated but Mvt2 is absent — year-end join will not fire."
|
||||
|
||||
echo "Next steps:"
|
||||
echo " 1. Build montages for completed movements:"
|
||||
echo " ./montage-mvt.sh 2026-04-19 $CAM # Spring Mvt1"
|
||||
echo " ./montage-mvt.sh 2026-01-18 $CAM # Winter Mvt1"
|
||||
echo " ./montage-mvt.sh 2026-02-16 $CAM # Winter Mvt2"
|
||||
echo " ./montage-mvt.sh 2026-03-19 $CAM # Winter Mvt3"
|
||||
echo " 2. Confirm each montage plays correctly with music."
|
||||
echo " 3. Delete temp files from old archive:"
|
||||
echo " find $OLD_ROOT -name '*-temp.mp4' -delete"
|
||||
echo " 4. Delete quarantined bad clips once confirmed:"
|
||||
echo " rm -rf $QUARANTINE"
|
||||
|
||||
Reference in New Issue
Block a user