#!/usr/bin/env bash # ============================================================== # browser - Simple browser dispatcher / launcher # -------------------------------------------------------------- # Author : Kris Yotam # Contact : krisyotam@protonmail.com # License : GNU GPLv3 # Created : 2025-10-27 # -------------------------------------------------------------- # Description: # Suckless, functionized launcher that routes URLs to the # appropriate browser or lets the user pick a browser from a # tiny TUI. Usage: # browser # interactive chooser # browser # launch specific browser (librewolf, brave, tor, surf) # browser # dispatch URL to the preferred browser # browser # open URL with chosen browser # # Dispatch rules (default): # - .onion -> TOR # - blog platforms (blogspot, medium, wordpress, ghost) -> surf # - otherwise -> librewolf # ============================================================== set -euo pipefail # -------------------- Configuration (like config.py header) ----------------- # Commands (override with env vars if needed) LIBREWOLF_CMD="${LIBREWOLF_CMD:-librewolf}" BRAVE_CMD="${BRAVE_CMD:-brave-browser}" TOR_CMD="${TOR_CMD:-torbrowser-launcher}" SURF_CMD="${SURF_CMD:-surf}" # Supported friendly names (lowercase) BROWSERS=(librewolf brave tor surf) # --------------------------------------------------------------------------- print_help() { cat <<'HELP' browser - Simple browser dispatcher / launcher Usage: browser # interactive chooser browser # launch specific browser (librewolf, brave, tor, surf) browser # dispatch URL to the preferred browser browser # open URL with chosen browser Examples: browser https://example.com browser surf https://blog.example.com browser brave HELP } choose_one() { # choose_one ... local prompt="$1"; shift local opts=("$@") local i=1 printf "%s\n" "$prompt" for o in "${opts[@]}"; do printf " %d) %s\n" "$i" "$o" i=$((i+1)) done printf "Choice [1-%d]: " $((i-1)) local choice IFS= read -r choice || choice='' if ! printf '%s' "$choice" | grep -qE '^[0-9]+$'; then return 1 fi if [ "$choice" -lt 1 ] || [ "$choice" -ge "$i" ]; then return 1 fi echo "${opts[$((choice-1))]}" } is_url() { # crude URL test: contains :// or starts with www. or contains a dot and no spaces local s="$1" case "$s" in *://*|www.*|*.*) return 0 ;; *) return 1 ;; esac } extract_host() { # accept full URL or bare host local u="$1" # strip protocol u="${u#*://}" # strip path u="${u%%/*}" # strip port u="${u%%:*}" printf '%s' "$u" } dispatch_url() { local url="$1" local host host=$(extract_host "$url") # lower-case host for pattern matching local host_lc host_lc=$(printf '%s' "$host" | tr '[:upper:]' '[:lower:]') case "$host_lc" in *.onion) launch_browser "tor" "$url" ;; *blogspot.*|*medium.*|*wordpress.*|*ghost.*) launch_browser "surf" "$url" ;; *) launch_browser "librewolf" "$url" ;; esac } launch_browser() { # launch_browser [url] local name="$1" local url="${2:-}" local cmd="" case "${name,,}" in librewolf) cmd="$LIBREWOLF_CMD" ;; brave) cmd="$BRAVE_CMD" ;; tor) cmd="$TOR_CMD" ;; surf) cmd="$SURF_CMD" ;; *) printf "Unknown browser: %s\n" "$name" >&2 return 2 ;; esac if [ -n "$url" ]; then # prefer to open in background so script exits setsid "$cmd" "$url" >/dev/null 2>&1 & else setsid "$cmd" >/dev/null 2>&1 & fi } main() { if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then print_help return 0 fi if [ "$#" -eq 0 ]; then # interactive chooser local choice choice=$(choose_one "Choose browser:" "${BROWSERS[@]}") || { printf "No valid choice. Exiting.\n"; return 1 } launch_browser "$choice" return 0 fi # If first arg matches a browser name -> explicit launch local first="${1,,}" if printf '%s\n' "${BROWSERS[@]}" | grep -Fxq -- "$first"; then if [ "$#" -ge 2 ]; then # browser name + url launch_browser "$first" "$2" else launch_browser "$first" fi return 0 fi # If first arg looks like a url -> dispatch if is_url "$1"; then dispatch_url "$1" return 0 fi # otherwise assume it's a hostname-like argument; dispatch dispatch_url "$1" } # If executed directly, run main with positional args if [ "${BASH_SOURCE[0]:-}" = "$0" ]; then main "$@" fi