481 lines
15 KiB
Bash
Executable File
481 lines
15 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Torrent Mover Configuration Utility
|
|
# A helper tool to safely update and manage your torrent-mover configuration
|
|
|
|
set -e
|
|
|
|
CONFIG_PATH="/etc/torrent/mover.conf"
|
|
BACKUP_DIR="/etc/torrent/backups"
|
|
DEFAULT_EDITOR="${EDITOR:-nano}"
|
|
|
|
# Colors for terminal output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[0;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
print_header() {
|
|
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${BLUE}║ Torrent Mover Config Utility ║${NC}"
|
|
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
|
|
echo ""
|
|
}
|
|
|
|
usage() {
|
|
print_header
|
|
echo -e "Usage: ${GREEN}$(basename "$0")${NC} [OPTION]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo -e " ${YELLOW}edit${NC} Edit the configuration file with your default editor"
|
|
echo -e " ${YELLOW}backup${NC} Create a backup of the current configuration"
|
|
echo -e " ${YELLOW}restore${NC} [file] Restore a previous backup (lists available backups if no file specified)"
|
|
echo -e " ${YELLOW}validate${NC} Check the configuration for errors"
|
|
echo -e " ${YELLOW}default${NC} Show the default configuration values"
|
|
echo -e " ${YELLOW}show${NC} Display the current configuration"
|
|
echo -e " ${YELLOW}set${NC} key value Update a specific configuration value"
|
|
echo -e " ${YELLOW}get${NC} key Get the value of a specific configuration key"
|
|
echo -e " ${YELLOW}help${NC} Display this help message"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $(basename "$0") edit # Edit the configuration file"
|
|
echo " $(basename "$0") backup # Create a timestamped backup"
|
|
echo " $(basename "$0") set COPY_MODE move # Change the copy mode to 'move'"
|
|
echo " $(basename "$0") get TRANSMISSION_IP # Show the Transmission server IP"
|
|
echo ""
|
|
}
|
|
|
|
# Check if user is root or using sudo
|
|
check_permissions() {
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo -e "${RED}Error: This command requires root privileges.${NC}"
|
|
echo "Please run with sudo:"
|
|
echo -e " ${YELLOW}sudo $(basename "$0") $*${NC}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Create a backup of the current configuration
|
|
backup_config() {
|
|
check_permissions "$@"
|
|
|
|
if [ ! -f "$CONFIG_PATH" ]; then
|
|
echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$BACKUP_DIR"
|
|
local timestamp=$(date +"%Y%m%d_%H%M%S")
|
|
local backup_file="$BACKUP_DIR/mover.conf.$timestamp"
|
|
|
|
cp "$CONFIG_PATH" "$backup_file"
|
|
echo -e "${GREEN}Configuration backed up to:${NC} $backup_file"
|
|
}
|
|
|
|
# Restore a configuration from backup
|
|
restore_config() {
|
|
check_permissions "$@"
|
|
|
|
if [ ! -d "$BACKUP_DIR" ]; then
|
|
echo -e "${RED}Error: Backup directory not found at $BACKUP_DIR${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$1" ]; then
|
|
# List available backups
|
|
echo -e "${BLUE}Available backups:${NC}"
|
|
local count=0
|
|
for file in "$BACKUP_DIR"/mover.conf.*; do
|
|
if [ -f "$file" ]; then
|
|
count=$((count+1))
|
|
local date_part=$(basename "$file" | cut -d. -f3)
|
|
echo -e "${YELLOW}$count)${NC} $(basename "$file") ($(date -d "${date_part:0:8} ${date_part:9:2}:${date_part:11:2}:${date_part:13:2}" "+%Y-%m-%d %H:%M:%S"))"
|
|
fi
|
|
done
|
|
|
|
if [ "$count" -eq 0 ]; then
|
|
echo -e "${YELLOW}No backups found.${NC}"
|
|
exit 0
|
|
fi
|
|
|
|
echo ""
|
|
read -p "Enter the number of the backup to restore: " selection
|
|
|
|
if ! [[ "$selection" =~ ^[0-9]+$ ]] || [ "$selection" -lt 1 ] || [ "$selection" -gt "$count" ]; then
|
|
echo -e "${RED}Error: Invalid selection.${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Get the filename of the selected backup
|
|
local selected_file=$(ls -1 "$BACKUP_DIR"/mover.conf.* | sed -n "${selection}p")
|
|
else
|
|
# Use the specified backup file
|
|
local selected_file="$BACKUP_DIR/$1"
|
|
|
|
if [ ! -f "$selected_file" ]; then
|
|
echo -e "${RED}Error: Backup file not found at $selected_file${NC}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Create a backup of the current config before restoring
|
|
backup_config
|
|
|
|
# Restore the selected backup
|
|
cp "$selected_file" "$CONFIG_PATH"
|
|
echo -e "${GREEN}Configuration restored from:${NC} $selected_file"
|
|
}
|
|
|
|
# Edit the configuration file
|
|
edit_config() {
|
|
check_permissions "$@"
|
|
|
|
if [ ! -f "$CONFIG_PATH" ]; then
|
|
echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Create a backup before editing
|
|
backup_config
|
|
|
|
# Open in the user's preferred editor
|
|
$DEFAULT_EDITOR "$CONFIG_PATH"
|
|
|
|
# Validate after editing
|
|
validate_config
|
|
}
|
|
|
|
# Validate the configuration for errors
|
|
validate_config() {
|
|
check_permissions "$@"
|
|
|
|
if [ ! -f "$CONFIG_PATH" ]; then
|
|
echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${BLUE}Validating configuration file...${NC}"
|
|
|
|
# Source the config file in a subshell to check for syntax errors
|
|
if ! (bash -n "$CONFIG_PATH"); then
|
|
echo -e "${RED}Error: The configuration file contains syntax errors.${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Load the configuration
|
|
source "$CONFIG_PATH"
|
|
|
|
# Check mandatory settings
|
|
local required_vars=(
|
|
"TRANSMISSION_IP"
|
|
"TRANSMISSION_PORT"
|
|
"TRANSMISSION_PATH_PREFIX"
|
|
"LOCAL_PATH_PREFIX"
|
|
"DIR_MOVIES_DST"
|
|
"DIR_APPS_DST"
|
|
"DIR_GAMES_DST"
|
|
"DIR_BOOKS_DST"
|
|
"DEFAULT_DST"
|
|
"COPY_MODE"
|
|
)
|
|
|
|
local error_count=0
|
|
for var in "${required_vars[@]}"; do
|
|
if [ -z "${!var}" ]; then
|
|
echo -e "${RED}Error: Required setting '$var' is not defined.${NC}"
|
|
error_count=$((error_count+1))
|
|
fi
|
|
done
|
|
|
|
# Validate COPY_MODE
|
|
if [ -n "$COPY_MODE" ] && [ "$COPY_MODE" != "copy" ] && [ "$COPY_MODE" != "move" ]; then
|
|
echo -e "${RED}Error: COPY_MODE must be 'copy' or 'move', not '$COPY_MODE'.${NC}"
|
|
error_count=$((error_count+1))
|
|
fi
|
|
|
|
# Validate directory paths
|
|
local dir_vars=(
|
|
"DIR_GAMES_DST"
|
|
"DIR_APPS_DST"
|
|
"DIR_MOVIES_DST"
|
|
"DIR_BOOKS_DST"
|
|
"DIR_TV_DST"
|
|
"DIR_MUSIC_DST"
|
|
"DEFAULT_DST"
|
|
)
|
|
|
|
for var in "${dir_vars[@]}"; do
|
|
if [ -n "${!var}" ]; then
|
|
if [[ ! "${!var}" == /* ]]; then
|
|
echo -e "${RED}Error: Directory path for '$var' must be absolute (start with /).${NC}"
|
|
error_count=$((error_count+1))
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Check if any pattern in CUSTOM_PATTERNS references undefined variables
|
|
if [ -n "$CUSTOM_PATTERNS" ]; then
|
|
IFS=';' read -ra PATTERN_ARRAY <<< "$CUSTOM_PATTERNS"
|
|
for pattern in "${PATTERN_ARRAY[@]}"; do
|
|
IFS='=' read -ra PARTS <<< "$pattern"
|
|
if [ "${#PARTS[@]}" -eq 2 ]; then
|
|
local dest="${PARTS[1]}"
|
|
if [[ "$dest" == *'${'*'}'* ]]; then
|
|
local var_name=$(echo "$dest" | sed -n 's/.*\${//;s/}.*//p')
|
|
if [ -z "${!var_name}" ]; then
|
|
echo -e "${RED}Error: Custom pattern uses undefined variable: \${$var_name}${NC}"
|
|
error_count=$((error_count+1))
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ "$error_count" -eq 0 ]; then
|
|
echo -e "${GREEN}Configuration validation passed. No errors found.${NC}"
|
|
else
|
|
echo -e "${RED}Configuration validation failed with $error_count error(s).${NC}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Show the current configuration
|
|
show_config() {
|
|
if [ ! -f "$CONFIG_PATH" ]; then
|
|
echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
print_header
|
|
echo -e "${BLUE}Current Configuration:${NC}"
|
|
echo ""
|
|
|
|
# Load config and display it categorized
|
|
source "$CONFIG_PATH"
|
|
|
|
echo -e "${YELLOW}=== Connection Settings ===${NC}"
|
|
echo -e "TRANSMISSION_IP=${GREEN}${TRANSMISSION_IP:-<not set>}${NC}"
|
|
echo -e "TRANSMISSION_PORT=${GREEN}${TRANSMISSION_PORT:-<not set>}${NC}"
|
|
if [ -n "$TRANSMISSION_USER" ]; then
|
|
echo -e "TRANSMISSION_USER=${GREEN}${TRANSMISSION_USER}${NC}"
|
|
echo -e "TRANSMISSION_PASSWORD=${GREEN}********${NC}"
|
|
else
|
|
echo -e "TRANSMISSION_USER=${YELLOW}<not set>${NC}"
|
|
echo -e "TRANSMISSION_PASSWORD=${YELLOW}<not set>${NC}"
|
|
fi
|
|
echo -e "TRANSMISSION_PATH_PREFIX=${GREEN}${TRANSMISSION_PATH_PREFIX:-<not set>}${NC}"
|
|
echo -e "LOCAL_PATH_PREFIX=${GREEN}${LOCAL_PATH_PREFIX:-<not set>}${NC}"
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}=== Destination Directories ===${NC}"
|
|
echo -e "DIR_GAMES_DST=${GREEN}${DIR_GAMES_DST:-<not set>}${NC}"
|
|
echo -e "DIR_APPS_DST=${GREEN}${DIR_APPS_DST:-<not set>}${NC}"
|
|
echo -e "DIR_MOVIES_DST=${GREEN}${DIR_MOVIES_DST:-<not set>}${NC}"
|
|
echo -e "DIR_BOOKS_DST=${GREEN}${DIR_BOOKS_DST:-<not set>}${NC}"
|
|
echo -e "DIR_TV_DST=${GREEN}${DIR_TV_DST:-<not set>}${NC}"
|
|
echo -e "DIR_MUSIC_DST=${GREEN}${DIR_MUSIC_DST:-<not set>}${NC}"
|
|
echo -e "DEFAULT_DST=${GREEN}${DEFAULT_DST:-<not set>}${NC}"
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}=== Additional Storage Libraries ===${NC}"
|
|
echo -e "STORAGE_DIRS=${GREEN}${STORAGE_DIRS:-<not set>}${NC}"
|
|
echo -e "STORAGE_TV_DIRS=${GREEN}${STORAGE_TV_DIRS:-<not set>}${NC}"
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}=== Security Settings ===${NC}"
|
|
echo -e "TORRENT_USER=${GREEN}${TORRENT_USER:-debian-transmission}${NC}"
|
|
echo -e "TORRENT_GROUP=${GREEN}${TORRENT_GROUP:-debian-transmission}${NC}"
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}=== Performance Settings ===${NC}"
|
|
echo -e "PARALLEL_THREADS=${GREEN}${PARALLEL_THREADS:-$(nproc)}${NC}"
|
|
echo -e "PARALLEL_PROCESSING=${GREEN}${PARALLEL_PROCESSING:-1}${NC}"
|
|
echo -e "COPY_MODE=${GREEN}${COPY_MODE:-<not set>}${NC}"
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}=== Error Recovery ===${NC}"
|
|
echo -e "MAX_RETRY_ATTEMPTS=${GREEN}${MAX_RETRY_ATTEMPTS:-3}${NC}"
|
|
echo -e "RETRY_WAIT_TIME=${GREEN}${RETRY_WAIT_TIME:-15}${NC}"
|
|
echo ""
|
|
|
|
echo -e "${YELLOW}=== Logging & Integrity ===${NC}"
|
|
echo -e "LOG_FILE=${GREEN}${LOG_FILE:-/var/log/torrent_mover.log}${NC}"
|
|
echo -e "LOG_LEVEL=${GREEN}${LOG_LEVEL:-INFO}${NC}"
|
|
echo -e "USE_SYSLOG=${GREEN}${USE_SYSLOG:-false}${NC}"
|
|
echo -e "PROCESSED_LOG=${GREEN}${PROCESSED_LOG:-/var/log/torrent_processed.log}${NC}"
|
|
echo -e "CHECKSUM_DB=${GREEN}${CHECKSUM_DB:-/var/lib/torrent/checksums.db}${NC}"
|
|
echo -e "CHECK_TRANSFER_INTEGRITY=${GREEN}${CHECK_TRANSFER_INTEGRITY:-true}${NC}"
|
|
echo ""
|
|
|
|
if [ -n "$CUSTOM_PATTERNS" ]; then
|
|
echo -e "${YELLOW}=== Custom Content Patterns ===${NC}"
|
|
IFS=';' read -ra PATTERN_ARRAY <<< "$CUSTOM_PATTERNS"
|
|
for pattern in "${PATTERN_ARRAY[@]}"; do
|
|
if [ -n "$pattern" ]; then
|
|
IFS='=' read -ra PARTS <<< "$pattern"
|
|
if [ "${#PARTS[@]}" -eq 2 ]; then
|
|
local regex="${PARTS[0]}"
|
|
local dest="${PARTS[1]}"
|
|
echo -e "Pattern: ${GREEN}${regex}${NC} → ${BLUE}${dest}${NC}"
|
|
fi
|
|
fi
|
|
done
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
# Update a specific configuration value
|
|
set_config_value() {
|
|
check_permissions "$@"
|
|
|
|
if [ -z "$1" ] || [ -z "$2" ]; then
|
|
echo -e "${RED}Error: Both key and value must be provided.${NC}"
|
|
echo "Usage: $(basename "$0") set KEY VALUE"
|
|
exit 1
|
|
fi
|
|
|
|
local key="$1"
|
|
local value="$2"
|
|
|
|
if [ ! -f "$CONFIG_PATH" ]; then
|
|
echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Create a backup before modifying
|
|
backup_config
|
|
|
|
# Check if the key already exists in the config
|
|
if grep -q "^$key=" "$CONFIG_PATH"; then
|
|
# Update the existing key
|
|
sed -i "s|^$key=.*|$key=\"$value\"|" "$CONFIG_PATH"
|
|
echo -e "${GREEN}Updated configuration:${NC} $key = \"$value\""
|
|
else
|
|
# Add the new key
|
|
echo "$key=\"$value\"" >> "$CONFIG_PATH"
|
|
echo -e "${GREEN}Added new configuration:${NC} $key = \"$value\""
|
|
fi
|
|
|
|
# Validate after updating
|
|
validate_config
|
|
}
|
|
|
|
# Get a specific configuration value
|
|
get_config_value() {
|
|
if [ -z "$1" ]; then
|
|
echo -e "${RED}Error: Key must be provided.${NC}"
|
|
echo "Usage: $(basename "$0") get KEY"
|
|
exit 1
|
|
fi
|
|
|
|
local key="$1"
|
|
|
|
if [ ! -f "$CONFIG_PATH" ]; then
|
|
echo -e "${RED}Error: Configuration file not found at $CONFIG_PATH${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Source the config file to get the value
|
|
source "$CONFIG_PATH"
|
|
|
|
if [ -n "${!key+x}" ]; then
|
|
echo -e "${key}=${GREEN}${!key}${NC}"
|
|
else
|
|
echo -e "${RED}Error: Configuration key '$key' is not defined.${NC}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Show default configuration options
|
|
show_default_config() {
|
|
print_header
|
|
echo -e "${BLUE}Default Configuration Values:${NC}"
|
|
echo ""
|
|
cat << EOF
|
|
# Transmission Settings
|
|
TRANSMISSION_IP="192.168.1.100"
|
|
TRANSMISSION_PORT="9091"
|
|
TRANSMISSION_USER=""
|
|
TRANSMISSION_PASSWORD=""
|
|
|
|
# Path Mapping
|
|
TRANSMISSION_PATH_PREFIX="/downloads"
|
|
LOCAL_PATH_PREFIX="/mnt/data"
|
|
|
|
# Destination Directories
|
|
DIR_GAMES_DST="/mnt/media/Games"
|
|
DIR_APPS_DST="/mnt/media/Apps"
|
|
DIR_MOVIES_DST="/mnt/media/Movies"
|
|
DIR_BOOKS_DST="/mnt/media/Books"
|
|
DIR_TV_DST="/mnt/media/TV"
|
|
DIR_MUSIC_DST="/mnt/media/Music"
|
|
DEFAULT_DST="/mnt/media/Other"
|
|
|
|
# Additional Storage
|
|
STORAGE_DIRS=""
|
|
STORAGE_TV_DIRS=""
|
|
|
|
# Security
|
|
TORRENT_USER="torrent-mover"
|
|
TORRENT_GROUP="torrent-mover"
|
|
|
|
# Error Recovery
|
|
MAX_RETRY_ATTEMPTS="3"
|
|
RETRY_WAIT_TIME="15"
|
|
|
|
# Performance
|
|
PARALLEL_THREADS="$(nproc)"
|
|
PARALLEL_PROCESSING="1"
|
|
COPY_MODE="copy"
|
|
|
|
# Logging & Integrity
|
|
LOG_FILE="/var/log/torrent_mover.log"
|
|
LOG_LEVEL="INFO"
|
|
USE_SYSLOG="false"
|
|
PROCESSED_LOG="/var/log/torrent_processed.log"
|
|
CHECKSUM_DB="/var/lib/torrent/checksums.db"
|
|
CHECK_TRANSFER_INTEGRITY="true"
|
|
|
|
# Custom Content Patterns
|
|
CUSTOM_PATTERNS=".*documentary.*=\${DIR_MOVIES_DST}/Documentary;.*anime.*=\${DIR_TV_DST}/Anime"
|
|
EOF
|
|
echo ""
|
|
}
|
|
|
|
# Main command processing
|
|
case "$1" in
|
|
edit)
|
|
edit_config "${@:2}"
|
|
;;
|
|
backup)
|
|
backup_config "${@:2}"
|
|
;;
|
|
restore)
|
|
restore_config "${@:2}"
|
|
;;
|
|
validate)
|
|
validate_config "${@:2}"
|
|
;;
|
|
show)
|
|
show_config
|
|
;;
|
|
set)
|
|
set_config_value "${@:2}"
|
|
;;
|
|
get)
|
|
get_config_value "${@:2}"
|
|
;;
|
|
default)
|
|
show_default_config
|
|
;;
|
|
help|--help|-h)
|
|
usage
|
|
;;
|
|
*)
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
exit 0 |