#!/bin/bash REQUIRED_TOOLS=("android-tools" "ideviceinstaller" "usbmuxd" "gum" "idevice_id") echo -n "📦 Checking and installing dependencies... " # OS Detection if [ -f /etc/os-release ]; then . /etc/os-release OS=$ID else echo "Unsupported OS. Manual installation required." exit 1 fi # Install dependancies install_tool() { local tool=$1 echo "--- Tool '$tool' is missing. ---" read -p "Would you like to install $tool? (y/n): " confirm if [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then case $OS in ubuntu|debian|kali|pop|mint|linuxmint|kubuntu|xubuntu|lubuntu|elementary|zorin) sudo apt update && sudo apt install -y "$tool" echo "'$tool' Installed" ;; fedora|rhel|centos) sudo dnf install -y "$tool" > /dev/null 2>&1 ;; *) echo "Package manager for '$OS' not defined in this script." exit 1 ;; esac else echo "Exiting: $tool is required for this script." exit 1 fi } # Confirm everything installed correctly for tool in "${REQUIRED_TOOLS[@]}"; do if ! command -v "$tool" &> /dev/null; then install_tool "$tool" fi done ORANGE="#FFA500" GREY="#808080" export GUM_STYLE_BORDER_FOREGROUND="$ORANGE" export GUM_STYLE_LABEL_FOREGROUND="$ORANGE" export GUM_STYLE_PROMPT_FOREGROUND="$ORANGE" export GUM_STYLE_CURSOR_FOREGROUND="$ORANGE" export GUM_STYLE_SELECTED_FOREGROUND="$ORANGE" export GUM_STYLE_FOREGROUND="$GREY" IPA_DIR="$HOME/Documents/Mobile_Apps/IPA" APK_DIR="$HOME/Documents/Mobile_Apps/APK" # Create folders if they don't exist mkdir -p "$IPA_DIR" mkdir -p "$APK_DIR" clear # Title gum style \ --border double \ --padding "1 4" \ --margin "1 2" \ --align center \ --foreground "$ORANGE" \ "📱 Linux Mobile App Installer" check_ios() { if ! idevice_id -l | grep -q .; then gum style --foreground "$ORANGE" --border rounded --padding "1 2" \ "❌ iPhone not found." return 1 fi return 0 } check_android() { if ! adb devices | grep -w "device" | grep -v "List" >/dev/null; then gum style --foreground "$ORANGE" --border rounded --padding "1 2" \ "❌ Android device not found." return 1 fi return 0 } ios_view_apps() { check_ios || return RAW=$(gum spin --spinner dot --title "Scanning apps..." -- \ ideviceinstaller list 2>/dev/null) APPS=$(echo "$RAW") if [ -z "$APPS" ]; then gum style --foreground "$GREY" "No apps found." else echo "$APPS" | gum pager fi } ios_install() { check_ios || return METHOD=$(printf "From IPA folder\nBrowse files" | gum choose) if [[ "$METHOD" == "From IPA folder" ]]; then FILE=$(ls "$IPA_DIR"/*.{ipa,tar.bz2} 2>/dev/null | gum choose) else FILE=$(gum file) fi [ ! -f "$FILE" ] && gum style --foreground "$ORANGE" "❌ Invalid file." && return TMP_DIR="" INSTALL_FILE="$FILE" if [[ "$FILE" == *.tar.bz2 ]]; then TMP_DIR=$(mktemp -d) gum spin --spinner dot --title "Extracting File..." -- \ bash -c "tar -xjf \"$FILE\" -C \"$TMP_DIR\" >/dev/null 2>&1" INSTALL_FILE=$(find "$TMP_DIR" -name "*.ipa" | head -n 1) [ -z "$INSTALL_FILE" ] && gum style --foreground "$ORANGE" "❌ No IPA found." && return fi OUTPUT=$(mktemp) gum spin --spinner dot --title "Installing app..." -- \ bash -c "ideviceinstaller install \"$INSTALL_FILE\" > \"$OUTPUT\" 2>&1" if grep -q "Install: Complete" "$OUTPUT"; then gum style --foreground "$ORANGE" --border rounded --padding "1 2" \ "✅ Installation successful!" else gum style --foreground "$ORANGE" --border rounded --padding "1 2" \ "⚠️ Installation may have failed.\n\n$(tail -n 5 "$OUTPUT")" fi rm -f "$OUTPUT" [ -n "$TMP_DIR" ] && rm -rf "$TMP_DIR" } ios_uninstall() { check_ios || return RAW=$(gum spin --spinner dot --title "Loading apps..." -- \ ideviceinstaller list 2>/dev/null) APPS=$(echo "$RAW") [ -z "$APPS" ] && gum style --foreground "$GREY" "No apps found." && return SELECT=$(echo "$APPS" | gum choose) BUNDLE=$(echo "$SELECT" | cut -d',' -f1) if gum confirm "Uninstall $BUNDLE?"; then OUT=$(mktemp) gum spin --spinner dot --title "Uninstalling..." -- \ bash -c "ideviceinstaller uninstall \"$BUNDLE\" > \"$OUT\" 2>&1" if grep -q "Complete" "$OUT"; then gum style --foreground "$ORANGE" --border rounded --padding "1 2" \ "✅ Uninstall successful!" else gum style --foreground "$ORANGE" --border rounded --padding "1 2" \ "⚠️ Uninstall may have failed." fi rm -f "$OUT" fi } android_view_apps() { check_android || return APPS=$(gum spin --spinner dot --title "Scanning apps..." -- \ adb shell pm list packages --user 0) [ -z "$APPS" ] && gum style --foreground "$GREY" "No apps found." || echo "$APPS" | gum pager } android_install() { check_android || return METHOD=$(printf "From APK folder\nBrowse files" | gum choose) if [[ "$METHOD" == "From APK folder" ]]; then FILE=$(ls "$APK_DIR"/*.{apk,tar.bz2} 2>/dev/null | gum choose) else FILE=$(gum file) fi [ ! -f "$FILE" ] && gum style --foreground "$ORANGE" "❌ Invalid file." && return TMP_DIR="" INSTALL_FILE="$FILE" # Handle tar.bz2 if [[ "$FILE" == *.tar.bz2 ]]; then TMP_DIR=$(mktemp -d) gum spin --spinner dot --title "Extracting File..." -- \ bash -c "tar -xjf \"$FILE\" -C \"$TMP_DIR\" >/dev/null 2>&1" INSTALL_FILE=$(find "$TMP_DIR" -name "*.apk" | head -n 1) if [ -z "$INSTALL_FILE" ]; then gum style --foreground "$ORANGE" "❌ No APK found in archive." rm -rf "$TMP_DIR" return fi fi OUT=$(mktemp) gum spin --spinner dot --title "Installing APK..." -- \ bash -c "adb install \"$INSTALL_FILE\" > \"$OUT\" 2>&1" if grep -q "Success" "$OUT"; then gum style \ --foreground "$ORANGE" \ --border rounded \ --padding "1 2" \ "✅ Installation successful!" else gum style \ --foreground "$ORANGE" \ --border rounded \ --padding "1 2" \ "⚠️ Install may have failed.\n\n$(tail -n 5 "$OUT")" fi rm -f "$OUT" [ -n "$TMP_DIR" ] && rm -rf "$TMP_DIR" } android_uninstall() { check_android || return METHOD=$(printf "View all\nSearch" | gum choose) if [[ "$METHOD" == "Search" ]]; then SEARCH_TERM=$(gum input --placeholder "Search app (e.g., netflix)") [ -z "$SEARCH_TERM" ] && return APPS=$(adb shell pm list packages --user 0 | grep -i "$SEARCH_TERM") else APPS=$(adb shell pm list packages --user 0) fi [ -z "$APPS" ] && gum style --foreground "$GREY" "No apps found." && return SELECT=$(echo "$APPS" | gum choose) [ -z "$SELECT" ] && return PKG=$(echo "$SELECT" | sed 's/package://') PKG=$(echo "$PKG" | tr -d '\r') if gum confirm "Uninstall $PKG?"; then OUT=$(mktemp) gum spin --spinner dot --title "Uninstalling..." -- \ bash -c "adb shell pm uninstall -k --user 0 \"$PKG\" > \"$OUT\" 2>&1" if grep -q "Success" "$OUT"; then gum style --foreground "$ORANGE" --border rounded --padding "1 2" \ "✅ Uninstall successful!" else gum style --foreground "$ORANGE" --border rounded --padding "1 2" \ "⚠️ Uninstall may have failed.\n\n$(cat "$OUT")" fi rm -f "$OUT" fi } ios_menu() { while true; do CHOICE=$(printf "View installed apps\nInstall IPA\nUninstall app\nBack" | gum choose) case "$CHOICE" in "View installed apps") ios_view_apps ;; "Install IPA") ios_install ;; "Uninstall app") ios_uninstall ;; "Back") return ;; esac done } android_menu() { while true; do CHOICE=$(printf "View installed apps\nInstall APK\nUninstall app\nBack" | gum choose) case "$CHOICE" in "View installed apps") android_view_apps ;; "Install APK") android_install ;; "Uninstall app") android_uninstall ;; "Back") return ;; esac done } while true; do CHOICE=$(printf "iPhone\nAndroid\nExit" | gum choose) case "$CHOICE" in "iPhone") ios_menu ;; "Android") android_menu ;; "Exit") clear; exit 0 ;; esac done