From 63f37380cdc156dffa20c2f0e145b56aad57e036 Mon Sep 17 00:00:00 2001 From: Bauke Date: Thu, 27 Nov 2025 11:42:34 +0100 Subject: [PATCH 1/6] Add support for unlimited number of qBittorrent instances --- includes/downloaders/mover-tuning-end.sh | 115 +++++++++++++++++--- includes/downloaders/mover-tuning-start.sh | 116 +++++++++++++++++++-- includes/downloaders/mover-tuning.cfg | 24 ++--- 3 files changed, 214 insertions(+), 41 deletions(-) diff --git a/includes/downloaders/mover-tuning-end.sh b/includes/downloaders/mover-tuning-end.sh index 096ef62533..ff0eb0d46a 100644 --- a/includes/downloaders/mover-tuning-end.sh +++ b/includes/downloaders/mover-tuning-end.sh @@ -3,12 +3,12 @@ set -euo pipefail # Exit on error, undefined variables, and pipe failures # ===================================== # Script: qBittorrent Cache Mover - End -# Version: 1.0.0 -# Updated: 20251121 +# Version: 1.1.0 +# Updated: 20251126 # ===================================== # Script version and update check URLs -readonly SCRIPT_VERSION="1.0.0" +readonly SCRIPT_VERSION="1.1.0" readonly SCRIPT_RAW_URL="https://raw.githubusercontent.com/TRaSH-Guides/Guides/refs/heads/master/includes/downloaders/mover-tuning-end.sh" # Get the directory where the script is located @@ -44,6 +44,59 @@ notify() { fi } +# ================================ +# CONFIG FORMAT DETECTION +# ================================ +detect_config_format() { + # Check if array-based config is used + if [[ -v HOSTS[@] ]] && [[ ${#HOSTS[@]} -gt 0 ]]; then + echo "array" + else + echo "legacy" + fi +} + +get_instance_count() { + local format + format=$(detect_config_format) + + if [[ "$format" == "array" ]]; then + echo "${#HOSTS[@]}" + else + # Legacy format: count based on ENABLE_QBIT_2 + if [[ "${ENABLE_QBIT_2:-false}" == true ]]; then + echo "2" + else + echo "1" + fi + fi +} + +get_instance_details() { + local index="$1" + local format + format=$(detect_config_format) + + if [[ "$format" == "array" ]]; then + # Array format: return details from arrays + local name="${NAMES[$index]:-qBit-Instance-$((index + 1))}" + local host="${HOSTS[$index]}" + local user="${USERS[$index]}" + local password="${PASSWORDS[$index]}" + + echo "$name|$host|$user|$password" + else + # Legacy format: map index to old variables + if [[ $index -eq 0 ]]; then + echo "${QBIT_NAME_1}|${QBIT_HOST_1}|${QBIT_USER_1}|${QBIT_PASS_1}" + elif [[ $index -eq 1 ]]; then + echo "${QBIT_NAME_2}|${QBIT_HOST_2}|${QBIT_USER_2}|${QBIT_PASS_2}" + else + error "Invalid instance index: $index" + fi + fi +} + # ================================ # VERSION CHECK FUNCTION # ================================ @@ -91,9 +144,14 @@ check_script_version() { # Compare versions if [[ "$SCRIPT_VERSION" != "$latest_version" ]]; then # Simple version comparison (works for semantic versioning) - if printf '%s\n' "$latest_version" "$SCRIPT_VERSION" | sort -V | head -n1 | grep -q "^$SCRIPT_VERSION$" 2>/dev/null || true; then + # Sort both versions and check if SCRIPT_VERSION comes first (is older) + if printf '%s\n' "$latest_version" "$SCRIPT_VERSION" | sort -V | head -n1 | grep -q "^$SCRIPT_VERSION$" 2>/dev/null; then + # SCRIPT_VERSION is older, so there's a newer version available log "⚠ New version available: $latest_version" notify "mover-tuning-end.sh Update" "Version $latest_version available (current: $SCRIPT_VERSION)

