#\!/bin/bash # Source configuration source /etc/torrent/mover.conf # Reset processed log > /var/log/torrent_processed.log # Process all torrents - smart version for shared directories echo "Starting smart torrent processor..." echo "This script will identify and copy files for completed torrents" echo "----------------------------------------------------------------" # Make sure destination directories exist mkdir -p /mnt/dsnas1/{Books,Movies,TV,Games,Apps,Music,Other} # Get list of torrents IDS=$(transmission-remote "${TRANSMISSION_IP}:${TRANSMISSION_PORT}" \ --auth "${TRANSMISSION_USER}:${TRANSMISSION_PASSWORD}" \ --list | tail -n +2 | head -n -1 | awk '{print $1}' | grep -v "Sum:" | grep -v "[a-zA-Z]") # Count torrents TOTAL_TORRENTS=$(echo "$IDS" | wc -l) echo "Found $TOTAL_TORRENTS torrents to process" # Process each torrent COUNT=0 for id in $IDS; do # Progress counter COUNT=$((COUNT+1)) # Get torrent info INFO=$(transmission-remote "${TRANSMISSION_IP}:${TRANSMISSION_PORT}" \ --auth "${TRANSMISSION_USER}:${TRANSMISSION_PASSWORD}" \ --torrent $id --info) # Extract key information NAME=$(echo "$INFO" | grep "Name:" | awk -F": " '{print $2}' | xargs) HASH=$(echo "$INFO" | grep "Hash:" | awk '{print $2}') PERCENT=$(echo "$INFO" | grep "Percent Done:" | awk '{gsub(/%/, ""); print $3 == "None" ? 0 : $3}') LOCATION=$(echo "$INFO" | grep -i "Location:" | awk -F": " '{print $2}' | xargs) # Skip if not 100% complete if [ $(bc <<< "$PERCENT < 100") -eq 1 ]; then echo "[$COUNT/$TOTAL_TORRENTS] Skipping incomplete torrent $id: $NAME ($PERCENT%)" continue fi # Skip if already processed if grep -q "$HASH" /var/log/torrent_processed.log; then echo "[$COUNT/$TOTAL_TORRENTS] Skipping already processed torrent $id: $NAME" continue fi echo "[$COUNT/$TOTAL_TORRENTS] Processing torrent $id: $NAME" # Apply path mapping SRC="${LOCATION/#$TRANSMISSION_PATH_PREFIX/$LOCAL_PATH_PREFIX}" # Set destination based on content type DST="$DEFAULT_DST" if [[ "$LOCATION" == */Books* || "$NAME" == *eBook* || "$NAME" == *ePub* ]]; then DST="$DIR_BOOKS_DST" echo " Categorized as: Book" elif [[ "$LOCATION" == */Movies* || "$NAME" == *1080p* || "$NAME" == *720p* ]]; then DST="$DIR_MOVIES_DST" echo " Categorized as: Movie" elif [[ "$LOCATION" == */TV* || "$NAME" == *S0* || "$NAME" == *S1* ]]; then DST="$DIR_TV_DST" echo " Categorized as: TV Show" elif [[ "$LOCATION" == */Games* || "$NAME" == *Game* ]]; then DST="$DIR_GAMES_DST" echo " Categorized as: Game" elif [[ "$LOCATION" == */Apps* || "$NAME" == *App* ]]; then DST="$DIR_APPS_DST" echo " Categorized as: App" elif [[ "$LOCATION" == */Music* || "$NAME" == *MP3* ]]; then DST="$DIR_MUSIC_DST" echo " Categorized as: Music" else echo " Categorized as: Other" fi # Make sure destination exists mkdir -p "$DST" # Now handle the file copying based on directory structure if [ -d "$SRC" ]; then echo " Source path: $SRC" echo " Destination: $DST" # Use find to locate specific content files (ignore small files like NFO) FILES_FOUND=0 echo " Looking for media files or content..." # Try to find files matching this specific torrent name NAME_PATTERN=$(echo "$NAME" | cut -d'-' -f1 | tr '.' ' ' | xargs | tr '[:upper:]' '[:lower:]') NAME_PATTERN=${NAME_PATTERN// /.} echo " Searching for files matching pattern: $NAME_PATTERN" # Search for matching files or directories MATCHING_FILES=() while IFS= read -r file; do file_basename=$(basename "$file" | tr '[:upper:]' '[:lower:]') if [[ "$file_basename" == *"$NAME_PATTERN"* ]]; then size=$(stat -c%s "$file") MATCHING_FILES+=("$file") echo " ✓ Match: $(basename "$file") ($(numfmt --to=iec $size))" fi done < <(find "$SRC" -type f -size +10k | sort -rn -k5 | head -n 20) if [ ${#MATCHING_FILES[@]} -gt 0 ]; then echo " Found ${#MATCHING_FILES[@]} matching files for this torrent" # Copy up to 3 matched files for ((i=0; i<3 && i<${#MATCHING_FILES[@]}; i++)); do file="${MATCHING_FILES[$i]}" echo " Copying: $(basename "$file") to $DST/" cp -v "$file" "$DST/" FILES_FOUND=$((FILES_FOUND+1)) done else echo " No exact matches found - falling back to content type detection" # Get a list of content files ordered by size (largest first) while IFS= read -r file; do extension="${file##*.}" extension="${extension,,}" # Convert to lowercase filename=$(basename "$file") # Skip small files under 1MB (likely not content) size=$(stat -c%s "$file") # Only include files based on type if [[ "$DST" == "$DIR_MOVIES_DST" && "$extension" == @(mkv|mp4|avi) ]]; then echo " Found movie: $filename (Size: $(numfmt --to=iec $size))" echo " Copying to $DST/" cp -v "$file" "$DST/" FILES_FOUND=$((FILES_FOUND+1)) elif [[ "$DST" == "$DIR_BOOKS_DST" && "$extension" == @(epub|pdf|mobi) ]]; then echo " Found book: $filename (Size: $(numfmt --to=iec $size))" echo " Copying to $DST/" cp -v "$file" "$DST/" FILES_FOUND=$((FILES_FOUND+1)) elif [[ "$DST" == "$DIR_TV_DST" && "$extension" == @(mkv|mp4|avi) ]]; then echo " Found TV episode: $filename (Size: $(numfmt --to=iec $size))" echo " Copying to $DST/" cp -v "$file" "$DST/" FILES_FOUND=$((FILES_FOUND+1)) elif [[ "$size" -gt 1000000 ]]; then # 1MB for other content types echo " Found content: $filename (Size: $(numfmt --to=iec $size))" echo " Copying to $DST/" cp -v "$file" "$DST/" FILES_FOUND=$((FILES_FOUND+1)) fi # Limit to first 3 content files to avoid excessive copying if [ $FILES_FOUND -ge 3 ]; then echo " Reached limit of 3 content files" break fi done < <(find "$SRC" -type f -size +100k | sort -rn -k5 | head -n 10) fi if [ $FILES_FOUND -gt 0 ]; then echo " ✅ Successfully copied $FILES_FOUND files" # Mark as processed echo "$HASH" >> /var/log/torrent_processed.log else echo " ❌ No suitable content files found" fi else echo " ❌ Source directory not found: $SRC" fi echo "------------------------------------------------------" done echo "Smart torrent processing completed" echo "Processed torrents are recorded in /var/log/torrent_processed.log"