yams/yams

232 lines
6.7 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
# Constants
readonly DC="docker compose -f <filename> -f <custom_file_filename>"
readonly INSTALL_DIRECTORY="<install_directory>"
readonly TIMEOUT_SECONDS=60
readonly IP_ENDPOINTS=(
"https://ipinfo.io/ip"
"https://api.ipify.org"
"https://checkip.amazonaws.com"
"https://tnedi.me"
"https://api.myip.la"
"https://wtfismyip.com/text"
)
# Color codes for better readability
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly NC='\033[0m' # No Color
# Available commands
declare -A COMMANDS=(
["--help"]="displays this help message"
["restart"]="restarts yams services"
["stop"]="stops all yams services"
["start"]="starts yams services"
["destroy"]="destroy yams services so you can start from scratch"
["check-vpn"]="checks if the VPN is working as expected"
["backup"]="backs up yams to the destination location"
)
# Functions
log_success() {
echo -e "${GREEN}$1${NC}"
}
log_error() {
echo -e "${RED}$1${NC}" >&2
exit 1
}
log_warning() {
echo -e "${YELLOW}$1${NC}"
}
show_help() {
echo "yams - Yet Another Media Server"
echo
echo "Usage: yams [command] [options]"
echo
echo "Commands:"
for cmd in "${!COMMANDS[@]}"; do
printf "%-25s %s\n" "$cmd" "${COMMANDS[$cmd]}"
done
echo
echo "Examples:"
echo " yams start # Start all YAMS services"
echo " yams backup /path/to/backup # Backup YAMS to specified directory"
}
wait_for_services() {
local wait_time=0
echo -n "Waiting for services to start"
while [ $wait_time -lt $TIMEOUT_SECONDS ]; do
# Get the total number of services and number of running services
local total_services
local running_services
total_services=$($DC ps --format '{{.Name}}' | wc -l)
running_services=$($DC ps --format '{{.Status}}' | grep -c "Up")
if [ "$total_services" -eq "$running_services" ]; then
echo
log_success "All $total_services services are up and running!"
return 0
fi
# Show progress with count
echo -n "."
sleep 1
((wait_time++))
# Every 10 seconds, show status
if [ $((wait_time % 10)) -eq 0 ]; then
echo
echo -n "$running_services/$total_services services running"
fi
done
echo
log_error "Not all services started within ${TIMEOUT_SECONDS} seconds ($running_services/$total_services running)"
}
find_available_ip_endpoint() {
for endpoint in "${IP_ENDPOINTS[@]}"; do
if curl -s --connect-timeout 5 "$endpoint" > /dev/null; then
echo "$endpoint"
return 0
fi
done
return 1
}
get_ip_with_retries() {
local context=$1 # "local" or "qbittorrent"
local cmd_prefix=""
if [ "$context" = "qbittorrent" ]; then
cmd_prefix="docker exec qbittorrent"
fi
for endpoint in "${IP_ENDPOINTS[@]}"; do
local ip
if [ "$context" = "local" ]; then
ip=$(curl -s --connect-timeout 5 "$endpoint")
else
ip=$($cmd_prefix curl -s --connect-timeout 5 "$endpoint")
fi
if [ -n "$ip" ] && [[ "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "$ip"
return 0
fi
done
return 1
}
check_vpn() {
echo "Getting your IP..."
local your_ip
your_ip=$(get_ip_with_retries "local") || log_error "Failed to get your IP address from any endpoint"
echo "Your IP: $your_ip"
local country
country=$(curl -s --connect-timeout 5 "https://am.i.mullvad.net/country") || log_warning "Couldn't determine your country"
[ -n "$country" ] && echo "Your local IP country is $country"
echo -e "\nGetting your qBittorrent IP..."
local qbit_ip
qbit_ip=$(get_ip_with_retries "qbittorrent") || log_error "Failed to get qBittorrent IP from any endpoint"
echo "qBittorrent IP: $qbit_ip"
local qbit_country
qbit_country=$(docker exec qbittorrent curl -s --connect-timeout 5 "https://am.i.mullvad.net/country") || log_warning "Couldn't determine qBittorrent country"
[ -n "$qbit_country" ] && echo "qBittorrent country is $qbit_country"
if [ "$qbit_ip" == "$your_ip" ]; then
log_error "⚠️ WARNING: Your IPs are the same! qBittorrent is exposing your IP!"
else
log_success "✅ Success: Your IPs are different. qBittorrent is masking your IP!"
fi
}
backup_yams() {
local destination=$1
local backup_date
backup_date=$(date '+%Y-%m-%d-%s')
local backup_file="$destination/yams-backup-$backup_date.tar.gz"
echo "Stopping YAMS services..."
$DC stop > /dev/null 2>&1 || log_error "Failed to stop services"
echo -e "\nBacking up YAMS to $destination..."
echo "This may take a while depending on the size of your installation."
echo "Please wait... ⌛"
# Copy current yams script and create backup
cp "$(which yams)" "$INSTALL_DIRECTORY" || log_warning "Failed to backup yams script"
tar --exclude='transcoding-temp' -czf "$backup_file" -C "$INSTALL_DIRECTORY" . ||
log_error "Failed to create backup archive"
echo -e "\nStarting YAMS services..."
$DC start > /dev/null 2>&1 || log_warning "Failed to restart services"
log_success "Backup completed successfully! 🎉"
echo "Backup file: $backup_file"
}
destroy_yams() {
echo -e "\nWARNING: This will destroy all your YAMS services!"
read -p "Are you sure you want to continue? This is not recoverable! ⚠️ 🚨 [y/N]: " -r
if [[ ${REPLY,,} =~ ^y$ ]]; then
$DC down || log_error "Failed to destroy services"
echo -e "\nYAMS services were destroyed. To restart, run: yams start"
fi
}
main() {
local command=${1:-"--help"}
local destination=${2:-.}
# Validate and normalize destination path if provided
if [ "$command" = "backup" ]; then
destination=$(realpath "$destination") || log_error "Invalid backup destination path"
fi
case "$command" in
--help)
show_help
;;
restart)
$DC stop && $DC up -d
wait_for_services
;;
stop)
$DC stop || log_error "Failed to stop services"
log_success "Services stopped successfully"
;;
start)
$DC up -d || log_error "Failed to start services"
wait_for_services
;;
check-vpn)
check_vpn
;;
destroy)
destroy_yams
;;
backup)
backup_yams "$destination"
;;
*)
log_error "Unknown command: $command\nRun 'yams --help' for usage information"
;;
esac
}
main "$@"