#\!/bin/bash # Source configuration source /etc/torrent/mover.conf # Create destination directories mkdir -p /mnt/dsnas1/{Books,Movies,TV,Games,Apps,Music,Other} # Function to display help show_help() { echo "Torrent Processor - Helper for torrent-mover" echo "" echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " --reset Clear processed log to re-process all torrents" echo " --books Process only book torrents" echo " --movies Process only movie torrents" echo " --tv Process only TV show torrents" echo " --apps Process only application torrents" echo " --games Process only game torrents" echo " --id NUMBER Process a specific torrent ID" echo " --help Show this help message" echo "" echo "Examples:" echo " $0 --reset --books Process all book torrents (even if previously processed)" echo " $0 --id 123 Process only torrent with ID 123" echo "" } # Parse command line options RESET=0 CATEGORY="" TORRENT_ID="" while [[ $# -gt 0 ]]; do key="$1" case $key in --reset) RESET=1 shift ;; --books) CATEGORY="books" shift ;; --movies) CATEGORY="movies" shift ;; --tv) CATEGORY="tv" shift ;; --apps) CATEGORY="apps" shift ;; --games) CATEGORY="games" shift ;; --id) TORRENT_ID="$2" shift shift ;; --help) show_help exit 0 ;; *) echo "Unknown option: $key" show_help exit 1 ;; esac done # Reset processed log if requested if [ $RESET -eq 1 ]; then echo "Clearing processed log to re-process all torrents" > /var/log/torrent_processed.log fi # Remove lock file if it exists rm -f /var/lock/torrent-mover.lock # Run torrent-mover based on options if [ -n "$TORRENT_ID" ]; then echo "Processing torrent ID: $TORRENT_ID" # Get torrent details info=$(transmission-remote "${TRANSMISSION_IP}:${TRANSMISSION_PORT}" \ --auth "${TRANSMISSION_USER}:${TRANSMISSION_PASSWORD}" \ --torrent $TORRENT_ID --info) name=$(echo "$info" | grep "Name:" | awk -F": " '{print $2}' | xargs) echo "Torrent name: $name" # Run torrent-mover with specific torrent ID torrent_id="$TORRENT_ID" # Check if output directory exists for this torrent output_dir=$(grep "Location:" <<< "$info" | awk -F": " '{print $2}' | xargs) if [[ -n "$output_dir" ]]; then echo "Torrent location: $output_dir" fi # We need to modify torrent-mover to handle single IDs # For now, we'll write a small temporary script to process just this ID TMP_SCRIPT=$(mktemp) cat > "$TMP_SCRIPT" << EOF #!/bin/bash source /etc/torrent/mover.conf source /usr/local/lib/torrent-mover/common.sh source /usr/local/lib/torrent-mover/file_operations.sh source /usr/local/lib/torrent-mover/transmission_handler.sh source /usr/local/lib/torrent-mover/archive_handler.sh # Set debug mode DEBUG=1 # Process just this one torrent process_single_torrent() { local id="\$1" log_debug "Processing single torrent ID: \$id" # Get torrent info local info info=\$(get_torrent_info "\${id}") if [[ -z "\$info" ]]; then log_error "Failed to get info for torrent \$id" return 1 fi # Process torrent info just like in the main script local hash hash=\$(grep "Hash:" <<< "\${info}" | awk '{print \$2}') local ratio ratio=\$(grep "Ratio:" <<< "\${info}" | awk '{print \$2 == "None" ? 0 : \$2}' | tr -cd '0-9.') ratio=\${ratio:-0} local time time=\$(grep "Seeding Time:" <<< "\${info}" | awk '{print \$3 == "None" ? 0 : \$3}' | tr -cd '0-9.') time=\${time:-0} local percent_done percent_done=\$(grep "Percent Done:" <<< "\${info}" | awk '{gsub(/%/, ""); print \$3 == "None" ? 0 : \$3}') percent_done=\${percent_done:-0} # Extract Transmission-reported directory and translate to local path. local reported_dir reported_dir=\$(grep -i "Location:" <<< "\${info}" | awk -F": " '{print \$2}' | xargs) log_debug "Raw reported directory: '\${reported_dir}'" # If the reported directory is empty, try to derive it from the name if [[ -z "\${reported_dir}" ]]; then local name name=\$(grep -i "Name:" <<< "\${info}" | awk -F": " '{print \$2}' | xargs) log_debug "Torrent name: '\${name}'" # Check if there are labels we can use local labels labels=\$(grep -i "Labels:" <<< "\${info}" | awk -F": " '{print \$2}' | xargs) log_debug "Torrent labels: '\${labels}'" if [[ "\${labels}" == *"Books"* ]]; then reported_dir="/downloads/Books" elif [[ "\${labels}" == *"Movies"* ]]; then reported_dir="/downloads/Movies" elif [[ "\${labels}" == *"TV"* ]]; then reported_dir="/downloads/TV" elif [[ "\${labels}" == *"Games"* ]]; then reported_dir="/downloads/Games" elif [[ "\${labels}" == *"Apps"* ]]; then reported_dir="/downloads/Apps" elif [[ "\${labels}" == *"Music"* ]]; then reported_dir="/downloads/Music" else # Default to Other if we can't determine reported_dir="/downloads/Other" fi log_debug "Derived directory from labels: '\${reported_dir}'" fi local dir dir=\$(translate_source "\${reported_dir}") log_info "Torrent source directory: '\${reported_dir}' translated to '\${dir}'" # Initialize empty directory mapping if needed if [[ -z "\$dir" ]]; then log_warn "Empty directory path detected, using default" dir="\${LOCAL_PATH_PREFIX}/Other" fi local dst dst=\$(get_destination "\${dir}") # Process the torrent if (( \$(bc <<< "\${percent_done} >= 100") )) && ! is_processed "\${hash}"; then log_info "Processing completed torrent \${id} (\${percent_done}% done)" process_copy "\${id}" "\${hash}" "\${dir}" "\${dst}" else log_info "Torrent \${id} already processed or not complete" fi # Check seed ratio/time criteria if (( \$(bc <<< "\${ratio} >= \${SEED_RATIO}") )) || (( \$(bc <<< "\${time} >= \${SEED_TIME}") )); then log_info "Removing torrent \${id} (Ratio: \${ratio}, Time: \${time})" process_removal "\${id}" fi } # Main function process_single_torrent "$torrent_id" EOF chmod +x "$TMP_SCRIPT" "$TMP_SCRIPT" rm -f "$TMP_SCRIPT" elif [ -n "$CATEGORY" ]; then echo "Processing category: $CATEGORY" # Set category-specific filter CATEGORY_PATH="" PATTERN="" case $CATEGORY in books) echo "Looking for book torrents..." CATEGORY_PATH="/downloads/Books" PATTERN="*books*|*ebook*|*epub*|*pdf*" ;; movies) echo "Looking for movie torrents..." CATEGORY_PATH="/downloads/Movies" PATTERN="*movies*|*film*|*video*" ;; tv) echo "Looking for TV show torrents..." CATEGORY_PATH="/downloads/TV" PATTERN="*tv*|*series*|*episode*" ;; apps) echo "Looking for application torrents..." CATEGORY_PATH="/downloads/Apps" PATTERN="*apps*|*applications*|*programs*|*software*" ;; games) echo "Looking for game torrents..." CATEGORY_PATH="/downloads/Games" PATTERN="*games*" ;; esac # Create a script to process just this category TMP_SCRIPT=$(mktemp) cat > "$TMP_SCRIPT" << EOF #!/bin/bash source /etc/torrent/mover.conf source /usr/local/lib/torrent-mover/common.sh source /usr/local/lib/torrent-mover/file_operations.sh source /usr/local/lib/torrent-mover/transmission_handler.sh source /usr/local/lib/torrent-mover/archive_handler.sh # Set debug mode DEBUG=1 # Get all torrents get_torrent_ids() { local cmd="transmission-remote \${TRANSMISSION_IP}:\${TRANSMISSION_PORT} -n \${TRANSMISSION_USER}:\${TRANSMISSION_PASSWORD} -l" local output output=\$(retry_command "\$cmd" 3 20) echo "\$output" | awk 'NR>1 && NF>1 {gsub(/^[ ]+/, "", \$1); if (\$1 ~ /^[0-9]+\$/) print \$1}' } # Process category torrents process_category_torrents() { local category_path="$CATEGORY_PATH" local pattern="$PATTERN" log_debug "Processing category: $CATEGORY with path \$category_path and pattern '\$pattern'" # Get list of all torrents local torrent_ids=\$(get_torrent_ids) # Process each torrent for id in \$torrent_ids; do # Get torrent info local info=\$(get_torrent_info "\$id") if [[ -z "\$info" ]]; then log_warn "Failed to get info for torrent \$id, skipping" continue fi # Extract name and location local name=\$(grep -i "Name:" <<< "\$info" | awk -F": " '{print \$2}' | xargs) local reported_dir=\$(grep -i "Location:" <<< "\$info" | awk -F": " '{print \$2}' | xargs) local labels=\$(grep -i "Labels:" <<< "\$info" | awk -F": " '{print \$2}' | xargs) # Check if this torrent matches our category if [[ "\$reported_dir" == "\$category_path" ]] || [[ "\$labels" == *"$CATEGORY"* ]] || [[ "\$name" =~ \$pattern ]]; then log_info "Found matching torrent: \$id - \$name" # Process torrent info local hash=\$(grep "Hash:" <<< "\$info" | awk '{print \$2}') local ratio=\$(grep "Ratio:" <<< "\$info" | awk '{print \$2 == "None" ? 0 : \$2}' | tr -cd '0-9.') ratio=\${ratio:-0} local time=\$(grep "Seeding Time:" <<< "\$info" | awk '{print \$3 == "None" ? 0 : \$3}' | tr -cd '0-9.') time=\${time:-0} local percent_done=\$(grep "Percent Done:" <<< "\$info" | awk '{gsub(/%/, ""); print \$3 == "None" ? 0 : \$3}') percent_done=\${percent_done:-0} # If the reported directory is empty, derive it if [[ -z "\$reported_dir" ]]; then reported_dir="\$category_path" log_debug "Using derived directory: '\$reported_dir'" fi # Process the torrent local dir=\$(translate_source "\$reported_dir") log_info "Torrent source directory: '\$reported_dir' translated to '\$dir'" # Initialize empty directory mapping if needed if [[ -z "\$dir" ]]; then log_warn "Empty directory path detected, using default" dir="\${LOCAL_PATH_PREFIX}/$CATEGORY" fi local dst=\$(get_destination "\$dir") # Process the torrent if (( \$(bc <<< "\${percent_done} >= 100") )) && ! is_processed "\${hash}"; then log_info "Processing completed torrent \${id} (\${percent_done}% done)" process_copy "\${id}" "\${hash}" "\${dir}" "\${dst}" else log_info "Torrent \${id} already processed or not complete" fi # Check seed ratio/time criteria if (( \$(bc <<< "\${ratio} >= \${SEED_RATIO}") )) || (( \$(bc <<< "\${time} >= \${SEED_TIME}") )); then log_info "Removing torrent \${id} (Ratio: \${ratio}, Time: \${time})" process_removal "\${id}" fi fi done } # Main function process_category_torrents EOF chmod +x "$TMP_SCRIPT" "$TMP_SCRIPT" rm -f "$TMP_SCRIPT" else echo "Processing all torrents" # Run the main torrent-mover script directly /usr/local/bin/torrent-mover --debug fi echo "Processing complete\!" echo "Check /var/log/torrent_mover.log for details"