~kris/dots

srice

srice/.local/bin/misc/browser -rw-r--r-- 4.9 KiB
e98f3b03 — Kris Yotam chore: sync local state after restore (push updates, no pull) a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/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 <name>          # launch specific browser (librewolf, brave, tor, surf)
#      browser <url>           # dispatch URL to the preferred browser
#      browser <name> <url>    # 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 <name>          # launch specific browser (librewolf, brave, tor, surf)
  browser <url>           # dispatch URL to the preferred browser
  browser <name> <url>    # open URL with chosen browser

Examples:
  browser https://example.com
  browser surf https://blog.example.com
  browser brave

HELP
}

choose_one() {
    # choose_one <prompt> <opt1> <opt2> ...
    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 <name> [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