#!/bin/bash # reorg-backup.sh — reorganize backup season files into astro-YEAR folders. # # Moves files from: # //Season/MvtN/YYYY-MM-DD_* # Into: # /astro-YEAR//Season/MvtN/YYYY-MM-DD_* # # Uses season_info.py to determine the correct ASTRO_YEAR from each file's date. # NEVER deletes anything — only moves files. # # Usage: # ./reorg-backup.sh [--dry-run] # # Example: # ./reorg-backup.sh ~/drives/data2-main --dry-run # ./reorg-backup.sh ~/drives/data2-main set -euo pipefail SCRIPT_DIR="$(dirname "$(realpath "$0")")" source "$SCRIPT_DIR/sky-cam.conf" export TIMEZONE BACKUP_ROOT="" DRY_RUN=false while [[ $# -gt 0 ]]; do case "$1" in --dry-run) DRY_RUN=true; shift ;; -*) echo "Unknown option: $1"; exit 1 ;; *) BACKUP_ROOT="$1"; shift ;; esac done if [ -z "$BACKUP_ROOT" ]; then echo "Usage: $0 [--dry-run]" echo " e.g. $0 ~/drives/data2-main --dry-run" exit 1 fi BACKUP_ROOT="$(realpath "$BACKUP_ROOT")" $DRY_RUN && echo "DRY RUN — no files will be moved" echo "Backup root: $BACKUP_ROOT" echo "" moved=0 skipped=0 errors=0 # Find all mp4 files in Season/MvtN directories (not already in astro-* dirs) while IFS= read -r -d '' src_file; do filename="$(basename "$src_file")" # Extract date: handles YYYY-MM-DD_ (underscore) prefix date_str="${filename%%_*}" if ! [[ "$date_str" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then echo "SKIP (unrecognised filename): $src_file" (( skipped++ )) || true continue fi # Get ASTRO_YEAR for this date _info="$(python3 "$SCRIPT_DIR/season_info.py" "$date_str" 2>/dev/null)" || { echo "SKIP (season_info.py failed for $date_str): $filename" (( skipped++ )) || true continue } eval "$_info" # Reconstruct target path: # /astro-YEAR///Mvt/ # Source path is: # ///Mvt/ rel_path="${src_file#$BACKUP_ROOT/}" # e.g. north/Winter/Mvt1/2025-01-06_... cam_and_below="${rel_path#*/}" # e.g. Winter/Mvt1/2025-01-06_... (strip cam) cam_name="${rel_path%%/*}" # e.g. north dest_dir="$BACKUP_ROOT/astro-${ASTRO_YEAR}/$cam_name/$(dirname "$cam_and_below")" dest_file="$dest_dir/$filename" if [ "$src_file" = "$dest_file" ]; then (( skipped++ )) || true continue fi if [ -f "$dest_file" ]; then echo "EXISTS — skip: astro-${ASTRO_YEAR}/$cam_name/$cam_and_below" (( skipped++ )) || true continue fi echo "MOVE astro-${ASTRO_YEAR}/$cam_name/$cam_and_below" if ! $DRY_RUN; then mkdir -p "$dest_dir" if mv "$src_file" "$dest_file"; then (( moved++ )) || true else echo " ERROR: mv failed" (( errors++ )) || true fi else (( moved++ )) || true fi done < <(find "$BACKUP_ROOT" \ -not -path "*/astro-*" \ -regextype posix-extended \ -regex ".*/[A-Z][a-z]+/Mvt[0-9]+/[0-9]{4}-[0-9]{2}-[0-9]{2}_.*\.mp4" \ -print0 | sort -z) echo "" echo "────────────────────────────────────────" echo "Moved: $moved Skipped: $skipped Errors: $errors" $DRY_RUN && echo "(dry run — re-run without --dry-run to move files)"