#!/usr/bin/env bash # iCloud Drive for Linux — installer # Installs icloud-linux (backend) + icloud-gui (GTK3 frontend) on ElementaryOS / Ubuntu / Debian. set -euo pipefail REPO_URL="https://github.com/IsmaeelAkram/icloud-linux" INSTALL_DIR="$HOME/.local/lib/icloud-linux" GUI_INSTALL="$HOME/.local/lib/icloud-gui" BIN_DIR="$HOME/.local/bin" DESKTOP_DIR="$HOME/.local/share/applications" ICONS_DIR="$HOME/.local/share/icons/hicolor/scalable/apps" BOLD="\033[1m" GREEN="\033[0;32m" YELLOW="\033[0;33m" CYAN="\033[0;36m" RED="\033[0;31m" RESET="\033[0m" info() { echo -e "${CYAN} →${RESET} $*"; } success() { echo -e "${GREEN} ✓${RESET} $*"; } warn() { echo -e "${YELLOW} !${RESET} $*"; } die() { echo -e "${RED} ✗ ERROR:${RESET} $*" >&2; exit 1; } header() { echo -e "\n${BOLD}$*${RESET}"; } # ── Detect distro ───────────────────────────────────────────────────────────── if ! command -v apt-get &>/dev/null; then die "This installer requires apt (Debian/Ubuntu/ElementaryOS). For other distros, install deps manually." fi header "iCloud Drive for Linux — Installer" echo " Target install: $INSTALL_DIR" echo " GUI install: $GUI_INSTALL" echo "" # ── System dependencies ─────────────────────────────────────────────────────── header "1/6 Installing system dependencies" PKGS=( python3 python3-venv python3-pip python3-gi python3-gi-cairo gir1.2-gtk-3.0 python3-yaml fuse git libfuse2 heif-gdk-pixbuf # HEIC/HEIF support for GNOME Photos ) # Elementary/Ubuntu 22+ ships libfuse3 but icloud-linux may need libfuse2 sudo apt-get update -qq sudo apt-get install -y "${PKGS[@]}" 2>&1 | grep -E "(install|already)" || true success "Dependencies installed" # ── Clone / update icloud-linux backend ─────────────────────────────────────── header "2/6 Installing icloud-linux backend" if [ -d "$INSTALL_DIR/.git" ]; then info "Already cloned — pulling latest" git -C "$INSTALL_DIR" pull --ff-only else info "Cloning $REPO_URL" git clone "$REPO_URL" "$INSTALL_DIR" fi # Set up Python venv and install requirements info "Setting up Python environment" python3 -m venv "$INSTALL_DIR/venv" "$INSTALL_DIR/venv/bin/pip" install -q --upgrade pip "$INSTALL_DIR/venv/bin/pip" install -q -r "$INSTALL_DIR/requirements.txt" success "Backend ready at $INSTALL_DIR" # ── Install the GUI ─────────────────────────────────────────────────────────── header "3/6 Installing iCloud Drive GUI" mkdir -p "$GUI_INSTALL" # Copy the GUI script alongside this installer script SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" if [ -f "$SCRIPT_DIR/icloud_gui.py" ]; then cp "$SCRIPT_DIR/icloud_gui.py" "$GUI_INSTALL/icloud_gui.py" success "Copied GUI from $SCRIPT_DIR" else die "icloud_gui.py not found next to install.sh — make sure you run install.sh from the icloud-gui directory." fi # ── Wrapper script in PATH ──────────────────────────────────────────────────── header "4/6 Creating launcher" mkdir -p "$BIN_DIR" cat > "$BIN_DIR/icloud-drive" < "$ICONS_DIR/com.elementary.icloud-linux.svg" <<'SVGEOF' SVGEOF cat > "$DESKTOP_DIR/com.elementary.icloud-linux.desktop" </dev/null || true update-desktop-database "$DESKTOP_DIR" 2>/dev/null || true success "App menu entry installed" # ── Update GUI config to point at correct icloudctl ────────────────────────── # Patch the ICLOUDCTL path in the installed GUI script ICLOUDCTL_PATH="$INSTALL_DIR/icloudctl" sed -i "s|ICLOUDCTL = .*|ICLOUDCTL = \"$ICLOUDCTL_PATH\"|" "$GUI_INSTALL/icloud_gui.py" success "GUI configured to use $ICLOUDCTL_PATH" # ── Enable service at boot ───────────────────────────────────────────────────── header "6/6 Enabling iCloud service at boot" SERVICE_DIR="$HOME/.config/systemd/user" mkdir -p "$SERVICE_DIR" # Only write the service file if icloud-linux provides one; otherwise create it if [ -f "$INSTALL_DIR/icloud-linux/icloud.service" ]; then cp "$INSTALL_DIR/icloud-linux/icloud.service" "$SERVICE_DIR/icloud.service" elif [ ! -f "$SERVICE_DIR/icloud.service" ]; then cat > "$SERVICE_DIR/icloud.service" </dev/null || true success "iCloud service enabled at boot (systemctl --user enable icloud.service)" # ── Done ────────────────────────────────────────────────────────────────────── header "Installation complete!" echo "" echo -e " ${BOLD}Next steps:${RESET}" echo " 1. Open ${BOLD}iCloud Drive${RESET} from your app menu (Slingshot)" echo " or run: icloud-drive" echo "" echo " 2. Go to ${BOLD}Settings${RESET} and enter your Apple ID + password" echo "" echo " 3. Go to ${BOLD}Sign In${RESET} and authenticate (handles 2FA)" echo "" echo " 4. On ${BOLD}Dashboard${RESET}, press ${BOLD}Start${RESET} to begin syncing" echo "" echo " The iCloud service will start automatically at every login." echo "" echo " To uninstall, run: $SCRIPT_DIR/uninstall.sh" echo ""