#!/bin/bash # Transmission-related functions for torrent-mover # get_destination: Maps a source directory to a destination directory based on keywords and patterns get_destination() { local source_path="$1" # Check if source_path is valid before accessing the array if [[ -z "${source_path}" ]]; then log_warn "Empty source path provided to get_destination" return "${DEFAULT_DST}" fi # Check if path is already in the cache if [[ -n "${PATH_CACHE["${source_path}"]+x}" ]]; then local cached_destination="${PATH_CACHE["${source_path}"]}" log_debug "Using cached destination for ${source_path}: ${cached_destination}" echo "${cached_destination}" return fi # Skip recursive path analysis - only log once if [[ "${source_path}" =~ ^/mnt/dsnas1/ ]]; then # Already in destination format, return as is log_debug "Path already in destination format: ${source_path}" PATH_CACHE["${source_path}"]="${source_path}" echo "${source_path}" return fi # For paths in dsnas2, check if they map to same structure in dsnas1 if [[ "${source_path}" =~ ^/mnt/dsnas2/ ]]; then local dir_suffix="${source_path#/mnt/dsnas2/}" local potential_dest="/mnt/dsnas1/${dir_suffix}" # If the directories match exactly in structure, only on different mounts, # return the source to avoid needless copying if [[ -d "${potential_dest}" ]]; then log_debug "Path maps to same structure on different mount: ${source_path} -> ${source_path}" PATH_CACHE["${source_path}"]="${source_path}" echo "${source_path}" return fi fi log_info "Analyzing path: ${source_path}" local destination="${DEFAULT_DST}" # Match using custom patterns from config file if they exist if [[ -n "${CUSTOM_PATTERNS}" ]]; then log_debug "Using custom patterns from config..." # Parse and apply each pattern IFS=';' read -ra PATTERN_ARRAY <<< "${CUSTOM_PATTERNS}" for pattern in "${PATTERN_ARRAY[@]}"; do IFS='=' read -ra PARTS <<< "${pattern}" if [[ "${#PARTS[@]}" -eq 2 ]]; then local regex="${PARTS[0]}" local dest="${PARTS[1]}" if [[ "${source_path,,}" =~ ${regex,,} ]]; then log_info "Custom pattern match: ${regex} -> ${dest}" destination="${dest}" break fi fi done fi # If no custom pattern matched, use default category mapping if [[ "${destination}" == "${DEFAULT_DST}" ]]; then case "${source_path,,}" in *games*) destination="${DIR_GAMES_DST}";; *apps*|*applications*|*programs*|*software*) destination="${DIR_APPS_DST}";; *movies*|*film*|*video*) destination="${DIR_MOVIES_DST}";; *books*|*ebook*|*pdf*|*epub*) destination="${DIR_BOOKS_DST}";; *tv*|*series*|*episode*) if [[ -n "${DIR_TV_DST}" ]]; then destination="${DIR_TV_DST}" else destination="${DIR_MOVIES_DST}" fi ;; *music*|*audio*|*mp3*|*flac*) if [[ -n "${DIR_MUSIC_DST}" ]]; then destination="${DIR_MUSIC_DST}" else destination="${DEFAULT_DST}" fi ;; esac fi log_info "Mapped to: ${destination}" # Only set in cache if source_path is not empty if [[ -n "${source_path}" ]]; then PATH_CACHE["${source_path}"]="${destination}" fi echo "${destination}" } # process_removal: Removes a torrent via Transmission. process_removal() { local id="$1" if (( DRY_RUN )); then log_info "[DRY RUN] Would remove torrent ${id}" return fi local cmd="transmission-remote ${TRANSMISSION_IP}:${TRANSMISSION_PORT} -n ${TRANSMISSION_USER}:${TRANSMISSION_PASSWORD} -t ${id} --remove-and-delete" retry_command "$cmd" 3 15 } # get_torrents: Retrieves a list of torrents from Transmission get_torrents() { local cmd="transmission-remote ${TRANSMISSION_IP}:${TRANSMISSION_PORT} -n ${TRANSMISSION_USER}:${TRANSMISSION_PASSWORD} -l" log_debug "Running command: $cmd" local output output=$(retry_command "$cmd" 3 20) # Extract IDs directly using awk # Skip the header line (NR>1) and print the first column # The IDs are right-aligned with spaces in front, so we need to trim them echo "$output" | awk 'NR>1 && NF>1 {gsub(/^[ ]+/, "", $1); if ($1 ~ /^[0-9]+$/) print $1}' } # get_torrent_info: Gets detailed info for a specific torrent get_torrent_info() { local id="$1" local cmd="transmission-remote ${TRANSMISSION_IP}:${TRANSMISSION_PORT} -n ${TRANSMISSION_USER}:${TRANSMISSION_PASSWORD} -t ${id} -i" retry_command "$cmd" 3 15 }