📖 Visit the TRaSH-Guides for the latest version" + else + # latest_version is older, local version is newer + log "✓ Local version ($SCRIPT_VERSION) is newer than remote ($latest_version)" fi else log "✓ Script is up to date" @@ -297,6 +355,31 @@ validate_config() { [[ -d "$CACHE_MOUNT" ]] || error "Cache mount not found: $CACHE_MOUNT" [[ -f "${QBIT_MOVER_PATH}mover.py" ]] || error "mover.py not found: ${QBIT_MOVER_PATH}mover.py" + # Validate instance configuration + local format + format=$(detect_config_format) + + if [[ "$format" == "array" ]]; then + # Validate array-based config + [[ ${#HOSTS[@]} -gt 0 ]] || error "HOSTS array is empty" + [[ ${#USERS[@]} -eq ${#HOSTS[@]} ]] || error "USERS array length doesn't match HOSTS" + [[ ${#PASSWORDS[@]} -eq ${#HOSTS[@]} ]] || error "PASSWORDS array length doesn't match HOSTS" + + # NAMES array is optional, but if present should match + if [[ -v NAMES[@] ]] && [[ ${#NAMES[@]} -gt 0 ]]; then + [[ ${#NAMES[@]} -eq ${#HOSTS[@]} ]] || error "NAMES array length doesn't match HOSTS" + fi + + log "✓ Using array-based configuration (${#HOSTS[@]} instance(s))" + else + # Validate legacy config + [[ -n "${QBIT_HOST_1:-}" ]] || error "QBIT_HOST_1 is not set" + [[ -n "${QBIT_USER_1:-}" ]] || error "QBIT_USER_1 is not set" + [[ -n "${QBIT_PASS_1:-}" ]] || error "QBIT_PASS_1 is not set" + + log "✓ Using legacy configuration" + fi + # Validate duplicate finder if enabled if [[ "$ENABLE_DUPLICATE_FINDER" == true ]]; then if [[ "$ENABLE_AUTO_INSTALLER" == true ]]; then @@ -372,18 +455,18 @@ main() { # Validate configuration validate_config || exit 1 - # Process primary instance - process_qbit_instance "$QBIT_NAME_1" "$QBIT_HOST_1" "$QBIT_USER_1" "$QBIT_PASS_1" || \ - ((failed_instances++)) - - # Process secondary instance if enabled - if [[ "$ENABLE_QBIT_2" == true ]]; then - log "Processing secondary instance..." - process_qbit_instance "$QBIT_NAME_2" "$QBIT_HOST_2" "$QBIT_USER_2" "$QBIT_PASS_2" || \ - ((failed_instances++)) - else - log "Secondary instance disabled" - fi + # Process all instances + local instance_count + instance_count=$(get_instance_count) + + for ((i=0; i/dev/null || log "⚠ Warning: Could not set ownership for $1" } +# ================================ +# CONFIG FORMAT DETECTION +# ================================ +detect_config_format() { + # Check if array-based config is used + if [[ -v HOSTS[@] ]] && [[ ${#HOSTS[@]} -gt 0 ]]; then + echo "array" + else + echo "legacy" + fi +} + +get_instance_count() { + local format + format=$(detect_config_format) + + if [[ "$format" == "array" ]]; then + echo "${#HOSTS[@]}" + else + # Legacy format: count based on ENABLE_QBIT_2 + if [[ "${ENABLE_QBIT_2:-false}" == true ]]; then + echo "2" + else + echo "1" + fi + fi +} + +get_instance_details() { + local index="$1" + local format + format=$(detect_config_format) + + if [[ "$format" == "array" ]]; then + # Array format: return details from arrays + local name="${NAMES[$index]:-qBit-Instance-$((index + 1))}" + local host="${HOSTS[$index]}" + local user="${USERS[$index]}" + local password="${PASSWORDS[$index]}" + + echo "$name|$host|$user|$password" + else + # Legacy format: map index to old variables + if [[ $index -eq 0 ]]; then + echo "${QBIT_NAME_1}|${QBIT_HOST_1}|${QBIT_USER_1}|${QBIT_PASS_1}" + elif [[ $index -eq 1 ]]; then + echo "${QBIT_NAME_2}|${QBIT_HOST_2}|${QBIT_USER_2}|${QBIT_PASS_2}" + else + error "Invalid instance index: $index" + fi + fi +} + # ================================ # VERSION CHECK FUNCTION # ================================ @@ -104,9 +157,14 @@ check_script_version() { # Compare versions if [[ "$SCRIPT_VERSION" != "$latest_version" ]]; then # Simple version comparison (works for semantic versioning) - if printf '%s\n' "$latest_version" "$SCRIPT_VERSION" | sort -V | head -n1 | grep -q "^$SCRIPT_VERSION$" 2>/dev/null || true; then + # Sort both versions and check if SCRIPT_VERSION comes first (is older) + if printf '%s\n' "$latest_version" "$SCRIPT_VERSION" | sort -V | head -n1 | grep -q "^$SCRIPT_VERSION$" 2>/dev/null; then + # SCRIPT_VERSION is older, so there's a newer version available log "⚠ New version available: $latest_version" notify "mover-tuning-start.sh Update" "Version $latest_version available (current: $SCRIPT_VERSION)

