- Fix bug in dependencies-module.sh that would prompt to install transmission-daemon for remote installations - Add checks for TRANSMISSION_REMOTE flag to correctly handle remote vs local installations - Update version to 2.0.2 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
374 lines
12 KiB
Bash
374 lines
12 KiB
Bash
#!/bin/bash
|
|
# Configuration module for Transmission RSS Manager Installation
|
|
|
|
# Configuration variables with defaults
|
|
INSTALL_DIR="/opt/transmission-rss-manager"
|
|
SERVICE_NAME="transmission-rss-manager"
|
|
PORT=3000
|
|
|
|
# Get default user safely - avoid using root
|
|
get_default_user() {
|
|
local default_user
|
|
|
|
# Try logname first to get the user who invoked sudo
|
|
if command -v logname &> /dev/null; then
|
|
default_user=$(logname 2>/dev/null)
|
|
fi
|
|
|
|
# If logname failed, try SUDO_USER
|
|
if [ -z "$default_user" ] && [ -n "$SUDO_USER" ]; then
|
|
default_user="$SUDO_USER"
|
|
fi
|
|
|
|
# Fallback to current user if both methods failed
|
|
if [ -z "$default_user" ]; then
|
|
default_user="$(whoami)"
|
|
fi
|
|
|
|
# Ensure the user is not root
|
|
if [ "$default_user" = "root" ]; then
|
|
echo "nobody"
|
|
else
|
|
echo "$default_user"
|
|
fi
|
|
}
|
|
|
|
# Initialize default user
|
|
USER=$(get_default_user)
|
|
|
|
# Transmission configuration variables
|
|
TRANSMISSION_REMOTE=false
|
|
TRANSMISSION_HOST="localhost"
|
|
TRANSMISSION_PORT=9091
|
|
TRANSMISSION_USER=""
|
|
TRANSMISSION_PASS=""
|
|
TRANSMISSION_RPC_PATH="/transmission/rpc"
|
|
TRANSMISSION_DOWNLOAD_DIR="/var/lib/transmission-daemon/downloads"
|
|
TRANSMISSION_DIR_MAPPING="{}"
|
|
|
|
# Media path defaults
|
|
MEDIA_DIR="/mnt/media"
|
|
ENABLE_BOOK_SORTING=true
|
|
|
|
# Helper function to validate port number
|
|
validate_port() {
|
|
local port="$1"
|
|
if [[ "$port" =~ ^[0-9]+$ ]] && [ "$port" -ge 1 ] && [ "$port" -le 65535 ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Helper function to validate URL hostname
|
|
validate_hostname() {
|
|
local hostname="$1"
|
|
if [[ "$hostname" =~ ^[a-zA-Z0-9]([a-zA-Z0-9\-\.]+[a-zA-Z0-9])?$ ]]; then
|
|
return 0
|
|
elif [[ "$hostname" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
function gather_configuration() {
|
|
log "INFO" "Starting configuration gathering"
|
|
echo -e "${BOLD}Installation Configuration:${NC}"
|
|
echo -e "Please provide the following configuration parameters:"
|
|
echo
|
|
|
|
read -p "Installation directory [$INSTALL_DIR]: " input_install_dir
|
|
if [ -n "$input_install_dir" ]; then
|
|
# Validate installation directory
|
|
if [[ ! "$input_install_dir" =~ ^/ ]]; then
|
|
log "WARN" "Installation directory must be an absolute path. Using default."
|
|
else
|
|
INSTALL_DIR="$input_install_dir"
|
|
fi
|
|
fi
|
|
|
|
# Using fixed port 3000 to avoid permission issues with ports below 1024
|
|
log "INFO" "Using port 3000 for the web interface"
|
|
log "INFO" "This is to avoid permission issues with ports below 1024 (like port 80)"
|
|
PORT=3000
|
|
|
|
# Get user
|
|
read -p "Run as user [$USER]: " input_user
|
|
if [ -n "$input_user" ]; then
|
|
# Check if user exists
|
|
if id "$input_user" &>/dev/null; then
|
|
USER="$input_user"
|
|
else
|
|
log "WARN" "User $input_user does not exist. Using $USER instead."
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
echo -e "${BOLD}Transmission Configuration:${NC}"
|
|
echo -e "Configure connection to your Transmission client:"
|
|
echo
|
|
|
|
# Ask if Transmission is remote
|
|
read -p "Is Transmission running on a remote server? (y/n) [n]: " input_remote
|
|
if [[ $input_remote =~ ^[Yy]$ ]]; then
|
|
TRANSMISSION_REMOTE=true
|
|
|
|
# Get and validate hostname
|
|
while true; do
|
|
read -p "Remote Transmission host [localhost]: " input_trans_host
|
|
if [ -z "$input_trans_host" ]; then
|
|
break
|
|
elif validate_hostname "$input_trans_host"; then
|
|
TRANSMISSION_HOST="$input_trans_host"
|
|
break
|
|
else
|
|
log "WARN" "Invalid hostname format."
|
|
fi
|
|
done
|
|
|
|
# Get and validate port
|
|
while true; do
|
|
read -p "Remote Transmission port [9091]: " input_trans_port
|
|
if [ -z "$input_trans_port" ]; then
|
|
break
|
|
elif validate_port "$input_trans_port"; then
|
|
TRANSMISSION_PORT="$input_trans_port"
|
|
break
|
|
else
|
|
log "WARN" "Invalid port number. Port must be between 1 and 65535."
|
|
fi
|
|
done
|
|
|
|
# Get credentials
|
|
read -p "Remote Transmission username []: " input_trans_user
|
|
TRANSMISSION_USER=${input_trans_user:-$TRANSMISSION_USER}
|
|
|
|
# Use read -s for password to avoid showing it on screen
|
|
read -s -p "Remote Transmission password []: " input_trans_pass
|
|
echo # Add a newline after the password input
|
|
if [ -n "$input_trans_pass" ]; then
|
|
# TODO: In a production environment, consider encrypting this password
|
|
TRANSMISSION_PASS="$input_trans_pass"
|
|
fi
|
|
|
|
read -p "Remote Transmission RPC path [/transmission/rpc]: " input_trans_path
|
|
if [ -n "$input_trans_path" ]; then
|
|
# Ensure path starts with / for consistency
|
|
if [[ ! "$input_trans_path" =~ ^/ ]]; then
|
|
input_trans_path="/$input_trans_path"
|
|
fi
|
|
TRANSMISSION_RPC_PATH="$input_trans_path"
|
|
fi
|
|
|
|
# Configure directory mapping for remote setup
|
|
echo
|
|
echo -e "${YELLOW}Directory Mapping Configuration${NC}"
|
|
echo -e "When using a remote Transmission server, you need to map paths between servers."
|
|
echo -e "For each directory on the remote server, specify the corresponding local directory."
|
|
echo
|
|
|
|
# Get remote download directory
|
|
read -p "Remote Transmission download directory: " REMOTE_DOWNLOAD_DIR
|
|
REMOTE_DOWNLOAD_DIR=${REMOTE_DOWNLOAD_DIR:-"/var/lib/transmission-daemon/downloads"}
|
|
|
|
# Get local directory that corresponds to remote download directory
|
|
read -p "Local directory that corresponds to the remote download directory: " LOCAL_DOWNLOAD_DIR
|
|
LOCAL_DOWNLOAD_DIR=${LOCAL_DOWNLOAD_DIR:-"/mnt/transmission-downloads"}
|
|
|
|
# Create mapping JSON - use proper JSON escaping for directory paths
|
|
REMOTE_DOWNLOAD_DIR_ESCAPED=$(echo "$REMOTE_DOWNLOAD_DIR" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')
|
|
LOCAL_DOWNLOAD_DIR_ESCAPED=$(echo "$LOCAL_DOWNLOAD_DIR" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')
|
|
|
|
TRANSMISSION_DIR_MAPPING="{\"$REMOTE_DOWNLOAD_DIR_ESCAPED\": \"$LOCAL_DOWNLOAD_DIR_ESCAPED\"}"
|
|
|
|
# Create the local directory
|
|
if ! mkdir -p "$LOCAL_DOWNLOAD_DIR"; then
|
|
log "ERROR" "Failed to create local download directory: $LOCAL_DOWNLOAD_DIR"
|
|
else
|
|
if ! chown -R "$USER:$USER" "$LOCAL_DOWNLOAD_DIR"; then
|
|
log "ERROR" "Failed to set permissions on local download directory: $LOCAL_DOWNLOAD_DIR"
|
|
fi
|
|
fi
|
|
|
|
# Ask if want to add more mappings
|
|
while true; do
|
|
read -p "Add another directory mapping? (y/n) [n]: " add_another
|
|
if [[ ! $add_another =~ ^[Yy]$ ]]; then
|
|
break
|
|
fi
|
|
|
|
read -p "Remote directory path: " remote_dir
|
|
read -p "Corresponding local directory path: " local_dir
|
|
|
|
if [ -n "$remote_dir" ] && [ -n "$local_dir" ]; then
|
|
# Escape directory paths for JSON
|
|
remote_dir_escaped=$(echo "$remote_dir" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')
|
|
local_dir_escaped=$(echo "$local_dir" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')
|
|
|
|
# Update mapping JSON (proper JSON manipulation)
|
|
# Remove the closing brace, add a comma and the new mapping, then close with brace
|
|
TRANSMISSION_DIR_MAPPING="${TRANSMISSION_DIR_MAPPING%\}}, \"$remote_dir_escaped\": \"$local_dir_escaped\"}"
|
|
|
|
# Create the local directory
|
|
if ! mkdir -p "$local_dir"; then
|
|
log "ERROR" "Failed to create directory: $local_dir"
|
|
else
|
|
if ! chown -R "$USER:$USER" "$local_dir"; then
|
|
log "WARN" "Failed to set permissions on directory: $local_dir"
|
|
fi
|
|
log "INFO" "Mapping added: $remote_dir → $local_dir"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Set Transmission download dir for configuration
|
|
TRANSMISSION_DOWNLOAD_DIR=$REMOTE_DOWNLOAD_DIR
|
|
else
|
|
# Local Transmission selected
|
|
echo -e "${YELLOW}You've selected to use a local Transmission installation.${NC}"
|
|
|
|
# Check if Transmission is already installed
|
|
if command -v transmission-daemon &> /dev/null; then
|
|
echo -e "${GREEN}Transmission is already installed on this system.${NC}"
|
|
else
|
|
echo -e "${YELLOW}NOTE: Transmission does not appear to be installed on this system.${NC}"
|
|
echo -e "${YELLOW}You will be prompted to install it during the dependency installation step.${NC}"
|
|
fi
|
|
|
|
# Get and validate port
|
|
while true; do
|
|
read -p "Local Transmission port [9091]: " input_trans_port
|
|
if [ -z "$input_trans_port" ]; then
|
|
break
|
|
elif validate_port "$input_trans_port"; then
|
|
TRANSMISSION_PORT="$input_trans_port"
|
|
break
|
|
else
|
|
log "WARN" "Invalid port number. Port must be between 1 and 65535."
|
|
fi
|
|
done
|
|
|
|
# Get credentials if any
|
|
read -p "Local Transmission username (leave empty if authentication is disabled) []: " input_trans_user
|
|
TRANSMISSION_USER=${input_trans_user:-$TRANSMISSION_USER}
|
|
|
|
if [ -n "$input_trans_user" ]; then
|
|
# Use read -s for password to hide it
|
|
read -s -p "Local Transmission password []: " input_trans_pass
|
|
echo # Add a newline after the password input
|
|
if [ -n "$input_trans_pass" ]; then
|
|
TRANSMISSION_PASS="$input_trans_pass"
|
|
fi
|
|
fi
|
|
|
|
read -p "Transmission download directory [/var/lib/transmission-daemon/downloads]: " input_trans_dir
|
|
if [ -n "$input_trans_dir" ]; then
|
|
if [[ ! "$input_trans_dir" =~ ^/ ]]; then
|
|
log "WARN" "Download directory must be an absolute path. Using default."
|
|
else
|
|
TRANSMISSION_DOWNLOAD_DIR="$input_trans_dir"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
echo -e "${BOLD}Media Destination Configuration:${NC}"
|
|
|
|
read -p "Media destination base directory [/mnt/media]: " input_media_dir
|
|
if [ -n "$input_media_dir" ]; then
|
|
if [[ ! "$input_media_dir" =~ ^/ ]]; then
|
|
log "WARN" "Media directory must be an absolute path. Using default."
|
|
else
|
|
MEDIA_DIR="$input_media_dir"
|
|
fi
|
|
fi
|
|
|
|
# Ask about enabling book/magazine sorting
|
|
echo
|
|
echo -e "${BOLD}Content Type Configuration:${NC}"
|
|
read -p "Enable book and magazine sorting? (y/n) [y]: " input_book_sorting
|
|
if [[ $input_book_sorting =~ ^[Nn]$ ]]; then
|
|
ENABLE_BOOK_SORTING=false
|
|
else
|
|
ENABLE_BOOK_SORTING=true
|
|
fi
|
|
|
|
# Security configuration
|
|
echo
|
|
echo -e "${BOLD}Security Configuration:${NC}"
|
|
|
|
# Ask about enabling authentication
|
|
read -p "Enable authentication? (y/n) [n]: " input_auth_enabled
|
|
AUTH_ENABLED=false
|
|
ADMIN_USERNAME=""
|
|
ADMIN_PASSWORD=""
|
|
|
|
if [[ $input_auth_enabled =~ ^[Yy]$ ]]; then
|
|
AUTH_ENABLED=true
|
|
|
|
# Get admin username and password
|
|
read -p "Admin username [admin]: " input_admin_username
|
|
ADMIN_USERNAME=${input_admin_username:-"admin"}
|
|
|
|
# Use read -s for password to avoid showing it on screen
|
|
read -s -p "Admin password: " input_admin_password
|
|
echo # Add a newline after the password input
|
|
|
|
if [ -z "$input_admin_password" ]; then
|
|
# Generate a random password if none provided
|
|
ADMIN_PASSWORD=$(openssl rand -base64 12)
|
|
echo -e "${YELLOW}Generated random admin password: $ADMIN_PASSWORD${NC}"
|
|
echo -e "${YELLOW}Please save this password somewhere safe!${NC}"
|
|
else
|
|
ADMIN_PASSWORD="$input_admin_password"
|
|
fi
|
|
fi
|
|
|
|
# Ask about enabling HTTPS
|
|
read -p "Enable HTTPS? (requires SSL certificate) (y/n) [n]: " input_https_enabled
|
|
HTTPS_ENABLED=false
|
|
SSL_CERT_PATH=""
|
|
SSL_KEY_PATH=""
|
|
|
|
if [[ $input_https_enabled =~ ^[Yy]$ ]]; then
|
|
HTTPS_ENABLED=true
|
|
|
|
# Get SSL certificate paths
|
|
read -p "SSL certificate path: " input_ssl_cert_path
|
|
if [ -n "$input_ssl_cert_path" ]; then
|
|
# Check if file exists
|
|
if [ -f "$input_ssl_cert_path" ]; then
|
|
SSL_CERT_PATH="$input_ssl_cert_path"
|
|
else
|
|
log "WARN" "SSL certificate file not found. HTTPS will be disabled."
|
|
HTTPS_ENABLED=false
|
|
fi
|
|
else
|
|
log "WARN" "SSL certificate path not provided. HTTPS will be disabled."
|
|
HTTPS_ENABLED=false
|
|
fi
|
|
|
|
# Only ask for key if cert was found
|
|
if [ "$HTTPS_ENABLED" = true ]; then
|
|
read -p "SSL key path: " input_ssl_key_path
|
|
if [ -n "$input_ssl_key_path" ]; then
|
|
# Check if file exists
|
|
if [ -f "$input_ssl_key_path" ]; then
|
|
SSL_KEY_PATH="$input_ssl_key_path"
|
|
else
|
|
log "WARN" "SSL key file not found. HTTPS will be disabled."
|
|
HTTPS_ENABLED=false
|
|
fi
|
|
else
|
|
log "WARN" "SSL key path not provided. HTTPS will be disabled."
|
|
HTTPS_ENABLED=false
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
log "INFO" "Configuration gathering complete"
|
|
echo -e "${GREEN}Configuration complete!${NC}"
|
|
echo
|
|
} |