Fix torrent processing issues in transmission_handler.sh
- Fix quote handling in transmission-remote commands - Add robust handling for empty torrent IDs - Improve path handling for empty directories - Update version to 9.1 with shared directory handling - Fix empty array subscript errors On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: README.md modified: etc/torrent/mover.conf modified: install.sh new file: usr/local/bin/smart-processor modified: usr/local/bin/torrent-mover new file: usr/local/bin/torrent-processor modified: usr/local/lib/torrent-mover/common.sh modified: usr/local/lib/torrent-mover/transmission_handler.sh
This commit is contained in:
Executable
+183
@@ -0,0 +1,183 @@
|
||||
#\!/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"
|
||||
Reference in New Issue
Block a user