Moved scripts to folder
This commit is contained in:
Executable
+120
@@ -0,0 +1,120 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==========================================
|
||||
# CONFIGURATION (Edit these!)
|
||||
# ==========================================
|
||||
GOTIFY_TOKEN="AH5NXt3g0lSCyfT" # <--- Paste your token here
|
||||
GOTIFY_URL="https://gotify.marlow.quest"
|
||||
SRC_DIR="$HOME/Videos/Compress"
|
||||
OUT_DIR="$SRC_DIR/Complete"
|
||||
|
||||
# ==========================================
|
||||
# DEPENDENCY CHECKS
|
||||
# ==========================================
|
||||
for cmd in gum HandBrakeCLI curl awk; do
|
||||
if ! command -v $cmd &> /dev/null; then
|
||||
echo "Error: '$cmd' is not installed."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Ensure directories exist
|
||||
mkdir -p "$SRC_DIR"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
# ==========================================
|
||||
# GUM UI & SETTINGS
|
||||
# ==========================================
|
||||
clear
|
||||
gum style \
|
||||
--border double --border-foreground 240 --foreground 208 \
|
||||
--padding "1 6" --margin "1 1" --align center \
|
||||
"Video Converter"
|
||||
|
||||
# 1. Quality Selection
|
||||
QUALITY=$(gum input --prompt "Enter Quality Factor (CQ): " --placeholder "35" --width 50)
|
||||
[ -z "$QUALITY" ] && exit 0
|
||||
export QUALITY
|
||||
|
||||
# 2. Gotify Toggle
|
||||
if gum confirm "Enable Gotify notification upon completion?" --default=no --affirmative "Yes" --negative "No"; then
|
||||
if [ -z "$GOTIFY_TOKEN" ]; then
|
||||
gum style --foreground 196 "!! Warning: Gotify enabled but GOTIFY_TOKEN is empty at top of script. Skipping notification."
|
||||
GOTIFY_ENABLED=false
|
||||
else
|
||||
GOTIFY_ENABLED=true
|
||||
fi
|
||||
else
|
||||
GOTIFY_ENABLED=false
|
||||
fi
|
||||
|
||||
# ==========================================
|
||||
# FILE PROCESSING
|
||||
# ==========================================
|
||||
shopt -s nocaseglob
|
||||
shopt -s nullglob
|
||||
cd "$SRC_DIR" || exit 1
|
||||
files=( *.mp4 *.mkv *.mov *.avi )
|
||||
|
||||
if [ ${#files[@]} -eq 0 ]; then
|
||||
gum style --foreground 208 "No video files found in $SRC_DIR."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TOTAL_OLD_BYTES=0
|
||||
TOTAL_NEW_BYTES=0
|
||||
FILE_COUNT=0
|
||||
|
||||
gum style --foreground 208 --margin "1 0" "Found ${#files[@]} files. Starting queue..."
|
||||
|
||||
for f in "${files[@]}"; do
|
||||
filename=$(basename -- "$f")
|
||||
basename="${filename%.*}"
|
||||
export IN_FILE="$f"
|
||||
export OUT_FILE="$OUT_DIR/${basename}.mkv"
|
||||
|
||||
# Size calculations
|
||||
old_size=$(wc -c < "$f")
|
||||
old_mb=$(awk "BEGIN {printf \"%.1f\", $old_size/1048576}")
|
||||
|
||||
# Spinner & Handbrake
|
||||
gum spin --spinner minidot --spinner.foreground 208 --title "Encoding: $filename ($old_mb MB)..." -- \
|
||||
bash -c 'HandBrakeCLI -i "$IN_FILE" -o "$OUT_FILE" -e svt_av1 --encoder-preset 8 -q "$QUALITY" --vfr -l 1080 -E opus -B 128 > /dev/null 2>&1'
|
||||
|
||||
if [ $? -eq 0 ] && [ -f "$OUT_FILE" ]; then
|
||||
new_size=$(wc -c < "$OUT_FILE")
|
||||
new_mb=$(awk "BEGIN {printf \"%.1f\", $new_size/1048576}")
|
||||
saved_mb=$(awk "BEGIN {printf \"%.1f\", $old_mb - $new_mb}")
|
||||
|
||||
gum style --foreground 76 "✓ $filename"
|
||||
gum style --foreground 245 " ↳ Size: ${old_mb}MB → ${new_mb}MB (Saved: ${saved_mb}MB)"
|
||||
|
||||
TOTAL_OLD_BYTES=$((TOTAL_OLD_BYTES + old_size))
|
||||
TOTAL_NEW_BYTES=$((TOTAL_NEW_BYTES + new_size))
|
||||
((FILE_COUNT++))
|
||||
else
|
||||
gum style --foreground 196 "✗ Failed: $filename"
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
# ==========================================
|
||||
# SUMMARY & NOTIFICATION
|
||||
# ==========================================
|
||||
TOTAL_SAVED_MB=$(awk "BEGIN {printf \"%.1f\", ($TOTAL_OLD_BYTES - TOTAL_NEW_BYTES)/1048576}")
|
||||
|
||||
gum style \
|
||||
--border rounded --border-foreground 208 --foreground 245 \
|
||||
--padding "1 2" --margin "1 0" \
|
||||
"Batch Complete! Processed: $FILE_COUNT files | Total Saved: $TOTAL_SAVED_MB MB"
|
||||
|
||||
if [ "$GOTIFY_ENABLED" = true ] && [ $FILE_COUNT -gt 0 ]; then
|
||||
MESSAGE="Finished processing $FILE_COUNT videos. Total space saved: $TOTAL_SAVED_MB MB."
|
||||
|
||||
curl -s -S "$GOTIFY_URL/message?token=$GOTIFY_TOKEN" \
|
||||
-F "title=✅ Video Encoding Complete" \
|
||||
-F "message=$MESSAGE" \
|
||||
-F "priority=5" > /dev/null
|
||||
|
||||
gum style --foreground 240 " (Gotify notification sent)"
|
||||
fi
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
#!/bin/bash
|
||||
|
||||
REQUIRED_TOOLS=("gum")
|
||||
|
||||
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
|
||||
|
||||
declare -A INSTALL_CMDS
|
||||
declare -a MENU_OPTIONS
|
||||
|
||||
add_app() {
|
||||
local name="$1"
|
||||
local desc="$2"
|
||||
local cmd="$3"
|
||||
# Format: Grey for the description text
|
||||
local menu_item=$(printf "%-12s | %s" "$name" "$desc")
|
||||
MENU_OPTIONS+=("$menu_item")
|
||||
INSTALL_CMDS["$menu_item"]="$cmd"
|
||||
}
|
||||
|
||||
# --- YOUR APPS ---
|
||||
add_app "Gradia" "Modern screenshot annotation" "flatpak install -y flathub be.alexandervanhee.gradia"
|
||||
add_app "Obsidian" "Markdown knowledge base" "flatpak install -y flathub md.obsidian.Obsidian"
|
||||
add_app "Brave" "Privacy browser" "sudo dnf install -y brave-browser"
|
||||
add_app "Newsflash" "Desktop RSS reader" "flatpak install -y flathub io.gitlab.news_flash.NewsFlash"
|
||||
add_app "Plex Amp" "Play music from Plex server" "flatpak install -y flathub com.plexamp.Plexamp"
|
||||
add_app "RPi Imager" "Raspber Pi Imager" "sudo dnf install -y rpi-imager"
|
||||
add_app "Local Send" "Send Files over the network" "flatpak install -y flathub org.localsend.localsend_app"
|
||||
add_app "Planify" "To Do List" "flatpak install -y flathub io.github.alainm23.planify"
|
||||
add_app "Whatsapp" "Zap Zap Whatsapp client" "flatpak install -y flathub com.rtosta.zapzap"
|
||||
add_app "Celluloid" "Video PLayer" "sudo dnf install -y celluloid"
|
||||
add_app "Remmina" "Remote Desktop" "sudo dnf install -y remmina"
|
||||
# -----------------
|
||||
|
||||
clear
|
||||
|
||||
# Title: Orange text with a Grey border
|
||||
gum style \
|
||||
--border rounded \
|
||||
--margin "1" \
|
||||
--padding "1 2" \
|
||||
--border-foreground 244 \
|
||||
--foreground 208 \
|
||||
" Fedora App Selector"
|
||||
|
||||
# 1. Selection
|
||||
SELECTIONS=$(printf "%s\n" "${MENU_OPTIONS[@]}" | gum choose --no-limit \
|
||||
--header "Select apps (Space to mark, Enter to confirm)" \
|
||||
--header.foreground 244 \
|
||||
--cursor.foreground 208 \
|
||||
--selected.foreground 208)
|
||||
|
||||
if [ -z "$SELECTIONS" ]; then
|
||||
gum style --foreground 244 "No apps selected. Exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 2. Confirmation (Orange theme)
|
||||
gum confirm --selected.background 208 "Ready to install?" || exit 0
|
||||
|
||||
# 3. Installation Loop
|
||||
echo "$SELECTIONS" | while IFS= read -r selection; do
|
||||
cmd="${INSTALL_CMDS[$selection]}"
|
||||
app_name=$(echo "$selection" | awk -F' \\| ' '{print $1}' | xargs)
|
||||
|
||||
# Spinner: Orange spinner with Grey text
|
||||
gum spin --spinner dot --title "Installing $app_name..." --title.foreground 244 --spinner.foreground 208 -- bash -c "$cmd > /dev/null 2>&1"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
gum style --foreground 208 " ✓ $app_name installed"
|
||||
else
|
||||
gum style --foreground 196 " ✗ Failed to install $app_name"
|
||||
fi
|
||||
done
|
||||
|
||||
# 4. Cleanup
|
||||
stty sane
|
||||
printf "\033[K"
|
||||
echo ""
|
||||
gum style --foreground 208 --bold " All tasks finished!"
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- Configuration & Theme ---
|
||||
ORANGE="#FF8700"
|
||||
GREY="#808080"
|
||||
|
||||
# Styling functions
|
||||
title_style() { gum style --foreground "$ORANGE" --bold --border double --border-foreground "$GREY" --padding "0 2" --margin "1" "$1"; }
|
||||
info_style() { gum style --foreground "$GREY" "$1"; }
|
||||
error_style() { gum style --foreground "#FF0000" --bold "Error: $1"; }
|
||||
|
||||
# --- Initialization ---
|
||||
clear
|
||||
title_style "NDS ROM PATCHER"
|
||||
|
||||
# 1. Select the Folder
|
||||
info_style "Navigate to the folder containing your ROM and Patch:"
|
||||
TARGET_DIR=$(gum file --directory --cursor.foreground "$ORANGE")
|
||||
|
||||
# Exit if no directory selected
|
||||
[[ -z "$TARGET_DIR" ]] && exit 1
|
||||
|
||||
cd "$TARGET_DIR" || exit 1
|
||||
|
||||
# 2. Identify Files
|
||||
# Find .nds files
|
||||
NDS_FILES=$(ls *.nds 2>/dev/null)
|
||||
if [[ -z "$NDS_FILES" ]]; then
|
||||
error_style "No .nds files found in $TARGET_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find .xdelta files
|
||||
PATCH_FILES=$(ls *.xdelta 2>/dev/null)
|
||||
if [[ -z "$PATCH_FILES" ]]; then
|
||||
error_style "No .xdelta files found in $TARGET_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. User Selection (if multiple files exist)
|
||||
ROM=$(echo "$NDS_FILES" | gum choose --header "Select the NDS ROM" --cursor.foreground "$ORANGE" --header.foreground "$GREY")
|
||||
PATCH=$(echo "$PATCH_FILES" | gum choose --header "Select the xdelta patch" --cursor.foreground "$ORANGE" --header.foreground "$GREY")
|
||||
|
||||
# 4. Prepare Output Name
|
||||
# Strips extension and adds -patch.nds
|
||||
FILENAME=$(basename "$ROM" .nds)
|
||||
OUTPUT="${FILENAME}-patch.nds"
|
||||
|
||||
# 5. Execute Patching
|
||||
echo ""
|
||||
gum spin --spinner dot --title "Applying patch to $ROM..." --title.foreground "$ORANGE" -- \
|
||||
xdelta3 -d -s "$ROM" "$PATCH" "$OUTPUT"
|
||||
|
||||
# 6. Result Check
|
||||
if [ $? -eq 0 ]; then
|
||||
gum style --foreground "$ORANGE" --border rounded --border-foreground "$GREY" --padding "1 2" \
|
||||
"SUCCESS!" "File created: $OUTPUT"
|
||||
else
|
||||
error_style "Patching failed. Ensure your ROM is a clean dump."
|
||||
fi
|
||||
Executable
+328
@@ -0,0 +1,328 @@
|
||||
#!/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
|
||||
Executable
+156
@@ -0,0 +1,156 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define Colors
|
||||
ORANGE="#FFA500"
|
||||
GREY="#808080"
|
||||
|
||||
# 1. Check for required tools
|
||||
for cmd in gum wit dolphin-tool; do
|
||||
if ! command -v $cmd &> /dev/null; then
|
||||
gum style --foreground 196 "Error: '$cmd' is not installed."
|
||||
[ "$cmd" == "dolphin-tool" ] && echo "Hint: Install it via your package manager (usually part of dolphin-emu)."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# 2. Aesthetic Header
|
||||
clear
|
||||
gum style \
|
||||
--border double \
|
||||
--border-foreground "$ORANGE" \
|
||||
--foreground "$ORANGE" \
|
||||
--margin "1 2" \
|
||||
--padding "1 4" \
|
||||
--align center \
|
||||
--width 50 \
|
||||
"NINTENDO USB LOADER"
|
||||
|
||||
# 3. Mode Selection
|
||||
gum style --foreground "$GREY" " > Select the console format:"
|
||||
MODE=$(gum choose --cursor.foreground "$ORANGE" "Wii (WBFS)" "GameCube (ISO)")
|
||||
[ -z "$MODE" ] && exit 1
|
||||
|
||||
# 4. Source Directory & File Selection
|
||||
gum style --foreground "$GREY" " > Step 1: Select the FOLDER containing your games"
|
||||
ISO_DIR=$(gum file --directory)
|
||||
[ -z "$ISO_DIR" ] && exit 1
|
||||
|
||||
# Move into the folder to get clean filenames
|
||||
pushd "$ISO_DIR" > /dev/null
|
||||
shopt -s nullglob
|
||||
available_files=(*.iso *.rvz)
|
||||
|
||||
if [ ${#available_files[@]} -eq 0 ]; then
|
||||
gum style --foreground 196 " No .iso or .rvz files found in $ISO_DIR"
|
||||
popd > /dev/null
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gum style --foreground "$GREY" " > Step 2: Select the GAMES to transfer"
|
||||
gum style --foreground "$GREY" " (Use SPACE to select multiple, ENTER to confirm)"
|
||||
SELECTED_FILES=$(gum choose --no-limit --cursor.foreground "$ORANGE" --selected.foreground "$ORANGE" "${available_files[@]}")
|
||||
popd > /dev/null
|
||||
|
||||
[ -z "$SELECTED_FILES" ] && exit 1
|
||||
|
||||
# Read the multiline selection from Gum into a safe Bash array
|
||||
mapfile -t selected_array <<< "$SELECTED_FILES"
|
||||
|
||||
# 5. USB Selection
|
||||
USER_MEDIA="/run/media/$USER"
|
||||
if [ ! -d "$USER_MEDIA" ] || [ -z "$(ls -A "$USER_MEDIA" 2>/dev/null)" ]; then
|
||||
gum style --foreground 196 " No USB drives detected in $USER_MEDIA"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gum style --foreground "$GREY" " > Select your destination USB drive"
|
||||
pushd "$USER_MEDIA" > /dev/null
|
||||
SELECTED_DRIVE=$(gum choose --cursor.foreground "$ORANGE" *)
|
||||
popd > /dev/null
|
||||
[ -z "$SELECTED_DRIVE" ] && exit 1
|
||||
|
||||
USB_DIR="$USER_MEDIA/$SELECTED_DRIVE"
|
||||
|
||||
# 6. Final Summary and Confirmation
|
||||
clear
|
||||
gum style --foreground "$ORANGE" "Ready to Process ${#selected_array[@]} $MODE title(s)"
|
||||
echo -e " \033[90mTarget: \033[0m $USB_DIR"
|
||||
echo ""
|
||||
|
||||
gum confirm --selected.background "$ORANGE" "Begin transfer?" || exit 0
|
||||
|
||||
# 7. Processing Loop
|
||||
clear
|
||||
gum style --foreground "$ORANGE" "Processing titles..."
|
||||
echo ""
|
||||
|
||||
for filename in "${selected_array[@]}"; do
|
||||
full_path="$ISO_DIR/$filename"
|
||||
ext="${filename##*.}"
|
||||
base_name="${filename%.*}"
|
||||
|
||||
# Defaults
|
||||
needs_cleanup=false
|
||||
working_iso="$full_path"
|
||||
|
||||
# --- RVZ UNPACKING LOGIC ---
|
||||
if [ "${ext,,}" == "rvz" ]; then
|
||||
working_iso="$ISO_DIR/${base_name}_temp.iso"
|
||||
|
||||
gum spin --spinner dot --title.foreground "$GREY" --title "Unpacking RVZ: $filename..." -- \
|
||||
dolphin-tool convert -i "$full_path" -o "$working_iso" -f iso
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
gum style --foreground 196 " ✘ Failed to unpack: $filename"
|
||||
continue
|
||||
fi
|
||||
# Flag the temporary ISO for deletion once we are done with it
|
||||
needs_cleanup=true
|
||||
fi
|
||||
|
||||
# --- TRANSFER LOGIC ---
|
||||
if [ "$MODE" == "Wii (WBFS)" ]; then
|
||||
# WII LOGIC
|
||||
gum spin --spinner dot --title.foreground "$GREY" --title "Converting to WBFS: $base_name..." -- \
|
||||
wit copy "$working_iso" --wbfs --split --dest "$USB_DIR/wbfs/%T [%I]/%I.wbfs"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
gum style --foreground "$ORANGE" " ✔ $base_name"
|
||||
else
|
||||
gum style --foreground 196 " ✘ Failed transfer: $base_name"
|
||||
fi
|
||||
|
||||
else
|
||||
# GAMECUBE LOGIC
|
||||
game_id=$(wit id "$working_iso" 2>/dev/null | tail -n 1 | awk '{print $1}')
|
||||
clean_title=$(echo "$base_name" | tr -d ':/\\*?<>|')
|
||||
DEST_FOLDER="$USB_DIR/games/$clean_title [$game_id]"
|
||||
|
||||
if [[ ! "$game_id" =~ ^[A-Z0-9]{6}$ ]]; then
|
||||
gum style --foreground 196 " ✘ Failed: $base_name (Invalid Game ID)"
|
||||
else
|
||||
gum spin --spinner dot --title.foreground "$GREY" --title "Moving: $clean_title..." -- \
|
||||
bash -c 'mkdir -p "$1" && cp "$2" "$1/game.iso"' _ "$DEST_FOLDER" "$working_iso"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
gum style --foreground "$ORANGE" " ✔ $clean_title"
|
||||
else
|
||||
gum style --foreground 196 " ✘ Failed: $clean_title"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- CLEANUP LOGIC ---
|
||||
if [ "$needs_cleanup" = true ]; then
|
||||
rm -f "$working_iso"
|
||||
fi
|
||||
done
|
||||
|
||||
# 8. Finished
|
||||
echo ""
|
||||
gum style \
|
||||
--border rounded \
|
||||
--border-foreground "$GREY" \
|
||||
--foreground "$ORANGE" \
|
||||
--padding "1 2" \
|
||||
"COMPLETE: Games synced to $SELECTED_DRIVE"
|
||||
Reference in New Issue
Block a user