📖 Visit the TRaSH-Guides for the latest version" + else + # latest_version is older, local version is newer + log "✓ Local version ($SCRIPT_VERSION) is newer than remote ($latest_version)" fi else log "✓ Script is up to date" @@ -162,9 +220,14 @@ check_config_version() { # Compare versions if [[ "$current_config_version" != "$remote_config_version" ]]; then # Simple version comparison (works for semantic versioning) - if printf '%s\n' "$remote_config_version" "$current_config_version" | sort -V | head -n1 | grep -q "^$current_config_version$" 2>/dev/null || true; then + # Sort both versions and check if current_config_version comes first (is older) + if printf '%s\n' "$remote_config_version" "$current_config_version" | sort -V | head -n1 | grep -q "^$current_config_version$" 2>/dev/null; then + # current_config_version is older, so there's a newer version available log "⚠ New config version available: $remote_config_version" notify "mover-tuning.cfg Update" "Config version $remote_config_version available
Current version: $current_config_version

📖 Visit the TRaSH-Guides for the latest version" + else + # remote_config_version is older, local version is newer + log "✓ Local config version ($current_config_version) is newer than remote ($remote_config_version)" fi else log "✓ Config is up to date" @@ -272,6 +335,31 @@ validate_config() { [[ "$DAYS_FROM" -ge 2 ]] || error "DAYS_FROM must be at least 2" [[ "$DAYS_TO" -ge "$DAYS_FROM" ]] || error "DAYS_TO must be >= DAYS_FROM" [[ -d "$CACHE_MOUNT" ]] || error "Cache mount does not exist: $CACHE_MOUNT" + + # Validate instance configuration + local format + format=$(detect_config_format) + + if [[ "$format" == "array" ]]; then + # Validate array-based config + [[ ${#HOSTS[@]} -gt 0 ]] || error "HOSTS array is empty" + [[ ${#USERS[@]} -eq ${#HOSTS[@]} ]] || error "USERS array length doesn't match HOSTS" + [[ ${#PASSWORDS[@]} -eq ${#HOSTS[@]} ]] || error "PASSWORDS array length doesn't match HOSTS" + + # NAMES array is optional, but if present should match + if [[ -v NAMES[@] ]] && [[ ${#NAMES[@]} -gt 0 ]]; then + [[ ${#NAMES[@]} -eq ${#HOSTS[@]} ]] || error "NAMES array length doesn't match HOSTS" + fi + + log "✓ Using array-based configuration (${#HOSTS[@]} instance(s))" + else + # Validate legacy config + [[ -n "${QBIT_HOST_1:-}" ]] || error "QBIT_HOST_1 is not set" + [[ -n "${QBIT_USER_1:-}" ]] || error "QBIT_USER_1 is not set" + [[ -n "${QBIT_PASS_1:-}" ]] || error "QBIT_PASS_1 is not set" + + log "✓ Using legacy configuration" + fi } # ================================ @@ -350,12 +438,18 @@ main() { fi fi - # Process instances - process_qbit_instance "$QBIT_NAME_1" "$QBIT_HOST_1" "$QBIT_USER_1" "$QBIT_PASS_1" || ((failed_instances++)) - - if [[ "$ENABLE_QBIT_2" == true ]]; then - process_qbit_instance "$QBIT_NAME_2" "$QBIT_HOST_2" "$QBIT_USER_2" "$QBIT_PASS_2" || ((failed_instances++)) - fi + # Process all instances + local instance_count + instance_count=$(get_instance_count) + + for ((i=0; i>> NOTE: Setting "DAYS_FROM" below 2 days may not work properly <<< readonly DAYS_FROM=25 # How old torrents must be (in days) before they're paused and moved (Must be at least 2 days) -readonly DAYS_TO=99 # Maximum age (days) for torrent selection +readonly DAYS_TO=99 # Maximum age (days) for torrent selection (must be >= DAYS_FROM) readonly CACHE_MOUNT="/mnt/cache/" # Cache mount point in Unraid readonly QBIT_MOVER_PATH="/mnt/user/appdata/qbt-mover/" # Path to mover.py -# Primary qBittorrent instance (REQUIRED) -readonly QBIT_NAME_1="qBit-Movies" # qBittorrent instance name -readonly QBIT_HOST_1="192.168.2.200:8800" # qBittorrent host:port -readonly QBIT_USER_1="admin" # qBittorrent username -readonly QBIT_PASS_1="qbt1-password" # qBittorrent password - -# Secondary qBittorrent instance (OPTIONAL) -readonly ENABLE_QBIT_2=false # Set to true to enable secondary instance -readonly QBIT_NAME_2="qBit-TV" # qBittorrent instance name -readonly QBIT_HOST_2="192.168.2.200:8811" # qBittorrent host:port -readonly QBIT_USER_2="admin" # qBittorrent username -readonly QBIT_PASS_2="qbt2-password" # qBittorrent password +# qBittorrent instances +# Supports unlimited qBittorrent instances +# Arrays NAMES, HOSTS, USERS and PASSWORDS must all have the same length +# NAMES array is optional - if omitted, instances will be named "qBit-Instance-1", "qBit-Instance-2", etc. +readonly NAMES=("qBit-Movies" "qBit-TV" "qBit-Music") # qBittorrent instance names +readonly HOSTS=("192.168.2.200:8088" "192.168.2.200:8811" "192.168.2.200:8822") # qBittorrent host:port +readonly USERS=("admin" "admin" "admin") # qBittorrent usernames +readonly PASSWORDS=("qbt1-password" "qbt2-password" "qbt3-password") # qBittorrent passwords # qBit-Manage integration (OPTIONAL) readonly ENABLE_QBIT_MANAGE=true # Set to false to disable qBit-Manage @@ -94,4 +90,4 @@ declare -A folders folders["Series"]="/mnt/user/data/torrents/tv/ /mnt/user/data/media/tv/" folders["Movies"]="/mnt/user/data/torrents/movies/ /mnt/user/data/media/movies/" # folders["Series-xseed"]="/mnt/user/data/torrents/tv/ /mnt/user/data/torrents/series_linkdir/" -# folders["Movies-xseed"]="/mnt/user/data/torrents/movies/ /mnt/user/data/torrents/movies_linkdir/" +# folders["Movies-xseed"]="/mnt/user/data/torrents/movies/ /mnt/user/data/torrents/movies_linkdir/" \ No newline at end of file From 888fe37095a5fc37c6b97ca8a159db4595c5e1e8 Mon Sep 17 00:00:00 2001 From: Bauke Date: Fri, 28 Nov 2025 11:51:21 +0100 Subject: [PATCH 2/6] Fixed issues sugested by sourcery-ai - Fixed the grep pipeline issue - Fixed the pipe delimiter issue in get_instance_details --- includes/downloaders/mover-tuning-end.sh | 36 ++++++++++--------- includes/downloaders/mover-tuning-start.sh | 41 +++++++++++++--------- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/includes/downloaders/mover-tuning-end.sh b/includes/downloaders/mover-tuning-end.sh index ff0eb0d46a..99d13b3398 100644 --- a/includes/downloaders/mover-tuning-end.sh +++ b/includes/downloaders/mover-tuning-end.sh @@ -4,7 +4,7 @@ set -euo pipefail # Exit on error, undefined variables, and pipe failures # ===================================== # Script: qBittorrent Cache Mover - End # Version: 1.1.0 -# Updated: 20251126 +# Updated: 20251128 # ===================================== # Script version and update check URLs @@ -78,19 +78,23 @@ get_instance_details() { format=$(detect_config_format) if [[ "$format" == "array" ]]; then - # Array format: return details from arrays - local name="${NAMES[$index]:-qBit-Instance-$((index + 1))}" - local host="${HOSTS[$index]}" - local user="${USERS[$index]}" - local password="${PASSWORDS[$index]}" - - echo "$name|$host|$user|$password" + # Array format: set global variables + INSTANCE_NAME="${NAMES[$index]:-qBit-Instance-$((index + 1))}" + INSTANCE_HOST="${HOSTS[$index]}" + INSTANCE_USER="${USERS[$index]}" + INSTANCE_PASSWORD="${PASSWORDS[$index]}" else # Legacy format: map index to old variables if [[ $index -eq 0 ]]; then - echo "${QBIT_NAME_1}|${QBIT_HOST_1}|${QBIT_USER_1}|${QBIT_PASS_1}" + INSTANCE_NAME="${QBIT_NAME_1}" + INSTANCE_HOST="${QBIT_HOST_1}" + INSTANCE_USER="${QBIT_USER_1}" + INSTANCE_PASSWORD="${QBIT_PASS_1}" elif [[ $index -eq 1 ]]; then - echo "${QBIT_NAME_2}|${QBIT_HOST_2}|${QBIT_USER_2}|${QBIT_PASS_2}" + INSTANCE_NAME="${QBIT_NAME_2}" + INSTANCE_HOST="${QBIT_HOST_2}" + INSTANCE_USER="${QBIT_USER_2}" + INSTANCE_PASSWORD="${QBIT_PASS_2}" else error "Invalid instance index: $index" fi @@ -145,7 +149,10 @@ check_script_version() { if [[ "$SCRIPT_VERSION" != "$latest_version" ]]; then # Simple version comparison (works for semantic versioning) # Sort both versions and check if SCRIPT_VERSION comes first (is older) - if printf '%s\n' "$latest_version" "$SCRIPT_VERSION" | sort -V | head -n1 | grep -q "^$SCRIPT_VERSION$" 2>/dev/null; then + local oldest_version + oldest_version=$(printf '%s\n' "$latest_version" "$SCRIPT_VERSION" | sort -V | head -n1) + + if [[ "$oldest_version" == "$SCRIPT_VERSION" ]]; then # SCRIPT_VERSION is older, so there's a newer version available log "⚠ New version available: $latest_version" notify "mover-tuning-end.sh Update" "Version $latest_version available (current: $SCRIPT_VERSION)

