#!/bin/bash # Configuration directories INSTALL_DIR="$HOME/.local/bin" APP_DIR="$HOME/.local/share/applications" SERVICE_MENU_DIR="$HOME/.local/share/kio/servicemenus" LEGACY_SERVICE_MENU_DIR="$HOME/.local/share/kservices5/ServiceMenus" # Check Python 3 and PySide6 dependency echo "Checking dependencies..." if ! command -v python3 &>/dev/null; then echo "Error: Python 3 is required but not found on your system." exit 1 fi if ! python3 -c "import PySide6" &>/dev/null; then echo "PySide6 is not installed. Attempting automatic installation..." if command -v pip3 &>/dev/null; then pip3 install PySide6 || pip3 install --break-system-packages PySide6 || true elif command -v pip &>/dev/null; then pip install PySide6 || pip install --break-system-packages PySide6 || true elif command -v dnf &>/dev/null; then echo "Installing python3-pyside6 via dnf..." sudo dnf install -y python3-pyside6 || true elif command -v apt-get &>/dev/null; then echo "Installing python3-pyside6 via apt..." sudo apt-get update && sudo apt-get install -y python3-pyside6 || true elif command -v pacman &>/dev/null; then echo "Installing python-pyside6 via pacman..." sudo pacman -S --noconfirm python-pyside6 || true elif command -v zypper &>/dev/null; then echo "Installing python3-pyside6 via zypper..." sudo zypper install -y python3-pyside6 || true fi fi if ! python3 -c "import PySide6" &>/dev/null; then echo "Warning: Could not automatically install PySide6. Please install 'PySide6' via pip or your distro package manager (e.g. python3-pyside6)." fi # Create necessary directories mkdir -p "$INSTALL_DIR" "$APP_DIR" "$SERVICE_MENU_DIR" "$LEGACY_SERVICE_MENU_DIR" # Clean legacy kde-uploader names rm -f "$INSTALL_DIR/kde-uploader" "$INSTALL_DIR/kde-uploader-gui" rm -f "$APP_DIR/kde-uploader.desktop" "$APP_DIR/kde-uploader-gui.desktop" rm -f "$SERVICE_MENU_DIR/kde-uploader-servicemenu.desktop" "$LEGACY_SERVICE_MENU_DIR/kde-uploader-servicemenu.desktop" rm -f "$HOME/.config/autostart/kde-uploader-gui.desktop" # 1. Install the scripts cp uploader.sh "$INSTALL_DIR/f0ckm-uploader" chmod +x "$INSTALL_DIR/f0ckm-uploader" cp gui.py "$INSTALL_DIR/f0ckm-uploader-gui" chmod +x "$INSTALL_DIR/f0ckm-uploader-gui" mkdir -p "$HOME/.local/share/icons/hicolor/scalable/apps" mkdir -p "$HOME/.local/share/pixmaps" # Generate multi-resolution PNG icons (32x32, 48x48, 64x64, 128x128, 256x256) for KRunner search compatibility python3 -c ' import os from PySide6.QtGui import QImage, QPainter from PySide6.QtSvg import QSvgRenderer try: renderer = QSvgRenderer("icon_app.svg") sizes = [32, 48, 64, 128, 256] for sz in sizes: dir_path = f"'$HOME'/.local/share/icons/hicolor/{sz}x{sz}/apps" os.makedirs(dir_path, exist_ok=True) img = QImage(sz, sz, QImage.Format_ARGB32) img.fill(0) p = QPainter(img) renderer.render(p) p.end() img.save(os.path.join(dir_path, "f0ckm-uploader.png")) img_48 = QImage(48, 48, QImage.Format_ARGB32) img_48.fill(0) p = QPainter(img_48) renderer.render(p) p.end() img_48.save("'$HOME'/.local/share/pixmaps/f0ckm-uploader.png") except Exception as e: pass ' &> /dev/null if [ -f icon_app.svg ]; then cp icon_app.svg "$INSTALL_DIR/icon_app.svg" cp icon_app.svg "$HOME/.local/share/icons/hicolor/scalable/apps/f0ckm-uploader.svg" elif [ -f icon.svg ]; then cp icon.svg "$HOME/.local/share/icons/hicolor/scalable/apps/f0ckm-uploader.svg" fi if [ -f icon.svg ]; then cp icon.svg "$INSTALL_DIR/icon.svg" fi if [ -f icon_light.svg ]; then cp icon_light.svg "$INSTALL_DIR/icon_light.svg" fi if [ -f .env ]; then cp .env "$INSTALL_DIR/.env" fi # Clean up any stale auto-generated desktop entries rm -f "$APP_DIR/net.local.spectacle_uploader.sh.desktop" ICON_PATH="f0ckm-uploader" # 2. Install standard application entry (for Spectacle - hidden from main menu) sed -e "s|__EXEC_PATH__|$INSTALL_DIR/f0ckm-uploader-gui --spectacle|g" -e "s|__ICON_PATH__|$ICON_PATH|g" f0ckm-uploader.desktop > "$APP_DIR/f0ckm-uploader.desktop" chmod +x "$APP_DIR/f0ckm-uploader.desktop" # 3. Install the GUI application entry (visible in main menu) sed -e "s|__EXEC_PATH__|$INSTALL_DIR/f0ckm-uploader-gui|g" -e "s|__ICON_PATH__|$ICON_PATH|g" f0ckm-uploader-gui.desktop > "$APP_DIR/f0ckm-uploader-gui.desktop" chmod +x "$APP_DIR/f0ckm-uploader-gui.desktop" update-desktop-database "$APP_DIR" &> /dev/null xdg-mime default f0ckm-uploader-gui.desktop x-scheme-handler/f0ckm x-scheme-handler/f0ckm-uploader &> /dev/null || true gtk-update-icon-cache -f -t "$HOME/.local/share/icons/hicolor" &> /dev/null || true kbuildsycoca6 --noincremental &> /dev/null || kbuildsycoca5 --noincremental &> /dev/null || true # 4. Install KDE Service Menu entry (for Dolphin) sed "s|__EXEC_PATH__|$INSTALL_DIR/f0ckm-uploader-gui --upload|g" f0ckm-uploader-servicemenu.desktop > "$SERVICE_MENU_DIR/f0ckm-uploader-servicemenu.desktop" chmod +x "$SERVICE_MENU_DIR/f0ckm-uploader-servicemenu.desktop" sed "s|__EXEC_PATH__|$INSTALL_DIR/f0ckm-uploader-gui --upload|g" f0ckm-uploader-servicemenu.desktop > "$LEGACY_SERVICE_MENU_DIR/f0ckm-uploader-servicemenu.desktop" chmod +x "$LEGACY_SERVICE_MENU_DIR/f0ckm-uploader-servicemenu.desktop" # 5. Migrate config to config.json if not present CONFIG_DIR="$HOME/.config/f0ckm-uploader" CONFIG_FILE="$CONFIG_DIR/config.json" if [ ! -f "$CONFIG_FILE" ]; then mkdir -p "$CONFIG_DIR" # Fallback to the default key in script if no config file is found cat < "$CONFIG_FILE" { "api_url": "", "api_key": "", "default_rating": "", "default_tags": "", "default_is_oc": false, "enable_notifications": true, "show_progress_dialog": true, "autostart": false } EOF echo "Initial configuration created at $CONFIG_FILE" fi # 6. Ensure autostart state matches config.json python3 -c ' import json, os try: cfg_path = os.path.expanduser("~/.config/f0ckm-uploader/config.json") if os.path.exists(cfg_path): with open(cfg_path, "r", encoding="utf-8") as f: cfg = json.load(f) autostart = cfg.get("autostart", False) autostart_dir = os.path.expanduser("~/.config/autostart") autostart_path = os.path.join(autostart_dir, "f0ckm-uploader-gui.desktop") if autostart: os.makedirs(autostart_dir, exist_ok=True) exec_path = os.path.expanduser("~/.local/bin/f0ckm-uploader-gui") content = f"""[Desktop Entry] Type=Application Name=f0ckm Uploader GUI Comment=System tray GUI and settings for f0ckm Uploader Exec={exec_path} Icon=f0ckm-uploader Terminal=false Categories=Utility;Network; StartupNotify=false X-GNOME-Autostart-enabled=true """ with open(autostart_path, "w", encoding="utf-8") as f: f.write(content) os.chmod(autostart_path, 0o755) print(f"Synced autostart desktop entry: {autostart_path}") else: if os.path.exists(autostart_path): os.remove(autostart_path) print(f"Removed autostart desktop entry: {autostart_path}") except Exception as e: print(f"Warning: could not sync autostart entry: {e}") ' echo "" echo "========================================================" echo " f0ckm Uploader Installation Complete!" echo "========================================================" echo " -> Executable installed: $INSTALL_DIR/f0ckm-uploader-gui" echo " -> Dolphin context menu registered (Right-click file -> Actions -> Upload to f0ckm)" echo " -> Spectacle screenshot export integration enabled" echo " -> Browser extension helper API ready on http://127.0.0.1:18739" echo "========================================================" echo "" # Launch GUI to prompt for API settings if API key or URL is not configured yet python3 -c ' import json, os cfg_path = os.path.expanduser("~/.config/f0ckm-uploader/config.json") if os.path.exists(cfg_path): with open(cfg_path) as f: cfg = json.load(f) if not cfg.get("api_url") or not cfg.get("api_key"): print("[!] API Key or URL not configured yet.") print(" Launching f0ckm Uploader GUI Settings for initial setup...") os.system("'$INSTALL_DIR'/f0ckm-uploader-gui &") ' || true