Skip to content

Commit acb512c

Browse files
committed
feat(downloaders): Add WebUI API key support for qBittorrent
1 parent 1d7937b commit acb512c

3 files changed

Lines changed: 74 additions & 40 deletions

File tree

includes/downloaders/mover-tuning-end.sh

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ set -euo pipefail # Exit on error, undefined variables, and pipe failures
33

44
# =====================================
55
# Script: qBittorrent Cache Mover - End
6-
# Version: 1.3.4
7-
# Updated: 20260614
6+
# Version: 1.3.5
7+
# Updated: 20260817
88
# =====================================
99

1010
# Script version and update check URLs
11-
readonly SCRIPT_VERSION="1.3.4"
11+
readonly SCRIPT_VERSION="1.3.5"
1212
readonly SCRIPT_RAW_URL="https://raw.githubusercontent.com/TRaSH-Guides/Guides/refs/heads/master/includes/downloaders/mover-tuning-end.sh"
1313

1414
# Get the directory where the script is located
@@ -83,6 +83,7 @@ get_instance_details() {
8383
INSTANCE_HOST="${HOSTS[$index]}"
8484
INSTANCE_USER="${USERS[$index]}"
8585
INSTANCE_PASSWORD="${PASSWORDS[$index]}"
86+
INSTANCE_API_KEY="${API_KEYS[$index]:-}"
8687
INSTANCE_CA_BUNDLE="${CA_BUNDLES[$index]:-}"
8788
else
8889
# Legacy format: map index to old variables
@@ -91,12 +92,14 @@ get_instance_details() {
9192
INSTANCE_HOST="${QBIT_HOST_1}"
9293
INSTANCE_USER="${QBIT_USER_1}"
9394
INSTANCE_PASSWORD="${QBIT_PASS_1}"
95+
INSTANCE_API_KEY="${QBIT_API_KEY_1:-}"
9496
INSTANCE_CA_BUNDLE="${QBIT_CA_BUNDLE_1:-}"
9597
elif [[ $index -eq 1 ]]; then
9698
INSTANCE_NAME="${QBIT_NAME_2}"
9799
INSTANCE_HOST="${QBIT_HOST_2}"
98100
INSTANCE_USER="${QBIT_USER_2}"
99101
INSTANCE_PASSWORD="${QBIT_PASS_2}"
102+
INSTANCE_API_KEY="${QBIT_API_KEY_2:-}"
100103
INSTANCE_CA_BUNDLE="${QBIT_CA_BUNDLE_2:-}"
101104
else
102105
error "Invalid instance index: $index"
@@ -391,6 +394,11 @@ validate_config() {
391394
[[ ${#NAMES[@]} -eq ${#HOSTS[@]} ]] || error "NAMES array length doesn't match HOSTS"
392395
fi
393396

397+
# API_KEYS array is optional, but if present should match
398+
if [[ -v API_KEYS ]] && [[ ${#API_KEYS[@]} -gt 0 ]]; then
399+
[[ ${#API_KEYS[@]} -eq ${#HOSTS[@]} ]] || error "API_KEYS array length doesn't match HOSTS"
400+
fi
401+
394402
# CA_BUNDLES array is optional, but if present should match
395403
if [[ -v CA_BUNDLES ]] && [[ ${#CA_BUNDLES[@]} -gt 0 ]]; then
396404
[[ ${#CA_BUNDLES[@]} -eq ${#HOSTS[@]} ]] || error "CA_BUNDLES array length doesn't match HOSTS"
@@ -429,7 +437,8 @@ process_qbit_instance() {
429437
local host="$2"
430438
local user="$3"
431439
local password="$4"
432-
local ca_bundle="${5:-}"
440+
local api_key="${5:-}"
441+
local ca_bundle="${6:-}"
433442

434443
log "Processing $name..."
435444

@@ -446,20 +455,25 @@ process_qbit_instance() {
446455
return 1
447456
fi
448457

449-
local ca_bundle_args=()
458+
local mover_args=(
459+
--resume
460+
--host "$host"
461+
--days_from "$DAYS_FROM"
462+
--days_to "$DAYS_TO"
463+
)
464+
465+
if [[ -n "$api_key" ]]; then
466+
mover_args+=(--api-key "$api_key")
467+
else
468+
mover_args+=(--user "$user" --password "$password")
469+
fi
470+
450471
if [[ -n "$ca_bundle" ]]; then
451-
ca_bundle_args=(--ca-bundle "$ca_bundle")
472+
mover_args+=(--ca-bundle "$ca_bundle")
452473
fi
453474

454475
# Execute mover script
455-
if "$python_cmd" "${QBIT_MOVER_PATH}mover.py" \
456-
--resume \
457-
--host "$host" \
458-
--user "$user" \
459-
--password "$password" \
460-
--days_from "$DAYS_FROM" \
461-
--days_to "$DAYS_TO" \
462-
"${ca_bundle_args[@]}"; then
476+
if "$python_cmd" "${QBIT_MOVER_PATH}mover.py" "${mover_args[@]}"; then
463477
log "✓ Successfully resumed torrents for $name"
464478
notify "$name" "Resumed @ $(date +%H:%M:%S)"
465479
return 0
@@ -495,7 +509,7 @@ main() {
495509
for ((i=0; i<instance_count; i++)); do
496510
get_instance_details "$i"
497511

498-
process_qbit_instance "$INSTANCE_NAME" "$INSTANCE_HOST" "$INSTANCE_USER" "$INSTANCE_PASSWORD" "$INSTANCE_CA_BUNDLE" || ((failed_instances++))
512+
process_qbit_instance "$INSTANCE_NAME" "$INSTANCE_HOST" "$INSTANCE_USER" "$INSTANCE_PASSWORD" "$INSTANCE_API_KEY" "$INSTANCE_CA_BUNDLE" || ((failed_instances++))
499513
done
500514

501515
# Run duplicate finder if enabled

includes/downloaders/mover-tuning-start.sh

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ set -euo pipefail # Exit on error, undefined variables, and pipe failures
33

44
# =======================================
55
# Script: qBittorrent Cache Mover - Start
6-
# Version: 1.3.3
7-
# Updated: 20260614
6+
# Version: 1.3.4
7+
# Updated: 20260817
88
# =======================================
99

1010
# Script version and update check URLs
11-
readonly SCRIPT_VERSION="1.3.3"
11+
readonly SCRIPT_VERSION="1.3.4"
1212
readonly SCRIPT_RAW_URL="https://raw.githubusercontent.com/TRaSH-Guides/Guides/refs/heads/master/includes/downloaders/mover-tuning-start.sh"
1313
readonly CONFIG_RAW_URL="https://raw.githubusercontent.com/TRaSH-Guides/Guides/refs/heads/master/includes/downloaders/mover-tuning.cfg"
1414

@@ -96,6 +96,7 @@ get_instance_details() {
9696
INSTANCE_HOST="${HOSTS[$index]}"
9797
INSTANCE_USER="${USERS[$index]}"
9898
INSTANCE_PASSWORD="${PASSWORDS[$index]}"
99+
INSTANCE_API_KEY="${API_KEYS[$index]:-}"
99100
INSTANCE_CA_BUNDLE="${CA_BUNDLES[$index]:-}"
100101
else
101102
# Legacy format: map index to old variables
@@ -104,12 +105,14 @@ get_instance_details() {
104105
INSTANCE_HOST="${QBIT_HOST_1}"
105106
INSTANCE_USER="${QBIT_USER_1}"
106107
INSTANCE_PASSWORD="${QBIT_PASS_1}"
108+
INSTANCE_API_KEY="${QBIT_API_KEY_1:-}"
107109
INSTANCE_CA_BUNDLE="${QBIT_CA_BUNDLE_1:-}"
108110
elif [[ $index -eq 1 ]]; then
109111
INSTANCE_NAME="${QBIT_NAME_2}"
110112
INSTANCE_HOST="${QBIT_HOST_2}"
111113
INSTANCE_USER="${QBIT_USER_2}"
112114
INSTANCE_PASSWORD="${QBIT_PASS_2}"
115+
INSTANCE_API_KEY="${QBIT_API_KEY_2:-}"
113116
INSTANCE_CA_BUNDLE="${QBIT_CA_BUNDLE_2:-}"
114117
else
115118
error "Invalid instance index: $index"
@@ -487,6 +490,14 @@ validate_config() {
487490
fi
488491
fi
489492

493+
# API_KEYS array is optional, but if present should match
494+
if [[ -v API_KEYS ]] && [[ ${#API_KEYS[@]} -gt 0 ]]; then
495+
if [[ ${#API_KEYS[@]} -ne ${#HOSTS[@]} ]]; then
496+
notify "Configuration Error" "API_KEYS array length (${#API_KEYS[@]}) doesn't match HOSTS (${#HOSTS[@]})"
497+
error "API_KEYS array length doesn't match HOSTS"
498+
fi
499+
fi
500+
490501
# CA_BUNDLES array is optional, but if present should match
491502
if [[ -v CA_BUNDLES ]] && [[ ${#CA_BUNDLES[@]} -gt 0 ]]; then
492503
if [[ ${#CA_BUNDLES[@]} -ne ${#HOSTS[@]} ]]; then
@@ -510,7 +521,7 @@ validate_config() {
510521
# PROCESS QBITTORRENT INSTANCE
511522
# ================================
512523
process_qbit_instance() {
513-
local name="$1" host="$2" user="$3" password="$4" ca_bundle="${5:-}"
524+
local name="$1" host="$2" user="$3" password="$4" api_key="${5:-}" ca_bundle="${6:-}"
514525

515526
log "Processing $name..."
516527

@@ -527,23 +538,29 @@ process_qbit_instance() {
527538
return 1
528539
fi
529540

530-
local ca_bundle_args=()
541+
local mover_args=(
542+
--pause
543+
--host "$host"
544+
--cache-mount "$CACHE_MOUNT"
545+
--days_from "$DAYS_FROM"
546+
--days_to "$DAYS_TO"
547+
)
548+
549+
if [[ -n "$api_key" ]]; then
550+
mover_args+=(--api-key "$api_key")
551+
else
552+
mover_args+=(--user "$user" --password "$password")
553+
fi
554+
531555
if [[ -n "$ca_bundle" ]]; then
532-
ca_bundle_args=(--ca-bundle "$ca_bundle")
533-
fi
534-
535-
# Run mover script
536-
if $python_cmd "$MOVER_SCRIPT" \
537-
--pause \
538-
--host "$host" \
539-
--user "$user" \
540-
--password "$password" \
541-
--cache-mount "$CACHE_MOUNT" \
542-
--days_from "$DAYS_FROM" \
543-
--days_to "$DAYS_TO" \
544-
"${ca_bundle_args[@]}" 2>&1 | while IFS= read -r line; do
556+
mover_args+=(--ca-bundle "$ca_bundle")
557+
fi
558+
559+
if "$python_cmd" "$MOVER_SCRIPT" "${mover_args[@]}" 2>&1 |
560+
while IFS= read -r line; do
545561
log " $line"
546-
done; then
562+
done
563+
then
547564
log "✓ Successfully processed $name"
548565
notify "$name" "Paused @ $(date +%H:%M:%S)"
549566
return 0
@@ -606,7 +623,7 @@ main() {
606623
for ((i=0; i<instance_count; i++)); do
607624
get_instance_details "$i"
608625

609-
process_qbit_instance "$INSTANCE_NAME" "$INSTANCE_HOST" "$INSTANCE_USER" "$INSTANCE_PASSWORD" "$INSTANCE_CA_BUNDLE" || ((failed_instances++))
626+
process_qbit_instance "$INSTANCE_NAME" "$INSTANCE_HOST" "$INSTANCE_USER" "$INSTANCE_PASSWORD" "$INSTANCE_API_KEY" "$INSTANCE_CA_BUNDLE" || ((failed_instances++))
610627
done
611628

612629
# Summary

includes/downloaders/mover-tuning.cfg

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# <----- Update and version settings ----->
33
# =============================================
44

5-
readonly CONFIG_VERSION="1.3.1" # ONLY UPDATE THE VERSION NUMBER WHEN A CONFIGURATION FILE CHANGE HAS BEEN MADE
5+
readonly CONFIG_VERSION="1.3.2" # ONLY UPDATE THE VERSION NUMBER WHEN A CONFIGURATION FILE CHANGE HAS BEEN MADE
66
readonly ENABLE_VERSION_CHECK=true # Set to false to disable all update checks and notifications (not recommended)
77

88
# =============================================
@@ -21,12 +21,15 @@ readonly QBIT_MOVER_PATH="/mnt/user/appdata/qbt-mover/" # Path to mover.py
2121

2222
# qBittorrent instances
2323
# Supports unlimited qBittorrent instances
24-
# Arrays NAMES, HOSTS, USERS and PASSWORDS must all have the same length
25-
# NAMES array is optional - if omitted, instances will be named "qBit-Instance-1", "qBit-Instance-2", etc.
24+
# Arrays HOSTS, USERS and PASSWORDS must all have the same length
25+
# Arrays NAMES, API_KEYS and CA_BUNDLES are optional but if present must also have the same length as HOSTS
26+
# NAMES array, if omitted, instances will be named "qBit-Instance-1", "qBit-Instance-2", etc.
27+
# API_KEYS, if specified, will be used instead of USER/PASSWORD for authentication. If both are specified, API_KEYS will take precedence.
2628
readonly NAMES=("qBit-Movies" "qBit-TV" "qBit-Music") # qBittorrent instance names
2729
readonly HOSTS=("192.168.2.200:8088" "192.168.2.200:8811" "192.168.2.200:8822") # qBittorrent host:port
28-
readonly USERS=("admin" "admin" "admin") # qBittorrent usernames
29-
readonly PASSWORDS=("qbt1-password" "qbt2-password" "qbt3-password") # qBittorrent passwords
30+
readonly USERS=("admin" "admin" "") # qBittorrent usernames
31+
readonly PASSWORDS=("qbt1-password" "qbt2-password" "") # qBittorrent passwords
32+
readonly API_KEYS=("" "qbt_abc" "qbt_xyz") # qBittorrent WebUI API keys
3033
readonly CA_BUNDLES=("/mnt/user/appdata/qbt-mover/qbit-movies-ca.crt" "/mnt/user/appdata/qbt-mover/qbit-tv-ca.crt" "") # Path to CA bundle for SSL with self signed cert
3134

3235
# Docker container management (OPTIONAL)

0 commit comments

Comments
 (0)