📖 Visit the TRaSH-Guides for the latest version" @@ -460,12 +467,9 @@ main() { instance_count=$(get_instance_count) for ((i=0; i/dev/null; then + local oldest_version + oldest_version=$(printf '%s\n' "$latest_version" "$SCRIPT_VERSION" | sort -V | head -n1) + + if [[ "$oldest_version" == "$SCRIPT_VERSION" ]]; then # SCRIPT_VERSION is older, so there's a newer version available log "⚠ New version available: $latest_version" notify "mover-tuning-start.sh Update" "Version $latest_version available (current: $SCRIPT_VERSION)

📖 Visit the TRaSH-Guides for the latest version" @@ -221,7 +228,10 @@ check_config_version() { if [[ "$current_config_version" != "$remote_config_version" ]]; then # Simple version comparison (works for semantic versioning) # Sort both versions and check if current_config_version comes first (is older) - if printf '%s\n' "$remote_config_version" "$current_config_version" | sort -V | head -n1 | grep -q "^$current_config_version$" 2>/dev/null; then + local oldest_version + oldest_version=$(printf '%s\n' "$remote_config_version" "$current_config_version" | sort -V | head -n1) + + if [[ "$oldest_version" == "$current_config_version" ]]; then # current_config_version is older, so there's a newer version available log "⚠ New config version available: $remote_config_version" notify "mover-tuning.cfg Update" "Config version $remote_config_version available
Current version: $current_config_version

