Skip to content

Instantly share code, notes, and snippets.

@acouvreur
Last active January 31, 2025 00:00
Show Gist options
  • Save acouvreur/25f90a605307705cd71c9399fa7eb5b8 to your computer and use it in GitHub Desktop.
Save acouvreur/25f90a605307705cd71c9399fa7eb5b8 to your computer and use it in GitHub Desktop.
Sync deleted files from Radarr/Sonarr
#!/bin/bash
# Find existing files in download/complete that are not in movies or tvshows.
export DOWNLOAD_FOLDER=path/to/downloads
export MOVIES_FOLDER=path/to/movies
export TVSHOWS_FOLDER=path/to/tvshows
findExistingFile() {
file=$(find $MOVIES_FOLDER/ $TVSHOWS_FOLDER/ -samefile "$1")
if [ -z "$file" ]; then
echo "File \"$1\" is not present in the movies or tvshows folders. Deleting..."
rm "$1"
fi;
}
export -f findExistingFile
find $DOWNLOAD_FOLDER -type f -size +1G -exec bash -c 'findExistingFile "$0"' {} \;
@acouvreur
Copy link
Author

Note that this will also deleted files that are completed but not imported!

This may happen quite often if you're close to full capacity and want to free space for completed downloads.

@Seluj78
Copy link

Seluj78 commented Jan 31, 2025

This works perfectly for me. I need this because of hard links.

#!/bin/bash

# Initialize dry-run mode
DRY_RUN=0
DELETE_ACTION="-delete"

# Check for dry-run argument
if [[ $# -ge 1 && "$1" == "--dry-run" ]]; then
    DRY_RUN=1
    DELETE_ACTION="-print"
    echo -e "\033[1;33mDRY RUN MODE ENABLED - No files will be deleted\033[0m"
fi

# Define directory pairs (media:done)
pairs=(
    "/home/data/media/movies:/home/data/torrents/radarr-done"
    "/home/data/media/tvshows:/home/data/torrents/sonarr-done"
    "/home/data/media/music:/home/data/torrents/lidarr-done"
)

for pair in "${pairs[@]}"; do
    IFS=':' read -r media_dir done_dir <<< "$pair"

    echo -e "\n\033[1;36mProcessing pair:\033[0m"
    echo "Media: $media_dir"
    echo "Done:  $done_dir"

    # Create temporary files for inode storage
    media_inodes=$(mktemp)
    done_inodes=$(mktemp)

    # Collect media inodes
    echo "Collecting media inodes..."
    find "$media_dir" -type f -printf '%i\n' 2>/dev/null | sort -u > "$media_inodes"

    # Collect done inodes
    echo "Collecting done inodes..."
    find "$done_dir" -type f -printf '%i\n' 2>/dev/null | sort -u > "$done_inodes"

    # Find orphaned files in done directory
    echo "Checking done directory for orphans..."
    comm -23 <(sort "$done_inodes") <(sort "$media_inodes") | while read -r inode; do
        if (( DRY_RUN )); then
            echo -e "\033[1;33m[WOULD DELETE]\033[0m Orphaned done files with inode $inode:"
        else
            echo -e "\033[1;31m[DELETING]\033[0m Orphaned done files with inode $inode"
        fi
        find "$done_dir" -type f -inum "$inode" $DELETE_ACTION 2>/dev/null
    done

    # Find orphaned files in media directory
    echo "Checking media directory for orphans..."
    comm -23 <(sort "$media_inodes") <(sort "$done_inodes") | while read -r inode; do
        if (( DRY_RUN )); then
            echo -e "\033[1;33m[WOULD DELETE]\033[0m Orphaned media files with inode $inode:"
        else
            echo -e "\033[1;31m[DELETING]\033[0m Orphaned media files with inode $inode"
        fi
        find "$media_dir" -type f -inum "$inode" $DELETE_ACTION 2>/dev/null
    done

    # Cleanup temporary files
    rm -f "$media_inodes" "$done_inodes"
    echo "Finished processing pair"
done

echo -e "\n\033[1;32mCleanup complete!\033[0m"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment