diff --git a/hosts/profiles/sync/tv/get-tv.sh b/hosts/profiles/sync/tv/get-tv.sh index 6df96ae..2677731 100644 --- a/hosts/profiles/sync/tv/get-tv.sh +++ b/hosts/profiles/sync/tv/get-tv.sh @@ -8,7 +8,7 @@ LOCAL_PATH="/tank/media/tv" TRACKING_FILE="/tank/media/tv/.downloaded_shows" LOG_FILE="/tank/media/tv/download-log" LOCK_FILE="/tmp/get-tv-sync.lock" -SONARR_API_KEY="PLACEHOLDER" +SONARR_API_KEY="9dba6d5f31eb42cf8c65f4f6f21cc8d2" SONARR_URL="http://localhost:8989" umask 002 @@ -19,6 +19,42 @@ touch "$TRACKING_FILE" log() { echo "$(date): $1" >>"$LOG_FILE"; } +# Extract a match key from a release name for fuzzy matching. +# Sonarr's sourceTitle often differs from the actual filename on the seedbox: +# - sourceTitle omits file extensions (.mkv, .ts, etc.) +# - sourceTitle omits episode titles that appear in the actual filename +# We match on episode identifier + release group, which are consistent on both sides. +# Returns "episode_id|||group" e.g. "Top.Chef.S23E01|||RAWR" or "Jeopardy.2026.03.19|||BTN" +match_key() { + local name="$1" + # Strip known video file extensions + name="${name%.mkv}" + name="${name%.ts}" + name="${name%.mp4}" + name="${name%.avi}" + name="${name%.m4v}" + + local ep_id="" group="" + + # Extract release group: everything after the last hyphen + if [[ "$name" == *-* ]]; then + group="${name##*-}" + fi + + # Extract episode identifier: show name + S##E##, YYYY.MM.DD, or S## pattern + if [[ "$name" =~ ^(.*\.[Ss][0-9]+[Ee][0-9]+) ]]; then + ep_id="${BASH_REMATCH[1]}" + elif [[ "$name" =~ ^(.*\.[0-9]{4}\.[0-9]{2}\.[0-9]{2}) ]]; then + ep_id="${BASH_REMATCH[1]}" + elif [[ "$name" =~ ^(.*\.[Ss][0-9]+)\. ]]; then + ep_id="${BASH_REMATCH[1]}" + fi + + if [ -n "$ep_id" ] && [ -n "$group" ]; then + echo "${ep_id}|||${group}" + fi +} + # Acquire exclusive lock to prevent concurrent runs exec 9>"$LOCK_FILE" if ! flock -n 9; then @@ -136,9 +172,25 @@ while IFS=$'\t' read -r source_title series_folder; do continue fi - # Check if it exists on the remote seedbox (exact match on entry name) - # Use ENVIRON to pass source_title to awk, avoiding backslash interpretation from -v - REMOTE_MATCH=$(SOURCE_TITLE="$source_title" awk -F'\t' 'BEGIN { name = ENVIRON["SOURCE_TITLE"] } $2 == name { print; exit }' "$REMOTE_LISTING_FILE") || true + # Match sourceTitle against remote seedbox entries using episode ID + release group. + # Sonarr's sourceTitle often differs from the actual filename (missing extension, + # missing episode title in the name), so exact matching doesn't work. + SOURCE_KEY=$(match_key "$source_title") + if [ -z "$SOURCE_KEY" ]; then + log "WARNING: Could not extract match key from sourceTitle: $source_title" + continue + fi + + REMOTE_MATCH="" + while IFS=$'\t' read -r rtype rname; do + [ -z "$rname" ] && continue + REMOTE_KEY=$(match_key "$rname") + if [ "$SOURCE_KEY" = "$REMOTE_KEY" ]; then + REMOTE_MATCH="$rtype"$'\t'"$rname" + break + fi + done <"$REMOTE_LISTING_FILE" + if [ -z "$REMOTE_MATCH" ]; then log "Not yet on seedbox (still downloading?): $source_title" continue @@ -146,31 +198,32 @@ while IFS=$'\t' read -r source_title series_folder; do # Determine if it's a directory or file from the listing ENTRY_TYPE=$(echo "$REMOTE_MATCH" | cut -f1) + REMOTE_NAME=$(echo "$REMOTE_MATCH" | cut -f2) - log "Downloading '$source_title' -> '$series_folder/'" + log "Downloading '$source_title' (remote: '$REMOTE_NAME') -> '$series_folder/'" mkdir -p "$LOCAL_PATH/$series_folder" if [ "$ENTRY_TYPE" = "d" ]; then # Directory: rsync recursively, trailing slash to put contents into series folder if rsync -rs --partial --timeout=600 --log-file="$LOG_FILE" \ - "$REMOTE_HOST:$REMOTE_PATH$source_title/" \ + "$REMOTE_HOST:$REMOTE_PATH$REMOTE_NAME/" \ "$LOCAL_PATH/$series_folder/"; then echo "$source_title" >>"$TRACKING_FILE" - log "Successfully downloaded directory: $source_title" + log "Successfully downloaded directory: $REMOTE_NAME" DOWNLOADED=$((DOWNLOADED + 1)) else - log "Failed to download directory: $source_title" + log "Failed to download directory: $REMOTE_NAME" fi else # Single file: rsync into series folder if rsync -s --partial --timeout=600 --log-file="$LOG_FILE" \ - "$REMOTE_HOST:$REMOTE_PATH$source_title" \ + "$REMOTE_HOST:$REMOTE_PATH$REMOTE_NAME" \ "$LOCAL_PATH/$series_folder/"; then echo "$source_title" >>"$TRACKING_FILE" - log "Successfully downloaded file: $source_title" + log "Successfully downloaded file: $REMOTE_NAME" DOWNLOADED=$((DOWNLOADED + 1)) else - log "Failed to download file: $source_title" + log "Failed to download file: $REMOTE_NAME" fi fi done <<<"$RECORDS"