diff --git a/README.md b/README.md index 89f5564..870ba15 100644 --- a/README.md +++ b/README.md @@ -56,28 +56,32 @@ After running the script: | Option | Description | What it does | |--------|-------------|--------------| -| **1** | User Privileges & Feedback | Add user to sudo group, enable password feedback (`pwfeedback`) | -| **2** | Configure Repositories | Setup official repos with/without backports (deb822 or classic format) | -| **3** | Setup Wireless & Firmware | Install WiFi firmware for Broadcom, Intel, and other chipsets | -| **4** | Configure Graphics Stack | AMD/Intel/NVIDIA drivers + monitoring tools (`nvtop`, `radeontop`) | -| **5** | Update Kernel to Backports | Install latest stable kernel from Debian backports (7.0+) | -| **6** | Gaming Setup and Performance | Steam, GameMode, MangoHud, Heroic Games Launcher | -| **7** | Install ZRAM (compressed swap) | Configure compressed RAM for memory optimization | -| **8** | Install Extra Applications | Select from 10+ categories: System Tools, Development, Media Players, Web Browsers, GTK/Icon Themes, Downloaders, Design Software | -| **9** | Exit | Return to terminal | +| **1** | System Info | Show detected hardware and OS details | +| **2** | User Privileges & Feedback | Add user to sudo group, enable password feedback (`pwfeedback`) | +| **3** | Configure Repositories | Setup official repos with/without backports (deb822 or classic format) | +| **4** | Setup Wireless & Firmware | Install WiFi firmware for Broadcom, Intel, and other chipsets | +| **5** | Configure Graphics Stack | AMD/Intel/NVIDIA drivers + monitoring tools (`nvtop`, `radeontop`) | +| **6** | Update Kernel to Backports | Install latest stable kernel from Debian backports (7.0+) | +| **7** | Gaming Setup and Performance | Steam, GameMode, MangoHud, Heroic Games Launcher | +| **8** | Install ZRAM (compressed swap) | Configure compressed RAM for memory optimization | +| **9** | Install Programs and Software | 10 categories: Essential, System, Dev, Players, Internet, Customization, Fetch, Download, Design | +| **10** | Exit | Return to terminal | -### Extra Applications Categories (Option 8) +### Extra Applications Categories (Option 9) -- **System Tools:** htop, btop, ncdu, timeshift, tmux, flatpak, virtualization tools -- **Development & Servers:** Docker, Nginx/Apache, PostgreSQL/MariaDB, SSH server, fail2ban -- **Media Players:** VLC, MPV, HandBrake -- **Web Browsers:** Firefox (Mozilla), LibreWolf, Floorp, Chromium, Thunderbird -- **GTK Themes:** Arc, Numix, Breeze, Bluebird, Blackbird, Greybird, Orchis -- **Icon Themes:** Papirus, Numix, Elementary, Deepin, Suru, Obsidian -- **Fetch Tools:** Neofetch/Fastfetch, Linux logo, Screenfetch -- **Downloaders:** aria2, ytdlp, FileZilla, Riseup VPN +- **Essential Pack:** Quick install of common tools (compression, system info, VLC, MS fonts) +- **System Tools:** htop, btop, ncdu, timeshift, tmux, flatpak, extrepo, virtualization tools +- **Development & Servers:** Docker, Nginx/Apache, PostgreSQL/MariaDB, SSH server, fail2ban, Python +- **Media Players:** VLC, MPV +- **Internet:** Firefox (Mozilla), LibreWolf, Floorp, Chromium, Thunderbird, Riseup VPN, Tor Browser +- **Customization → Desktop Themes (GTK/KDE):** Arc, Numix, Breeze GTK, Bluebird, Blackbird, Greybird, Orchis +- **Customization → Icon Themes:** Papirus, Numix, Elementary, Deepin, Suru, Obsidian, Breeze, Moka +- **Customization → Cursor Themes:** Bibata, Breeze, Chameleon, DMZ, XCursor, Oxygen +- **Customization → Fonts:** Bebas Neue, Anonymous Pro, ADF Verana, 3270, Liberation, MS Core, Ubuntu, Recommended +- **Fetch Tools:** Neofetch/Fastfetch, hyfetch, Linux logo, Screenfetch +- **Downloaders:** aria2, ytdlp, FileZilla - **Torrent Clients:** qBittorrent, Deluge, Transmission, mktorrent -- **Multimedia & Design:** GIMP, Kdenlive, Blender, OBS Studio, Audacity, Inkscape +- **Multimedia & Design:** GIMP, Kdenlive, Blender, OBS Studio, Audacity, Inkscape, HandBrake --- @@ -87,19 +91,36 @@ After running the script: |----------------|-------------| | `./debianito.sh` | Main entry point; handles menu navigation and system detection. | | `/modules/` | Modular scripts for specific tasks: `sudo_config`, `repos`, `firmware`, `gpu`, etc. | +| `/modules/extras/` | Split-by-category sub-modules for the "Install Programs and Software" menu. | ```bash -├── debianito.sh # Main entry point; handles menu navigation and system detection +├── debianito.sh # Main entry point; menu + system detection └── modules/ - ├── utils.sh # System info helpers (CPU/RAM/GPU/WiFi detection) - ├── sudo_config.sh # User group + pwfeedback setup - ├── repos.sh # Repository configuration (classic/deb822 format) - ├── firmware.sh # WiFi microcode and chipset-specific support - ├── gpu.sh # AMD, Intel, NVIDIA driver/firmware handling - ├── kernel.sh # Update Kernel to Backports with NVIDIA warnings - ├── gaming.sh # Steam installation & performance tools (MangoHud/GameMode) - ├── extras.sh # Extra applications installer with 10+ categories - └── zram.sh # ZRAM compressed swap configuration and optimization + ├── utils.sh # System info helpers (CPU/RAM/GPU/WiFi detection) + ├── sudo_config.sh # User group + pwfeedback setup + ├── repos.sh # Repository configuration (classic/deb822 format) + ├── firmware.sh # WiFi microcode and chipset-specific support + ├── gpu.sh # AMD, Intel, NVIDIA driver/firmware handling + ├── kernel.sh # Update Kernel to Backports with NVIDIA warnings + ├── gaming.sh # Steam installation & performance tools + ├── extras.sh # Dispatcher for the "Extras" submenu + ├── extras/ # Category modules (one folder per category) + │ ├── _helpers.sh # _inst() / _state() shared helpers + │ ├── essential/essential.sh # One-click essentials pack + │ ├── system/system.sh # System Tools (25 items) + │ ├── dev/dev.sh # Development & Servers (15 items) + │ ├── players/players.sh # Media Players (mpv, vlc) + │ ├── internet/internet.sh # Browsers, Email, VPN (incl. Mozilla/Floorp/LibreWolf) + │ ├── themes/ # Customization submenu (4 options) + │ │ ├── themes.sh # Submenu dispatcher + │ │ ├── desktop-themes/desktop-themes.sh # GTK/KDE themes (7) + │ │ ├── icons/icons.sh # Icon themes (11-12) + │ │ ├── cursors/cursors.sh # Cursor themes (6) + │ │ └── fonts/fonts.sh # Fonts (8) + │ ├── fetch/fetch.sh # System info tools (neofetch/fastfetch/hyfetch) + │ ├── download/download.sh # Downloaders + Torrent clients + │ └── design/design.sh # Multimedia & Design (12+ items) + └── zram.sh # ZRAM compressed swap configuration ``` > 🤖 AI-Assisted Development Note This project was developed with assistance from large language models for code generation, documentation and testing suggestions. The author takes full responsibility for the accuracy of all scripts included in this repository. All modifications have been reviewed manually before inclusion to ensure compatibility with Debian systems. diff --git a/modules/extras.sh b/modules/extras.sh index e2b1d4d..6414ef8 100644 --- a/modules/extras.sh +++ b/modules/extras.sh @@ -1,19 +1,25 @@ #!/usr/bin/env bash -# extras.sh +# extras.sh — Dispatcher: loads extras category modules and shows submenu -_inst() { - if is_installed "$1"; then echo " (installed)"; else echo ""; fi +_EXTRAS_DIR="${MODULES_DIR}/extras" + +_load_extras() { + [ -n "${_EXTRAS_LOADED:-}" ] && return + [ -f "${_EXTRAS_DIR}/_helpers.sh" ] && source "${_EXTRAS_DIR}/_helpers.sh" + shopt -s nullglob + for _mod in "${_EXTRAS_DIR}"/*/*.sh "${_EXTRAS_DIR}"/*/*/*.sh; do + [ -f "$_mod" ] || continue + source "$_mod" + done + shopt -u nullglob + unset _mod + _EXTRAS_LOADED=1 } install_extras() { - echo -e "${YELLOW}Extra software installation...${NC}" + _load_extras - local fetch_pkg - if [ "$DEBIAN_CODENAME" = "bookworm" ]; then - fetch_pkg="neofetch" - else - fetch_pkg="fastfetch" - fi + echo -e "${YELLOW}Extra software installation...${NC}" if _is_headless; then _msg "Headless Mode" "No graphical display detected.\n\nOnly terminal-friendly packages will be shown.\nGUI applications (browsers, media players, design tools)\nwill be skipped automatically." 12 60 @@ -24,804 +30,34 @@ install_extras() { cat_choice=$(whiptail --title "Extra Software" --menu \ "Select a category:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ "0" "Essential Pack" \ - "1" "System Tools" \ - "2" "Development & Servers" \ - "3" "Media Players" \ - "4" "Web Browsers" \ - "5" "Customization System" \ - "6" "Fetch / System Info" \ - "7" "Download & Network" \ - "8" "Multimedia & Design" \ - "9" "Back to main menu" \ + "1" "Customization System" \ + "2" "Download & Network" \ + "3" "Internet (Browsers, Email, VPN)" \ + "4" "Media Players" \ + "5" "Multimedia & Design" \ + "6" "Programming Applications" \ + "7" "Security & Networking" \ + "8" "System Tools" \ + "9" "Fetch / System Info" \ + "10" "Back to main menu" \ 3>&1 1>&2 2>&3) [ -z "$cat_choice" ] && return clear case "$cat_choice" in - 0) _quick_install ;; - 1) _cat_general ;; - 2) _cat_dev ;; - 3) _cat_players ;; - 4) _cat_browsers ;; - 5) _cat_customization ;; - 6) _cat_fetch ;; - 7) _cat_download ;; - 8) _cat_design ;; - 9) return ;; + 0) _quick_install ;; + 1) _cat_customization ;; + 2) _cat_download ;; + 3) _cat_internet ;; + 4) _cat_players ;; + 5) _cat_design ;; + 6) _cat_programming ;; + 7) _cat_security ;; + 8) _cat_general ;; + 9) _cat_fetch ;; + 10) return ;; esac clear done } - -_quick_install() { - _msg "Essential Pack" \ - "Install basic programs:\n\n - Compression (zip, unrar, 7z)\n - System tools (htop, inxi, fastfetch)\n - VLC media player\n - Microsoft fonts" 13 60 - - local quick_pkgs=( - zip unzip rar unrar p7zip-full p7zip-rar - "$fetch_pkg" htop vlc inxi ttf-mscorefonts-installer - ) - _run_install_batch "${quick_pkgs[@]}" - echo -e "${GREEN}Essential Pack installed.${NC}" -} - -_cat_general() { - local headless=false - _is_headless && headless=true - local alacritty_state="OFF"; is_installed "alacritty" && alacritty_state="ON" - local btop_state="OFF"; is_installed "btop" && btop_state="ON" - local compress_state="OFF"; is_installed "zip" && is_installed "unzip" && is_installed "p7zip-full" && compress_state="ON" - local conky_state="OFF"; is_installed "conky" && conky_state="ON" - local corectrl_state="OFF"; is_installed "corectrl" && corectrl_state="ON" - local cpufetch_state="OFF"; is_installed "cpufetch" && cpufetch_state="ON" - local cpu_x_state="OFF"; is_installed "cpu-x" && cpu_x_state="ON" - local curl_wget_state="OFF"; is_installed "curl" && is_installed "wget" && curl_wget_state="ON" - local flatpak_state="OFF"; is_installed "flatpak" && flatpak_state="ON" - local fonts_state="OFF"; is_installed "fonts-ubuntu" && fonts_state="ON" - local fwupd_state="OFF"; is_installed "fwupd" && fwupd_state="ON" - local disks_state="OFF"; is_installed "gnome-disk-utility" && disks_state="ON" - local gparted_state="OFF"; is_installed "gparted" && gparted_state="ON" - local hardinfo_state="OFF"; is_installed "hardinfo" && hardinfo_state="ON" - local htop_state="OFF"; is_installed "htop" && htop_state="ON" - local inxi_state="OFF"; is_installed "inxi" && inxi_state="ON" - local kitty_state="OFF"; is_installed "kitty" && kitty_state="ON" - local kvm_state="OFF"; is_installed "virt-manager" && kvm_state="ON" - local lshw_state="OFF"; is_installed "lshw" && lshw_state="ON" - local mc_state="OFF"; is_installed "mc" && mc_state="ON" - local nala_state="OFF"; is_installed "nala" && nala_state="ON" - local ncdu_state="OFF"; is_installed "ncdu" && ncdu_state="ON" - local psensor_state="OFF"; is_installed "psensor" && psensor_state="ON" - local timeshift_state="OFF"; is_installed "timeshift" && timeshift_state="ON" - local tmux_state="OFF"; is_installed "tmux" && tmux_state="ON" - local ttf_state="OFF"; is_installed "ttf-mscorefonts-installer" && ttf_state="ON" - - local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) - local choices - choices=$(whiptail --title "System Tools" --checklist \ - "Select system utilities to install (26 items, ↑↓ scroll):" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "alacritty" "GPU-accelerated terminal$(_inst alacritty)" "$alacritty_state" \ - "btop" "Resource monitor (fancy top)$(_inst btop)" "$btop_state" \ - "compress" "Compression tools (zip, unrar, 7z)$(_inst zip)" "$compress_state" \ - "conky" "System monitor for desktop$(_inst conky)" "$conky_state" \ - "corectrl" "AMD GPU control (CoreCtrl)$(_inst corectrl)" "$corectrl_state" \ - "cpufetch" "CPU info fetcher$(_inst cpufetch)" "$cpufetch_state" \ - "cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$cpu_x_state" \ - "curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$curl_wget_state" \ - "flatpak" "Flatpak sandbox + Flathub$(_inst flatpak)" "$flatpak_state" \ - "fonts-ubuntu" "Ubuntu font family$(_inst fonts-ubuntu)" "$fonts_state" \ - "fwupd" "Firmware update daemon$(_inst fwupd)" "$fwupd_state" \ - "gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$disks_state" \ - "gparted" "GNOME partition editor$(_inst gparted)" "$gparted_state" \ - "hardinfo" "Graphical system profiler$(_inst hardinfo)" "$hardinfo_state" \ - "htop" "Interactive process viewer$(_inst htop)" "$htop_state" \ - "inxi" "System information tool$(_inst inxi)" "$inxi_state" \ - "kitty" "GPU-based terminal emulator$(_inst kitty)" "$kitty_state" \ - "kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$kvm_state" \ - "lshw" "List hardware details$(_inst lshw)" "$lshw_state" \ - "mc" "Midnight Commander (file manager)$(_inst mc)" "$mc_state" \ - "nala" "APT frontend (parallel downloads)$(_inst nala)" "$nala_state" \ - "ncdu" "Disk usage analyzer (ncurses)$(_inst ncdu)" "$ncdu_state" \ - "psensor" "Hardware temperature monitor$(_inst psensor)" "$psensor_state" \ - "timeshift" "System restore snapshots$(_inst timeshift)" "$timeshift_state" \ - "tmux" "Terminal multiplexer$(_inst tmux)" "$tmux_state" \ - "ttf-mscorefonts-installer" "Microsoft fonts (Times, Arial)$(_inst ttf-mscorefonts-installer)" "$ttf_state" \ - 3>&1 1>&2 2>&3) - clear - - [ -z "$choices" ] && return - - local cleaned; cleaned=$(echo "$choices" | tr -d '"') - - for pkg in $cleaned; do - case $pkg in - compress) - local need=() - ! is_installed "zip" && need+=("zip") - ! is_installed "unzip" && need+=("unzip") - ! is_installed "rar" && need+=("rar") - ! is_installed "unrar" && need+=("unrar") - ! is_installed "p7zip-full" && need+=("p7zip-full") - ! is_installed "p7zip-rar" && need+=("p7zip-rar") - if [ ${#need[@]} -gt 0 ]; then - _run_install_batch "${need[@]}" - echo -e "${GREEN}Compression utilities installed.${NC}" - fi - ;; - curl-wget) - local need=() - ! is_installed "curl" && need+=("curl") - ! is_installed "wget" && need+=("wget") - if [ ${#need[@]} -gt 0 ]; then - _run_install_batch "${need[@]}" - else - echo "curl and wget already installed." - fi - ;; - flatpak) - if ! is_installed "flatpak"; then - _run_cmd "Flatpak" "sudo apt install -y flatpak" "Installing Flatpak..." - if command -v plasma-discover &>/dev/null; then - _run_cmd "Flatpak" "sudo apt install -y plasma-discover-backend-flatpak" "Installing Flatpak backend..." - echo "Flatpak backend for Discover installed." - elif command -v gnome-software &>/dev/null; then - _run_cmd "Flatpak" "sudo apt install -y gnome-software-plugin-flatpak" "Installing Flatpak plugin..." - echo "Flatpak plugin for GNOME Software installed." - fi - else - echo "Flatpak already installed." - fi - flatpak remote-add --if-not-exists flathub \ - https://dl.flathub.org/repo/flathub.flatpakrepo - echo "Flathub repository added." - echo -e "${GREEN}A reboot is recommended.${NC}" - ;; - kvm) - if ! is_installed "virt-manager"; then - _run_cmd "KVM" "sudo apt install -y qemu-system-x86 qemu-utils libvirt-daemon-system libvirt-clients bridge-utils virt-manager" "Installing KVM..." - sudo adduser "$USER" libvirt 2>/dev/null || true - sudo adduser "$USER" kvm 2>/dev/null || true - echo -e "${GREEN}QEMU/KVM installed. A reboot is recommended.${NC}" - else - echo "QEMU/KVM already installed." - fi - ;; - *) - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - ;; - esac - done - - echo -e "${GREEN}System tools installed.${NC}" -} - -_cat_dev() { - local headless=false - _is_headless && headless=true - local apache_state="OFF"; is_installed "apache2" && apache_state="ON" - local build_state="OFF"; is_installed "build-essential" && build_state="ON" - local certbot_state="OFF"; is_installed "certbot" && certbot_state="ON" - local docker_state="OFF"; is_installed "docker.io" && docker_state="ON" - local extrepo_state="OFF"; is_installed "extrepo" && extrepo_state="ON" - local fail2ban_state="OFF"; is_installed "fail2ban" && fail2ban_state="ON" - local mariadb_state="OFF"; is_installed "mariadb-server" && mariadb_state="ON" - local netcat_state="OFF"; is_installed "netcat-openbsd" && netcat_state="ON" - local nginx_state="OFF"; is_installed "nginx" && nginx_state="ON" - local ssh_state="OFF"; is_installed "openssh-server" && ssh_state="ON" - local openssl_state="OFF"; is_installed "openssl" && openssl_state="ON" - local pg_state="OFF"; is_installed "postgresql" && pg_state="ON" - local pip_state="OFF"; is_installed "python3-pip" && pip_state="ON" - local redis_state="OFF"; is_installed "redis-server" && redis_state="ON" - local props_state="OFF"; is_installed "software-properties-common" && props_state="ON" - local sqlite_state="OFF"; is_installed "sqlite3" && sqlite_state="ON" - local ufw_state="OFF"; is_installed "ufw" && ufw_state="ON" - local zenmap_state="OFF"; is_installed "zenmap" && zenmap_state="ON" - - local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) - choices=$(whiptail --title "Development & Servers" --checklist \ - "Select development tools and servers (18 items, ↑↓ scroll):" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "apache2" "Apache web server$(_inst apache2)" "$apache_state" \ - "build-essential" "C/C++ build tools (gcc, make)$(_inst build-essential)" "$build_state" \ - "certbot" "Let's Encrypt TLS certificates$(_inst certbot)" "$certbot_state" \ - "docker" "Docker + docker-compose$(_inst docker.io)" "$docker_state" \ - "extrepo" "External repository manager$(_inst extrepo)" "$extrepo_state" \ - "fail2ban" "Brute-force protection$(_inst fail2ban)" "$fail2ban_state" \ - "mariadb-server" "MariaDB database server$(_inst mariadb-server)" "$mariadb_state" \ - "netcat-openbsd" "TCP/IP networking utility$(_inst netcat-openbsd)" "$netcat_state" \ - "nginx" "Nginx web server$(_inst nginx)" "$nginx_state" \ - "openssh-server" "SSH server$(_inst openssh-server)" "$ssh_state" \ - "openssl" "OpenSSL cryptography toolkit$(_inst openssl)" "$openssl_state" \ - "postgresql" "PostgreSQL database server$(_inst postgresql)" "$pg_state" \ - "python3-pip" "Python 3 pip + venv + dev$(_inst python3-pip)" "$pip_state" \ - "redis-server" "Redis key-value store$(_inst redis-server)" "$redis_state" \ - "software-properties-common" "Repository management (PPA)$(_inst software-properties-common)" "$props_state" \ - "sqlite3" "SQLite database engine$(_inst sqlite3)" "$sqlite_state" \ - "ufw" "Uncomplicated firewall$(_inst ufw)" "$ufw_state" \ - "zenmap" "Network scanner GUI (Nmap frontend)$(_inst zenmap)" "$zenmap_state" \ - 3>&1 1>&2 2>&3) - clear - - [ -z "$choices" ] && return - - local cleaned; cleaned=$(echo "$choices" | tr -d '"') - - for pkg in $cleaned; do - case $pkg in - python3-pip) - local need=() - ! is_installed "python3-pip" && need+=("python3-pip") - ! is_installed "python3-venv" && need+=("python3-venv") - ! is_installed "python3-dev" && need+=("python3-dev") - if [ ${#need[@]} -gt 0 ]; then - _run_install_batch "${need[@]}" - else - echo "Python 3 tools already installed." - fi - ;; - docker) - local need=() - ! is_installed "docker.io" && need+=("docker.io") - ! is_installed "docker-compose" && need+=("docker-compose") - if [ ${#need[@]} -gt 0 ]; then - _run_install_batch "${need[@]}" - else - echo "Docker already installed." - fi - ;; - zenmap) - install_backports_or_stable zenmap - ;; - *) - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - ;; - esac - done - - echo -e "${GREEN}Development tools and servers installed.${NC}" -} - -_cat_players() { - local headless=false - _is_headless && headless=true - local handbrake_state="OFF"; is_installed "handbrake" && handbrake_state="ON" - local mpv_state="OFF"; is_installed "mpv" && mpv_state="ON" - local vlc_state="OFF"; is_installed "vlc" && vlc_state="ON" - - local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) - local choices - choices=$(whiptail --title "Media Players" --checklist \ - "Select media players:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "handbrake" "Video transcoder (DVD ripper)$(_inst handbrake)" "$handbrake_state" \ - "mpv" "Lightweight media player$(_inst mpv)" "$mpv_state" \ - "vlc" "VLC media player$(_inst vlc)" "$vlc_state" \ - 3>&1 1>&2 2>&3) - clear - - [ -z "$choices" ] && return - - local cleaned; cleaned=$(echo "$choices" | tr -d '"') - - for pkg in $cleaned; do - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - done - - echo -e "${GREEN}Media players installed.${NC}" -} - -_cat_browsers() { - local headless=false - _is_headless && headless=true - local chromium_state="OFF"; is_installed "chromium" && chromium_state="ON" - local dillo_state="OFF"; is_installed "dillo" && dillo_state="ON" - local elinks_state="OFF"; is_installed "elinks" && elinks_state="ON" - local epiphany_state="OFF"; is_installed "epiphany-browser" && epiphany_state="ON" - local falkon_state="OFF"; is_installed "falkon" && falkon_state="ON" - local firefox_state="OFF" - if command -v firefox &>/dev/null && ! command -v firefox-esr &>/dev/null; then - firefox_state="ON" - fi - local floorp_state="OFF"; is_installed "floorp" && floorp_state="ON" - local konqueror_state="OFF"; is_installed "konqueror" && konqueror_state="ON" - local librewolf_state="OFF"; is_installed "librewolf" && librewolf_state="ON" - local privacybrowser_state="OFF"; is_installed "privacybrowser" && privacybrowser_state="ON" - local qutebrowser_state="OFF"; is_installed "qutebrowser" && qutebrowser_state="ON" - local thunderbird_state="OFF"; is_installed "thunderbird" && thunderbird_state="ON" - local torbrowser_state="OFF"; is_installed "torbrowser-launcher" && torbrowser_state="ON" - local w3m_state="OFF"; is_installed "w3m" && w3m_state="ON" - - local choices - choices=$(whiptail --title "Web Browsers" --checklist \ - "Select web browsers:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "chromium" "Chromium web browser$(_inst chromium)" "$chromium_state" \ - "dillo" "Lightweight graphical browser$(_inst dillo)" "$dillo_state" \ - "elinks" "Text-mode web browser$(_inst elinks)" "$elinks_state" \ - "epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$epiphany_state" \ - "falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$falkon_state" \ - "firefox" "Firefox from Mozilla (replaces ESR)" "$firefox_state" \ - "floorp" "Firefox-based browser (external repo)" "$floorp_state" \ - "konqueror" "KDE file manager / web browser$(_inst konqueror)" "$konqueror_state" \ - "librewolf" "Privacy-focused Firefox fork$(_inst librewolf)" "$librewolf_state" \ - "privacybrowser" "Privacy-focused web browser$(_inst privacybrowser)" "$privacybrowser_state" \ - "qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$qutebrowser_state" \ - "thunderbird" "Email client$(_inst thunderbird)" "$thunderbird_state" \ - "torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$torbrowser_state" \ - "w3m" "Text-mode browser + deps (w3m-img)$(_inst w3m)" "$w3m_state" \ - 3>&1 1>&2 2>&3) - clear - - [ -z "$choices" ] && return - - local cleaned; cleaned=$(echo "$choices" | tr -d '"') - - for pkg in $cleaned; do - case $pkg in - firefox) - install_firefox_mozilla - ;; - floorp) - if ! is_installed "floorp"; then - echo "Setting up Floorp repository..." - ! is_installed "curl" && _run_install curl - ! is_installed "gpg" && _run_install gpg - sudo install -d -m 0755 /etc/apt/keyrings - curl -fsSL https://ppa.floorp.app/KEY.gpg | \ - sudo gpg --dearmor -o /usr/share/keyrings/Floorp.gpg - sudo curl -sS --compressed -o /etc/apt/sources.list.d/Floorp.list \ - 'https://ppa.floorp.app/Floorp.list' - sudo tee /etc/apt/preferences.d/floorp > /dev/null << EOF -Package: * -Pin: origin ppa.floorp.app -Pin-Priority: 1000 -EOF - _run_cmd "APT Update" "sudo apt update" "Updating package lists..." - _run_install floorp - echo -e "${GREEN}Floorp installed.${NC}" - else - echo "Floorp already installed." - fi - ;; - librewolf) - if ! is_installed "librewolf"; then - echo "Installing LibreWolf..." - _run_install extrepo - sudo extrepo enable librewolf 2>/dev/null || true - _run_cmd "APT Update" "sudo apt update" "Updating package lists..." - _run_install librewolf - echo -e "${GREEN}LibreWolf installed.${NC}" - else - echo "LibreWolf already installed." - fi - ;; - w3m) - local need=() - ! is_installed "w3m" && need+=("w3m") - ! is_installed "w3m-img" && need+=("w3m-img") - ! is_installed "ca-certificates" && need+=("ca-certificates") - ! is_installed "xsel" && need+=("xsel") - if [ ${#need[@]} -gt 0 ]; then - _run_install_batch w3m w3m-img ca-certificates xsel - else - echo "w3m already installed." - fi - ;; - *) - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - ;; - esac - done - - echo -e "${GREEN}Web browsers installed.${NC}" -} - -_cat_customization() { - local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) - local sub - sub=$(whiptail --title "Customization System" --menu \ - "Select type:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "1" "GTK Themes" \ - "2" "Icon Themes" \ - 3>&1 1>&2 2>&3) - [ -z "$sub" ] && return - case $sub in - 1) _cat_themes ;; - 2) _cat_icons ;; - esac -} - -_cat_themes() { - local headless=false - _is_headless && headless=true - local arc_state="OFF"; is_installed "arc-theme" && arc_state="ON" - local blackbird_state="OFF"; is_installed "blackbird-gtk-theme" && blackbird_state="ON" - local bluebird_state="OFF"; is_installed "bluebird-gtk-theme" && bluebird_state="ON" - local breeze_gtk_state="OFF"; is_installed "breeze-gtk-theme" && breeze_gtk_state="ON" - local greybird_state="OFF"; is_installed "greybird-gtk-theme" && greybird_state="ON" - local numix_gtk_state="OFF"; is_installed "numix-gtk-theme" && numix_gtk_state="ON" - local orchis_state="OFF"; is_installed "orchis-gtk-theme" && orchis_state="ON" - - local choices - choices=$(whiptail --title "GTK Themes" --checklist \ - "Select GTK themes to install:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "arc-theme" "Arc GTK theme$(_inst arc-theme)" "$arc_state" \ - "blackbird-gtk-theme" "Blackbird GTK theme$(_inst blackbird-gtk-theme)" "$blackbird_state" \ - "bluebird-gtk-theme" "Bluebird GTK theme$(_inst bluebird-gtk-theme)" "$bluebird_state" \ - "breeze-gtk-theme" "Breeze GTK theme$(_inst breeze-gtk-theme)" "$breeze_gtk_state" \ - "greybird-gtk-theme" "Greybird GTK theme$(_inst greybird-gtk-theme)" "$greybird_state" \ - "numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$numix_gtk_state" \ - "orchis-gtk-theme" "Orchis GTK theme$(_inst orchis-gtk-theme)" "$orchis_state" \ - 3>&1 1>&2 2>&3) - clear - - [ -z "$choices" ] && return - - local cleaned; cleaned=$(echo "$choices" | tr -d '"') - - for pkg in $cleaned; do - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - done - - echo -e "${GREEN}GTK themes installed.${NC}" -} - -_cat_icons() { - local headless=false - _is_headless && headless=true - local breeze_state="OFF"; is_installed "breeze-icon-theme" && breeze_state="ON" - local deepin_state="OFF"; is_installed "deepin-icon-theme" && deepin_state="ON" - local ele_state="OFF"; is_installed "elementary-icon-theme" && ele_state="ON" - local ele_xfce_state="OFF"; is_installed "elementary-xfce-icon-theme" && ele_xfce_state="ON" - local moka_state="OFF"; is_installed "moka-icon-theme" && moka_state="ON" - local numix_state="OFF"; is_installed "numix-icon-theme" && numix_state="ON" - local numix_c_state="OFF"; is_installed "numix-icon-theme-circle" && numix_c_state="ON" - local obsidian_state="OFF"; is_installed "obsidian-icon-theme" && obsidian_state="ON" - local papirus_state="OFF"; is_installed "papirus-icon-theme" && papirus_state="ON" - local paper_state="OFF"; is_installed "paper-icon-theme" && paper_state="ON" - local suru_state="OFF"; is_installed "suru-icon-theme" && suru_state="ON" - - local kf6_state="OFF" - local has_kf6=false - if [ "$DEBIAN_CODENAME" = "trixie" ]; then - is_installed "kf6-breeze-icon-theme" && kf6_state="ON" - has_kf6=true - fi - - local items=( - "breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$breeze_state" - "deepin-icon-theme" "Deepin icon theme$(_inst deepin-icon-theme)" "$deepin_state" - "elementary-icon-theme" "Elementary icon theme$(_inst elementary-icon-theme)" "$ele_state" - "elementary-xfce-icon-theme" "Elementary Xfce icons$(_inst elementary-xfce-icon-theme)" "$ele_xfce_state" - "moka-icon-theme" "Moka icon theme$(_inst moka-icon-theme)" "$moka_state" - "numix-icon-theme" "Numix icon theme$(_inst numix-icon-theme)" "$numix_state" - "numix-icon-theme-circle" "Numix Circle icon theme$(_inst numix-icon-theme-circle)" "$numix_c_state" - "obsidian-icon-theme" "Obsidian icon theme$(_inst obsidian-icon-theme)" "$obsidian_state" - "papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$papirus_state" - "paper-icon-theme" "Paper icon theme$(_inst paper-icon-theme)" "$paper_state" - "suru-icon-theme" "Suru icon theme$(_inst suru-icon-theme)" "$suru_state" - ) - if $has_kf6; then - items+=("kf6-breeze-icon-theme" "KF6 Breeze icon theme$(_inst kf6-breeze-icon-theme)" "$kf6_state") - fi - - local choices - choices=$(whiptail --title "Icon Themes" --checklist \ - "Select icon themes to install:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "${items[@]}" \ - 3>&1 1>&2 2>&3) - clear - - [ -z "$choices" ] && return - - local cleaned; cleaned=$(echo "$choices" | tr -d '"') - - for pkg in $cleaned; do - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - done - - echo -e "${GREEN}Icon themes installed.${NC}" -} - -_cat_fetch() { - local fetch_pkg - if [ "$DEBIAN_CODENAME" = "bookworm" ]; then - fetch_pkg="neofetch" - else - fetch_pkg="fastfetch" - fi - - local fetch_state="OFF"; is_installed "$fetch_pkg" && fetch_state="ON" - local linuxlogo_state="OFF"; is_installed "linuxlogo" && linuxlogo_state="ON" - local screenfetch_state="OFF"; is_installed "screenfetch" && screenfetch_state="ON" - - local hyfetch_state="OFF" - if [ "$DEBIAN_CODENAME" = "trixie" ]; then - is_installed "hyfetch" && hyfetch_state="ON" - fi - - local items=() - - if [ "$fetch_pkg" = "fastfetch" ]; then - items+=("fastfetch" "System info fetcher$(_inst fastfetch)" "$fetch_state") - if [ "$DEBIAN_CODENAME" = "trixie" ]; then - items+=("hyfetch" "Neofetch with pride flags$(_inst hyfetch)" "$hyfetch_state") - fi - fi - items+=("linuxlogo" "Linux logo + system info$(_inst linuxlogo)" "$linuxlogo_state") - if [ "$fetch_pkg" = "neofetch" ]; then - items+=("neofetch" "System info fetcher$(_inst neofetch)" "$fetch_state") - if [ "$DEBIAN_CODENAME" = "trixie" ]; then - items+=("hyfetch" "Neofetch with pride flags$(_inst hyfetch)" "$hyfetch_state") - fi - fi - items+=("screenfetch" "System info (BSD/Linux)$(_inst screenfetch)" "$screenfetch_state") - - local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) - local choices - choices=$(whiptail --title "Fetch Tools" --checklist \ - "Select system info tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "${items[@]}" \ - 3>&1 1>&2 2>&3) - clear - - [ -z "$choices" ] && return - - local cleaned; cleaned=$(echo "$choices" | tr -d '"') - - for pkg in $cleaned; do - case $pkg in - neofetch|fastfetch) - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - ;; - *) - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - ;; - esac - done - - echo -e "${GREEN}Fetch tools installed.${NC}" -} - -_cat_download() { - local headless=false - _is_headless && headless=true - local aria2_state="OFF"; is_installed "aria2" && aria2_state="ON" - local filezilla_state="OFF"; is_installed "filezilla" && filezilla_state="ON" - local riseupvpn_state="OFF"; is_installed "riseup-vpn" && riseupvpn_state="ON" - local ytdlp_state="OFF"; is_installed "yt-dlp" && ytdlp_state="ON" - local ytdlp_gui_state="OFF"; is_installed "youtubedl-gui" && ytdlp_gui_state="ON" - - local deluge_state="OFF"; is_installed "deluge" && deluge_state="ON" - local deluged_state="OFF"; is_installed "deluged" && deluged_state="ON" - local mktorrent_state="OFF"; is_installed "mktorrent" && mktorrent_state="ON" - local qbit_state="OFF"; is_installed "qbittorrent" && qbit_state="ON" - local qbitnox_state="OFF"; is_installed "qbittorrent-nox" && qbitnox_state="ON" - local tr_cli_state="OFF"; is_installed "transmission-cli" && tr_cli_state="ON" - local tr_gtk_state="OFF"; is_installed "transmission-gtk" && tr_gtk_state="ON" - local tr_qt_state="OFF"; is_installed "transmission-qt" && tr_qt_state="ON" - - local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) - local choices1 choices2="" - - choices1=$(whiptail --title "Download & Network — Downloaders" --checklist \ - "Select download tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$aria2_state" \ - "filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$filezilla_state" \ - "riseup-vpn" "Riseup VPN client$(_inst riseup-vpn)" "$riseupvpn_state" \ - "yt-dlp" "Video downloader CLI$(_inst yt-dlp)" "$ytdlp_state" \ - "youtubedl-gui" "GUI for yt-dlp$(_inst youtubedl-gui)" "$ytdlp_gui_state" \ - 3>&1 1>&2 2>&3) - clear - - choices2=$(whiptail --title "Download & Network — Torrent Clients" --checklist \ - "Select torrent clients:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "deluge" "BitTorrent client (GTK)$(_inst deluge)" "$deluge_state" \ - "deluged" "BitTorrent daemon/server$(_inst deluged)" "$deluged_state" \ - "mktorrent" "Torrent metainfo creator (CLI)$(_inst mktorrent)" "$mktorrent_state" \ - "qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$qbit_state" \ - "qbittorrent-nox" "BitTorrent WebUI/CLI$(_inst qbittorrent-nox)" "$qbitnox_state" \ - "transmission-cli" "BitTorrent client (CLI)$(_inst transmission-cli)" "$tr_cli_state" \ - "transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$tr_gtk_state" \ - "transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$tr_qt_state" \ - 3>&1 1>&2 2>&3) - clear - - local cleaned - cleaned=$(echo "$choices1 $choices2" | tr -d '"') - - [ -z "$cleaned" ] && { echo "No download tools selected."; return; } - - for pkg in $cleaned; do - case $pkg in - riseup-vpn) - install_backports_or_stable riseup-vpn - ;; - yt-dlp) - install_backports_or_stable yt-dlp - ;; - qbittorrent) - install_backports_or_stable qbittorrent - ;; - qbittorrent-nox) - install_backports_or_stable qbittorrent-nox - ;; - *) - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - ;; - esac - done - - echo -e "${GREEN}Download & network tools installed.${NC}" -} - -_cat_design() { - local headless=false - _is_headless && headless=true - local audacity_state="OFF"; is_installed "audacity" && audacity_state="ON" - local ardour_state="OFF"; is_installed "ardour" && ardour_state="ON" - local blender_state="OFF"; is_installed "blender" && blender_state="ON" - local ffmpeg_state="OFF"; is_installed "ffmpeg" && ffmpeg_state="ON" - local gimp_state="OFF"; is_installed "gimp" && gimp_state="ON" - local inkscape_state="OFF"; is_installed "inkscape" && inkscape_state="ON" - local kdenlive_state="OFF"; is_installed "kdenlive" && kdenlive_state="ON" - local krita_state="OFF"; is_installed "krita" && krita_state="ON" - local obs_state="OFF"; is_installed "obs-studio" && obs_state="ON" - local openshot_state="OFF"; is_installed "openshot-qt" && openshot_state="ON" - local scribus_state="OFF"; is_installed "scribus" && scribus_state="ON" - local shotcut_state="OFF"; is_installed "shotcut" && shotcut_state="ON" - - local choices - choices=$(whiptail --title "Multimedia & Design" --checklist \ - "Select multimedia and design tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "audacity" "Audio editor/recorder$(_inst audacity)" "$audacity_state" \ - "ardour" "Digital audio workstation$(_inst ardour)" "$ardour_state" \ - "blender" "3D modeling/animation suite$(_inst blender)" "$blender_state" \ - "ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$ffmpeg_state" \ - "gimp" "Image editor (Photoshop alternative)$(_inst gimp)" "$gimp_state" \ - "inkscape" "Vector graphics editor$(_inst inkscape)" "$inkscape_state" \ - "kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$kdenlive_state" \ - "krita" "Digital painting/illustration$(_inst krita)" "$krita_state" \ - "obs-studio" "Screen recording/streaming$(_inst obs-studio)" "$obs_state" \ - "openshot-qt" "Video editor (simple)$(_inst openshot-qt)" "$openshot_state" \ - "scribus" "Desktop publishing (DTP)$(_inst scribus)" "$scribus_state" \ - "shotcut" "Video editor (cross-platform)$(_inst shotcut)" "$shotcut_state" \ - 3>&1 1>&2 2>&3) - clear - - [ -z "$choices" ] && return - - local cleaned; cleaned=$(echo "$choices" | tr -d '"') - - for pkg in $cleaned; do - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi - if ! is_installed "$pkg"; then - _run_install "$pkg" - else - echo "$pkg already installed." - fi - done - - echo -e "${GREEN}Multimedia & design tools installed.${NC}" -} - -install_firefox_mozilla() { - if command -v firefox &>/dev/null && ! command -v firefox-esr &>/dev/null; then - echo "Firefox (Mozilla) is already installed." - return - fi - - echo "Setting up Mozilla APT repository for Firefox..." - - if is_installed "firefox-esr"; then - if _confirm "Firefox ESR" "Firefox ESR is installed.\nRemove it before installing Mozilla Firefox?"; then - echo "Removing Firefox ESR..." - sudo apt remove -y firefox-esr - else - echo "Keeping Firefox ESR." - fi - fi - - ! is_installed "wget" && _run_install wget - ! is_installed "gpg" && _run_install gpg - - sudo install -d -m 0755 /etc/apt/keyrings - - wget -q https://packages.mozilla.org/apt/repo-signing-key.gpg -O- | \ - sudo tee /etc/apt/keyrings/packages.mozilla.org.asc > /dev/null - - local fp - fp=$(gpg -n -q --import --import-options import-show \ - /etc/apt/keyrings/packages.mozilla.org.asc 2>/dev/null | \ - awk '/pub/{getline; gsub(/^ +| +$/,""); print}') - if [ "$fp" != "35BAA0B33E9EB396F59CA838C0BA5CE6DC6315A3" ]; then - echo -e "${YELLOW}Warning: Mozilla key fingerprint does not match expected value.${NC}" - fi - - local use_deb822=false - [ -f /etc/apt/sources.list.d/debian.sources ] && use_deb822=true - - if $use_deb822; then - sudo tee /etc/apt/sources.list.d/mozilla.sources > /dev/null << EOF -Types: deb -URIs: https://packages.mozilla.org/apt -Suites: mozilla -Components: main -Signed-By: /etc/apt/keyrings/packages.mozilla.org.asc -EOF - else - echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" | \ - sudo tee /etc/apt/sources.list.d/mozilla.list > /dev/null - fi - - sudo tee /etc/apt/preferences.d/mozilla > /dev/null << EOF -Package: * -Pin: origin packages.mozilla.org -Pin-Priority: 1000 -EOF - - _run_cmd "APT Update" "sudo apt update" "Updating package lists..." - _run_install firefox - - echo -e "${GREEN}Firefox (Mozilla) installed.${NC}" -} diff --git a/modules/extras/_helpers.sh b/modules/extras/_helpers.sh new file mode 100644 index 0000000..3187e4f --- /dev/null +++ b/modules/extras/_helpers.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# Shared helpers for extras categories + +_inst() { + if is_installed "$1"; then echo " (installed)"; else echo ""; fi +} + +_state() { + is_installed "$1" && echo "ON" || echo "OFF" +} diff --git a/modules/extras/design/design.sh b/modules/extras/design/design.sh new file mode 100644 index 0000000..29f4d5d --- /dev/null +++ b/modules/extras/design/design.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# design.sh — Multimedia & Design (handbrake moved here from Media Players) + +_cat_design() { + local headless=false + _is_headless && headless=true + local audacity_state; audacity_state=$(_state "audacity") + local ardour_state; ardour_state=$(_state "ardour") + local blender_state; blender_state=$(_state "blender") + local ffmpeg_state; ffmpeg_state=$(_state "ffmpeg") + local gimp_state; gimp_state=$(_state "gimp") + local handbrake_state; handbrake_state=$(_state "handbrake") + local inkscape_state; inkscape_state=$(_state "inkscape") + local kdenlive_state; kdenlive_state=$(_state "kdenlive") + local krita_state; krita_state=$(_state "krita") + local obs_state; obs_state=$(_state "obs-studio") + local openshot_state; openshot_state=$(_state "openshot-qt") + local scribus_state; scribus_state=$(_state "scribus") + local shotcut_state; shotcut_state=$(_state "shotcut") + + local choices + choices=$(whiptail --title "Multimedia & Design" --checklist \ + "Select multimedia and design tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ + "audacity" "Audio editor/recorder$(_inst audacity)" "$audacity_state" \ + "ardour" "Digital audio workstation$(_inst ardour)" "$ardour_state" \ + "blender" "3D modeling/animation suite$(_inst blender)" "$blender_state" \ + "ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$ffmpeg_state" \ + "gimp" "Image editor (Photoshop alternative)$(_inst gimp)" "$gimp_state" \ + "handbrake" "Video transcoder (DVD ripper)$(_inst handbrake)" "$handbrake_state" \ + "inkscape" "Vector graphics editor$(_inst inkscape)" "$inkscape_state" \ + "kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$kdenlive_state" \ + "krita" "Digital painting/illustration$(_inst krita)" "$krita_state" \ + "obs-studio" "Screen recording/streaming$(_inst obs-studio)" "$obs_state" \ + "openshot-qt" "Video editor (simple)$(_inst openshot-qt)" "$openshot_state" \ + "scribus" "Desktop publishing (DTP)$(_inst scribus)" "$scribus_state" \ + "shotcut" "Video editor (cross-platform)$(_inst shotcut)" "$shotcut_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + if $headless; then + echo "Skipping $pkg (headless mode)" + continue + fi + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + done + + echo -e "${GREEN}Multimedia & design tools installed.${NC}" +} diff --git a/modules/extras/dev/dev.sh b/modules/extras/dev/dev.sh new file mode 100644 index 0000000..466cc81 --- /dev/null +++ b/modules/extras/dev/dev.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +# dev.sh — Development & Servers (extrepo, zenmap, fail2ban, ufw moved out) + +_cat_dev() { + local headless=false + _is_headless && headless=true + local apache_state; apache_state=$(_state "apache2") + local build_state; build_state=$(_state "build-essential") + local certbot_state; certbot_state=$(_state "certbot") + local docker_state; docker_state=$(_state "docker.io") + local mariadb_state; mariadb_state=$(_state "mariadb-server") + local netcat_state; netcat_state=$(_state "netcat-openbsd") + local nginx_state; nginx_state=$(_state "nginx") + local ssh_state; ssh_state=$(_state "openssh-server") + local openssl_state; openssl_state=$(_state "openssl") + local pg_state; pg_state=$(_state "postgresql") + local pip_state; pip_state=$(_state "python3-pip") + local redis_state; redis_state=$(_state "redis-server") + local sqlite_state; sqlite_state=$(_state "sqlite3") + + local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) + local choices + choices=$(whiptail --title "Development & Servers" --checklist \ + "Select development tools and servers (12 items, ↑↓ scroll):" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ + "apache2" "Apache web server$(_inst apache2)" "$apache_state" \ + "build-essential" "C/C++ build tools (gcc, make)$(_inst build-essential)" "$build_state" \ + "certbot" "Let's Encrypt TLS certificates$(_inst certbot)" "$certbot_state" \ + "docker" "Docker + docker-compose$(_inst docker.io)" "$docker_state" \ + "mariadb-server" "MariaDB database server$(_inst mariadb-server)" "$mariadb_state" \ + "netcat-openbsd" "TCP/IP networking utility$(_inst netcat-openbsd)" "$netcat_state" \ + "nginx" "Nginx web server$(_inst nginx)" "$nginx_state" \ + "openssh-server" "SSH server$(_inst openssh-server)" "$ssh_state" \ + "openssl" "OpenSSL cryptography toolkit$(_inst openssl)" "$openssl_state" \ + "postgresql" "PostgreSQL database server$(_inst postgresql)" "$pg_state" \ + "python3-pip" "Python 3 pip + venv + dev$(_inst python3-pip)" "$pip_state" \ + "redis-server" "Redis key-value store$(_inst redis-server)" "$redis_state" \ + "sqlite3" "SQLite database engine$(_inst sqlite3)" "$sqlite_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + case $pkg in + python3-pip) + local need=() + ! is_installed "python3-pip" && need+=("python3-pip") + ! is_installed "python3-venv" && need+=("python3-venv") + ! is_installed "python3-dev" && need+=("python3-dev") + if [ ${#need[@]} -gt 0 ]; then + _run_install_batch "${need[@]}" + else + echo "Python 3 tools already installed." + fi + ;; + docker) + local need=() + ! is_installed "docker.io" && need+=("docker.io") + ! is_installed "docker-compose" && need+=("docker-compose") + if [ ${#need[@]} -gt 0 ]; then + _run_install_batch "${need[@]}" + else + echo "Docker already installed." + fi + ;; + *) + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + ;; + esac + done + + echo -e "${GREEN}Development tools and servers installed.${NC}" +} diff --git a/modules/extras/download/download.sh b/modules/extras/download/download.sh new file mode 100644 index 0000000..e7cb695 --- /dev/null +++ b/modules/extras/download/download.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# download.sh — Downloaders and Torrent clients (riseup-vpn moved to Internet) + +_cat_download() { + local headless=false + _is_headless && headless=true + local aria2_state; aria2_state=$(_state "aria2") + local filezilla_state; filezilla_state=$(_state "filezilla") + local ytdlp_state; ytdlp_state=$(_state "yt-dlp") + local ytdlp_gui_state; ytdlp_gui_state=$(_state "youtubedl-gui") + + local deluge_state; deluge_state=$(_state "deluge") + local deluged_state; deluged_state=$(_state "deluged") + local mktorrent_state; mktorrent_state=$(_state "mktorrent") + local qbit_state; qbit_state=$(_state "qbittorrent") + local qbitnox_state; qbitnox_state=$(_state "qbittorrent-nox") + local tr_cli_state; tr_cli_state=$(_state "transmission-cli") + local tr_gtk_state; tr_gtk_state=$(_state "transmission-gtk") + local tr_qt_state; tr_qt_state=$(_state "transmission-qt") + + local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) + local choices1 choices2="" + + choices1=$(whiptail --title "Downloaders" --checklist \ + "Select download tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ + "aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$aria2_state" \ + "filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$filezilla_state" \ + "yt-dlp" "Video downloader CLI$(_inst yt-dlp)" "$ytdlp_state" \ + "youtubedl-gui" "GUI for yt-dlp$(_inst youtubedl-gui)" "$ytdlp_gui_state" \ + 3>&1 1>&2 2>&3) + clear + + choices2=$(whiptail --title "Torrent Clients" --checklist \ + "Select torrent clients:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ + "deluge" "BitTorrent client (GTK)$(_inst deluge)" "$deluge_state" \ + "deluged" "BitTorrent daemon/server$(_inst deluged)" "$deluged_state" \ + "mktorrent" "Torrent metainfo creator (CLI)$(_inst mktorrent)" "$mktorrent_state" \ + "qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$qbit_state" \ + "qbittorrent-nox" "BitTorrent WebUI/CLI$(_inst qbittorrent-nox)" "$qbitnox_state" \ + "transmission-cli" "BitTorrent client (CLI)$(_inst transmission-cli)" "$tr_cli_state" \ + "transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$tr_gtk_state" \ + "transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$tr_qt_state" \ + 3>&1 1>&2 2>&3) + clear + + local cleaned + cleaned=$(echo "$choices1 $choices2" | tr -d '"') + + [ -z "$cleaned" ] && { echo "No download tools selected."; return; } + + for pkg in $cleaned; do + case $pkg in + yt-dlp) + install_backports_or_stable yt-dlp + ;; + qbittorrent) + install_backports_or_stable qbittorrent + ;; + qbittorrent-nox) + install_backports_or_stable qbittorrent-nox + ;; + *) + if $headless; then + echo "Skipping $pkg (headless mode)" + continue + fi + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + ;; + esac + done + + echo -e "${GREEN}Download & network tools installed.${NC}" +} diff --git a/modules/extras/essential/essential.sh b/modules/extras/essential/essential.sh new file mode 100644 index 0000000..4115762 --- /dev/null +++ b/modules/extras/essential/essential.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# essential.sh — one-click essentials pack + +_quick_install() { + local fetch_pkg + if [ "$DEBIAN_CODENAME" = "bookworm" ]; then + fetch_pkg="neofetch" + else + fetch_pkg="fastfetch" + fi + + _msg "Essential Pack" \ + "Install basic programs:\n\n - Compression (zip, unrar, 7z)\n - System tools (htop, inxi, ${fetch_pkg})\n - VLC media player\n - Microsoft fonts" 13 60 + + local quick_pkgs=( + zip unzip rar unrar p7zip-full p7zip-rar + "$fetch_pkg" htop vlc inxi ttf-mscorefonts-installer + ) + _run_install_batch "${quick_pkgs[@]}" + echo -e "${GREEN}Essential Pack installed.${NC}" +} diff --git a/modules/extras/fetch/fetch.sh b/modules/extras/fetch/fetch.sh new file mode 100644 index 0000000..a0e5e86 --- /dev/null +++ b/modules/extras/fetch/fetch.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +# fetch.sh — System info / fetch tools + +_cat_fetch() { + local fetch_pkg + if [ "$DEBIAN_CODENAME" = "bookworm" ]; then + fetch_pkg="neofetch" + else + fetch_pkg="fastfetch" + fi + + local fetch_state; fetch_state=$(_state "$fetch_pkg") + local linuxlogo_state; linuxlogo_state=$(_state "linuxlogo") + local screenfetch_state; screenfetch_state=$(_state "screenfetch") + + local hyfetch_state="OFF" + if [ "$DEBIAN_CODENAME" = "trixie" ]; then + hyfetch_state=$(_state "hyfetch") + fi + + local items=() + + if [ "$fetch_pkg" = "fastfetch" ]; then + items+=("fastfetch" "System info fetcher$(_inst fastfetch)" "$fetch_state") + if [ "$DEBIAN_CODENAME" = "trixie" ]; then + items+=("hyfetch" "Neofetch with pride flags$(_inst hyfetch)" "$hyfetch_state") + fi + fi + items+=("linuxlogo" "Linux logo + system info$(_inst linuxlogo)" "$linuxlogo_state") + if [ "$fetch_pkg" = "neofetch" ]; then + items+=("neofetch" "System info fetcher$(_inst neofetch)" "$fetch_state") + if [ "$DEBIAN_CODENAME" = "trixie" ]; then + items+=("hyfetch" "Neofetch with pride flags$(_inst hyfetch)" "$hyfetch_state") + fi + fi + items+=("screenfetch" "System info (BSD/Linux)$(_inst screenfetch)" "$screenfetch_state") + + local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) + local choices + choices=$(whiptail --title "Fetch Tools" --checklist \ + "Select system info tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ + "${items[@]}" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + case $pkg in + neofetch|fastfetch) + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + ;; + *) + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + ;; + esac + done + + echo -e "${GREEN}Fetch tools installed.${NC}" +} diff --git a/modules/extras/internet/internet.sh b/modules/extras/internet/internet.sh new file mode 100644 index 0000000..aff0f04 --- /dev/null +++ b/modules/extras/internet/internet.sh @@ -0,0 +1,181 @@ +#!/usr/bin/env bash +# internet.sh — Browsers, email, VPN (was _cat_browsers, now includes riseup-vpn) + +_cat_internet() { + local headless=false + _is_headless && headless=true + local chromium_state; chromium_state=$(_state "chromium") + local dillo_state; dillo_state=$(_state "dillo") + local elinks_state; elinks_state=$(_state "elinks") + local epiphany_state; epiphany_state=$(_state "epiphany-browser") + local falkon_state; falkon_state=$(_state "falkon") + local firefox_state="OFF" + if command -v firefox &>/dev/null && ! command -v firefox-esr &>/dev/null; then + firefox_state="ON" + fi + local floorp_state; floorp_state=$(_state "floorp") + local konqueror_state; konqueror_state=$(_state "konqueror") + local librewolf_state; librewolf_state=$(_state "librewolf") + local privacybrowser_state; privacybrowser_state=$(_state "privacybrowser") + local qutebrowser_state; qutebrowser_state=$(_state "qutebrowser") + local riseupvpn_state; riseupvpn_state=$(_state "riseup-vpn") + local thunderbird_state; thunderbird_state=$(_state "thunderbird") + local torbrowser_state; torbrowser_state=$(_state "torbrowser-launcher") + local w3m_state; w3m_state=$(_state "w3m") + + local choices + choices=$(whiptail --title "Internet" --checklist \ + "Select browsers, email, and VPN tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ + "chromium" "Chromium web browser$(_inst chromium)" "$chromium_state" \ + "dillo" "Lightweight graphical browser$(_inst dillo)" "$dillo_state" \ + "elinks" "Text-mode web browser$(_inst elinks)" "$elinks_state" \ + "epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$epiphany_state" \ + "falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$falkon_state" \ + "firefox" "Firefox from Mozilla (replaces ESR)" "$firefox_state" \ + "floorp" "Firefox-based browser (external repo)" "$floorp_state" \ + "konqueror" "KDE file manager / web browser$(_inst konqueror)" "$konqueror_state" \ + "librewolf" "Privacy-focused Firefox fork$(_inst librewolf)" "$librewolf_state" \ + "privacybrowser" "Privacy-focused web browser$(_inst privacybrowser)" "$privacybrowser_state" \ + "qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$qutebrowser_state" \ + "riseup-vpn" "Riseup VPN client$(_inst riseup-vpn)" "$riseupvpn_state" \ + "thunderbird" "Email client$(_inst thunderbird)" "$thunderbird_state" \ + "torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$torbrowser_state" \ + "w3m" "Text-mode browser + deps (w3m-img)$(_inst w3m)" "$w3m_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + case $pkg in + firefox) + install_firefox_mozilla + ;; + floorp) + if ! is_installed "floorp"; then + echo "Setting up Floorp repository..." + ! is_installed "curl" && _run_install curl + ! is_installed "gpg" && _run_install gpg + sudo install -d -m 0755 /etc/apt/keyrings + curl -fsSL https://ppa.floorp.app/KEY.gpg | \ + sudo gpg --dearmor -o /usr/share/keyrings/Floorp.gpg + sudo curl -sS --compressed -o /etc/apt/sources.list.d/Floorp.list \ + 'https://ppa.floorp.app/Floorp.list' + sudo tee /etc/apt/preferences.d/floorp > /dev/null << EOF +Package: * +Pin: origin ppa.floorp.app +Pin-Priority: 1000 +EOF + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." + _run_install floorp + echo -e "${GREEN}Floorp installed.${NC}" + else + echo "Floorp already installed." + fi + ;; + librewolf) + if ! is_installed "librewolf"; then + echo "Installing LibreWolf..." + install_backports_or_stable extrepo + sudo extrepo enable librewolf 2>/dev/null || true + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." + _run_install librewolf + echo -e "${GREEN}LibreWolf installed.${NC}" + else + echo "LibreWolf already installed." + fi + ;; + riseup-vpn) + install_backports_or_stable riseup-vpn + ;; + w3m) + local need=() + ! is_installed "w3m" && need+=("w3m") + ! is_installed "w3m-img" && need+=("w3m-img") + ! is_installed "ca-certificates" && need+=("ca-certificates") + ! is_installed "xsel" && need+=("xsel") + if [ ${#need[@]} -gt 0 ]; then + _run_install_batch w3m w3m-img ca-certificates xsel + else + echo "w3m already installed." + fi + ;; + *) + if $headless; then + echo "Skipping $pkg (headless mode)" + continue + fi + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + ;; + esac + done + + echo -e "${GREEN}Internet tools installed.${NC}" +} + +install_firefox_mozilla() { + if command -v firefox &>/dev/null && ! command -v firefox-esr &>/dev/null; then + echo "Firefox (Mozilla) is already installed." + return + fi + + echo "Setting up Mozilla APT repository for Firefox..." + + if is_installed "firefox-esr"; then + if _confirm "Firefox ESR" "Firefox ESR is installed.\nRemove it before installing Mozilla Firefox?"; then + echo "Removing Firefox ESR..." + sudo apt remove -y firefox-esr + else + echo "Keeping Firefox ESR." + fi + fi + + ! is_installed "wget" && _run_install wget + ! is_installed "gpg" && _run_install gpg + + sudo install -d -m 0755 /etc/apt/keyrings + + wget -q https://packages.mozilla.org/apt/repo-signing-key.gpg -O- | \ + sudo tee /etc/apt/keyrings/packages.mozilla.org.asc > /dev/null + + local fp + fp=$(gpg -n -q --import --import-options import-show \ + /etc/apt/keyrings/packages.mozilla.org.asc 2>/dev/null | \ + awk '/pub/{getline; gsub(/^ +| +$/,""); print}') + if [ "$fp" != "35BAA0B33E9EB396F59CA838C0BA5CE6DC6315A3" ]; then + echo -e "${YELLOW}Warning: Mozilla key fingerprint does not match expected value.${NC}" + fi + + local use_deb822=false + [ -f /etc/apt/sources.list.d/debian.sources ] && use_deb822=true + + if $use_deb822; then + sudo tee /etc/apt/sources.list.d/mozilla.sources > /dev/null << EOF +Types: deb +URIs: https://packages.mozilla.org/apt +Suites: mozilla +Components: main +Signed-By: /etc/apt/keyrings/packages.mozilla.org.asc +EOF + else + echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" | \ + sudo tee /etc/apt/sources.list.d/mozilla.list > /dev/null + fi + + sudo tee /etc/apt/preferences.d/mozilla > /dev/null << EOF +Package: * +Pin: origin packages.mozilla.org +Pin-Priority: 1000 +EOF + + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." + _run_install firefox + + echo -e "${GREEN}Firefox (Mozilla) installed.${NC}" +} diff --git a/modules/extras/players/players.sh b/modules/extras/players/players.sh new file mode 100644 index 0000000..e091f94 --- /dev/null +++ b/modules/extras/players/players.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# players.sh — Media Players (handbrake moved to Multimedia & Design) + +_cat_players() { + local headless=false + _is_headless && headless=true + local mpv_state; mpv_state=$(_state "mpv") + local vlc_state; vlc_state=$(_state "vlc") + + local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) + local choices + choices=$(whiptail --title "Media Players" --checklist \ + "Select media players:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ + "mpv" "Lightweight media player$(_inst mpv)" "$mpv_state" \ + "vlc" "VLC media player$(_inst vlc)" "$vlc_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + if $headless; then + echo "Skipping $pkg (headless mode)" + continue + fi + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + done + + echo -e "${GREEN}Media players installed.${NC}" +} diff --git a/modules/extras/programming/programming.sh b/modules/extras/programming/programming.sh new file mode 100644 index 0000000..bff378c --- /dev/null +++ b/modules/extras/programming/programming.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# programming.sh — Programming Applications (text editors + IDEs) + +_cat_programming() { + local headless=false + _is_headless && headless=true + local vim_state; vim_state=$(_state "vim") + local vimgtk_state; vimgtk_state=$(_state "vim-gtk3") + local neovim_state; neovim_state=$(_state "neovim") + local hx_state; hx_state=$(_state "hx") + local nano_state; nano_state=$(_state "nano") + local emacs_state; emacs_state=$(_state "emacs") + local kate_state; kate_state=$(_state "kate") + local mousepad_state; mousepad_state=$(_state "mousepad") + local gedit_state; gedit_state=$(_state "gedit") + local geany_state; geany_state=$(_state "geany") + local gte_state; gte_state=$(_state "gnome-text-editor") + local codium_state="OFF" + if command -v codium &>/dev/null; then + codium_state="ON" + fi + + local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) + local choices + choices=$(whiptail --title "Programming Applications" --checklist \ + "Select editors and IDEs (12 items, ↑↓ scroll):" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ + "vim" "Classic terminal editor$(_inst vim)" "$vim_state" \ + "vim-gtk3" "Vim with GTK3 GUI$(_inst vim-gtk3)" "$vimgtk_state" \ + "neovim" "Modern vim fork$(_inst neovim)" "$neovim_state" \ + "hx" "Helix modal editor (Rust)$(_inst hx)" "$hx_state" \ + "nano" "Simple terminal editor$(_inst nano)" "$nano_state" \ + "emacs" "Extensible editor / IDE$(_inst emacs)" "$emacs_state" \ + "kate" "KDE advanced text editor$(_inst kate)" "$kate_state" \ + "mousepad" "Xfce text editor$(_inst mousepad)" "$mousepad_state" \ + "gedit" "GNOME text editor$(_inst gedit)" "$gedit_state" \ + "geany" "Lightweight IDE$(_inst geany)" "$geany_state" \ + "gnome-text-editor" "GNOME modern text editor$(_inst gnome-text-editor)" "$gte_state" \ + "vscodium" "VS Code open-source (external repo)$(_inst codium)" "$codium_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + case $pkg in + vscodium) + install_vscodium + ;; + *) + if $headless; then + echo "Skipping $pkg (headless mode)" + continue + fi + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + ;; + esac + done + + echo -e "${GREEN}Programming applications installed.${NC}" +} + +install_vscodium() { + if command -v codium &>/dev/null; then + echo "VSCodium is already installed." + return + fi + + echo "Setting up VSCodium repository..." + + ! is_installed "wget" && _run_install wget + ! is_installed "gpg" && _run_install gpg + + sudo install -d -m 0755 /usr/share/keyrings + + wget -qO - https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg \ + | gpg --dearmor \ + | sudo dd of=/usr/share/keyrings/vscodium-archive-keyring.gpg 2>/dev/null + + local use_deb822=false + [ -f /etc/apt/sources.list.d/debian.sources ] && use_deb822=true + + if $use_deb822; then + sudo tee /etc/apt/sources.list.d/vscodium.sources > /dev/null << 'EOF' +Types: deb +URIs: https://download.vscodium.com/debs +Suites: vscodium +Components: main +Architectures: amd64 arm64 +Signed-by: /usr/share/keyrings/vscodium-archive-keyring.gpg +EOF + else + echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/vscodium-archive-keyring.gpg] https://download.vscodium.com/debs vscodium main" \ + | sudo tee /etc/apt/sources.list.d/vscodium.list > /dev/null + fi + + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." + _run_install codium + + echo -e "${GREEN}VSCodium installed.${NC}" +} diff --git a/modules/extras/security/security.sh b/modules/extras/security/security.sh new file mode 100644 index 0000000..4e3a3aa --- /dev/null +++ b/modules/extras/security/security.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# security.sh — Security & Networking + +_cat_security() { + local headless=false + _is_headless && headless=true + local wireshark_state; wireshark_state=$(_state "wireshark") + local tcpdump_state; tcpdump_state=$(_state "tcpdump") + local zenmap_state; zenmap_state=$(_state "zenmap") + local fail2ban_state; fail2ban_state=$(_state "fail2ban") + local ufw_state; ufw_state=$(_state "ufw") + + local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) + local choices + choices=$(whiptail --title "Security & Networking" --checklist \ + "Select security and networking tools (5 items):" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ + "wireshark" "Network protocol analyzer (GUI)$(_inst wireshark)" "$wireshark_state" \ + "tcpdump" "Command-line packet analyzer$(_inst tcpdump)" "$tcpdump_state" \ + "zenmap" "Network scanner GUI (Nmap frontend)$(_inst zenmap)" "$zenmap_state" \ + "fail2ban" "Brute-force protection daemon$(_inst fail2ban)" "$fail2ban_state" \ + "ufw" "Uncomplicated firewall$(_inst ufw)" "$ufw_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + case $pkg in + zenmap) + install_backports_or_stable zenmap + ;; + *) + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + ;; + esac + done + + echo -e "${GREEN}Security & networking tools installed.${NC}" +} diff --git a/modules/extras/system/system.sh b/modules/extras/system/system.sh new file mode 100644 index 0000000..f7461cf --- /dev/null +++ b/modules/extras/system/system.sh @@ -0,0 +1,193 @@ +#!/usr/bin/env bash +# system.sh — System Tools (extrepo moved here from Dev & Servers) + +_cat_general() { + local headless=false + _is_headless && headless=true + local alacritty_state; alacritty_state=$(_state "alacritty") + local btop_state; btop_state=$(_state "btop") + local compress_state + if is_installed "zip" && is_installed "unzip" && is_installed "p7zip-full"; then + compress_state="ON" + else + compress_state="OFF" + fi + local conky_state; conky_state=$(_state "conky") + local corectrl_state; corectrl_state=$(_state "corectrl") + local cpufetch_state; cpufetch_state=$(_state "cpufetch") + local cpu_x_state; cpu_x_state=$(_state "cpu-x") + local curl_wget_state + if is_installed "curl" && is_installed "wget"; then + curl_wget_state="ON" + else + curl_wget_state="OFF" + fi + local dcgtk_state; dcgtk_state=$(_state "doublecmd-gtk") + local dcqt_state; dcqt_state=$(_state "doublecmd-qt") + local extrepo_state; extrepo_state=$(_state "extrepo") + local flatpak_state; flatpak_state=$(_state "flatpak") + local fwupd_state; fwupd_state=$(_state "fwupd") + local disks_state; disks_state=$(_state "gnome-disk-utility") + local gparted_state; gparted_state=$(_state "gparted") + local hardinfo_state; hardinfo_state=$(_state "hardinfo") + local htop_state; htop_state=$(_state "htop") + local inxi_state; inxi_state=$(_state "inxi") + local kitty_state; kitty_state=$(_state "kitty") + local kvm_state; kvm_state=$(_state "virt-manager") + local lshw_state; lshw_state=$(_state "lshw") + local mc_state; mc_state=$(_state "mc") + local nala_state; nala_state=$(_state "nala") + local ncdu_state; ncdu_state=$(_state "ncdu") + local psensor_state; psensor_state=$(_state "psensor") + local timeshift_state; timeshift_state=$(_state "timeshift") + local tmux_state; tmux_state=$(_state "tmux") + local wine_state; wine_state=$(_state "wine") + + local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) + local choices + choices=$(whiptail --title "System Tools" --checklist \ + "Select system utilities to install (28 items, ↑↓ scroll):" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ + "alacritty" "GPU-accelerated terminal$(_inst alacritty)" "$alacritty_state" \ + "btop" "Resource monitor (fancy top)$(_inst btop)" "$btop_state" \ + "compress" "Compression tools (zip, unrar, 7z)$(_inst zip)" "$compress_state" \ + "conky" "System monitor for desktop$(_inst conky)" "$conky_state" \ + "corectrl" "AMD GPU control (CoreCtrl)$(_inst corectrl)" "$corectrl_state" \ + "cpufetch" "CPU info fetcher$(_inst cpufetch)" "$cpufetch_state" \ + "cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$cpu_x_state" \ + "curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$curl_wget_state" \ + "doublecmd-gtk" "Dual-panel file manager (GTK)$(_inst doublecmd-gtk)" "$dcgtk_state" \ + "doublecmd-qt" "Dual-panel file manager (Qt)$(_inst doublecmd-qt)" "$dcqt_state" \ + "extrepo" "External repository manager$(_inst extrepo)" "$extrepo_state" \ + "flatpak" "Flatpak sandbox + Flathub$(_inst flatpak)" "$flatpak_state" \ + "fwupd" "Firmware update daemon$(_inst fwupd)" "$fwupd_state" \ + "gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$disks_state" \ + "gparted" "GNOME partition editor$(_inst gparted)" "$gparted_state" \ + "hardinfo" "Graphical system profiler$(_inst hardinfo)" "$hardinfo_state" \ + "htop" "Interactive process viewer$(_inst htop)" "$htop_state" \ + "inxi" "System information tool$(_inst inxi)" "$inxi_state" \ + "kitty" "GPU-based terminal emulator$(_inst kitty)" "$kitty_state" \ + "kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$kvm_state" \ + "lshw" "List hardware details$(_inst lshw)" "$lshw_state" \ + "mc" "Midnight Commander (file manager)$(_inst mc)" "$mc_state" \ + "nala" "APT frontend (parallel downloads)$(_inst nala)" "$nala_state" \ + "ncdu" "Disk usage analyzer (ncurses)$(_inst ncdu)" "$ncdu_state" \ + "psensor" "Hardware temperature monitor$(_inst psensor)" "$psensor_state" \ + "timeshift" "System restore snapshots$(_inst timeshift)" "$timeshift_state" \ + "tmux" "Terminal multiplexer$(_inst tmux)" "$tmux_state" \ + "wine" "Windows compatibility layer$(_inst wine)" "$wine_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + case $pkg in + compress) + local need=() + ! is_installed "zip" && need+=("zip") + ! is_installed "unzip" && need+=("unzip") + ! is_installed "rar" && need+=("rar") + ! is_installed "unrar" && need+=("unrar") + ! is_installed "p7zip-full" && need+=("p7zip-full") + ! is_installed "p7zip-rar" && need+=("p7zip-rar") + if [ ${#need[@]} -gt 0 ]; then + _run_install_batch "${need[@]}" + echo -e "${GREEN}Compression utilities installed.${NC}" + fi + ;; + curl-wget) + local need=() + ! is_installed "curl" && need+=("curl") + ! is_installed "wget" && need+=("wget") + if [ ${#need[@]} -gt 0 ]; then + _run_install_batch "${need[@]}" + else + echo "curl and wget already installed." + fi + ;; + extrepo) + install_backports_or_stable extrepo + ;; + flatpak) + if ! is_installed "flatpak"; then + _run_cmd "Flatpak" "sudo apt install -y flatpak" "Installing Flatpak..." + if command -v plasma-discover &>/dev/null; then + _run_cmd "Flatpak" "sudo apt install -y plasma-discover-backend-flatpak" "Installing Flatpak backend..." + echo "Flatpak backend for Discover installed." + elif command -v gnome-software &>/dev/null; then + _run_cmd "Flatpak" "sudo apt install -y gnome-software-plugin-flatpak" "Installing Flatpak plugin..." + echo "Flatpak plugin for GNOME Software installed." + fi + else + echo "Flatpak already installed." + fi + flatpak remote-add --if-not-exists flathub \ + https://dl.flathub.org/repo/flathub.flatpakrepo + echo "Flathub repository added." + echo -e "${GREEN}A reboot is recommended.${NC}" + ;; + fwupd) + if ! is_installed "fwupd"; then + _run_cmd "fwupd" "sudo apt install -y fwupd" "Installing fwupd..." + else + echo "fwupd already installed." + fi + if _confirm "Firmware Scan" "Scan for firmware updates now?\n\nThis will run:\n fwupdmgr refresh\n fwupdmgr get-updates\n fwupdmgr update (if available)"; then + _run_cmd "fwupd" "sudo fwupdmgr refresh --force" "Refreshing firmware metadata..." + echo "" + echo "Checking for firmware updates..." + sudo fwupdmgr get-updates 2>&1 || true + if sudo fwupdmgr get-updates 2>&1 | grep -q "available"; then + if _confirm "Firmware Update" "Firmware updates are available.\nInstall them now?"; then + _run_cmd "fwupd" "sudo fwupdmgr update -y" "Installing firmware updates..." + else + echo "Skipping firmware update." + fi + else + echo "No firmware updates available." + fi + fi + echo -e "${GREEN}fwupd setup complete.${NC}" + ;; + kvm) + if ! is_installed "virt-manager"; then + _run_cmd "KVM" "sudo apt install -y qemu-system-x86 qemu-utils libvirt-daemon-system libvirt-clients bridge-utils virt-manager" "Installing KVM..." + sudo adduser "$USER" libvirt 2>/dev/null || true + sudo adduser "$USER" kvm 2>/dev/null || true + echo -e "${GREEN}QEMU/KVM installed. A reboot is recommended.${NC}" + else + echo "QEMU/KVM already installed." + fi + ;; + wine) + if ! is_installed "wine"; then + echo "Checking for i386 architecture..." + if ! dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then + echo "Enabling i386 architecture for Wine..." + sudo dpkg --add-architecture i386 + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." + fi + _run_cmd "Wine" "sudo apt install -y wine wine32 wine64 libwine libwine:i386 fonts-wine" "Installing Wine..." + echo -e "${GREEN}Wine installed. Run 'winecfg' to configure.${NC}" + else + echo "Wine already installed." + fi + ;; + *) + if $headless; then + echo "Skipping $pkg (headless mode)" + continue + fi + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + ;; + esac + done + + echo -e "${GREEN}System tools installed.${NC}" +} diff --git a/modules/extras/themes/cursors/cursors.sh b/modules/extras/themes/cursors/cursors.sh new file mode 100644 index 0000000..baac2ef --- /dev/null +++ b/modules/extras/themes/cursors/cursors.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# cursors.sh — Cursor themes + +_cat_cursors() { + local bibata_state; bibata_state=$(_state "bibata-cursor-theme") + local breeze_state; breeze_state=$(_state "breeze-cursor-theme") + local chameleon_state; chameleon_state=$(_state "chameleon-cursor-theme") + local dmz_state; dmz_state=$(_state "dmz-cursor-theme") + local xcursor_state; xcursor_state=$(_state "xcursor-themes") + local oxygen_state; oxygen_state=$(_state "oxygencursors") + + local choices + choices=$(whiptail --title "Cursor Themes" --checklist \ + "Select cursor themes to install:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ + "bibata-cursor-theme" "Bibata cursors$(_inst bibata-cursor-theme)" "$bibata_state" \ + "breeze-cursor-theme" "Breeze cursors (KDE)$(_inst breeze-cursor-theme)" "$breeze_state" \ + "chameleon-cursor-theme" "Chameleon cursors$(_inst chameleon-cursor-theme)" "$chameleon_state" \ + "dmz-cursor-theme" "DMZ cursors$(_inst dmz-cursor-theme)" "$dmz_state" \ + "xcursor-themes" "X11 base cursors$(_inst xcursor-themes)" "$xcursor_state" \ + "oxygencursors" "Oxygen cursors (KDE legacy)$(_inst oxygencursors)" "$oxygen_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + done + + echo -e "${GREEN}Cursor themes installed.${NC}" +} diff --git a/modules/extras/themes/desktop-themes/desktop-themes.sh b/modules/extras/themes/desktop-themes/desktop-themes.sh new file mode 100644 index 0000000..809c9e4 --- /dev/null +++ b/modules/extras/themes/desktop-themes/desktop-themes.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# desktop-themes.sh — GTK and KDE desktop themes + +_cat_themes() { + local headless=false + _is_headless && headless=true + local arc_state; arc_state=$(_state "arc-theme") + local blackbird_state; blackbird_state=$(_state "blackbird-gtk-theme") + local bluebird_state; bluebird_state=$(_state "bluebird-gtk-theme") + local breeze_gtk_state; breeze_gtk_state=$(_state "breeze-gtk-theme") + local greybird_state; greybird_state=$(_state "greybird-gtk-theme") + local numix_gtk_state; numix_gtk_state=$(_state "numix-gtk-theme") + local orchis_state; orchis_state=$(_state "orchis-gtk-theme") + + local choices + choices=$(whiptail --title "Desktop Themes (GTK/KDE)" --checklist \ + "Select desktop themes to install:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ + "arc-theme" "Arc GTK theme$(_inst arc-theme)" "$arc_state" \ + "blackbird-gtk-theme" "Blackbird GTK theme$(_inst blackbird-gtk-theme)" "$blackbird_state" \ + "bluebird-gtk-theme" "Bluebird GTK theme$(_inst bluebird-gtk-theme)" "$bluebird_state" \ + "breeze-gtk-theme" "Breeze GTK theme (KDE port)$(_inst breeze-gtk-theme)" "$breeze_gtk_state" \ + "greybird-gtk-theme" "Greybird GTK theme$(_inst greybird-gtk-theme)" "$greybird_state" \ + "numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$numix_gtk_state" \ + "orchis-gtk-theme" "Orchis GTK theme$(_inst orchis-gtk-theme)" "$orchis_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + if $headless; then + echo "Skipping $pkg (headless mode)" + continue + fi + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + done + + echo -e "${GREEN}Desktop themes installed.${NC}" +} diff --git a/modules/extras/themes/fonts/fonts.sh b/modules/extras/themes/fonts/fonts.sh new file mode 100644 index 0000000..06cf0de --- /dev/null +++ b/modules/extras/themes/fonts/fonts.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# fonts.sh — Fonts + +_cat_fonts() { + local bebas_state; bebas_state=$(_state "fonts-bebas-neue") + local anon_state; anon_state=$(_state "fonts-anonymous-pro") + local verana_state; verana_state=$(_state "fonts-adf-verana") + local f3270_state; f3270_state=$(_state "fonts-3270") + local liberation_state; liberation_state=$(_state "fonts-liberation") + local mscore_state; mscore_state=$(_state "ttf-mscorefonts-installer") + local ubuntu_state; ubuntu_state=$(_state "fonts-ubuntu") + local recommended_state; recommended_state=$(_state "fonts-recommended") + + local choices + choices=$(whiptail --title "Fonts" --checklist \ + "Select fonts to install:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ + "fonts-bebas-neue" "Bebas Neue (display)$(_inst fonts-bebas-neue)" "$bebas_state" \ + "fonts-anonymous-pro" "Anonymous Pro (monospace)$(_inst fonts-anonymous-pro)" "$anon_state" \ + "fonts-adf-verana" "ADF Verana (sans-serif)$(_inst fonts-adf-verana)" "$verana_state" \ + "fonts-3270" "IBM 3270 terminal font$(_inst fonts-3270)" "$f3270_state" \ + "fonts-liberation" "Liberation (MS-compatible)$(_inst fonts-liberation)" "$liberation_state" \ + "ttf-mscorefonts-installer" "Microsoft fonts (EULA required)$(_inst ttf-mscorefonts-installer)" "$mscore_state" \ + "fonts-ubuntu" "Ubuntu font family$(_inst fonts-ubuntu)" "$ubuntu_state" \ + "fonts-recommended" "Debian recommended fonts$(_inst fonts-recommended)" "$recommended_state" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + done + + echo -e "${GREEN}Fonts installed.${NC}" +} diff --git a/modules/extras/themes/icons/icons.sh b/modules/extras/themes/icons/icons.sh new file mode 100644 index 0000000..9a5914a --- /dev/null +++ b/modules/extras/themes/icons/icons.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# icons.sh — Icon themes + +_cat_icons() { + local headless=false + _is_headless && headless=true + local breeze_state; breeze_state=$(_state "breeze-icon-theme") + local deepin_state; deepin_state=$(_state "deepin-icon-theme") + local ele_state; ele_state=$(_state "elementary-icon-theme") + local ele_xfce_state; ele_xfce_state=$(_state "elementary-xfce-icon-theme") + local moka_state; moka_state=$(_state "moka-icon-theme") + local numix_state; numix_state=$(_state "numix-icon-theme") + local numix_c_state; numix_c_state=$(_state "numix-icon-theme-circle") + local obsidian_state; obsidian_state=$(_state "obsidian-icon-theme") + local papirus_state; papirus_state=$(_state "papirus-icon-theme") + local paper_state; paper_state=$(_state "paper-icon-theme") + local suru_state; suru_state=$(_state "suru-icon-theme") + + local kf6_state="OFF" + local has_kf6=false + if [ "$DEBIAN_CODENAME" = "trixie" ]; then + kf6_state=$(_state "kf6-breeze-icon-theme") + has_kf6=true + fi + + local items=( + "breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$breeze_state" + "deepin-icon-theme" "Deepin icon theme$(_inst deepin-icon-theme)" "$deepin_state" + "elementary-icon-theme" "Elementary icon theme$(_inst elementary-icon-theme)" "$ele_state" + "elementary-xfce-icon-theme" "Elementary Xfce icons$(_inst elementary-xfce-icon-theme)" "$ele_xfce_state" + "moka-icon-theme" "Moka icon theme$(_inst moka-icon-theme)" "$moka_state" + "numix-icon-theme" "Numix icon theme$(_inst numix-icon-theme)" "$numix_state" + "numix-icon-theme-circle" "Numix Circle icon theme$(_inst numix-icon-theme-circle)" "$numix_c_state" + "obsidian-icon-theme" "Obsidian icon theme$(_inst obsidian-icon-theme)" "$obsidian_state" + "papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$papirus_state" + "paper-icon-theme" "Paper icon theme$(_inst paper-icon-theme)" "$paper_state" + "suru-icon-theme" "Suru icon theme$(_inst suru-icon-theme)" "$suru_state" + ) + if $has_kf6; then + items+=("kf6-breeze-icon-theme" "KF6 Breeze icon theme$(_inst kf6-breeze-icon-theme)" "$kf6_state") + fi + + local choices + choices=$(whiptail --title "Icon Themes" --checklist \ + "Select icon themes to install:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ + "${items[@]}" \ + 3>&1 1>&2 2>&3) + clear + + [ -z "$choices" ] && return + + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + if $headless; then + echo "Skipping $pkg (headless mode)" + continue + fi + if ! is_installed "$pkg"; then + _run_install "$pkg" + else + echo "$pkg already installed." + fi + done + + echo -e "${GREEN}Icon themes installed.${NC}" +} diff --git a/modules/extras/themes/themes.sh b/modules/extras/themes/themes.sh new file mode 100644 index 0000000..90a2d07 --- /dev/null +++ b/modules/extras/themes/themes.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# themes.sh — Customization submenu dispatcher + +_cat_customization() { + local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) + local sub + sub=$(whiptail --title "Customization System" --menu \ + "Select type:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ + "1" "Desktop Themes (GTK/KDE)" \ + "2" "Icon Themes" \ + "3" "Cursor Themes" \ + "4" "Fonts" \ + 3>&1 1>&2 2>&3) + [ -z "$sub" ] && return + case $sub in + 1) _cat_themes ;; + 2) _cat_icons ;; + 3) _cat_cursors ;; + 4) _cat_fonts ;; + esac +}