Merge pull request #23 from outis1one/claude/fix-magic-mirror-setup-LWG3r
Claude/fix magic mirror setup lwg3r
This commit is contained in:
+177
-21
@@ -1473,6 +1473,127 @@ CADDY_BLOCK
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# CHECK IF SERVICE EXISTS AND ASK USER ACTION
|
||||
# ============================================================================
|
||||
check_service_exists() {
|
||||
local SERVICE_NAME="$1"
|
||||
local SERVICE_DIR="$2"
|
||||
local RETURN_VAR="$3" # Variable name to set (true/false)
|
||||
|
||||
if [ -f "$SERVICE_DIR/docker-compose.yml" ]; then
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " $SERVICE_NAME is already installed at $SERVICE_DIR"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " 1. Skip (keep existing configuration)"
|
||||
echo " 2. Reconfigure (will backup existing config)"
|
||||
echo " 3. Restart containers only"
|
||||
echo ""
|
||||
local ACTION=""
|
||||
prompt_text "Choose option [1/2/3]:" "1" ACTION
|
||||
|
||||
case "$ACTION" in
|
||||
2)
|
||||
echo " Backing up existing configuration..."
|
||||
local BACKUP_NAME=$(echo "$SERVICE_NAME" | tr '[:upper:] ' '[:lower:]-')
|
||||
BACKUP_DIR="$DOCKER_DIR/backups/$(date +%Y%m%d-%H%M%S)-$BACKUP_NAME"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
cp -r "$SERVICE_DIR" "$BACKUP_DIR/"
|
||||
echo " ✓ Backup saved to: $BACKUP_DIR"
|
||||
eval "$RETURN_VAR=true"
|
||||
return 0
|
||||
;;
|
||||
3)
|
||||
echo " Restarting $SERVICE_NAME containers..."
|
||||
cd "$SERVICE_DIR"
|
||||
docker compose restart 2>/dev/null && echo " ✓ $SERVICE_NAME restarted" || echo " ⚠ Failed to restart"
|
||||
eval "$RETURN_VAR=false"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo " Skipping $SERVICE_NAME (already configured)"
|
||||
eval "$RETURN_VAR=false"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
else
|
||||
# Service doesn't exist, proceed with installation
|
||||
eval "$RETURN_VAR=true"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# DETECT AVAILABLE DRIVES (RUN ONCE)
|
||||
# ============================================================================
|
||||
detect_drives() {
|
||||
# Global variables set by this function:
|
||||
# - DRIVES_DETECTED: true/false
|
||||
# - PRIMARY_DRIVE: name of first drive (e.g., "storage1")
|
||||
# - PRIMARY_DRIVE_PATH: full path to first drive
|
||||
# - DRIVES_DIR: base drives directory
|
||||
# - AVAILABLE_DRIVES_COUNT: number of drives found
|
||||
|
||||
DRIVES_DIR="$ACTUAL_HOME/drives"
|
||||
DRIVES_DETECTED=false
|
||||
PRIMARY_DRIVE=""
|
||||
PRIMARY_DRIVE_PATH=""
|
||||
AVAILABLE_DRIVES_COUNT=0
|
||||
|
||||
if [ -d "$DRIVES_DIR" ]; then
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " DETECTED DRIVES"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
for drive in "$DRIVES_DIR"/*; do
|
||||
if [ -d "$drive" ]; then
|
||||
drive_name=$(basename "$drive")
|
||||
drive_size=$(df -h "$drive" 2>/dev/null | awk 'NR==2 {print $2}')
|
||||
drive_used=$(df -h "$drive" 2>/dev/null | awk 'NR==2 {print $3}')
|
||||
drive_avail=$(df -h "$drive" 2>/dev/null | awk 'NR==2 {print $4}')
|
||||
|
||||
echo " ✓ $drive_name"
|
||||
if [ -n "$drive_size" ]; then
|
||||
echo " Path: $drive"
|
||||
echo " Size: $drive_size (Used: $drive_used, Available: $drive_avail)"
|
||||
else
|
||||
echo " Path: $drive"
|
||||
fi
|
||||
|
||||
# Set PRIMARY_DRIVE to the first drive found
|
||||
if [ -z "$PRIMARY_DRIVE" ]; then
|
||||
PRIMARY_DRIVE="$drive_name"
|
||||
PRIMARY_DRIVE_PATH="$drive"
|
||||
fi
|
||||
|
||||
AVAILABLE_DRIVES_COUNT=$((AVAILABLE_DRIVES_COUNT + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $AVAILABLE_DRIVES_COUNT -gt 0 ]; then
|
||||
DRIVES_DETECTED=true
|
||||
echo ""
|
||||
echo " Using '$PRIMARY_DRIVE' as primary drive for default paths"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If no drives detected, use home directory
|
||||
if [ "$DRIVES_DETECTED" = "false" ]; then
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " No ~/drives directory found"
|
||||
echo " Using $ACTUAL_HOME for default paths"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
PRIMARY_DRIVE_PATH="$ACTUAL_HOME"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# SHOW CURRENT INSTALLATION STATUS
|
||||
# ============================================================================
|
||||
@@ -2312,6 +2433,11 @@ else
|
||||
chown "$ACTUAL_USER:$ACTUAL_USER" "$DOCKER_DIR"
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# DETECT DRIVES (ONCE FOR ALL SERVICES)
|
||||
# ============================================================================
|
||||
detect_drives
|
||||
|
||||
# ============================================================================
|
||||
# SERVICE SELECTION MENU
|
||||
# ============================================================================
|
||||
@@ -2631,9 +2757,14 @@ else
|
||||
fi
|
||||
|
||||
if [ "$INSTALL_IMMICH" = "y" ] || [ "$INSTALL_IMMICH" = "Y" ]; then
|
||||
echo "Installing Immich..."
|
||||
IMMICH_DIR="$DOCKER_DIR/immich"
|
||||
|
||||
# Check if already installed and ask what to do
|
||||
check_service_exists "Immich" "$IMMICH_DIR" IMMICH_RECONFIGURE
|
||||
|
||||
if [ "$IMMICH_RECONFIGURE" = "true" ]; then
|
||||
echo "Installing Immich..."
|
||||
|
||||
# Photo storage configuration
|
||||
echo ""
|
||||
echo "Photo Storage Configuration:"
|
||||
@@ -2643,21 +2774,22 @@ else
|
||||
echo " 2. EXTERNAL folder - Where EXISTING photos are (read-only access)"
|
||||
echo ""
|
||||
|
||||
# Use globally detected drives
|
||||
# Upload location (for new photos)
|
||||
DEFAULT_UPLOAD_DIR="$HOME_DIR/drives/primary/photos/immich-uploads"
|
||||
DEFAULT_UPLOAD_DIR="$PRIMARY_DRIVE_PATH/photos/immich-uploads"
|
||||
echo "NEW UPLOADS (from phone apps, web uploads):"
|
||||
echo " Default: $DEFAULT_UPLOAD_DIR"
|
||||
prompt_text " Upload folder path:" "$DEFAULT_UPLOAD_DIR" UPLOAD_LOCATION 2>/dev/null || UPLOAD_LOCATION="$DEFAULT_UPLOAD_DIR"
|
||||
UPLOAD_LOCATION="${UPLOAD_LOCATION/#\~/$HOME_DIR}"
|
||||
UPLOAD_LOCATION="${UPLOAD_LOCATION/#\~/$ACTUAL_HOME}"
|
||||
|
||||
# External library (for existing photos)
|
||||
echo ""
|
||||
DEFAULT_EXTERNAL_DIR="$HOME_DIR/drives/primary/photos"
|
||||
DEFAULT_EXTERNAL_DIR="$PRIMARY_DRIVE_PATH/photos"
|
||||
echo "EXISTING PHOTOS (external library, read-only):"
|
||||
echo " Default: $DEFAULT_EXTERNAL_DIR"
|
||||
echo " Leave blank if you don't have existing photos to import"
|
||||
prompt_text " Existing photos path:" "$DEFAULT_EXTERNAL_DIR" EXTERNAL_LIBRARY 2>/dev/null || EXTERNAL_LIBRARY=""
|
||||
EXTERNAL_LIBRARY="${EXTERNAL_LIBRARY/#\~/$HOME_DIR}"
|
||||
EXTERNAL_LIBRARY="${EXTERNAL_LIBRARY/#\~/$ACTUAL_HOME}"
|
||||
|
||||
# If external library is same as upload, warn
|
||||
if [ -n "$EXTERNAL_LIBRARY" ] && [ "$EXTERNAL_LIBRARY" = "$UPLOAD_LOCATION" ]; then
|
||||
@@ -2830,7 +2962,8 @@ IMMICH_ENV
|
||||
echo " immich upload --recursive /path/to/old/photos"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
fi # End IMMICH_RECONFIGURE check
|
||||
fi # End INSTALL_IMMICH check
|
||||
|
||||
# ---- AUDIOBOOKSHELF ----
|
||||
if [ "$WHIPTAIL_USED" != true ] && [ -z "$INSTALL_AUDIOBOOKSHELF" ]; then
|
||||
@@ -2844,16 +2977,21 @@ IMMICH_ENV
|
||||
fi
|
||||
|
||||
if [ "$INSTALL_AUDIOBOOKSHELF" = "y" ] || [ "$INSTALL_AUDIOBOOKSHELF" = "Y" ]; then
|
||||
echo "Installing Audiobookshelf..."
|
||||
ABS_DIR="$DOCKER_DIR/audiobookshelf"
|
||||
|
||||
# Check if already installed and ask what to do
|
||||
check_service_exists "AudioBookshelf" "$ABS_DIR" ABS_RECONFIGURE
|
||||
|
||||
if [ "$ABS_RECONFIGURE" = "true" ]; then
|
||||
echo "Installing Audiobookshelf..."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
echo "[DRY-RUN] Would create $ABS_DIR"
|
||||
else
|
||||
mkdir -p "$ABS_DIR"
|
||||
cd "$ABS_DIR"
|
||||
|
||||
prompt_text "Path to audiobooks folder [default: $ACTUAL_HOME/drives/primary/audiobooks]:" "$ACTUAL_HOME/drives/primary/audiobooks" AUDIOBOOKS_PATH
|
||||
prompt_text "Path to audiobooks folder [default: $PRIMARY_DRIVE_PATH/audiobooks]:" "$PRIMARY_DRIVE_PATH/audiobooks" AUDIOBOOKS_PATH
|
||||
|
||||
cat > docker-compose.yml << ABS_COMPOSE
|
||||
name: audiobookshelf
|
||||
@@ -2897,7 +3035,8 @@ ABS_ENV
|
||||
echo " Access at: http://localhost:13378"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
fi # End ABS_RECONFIGURE check
|
||||
fi # End INSTALL_AUDIOBOOKSHELF check
|
||||
|
||||
# ---- EMBY ----
|
||||
if [ "$WHIPTAIL_USED" != true ] && [ -z "$INSTALL_EMBY" ]; then
|
||||
@@ -2911,16 +3050,21 @@ ABS_ENV
|
||||
fi
|
||||
|
||||
if [ "$INSTALL_EMBY" = "y" ] || [ "$INSTALL_EMBY" = "Y" ]; then
|
||||
echo "Installing Emby..."
|
||||
EMBY_DIR="$DOCKER_DIR/emby"
|
||||
|
||||
# Check if already installed and ask what to do
|
||||
check_service_exists "Emby" "$EMBY_DIR" EMBY_RECONFIGURE
|
||||
|
||||
if [ "$EMBY_RECONFIGURE" = "true" ]; then
|
||||
echo "Installing Emby..."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
echo "[DRY-RUN] Would create $EMBY_DIR"
|
||||
else
|
||||
mkdir -p "$EMBY_DIR"
|
||||
cd "$EMBY_DIR"
|
||||
|
||||
prompt_text "Path to media folder [default: $ACTUAL_HOME/drives/primary/media]:" "$ACTUAL_HOME/drives/primary/media" MEDIA_PATH
|
||||
prompt_text "Path to media folder [default: $PRIMARY_DRIVE_PATH/media]:" "$PRIMARY_DRIVE_PATH/media" MEDIA_PATH
|
||||
|
||||
cat > docker-compose.yml << EMBY_COMPOSE
|
||||
name: emby
|
||||
@@ -2967,7 +3111,8 @@ EMBY_ENV
|
||||
echo " Access at: http://localhost:8096"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
fi # End EMBY_RECONFIGURE check
|
||||
fi # End INSTALL_EMBY check
|
||||
|
||||
# ---- A.R.M. (Automatic Ripping Machine) ----
|
||||
if [ "$WHIPTAIL_USED" != true ] && [ -z "$INSTALL_ARM" ]; then
|
||||
@@ -2981,8 +3126,11 @@ EMBY_ENV
|
||||
fi
|
||||
|
||||
if [ "$INSTALL_ARM" = "y" ] || [ "$INSTALL_ARM" = "Y" ]; then
|
||||
echo "Installing A.R.M...."
|
||||
ARM_DIR="$DOCKER_DIR/arm"
|
||||
check_service_exists "A.R.M." "$ARM_DIR" ARM_RECONFIGURE
|
||||
|
||||
if [ "$ARM_RECONFIGURE" = "true" ]; then
|
||||
echo "Installing A.R.M...."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
echo "[DRY-RUN] Would create $ARM_DIR"
|
||||
@@ -2990,7 +3138,7 @@ EMBY_ENV
|
||||
mkdir -p "$ARM_DIR"
|
||||
cd "$ARM_DIR"
|
||||
|
||||
prompt_text "Path for ripped media output [default: $ACTUAL_HOME/drives/primary/ripped]:" "$ACTUAL_HOME/drives/primary/ripped" ARM_OUTPUT
|
||||
prompt_text "Path for ripped media output [default: $PRIMARY_DRIVE_PATH/ripped]:" "$PRIMARY_DRIVE_PATH/ripped" ARM_OUTPUT
|
||||
|
||||
# Detect optical drives
|
||||
echo ""
|
||||
@@ -3051,7 +3199,8 @@ ARM_ENV
|
||||
echo " Note: Edit docker-compose.yml to add more optical drives"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
fi # End ARM_RECONFIGURE check
|
||||
fi # End INSTALL_ARM check
|
||||
|
||||
# ---- FILEBROWSER ----
|
||||
if [ "$WHIPTAIL_USED" != true ] && [ -z "$INSTALL_FILEBROWSER" ]; then
|
||||
@@ -3065,8 +3214,11 @@ ARM_ENV
|
||||
fi
|
||||
|
||||
if [ "$INSTALL_FILEBROWSER" = "y" ] || [ "$INSTALL_FILEBROWSER" = "Y" ]; then
|
||||
echo "Installing Filebrowser..."
|
||||
FB_DIR="$DOCKER_DIR/filebrowser"
|
||||
check_service_exists "FileBrowser" "$FB_DIR" FB_RECONFIGURE
|
||||
|
||||
if [ "$FB_RECONFIGURE" = "true" ]; then
|
||||
echo "Installing Filebrowser..."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
echo "[DRY-RUN] Would create $FB_DIR"
|
||||
@@ -3074,7 +3226,7 @@ ARM_ENV
|
||||
mkdir -p "$FB_DIR"
|
||||
cd "$FB_DIR"
|
||||
|
||||
prompt_text "Path to browse [default: $ACTUAL_HOME/drives/primary]:" "$ACTUAL_HOME/drives/primary" FB_PATH
|
||||
prompt_text "Path to browse [default: $PRIMARY_DRIVE_PATH]:" "$PRIMARY_DRIVE_PATH" FB_PATH
|
||||
|
||||
cat > docker-compose.yml << FB_COMPOSE
|
||||
name: filebrowser
|
||||
@@ -3128,7 +3280,8 @@ FB_SETTINGS
|
||||
echo " Default login: admin / admin (change immediately!)"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
fi # End FB_RECONFIGURE check
|
||||
fi # End INSTALL_FILEBROWSER check
|
||||
|
||||
# ---- MAGIC MIRROR ----
|
||||
if [ "$WHIPTAIL_USED" != true ] && [ -z "$INSTALL_MAGICMIRROR" ]; then
|
||||
@@ -3376,7 +3529,9 @@ MM_CONFIG
|
||||
|
||||
if [ "$INSTALL_ACTUALBUDGET" = "y" ] || [ "$INSTALL_ACTUALBUDGET" = "Y" ]; then
|
||||
AB_DIR="$DOCKER_DIR/actualbudget"
|
||||
check_service_exists "ActualBudget" "$AB_DIR" AB_RECONFIGURE
|
||||
|
||||
if [ "$AB_RECONFIGURE" = "true" ]; then
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
echo "[DRY-RUN] Would create $AB_DIR"
|
||||
else
|
||||
@@ -3419,7 +3574,8 @@ AB_COMPOSE
|
||||
echo " Data dir: $AB_DIR/data"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
fi # End AB_RECONFIGURE check
|
||||
fi # End INSTALL_ACTUALBUDGET check
|
||||
|
||||
# ---- KEYCLOAK ----
|
||||
if [ "$WHIPTAIL_USED" != true ] && [ -z "$INSTALL_KEYCLOAK" ]; then
|
||||
@@ -4232,7 +4388,7 @@ backend = auto"
|
||||
mkdir -p "$LMS_DIR"
|
||||
cd "$LMS_DIR"
|
||||
|
||||
prompt_text "Path to music folder [default: $ACTUAL_HOME/drives/primary/music]:" "$ACTUAL_HOME/drives/primary/music" MUSIC_PATH
|
||||
prompt_text "Path to music folder [default: $PRIMARY_DRIVE_PATH/music]:" "$PRIMARY_DRIVE_PATH/music" MUSIC_PATH
|
||||
|
||||
cat > docker-compose.yml << LMS_COMPOSE
|
||||
name: lyrion
|
||||
@@ -4520,7 +4676,7 @@ MC_ENV
|
||||
mkdir -p "$JELLYFIN_DIR"
|
||||
cd "$JELLYFIN_DIR"
|
||||
|
||||
prompt_text "Path to media folder [default: $ACTUAL_HOME/drives/primary/media]:" "$ACTUAL_HOME/drives/primary/media" MEDIA_PATH
|
||||
prompt_text "Path to media folder [default: $PRIMARY_DRIVE_PATH/media]:" "$PRIMARY_DRIVE_PATH/media" MEDIA_PATH
|
||||
|
||||
# Get render group ID for hardware acceleration
|
||||
RENDER_GID=$(getent group render | cut -d: -f3 2>/dev/null || echo "989")
|
||||
|
||||
Reference in New Issue
Block a user