#!/usr/bin/env python3 """ Illuscape uninstaller — cross-platform (Linux, Windows, macOS). Usage: python3 uninstall.py ./uninstall.sh (Linux / macOS) """ from __future__ import annotations import os import platform import shutil import subprocess import sys from pathlib import Path SCRIPT_DIR = Path(__file__).parent sys.path.insert(0, str(SCRIPT_DIR / "scripts")) from detect_platform import detect_config # noqa: E402 ICON_SIZES = (16, 32, 48, 64, 128, 256, 512) # All files installed by install.py, keyed by subdirectory _INSTALLED_FILES: dict[str, list[str]] = { "keys": [ "illustrator-cc.xml", "illustrator-cs6.xml", ], "palettes": [ "Illustrator-Defaults.gpl", "Illustrator-Grays.gpl", "Illustrator-Earth.gpl", ], "templates": [ "Letter.svg", "A4.svg", "Web-1920x1080.svg", "Web-1280x720.svg", "Print-CMYK-Letter.svg", "Print-CMYK-A4.svg", ], "symbols": [ "illuscape-common.svg", ], "splashscreens": [ "illuscape-splash.png", ], } # ── Backup discovery ────────────────────────────────────────────────────────── def find_backup(config_path: Path) -> Path | None: """Return the most recent illuscape backup directory, or None.""" backups = sorted(config_path.parent.glob(config_path.name + ".bak-illuscape-*")) return backups[-1] if backups else None # ── Restore ─────────────────────────────────────────────────────────────────── def restore_prefs(backup: Path, config_path: Path) -> None: """Copy preferences.xml back from the backup directory.""" src = backup / "preferences.xml" dst = config_path / "preferences.xml" if src.exists(): shutil.copy2(src, dst) print(f"→ preferences.xml restored from: {backup}") else: print("⚠ No preferences.xml in backup — skipping restore") # ── File removal ────────────────────────────────────────────────────────────── def remove_files(config_path: Path) -> None: """Delete all files that install.py placed in the Inkscape config dir.""" for subdir, names in _INSTALLED_FILES.items(): for name in names: (config_path / subdir / name).unlink(missing_ok=True) (config_path / "illuscape.ico").unlink(missing_ok=True) print("→ Illuscape config files removed") # ── Desktop cleanup ─────────────────────────────────────────────────────────── def remove_desktop(install_method: str) -> None: """Remove the desktop launcher / Start Menu shortcut for the current platform.""" system = platform.system() if system == "Linux" and install_method == "native": _remove_linux_desktop() elif system == "Windows": _remove_windows_desktop() def _remove_linux_desktop() -> None: lnk = Path.home() / ".local/share/applications/org.inkscape.Inkscape.desktop" lnk.unlink(missing_ok=True) for size in ICON_SIZES: icon = ( Path.home() / f".local/share/icons/hicolor/{size}x{size}/apps/illuscape.png" ) icon.unlink(missing_ok=True) app_dir = Path.home() / ".local/share/applications" subprocess.run(["update-desktop-database", str(app_dir)], capture_output=True) print("→ Desktop launcher removed") def _remove_windows_desktop() -> None: lnk = ( Path(os.environ.get("APPDATA", "")) / "Microsoft/Windows/Start Menu/Programs/Illuscape.lnk" ) lnk.unlink(missing_ok=True) print("→ Start Menu shortcut removed") # ── Main ────────────────────────────────────────────────────────────────────── def main() -> None: print("╔══════════════════════════════╗") print("║ Illuscape Uninstaller ║") print("╚══════════════════════════════╝") print() config_path, install_method = detect_config() print(f"→ Inkscape config: {config_path} ({install_method})") backup = find_backup(config_path) if backup is None: print(f"⚠ No Illuscape backup found at {config_path}.bak-illuscape-*") print(" Cannot restore original preferences.xml automatically.") print(" Removing only Illuscape-installed files.") else: restore_prefs(backup, config_path) remove_files(config_path) remove_desktop(install_method) print() print("✓ Illuscape uninstalled.") print() print(" Note: Your Inkscape preferences may have changed since Illuscape was") print(" installed. If anything looks wrong, review:") print(f" {config_path}/preferences.xml") print() if __name__ == "__main__": main()