📖 Visit the TRaSH-Guides for the latest version" @@ -443,12 +453,9 @@ main() { instance_count=$(get_instance_count) for ((i=0; i Date: Fri, 28 Nov 2025 11:54:27 +0100 Subject: [PATCH 3/6] Fix lint issues --- includes/downloaders/mover-tuning-end.sh | 18 +++++++++--------- includes/downloaders/mover-tuning-start.sh | 22 +++++++++++----------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/includes/downloaders/mover-tuning-end.sh b/includes/downloaders/mover-tuning-end.sh index 99d13b3398..2765393a90 100644 --- a/includes/downloaders/mover-tuning-end.sh +++ b/includes/downloaders/mover-tuning-end.sh @@ -59,7 +59,7 @@ detect_config_format() { get_instance_count() { local format format=$(detect_config_format) - + if [[ "$format" == "array" ]]; then echo "${#HOSTS[@]}" else @@ -76,7 +76,7 @@ get_instance_details() { local index="$1" local format format=$(detect_config_format) - + if [[ "$format" == "array" ]]; then # Array format: set global variables INSTANCE_NAME="${NAMES[$index]:-qBit-Instance-$((index + 1))}" @@ -151,7 +151,7 @@ check_script_version() { # Sort both versions and check if SCRIPT_VERSION comes first (is older) local oldest_version oldest_version=$(printf '%s\n' "$latest_version" "$SCRIPT_VERSION" | sort -V | head -n1) - + if [[ "$oldest_version" == "$SCRIPT_VERSION" ]]; then # SCRIPT_VERSION is older, so there's a newer version available log "⚠ New version available: $latest_version" @@ -365,25 +365,25 @@ validate_config() { # Validate instance configuration local format format=$(detect_config_format) - + if [[ "$format" == "array" ]]; then # Validate array-based config [[ ${#HOSTS[@]} -gt 0 ]] || error "HOSTS array is empty" [[ ${#USERS[@]} -eq ${#HOSTS[@]} ]] || error "USERS array length doesn't match HOSTS" [[ ${#PASSWORDS[@]} -eq ${#HOSTS[@]} ]] || error "PASSWORDS array length doesn't match HOSTS" - + # NAMES array is optional, but if present should match if [[ -v NAMES[@] ]] && [[ ${#NAMES[@]} -gt 0 ]]; then [[ ${#NAMES[@]} -eq ${#HOSTS[@]} ]] || error "NAMES array length doesn't match HOSTS" fi - + log "✓ Using array-based configuration (${#HOSTS[@]} instance(s))" else # Validate legacy config [[ -n "${QBIT_HOST_1:-}" ]] || error "QBIT_HOST_1 is not set" [[ -n "${QBIT_USER_1:-}" ]] || error "QBIT_USER_1 is not set" [[ -n "${QBIT_PASS_1:-}" ]] || error "QBIT_PASS_1 is not set" - + log "✓ Using legacy configuration" fi @@ -465,10 +465,10 @@ main() { # Process all instances local instance_count instance_count=$(get_instance_count) - + for ((i=0; i= DAYS_FROM" [[ -d "$CACHE_MOUNT" ]] || error "Cache mount does not exist: $CACHE_MOUNT" - + # Validate instance configuration local format format=$(detect_config_format) - + if [[ "$format" == "array" ]]; then # Validate array-based config [[ ${#HOSTS[@]} -gt 0 ]] || error "HOSTS array is empty" [[ ${#USERS[@]} -eq ${#HOSTS[@]} ]] || error "USERS array length doesn't match HOSTS" [[ ${#PASSWORDS[@]} -eq ${#HOSTS[@]} ]] || error "PASSWORDS array length doesn't match HOSTS" - + # NAMES array is optional, but if present should match if [[ -v NAMES[@] ]] && [[ ${#NAMES[@]} -gt 0 ]]; then [[ ${#NAMES[@]} -eq ${#HOSTS[@]} ]] || error "NAMES array length doesn't match HOSTS" fi - + log "✓ Using array-based configuration (${#HOSTS[@]} instance(s))" else # Validate legacy config [[ -n "${QBIT_HOST_1:-}" ]] || error "QBIT_HOST_1 is not set" [[ -n "${QBIT_USER_1:-}" ]] || error "QBIT_USER_1 is not set" [[ -n "${QBIT_PASS_1:-}" ]] || error "QBIT_PASS_1 is not set" - + log "✓ Using legacy configuration" fi } @@ -451,10 +451,10 @@ main() { # Process all instances local instance_count instance_count=$(get_instance_count) - + for ((i=0; i Date: Fri, 28 Nov 2025 11:59:43 +0100 Subject: [PATCH 4/6] Fix one more lint issue --- includes/downloaders/mover-tuning.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/downloaders/mover-tuning.cfg b/includes/downloaders/mover-tuning.cfg index ce39eb76c5..886423e8ce 100644 --- a/includes/downloaders/mover-tuning.cfg +++ b/includes/downloaders/mover-tuning.cfg @@ -90,4 +90,4 @@ declare -A folders folders["Series"]="/mnt/user/data/torrents/tv/ /mnt/user/data/media/tv/" folders["Movies"]="/mnt/user/data/torrents/movies/ /mnt/user/data/media/movies/" # folders["Series-xseed"]="/mnt/user/data/torrents/tv/ /mnt/user/data/torrents/series_linkdir/" -# folders["Movies-xseed"]="/mnt/user/data/torrents/movies/ /mnt/user/data/torrents/movies_linkdir/" \ No newline at end of file +# folders["Movies-xseed"]="/mnt/user/data/torrents/movies/ /mnt/user/data/torrents/movies_linkdir/" From a25289ea1e1ae7b315a24ee0e3dbf4c66524291f Mon Sep 17 00:00:00 2001 From: Bauke Date: Mon, 1 Dec 2025 13:53:21 +0100 Subject: [PATCH 5/6] Add Unraid notifications for configuration errors mover-tuning-start.sh: Full validation with Unraid notifications for configuration errors Shows detailed error messages with array lengths mover-tuning-end.sh: Basic validation (still checks for errors to prevent execution with bad config) Only logs to terminal, no Unraid notifications --- includes/downloaders/mover-tuning-end.sh | 2 +- includes/downloaders/mover-tuning-start.sh | 24 +++++++++++++++++----- includes/downloaders/mover-tuning.cfg | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/includes/downloaders/mover-tuning-end.sh b/includes/downloaders/mover-tuning-end.sh index 2765393a90..310bf5d7fa 100644 --- a/includes/downloaders/mover-tuning-end.sh +++ b/includes/downloaders/mover-tuning-end.sh @@ -4,7 +4,7 @@ set -euo pipefail # Exit on error, undefined variables, and pipe failures # ===================================== # Script: qBittorrent Cache Mover - End # Version: 1.1.0 -# Updated: 20251128 +# Updated: 20251201 # ===================================== # Script version and update check URLs diff --git a/includes/downloaders/mover-tuning-start.sh b/includes/downloaders/mover-tuning-start.sh index 23e68bc2ba..41689fc6a9 100644 --- a/includes/downloaders/mover-tuning-start.sh +++ b/includes/downloaders/mover-tuning-start.sh @@ -4,7 +4,7 @@ set -euo pipefail # Exit on error, undefined variables, and pipe failures # ======================================= # Script: qBittorrent Cache Mover - Start # Version: 1.1.0 -# Updated: 20251128 +# Updated: 20251201 # ======================================= # Script version and update check URLs @@ -352,13 +352,27 @@ validate_config() { if [[ "$format" == "array" ]]; then # Validate array-based config - [[ ${#HOSTS[@]} -gt 0 ]] || error "HOSTS array is empty" - [[ ${#USERS[@]} -eq ${#HOSTS[@]} ]] || error "USERS array length doesn't match HOSTS" - [[ ${#PASSWORDS[@]} -eq ${#HOSTS[@]} ]] || error "PASSWORDS array length doesn't match HOSTS" + if [[ ${#HOSTS[@]} -eq 0 ]]; then + notify "Configuration Error" "HOSTS array is empty" + error "HOSTS array is empty" + fi + + if [[ ${#USERS[@]} -ne ${#HOSTS[@]} ]]; then + notify "Configuration Error" "USERS array length (${#USERS[@]}) doesn't match HOSTS (${#HOSTS[@]})" + error "USERS array length doesn't match HOSTS" + fi + + if [[ ${#PASSWORDS[@]} -ne ${#HOSTS[@]} ]]; then + notify "Configuration Error" "PASSWORDS array length (${#PASSWORDS[@]}) doesn't match HOSTS (${#HOSTS[@]})" + error "PASSWORDS array length doesn't match HOSTS" + fi # NAMES array is optional, but if present should match if [[ -v NAMES[@] ]] && [[ ${#NAMES[@]} -gt 0 ]]; then - [[ ${#NAMES[@]} -eq ${#HOSTS[@]} ]] || error "NAMES array length doesn't match HOSTS" + if [[ ${#NAMES[@]} -ne ${#HOSTS[@]} ]]; then + notify "Configuration Error" "NAMES array length (${#NAMES[@]}) doesn't match HOSTS (${#HOSTS[@]})" + error "NAMES array length doesn't match HOSTS" + fi fi log "✓ Using array-based configuration (${#HOSTS[@]} instance(s))" diff --git a/includes/downloaders/mover-tuning.cfg b/includes/downloaders/mover-tuning.cfg index 886423e8ce..4497d8ef1a 100644 --- a/includes/downloaders/mover-tuning.cfg +++ b/includes/downloaders/mover-tuning.cfg @@ -2,7 +2,7 @@ # <----- Update and version settings -----> # ============================================= -readonly CONFIG_VERSION="1.0.0" # ONLY UPDATE THE VERSION NUMBER WHEN A CONFIGURATION FILE CHANGE HAS BEEN MADE +readonly CONFIG_VERSION="1.1.0" # ONLY UPDATE THE VERSION NUMBER WHEN A CONFIGURATION FILE CHANGE HAS BEEN MADE readonly ENABLE_VERSION_CHECK=true # Set to false to disable all update checks and notifications (not recommended) # ============================================= From 0965797380e8096f2745d7f68f416173423516a4 Mon Sep 17 00:00:00 2001 From: Bauke Date: Fri, 5 Dec 2025 12:19:02 +0100 Subject: [PATCH 6/6] Include .cfg files to the Fixing Run Errors command. mover-tuning.cfg also needs to have Unix line endings for it to work. --- .../Tips/How-to-run-the-unRaid-mover-for-qBittorrent.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Downloaders/qBittorrent/Tips/How-to-run-the-unRaid-mover-for-qBittorrent.md b/docs/Downloaders/qBittorrent/Tips/How-to-run-the-unRaid-mover-for-qBittorrent.md index 5e1daa7b0f..3749aaeaa6 100644 --- a/docs/Downloaders/qBittorrent/Tips/How-to-run-the-unRaid-mover-for-qBittorrent.md +++ b/docs/Downloaders/qBittorrent/Tips/How-to-run-the-unRaid-mover-for-qBittorrent.md @@ -125,10 +125,10 @@ chmod +x /mnt/user/appdata/qbt-mover/mover-tuning-end.sh After editing the scripts, make sure they use LF line endings (Unix format). If you edited the files on Windows, they may have CRLF line endings, which can cause errors. -Run the following command to convert all `.sh` files to the correct format: +Run the following command to convert all `.sh` and `.cfg` files to the correct format: ```bash -for file in *.sh; do [ -f "$file" ] && sed -i 's/\r$//' "$file" && echo "Converted $file"; done +for file in *.sh *.cfg; do [ -f "$file" ] && sed -i 's/\r$//' "$file" && echo "Converted $file"; done ``` **How to use this command:** @@ -143,7 +143,7 @@ for file in *.sh; do [ -f "$file" ] && sed -i 's/\r$//' "$file" && echo "Convert 3. Paste the command above 4. Press ++enter++ -This converts all `.sh` files from CRLF (Windows line endings) to LF (Unix line endings) in the current directory. +This converts all `.sh` and `.cfg` files from CRLF (Windows line endings) to LF (Unix line endings) in the current directory. ---