commit 00777a339951cafb574986bb3d15b43d3525c134 (patch)
parent f72cc04de2e058f975cc1fcdfc43bde69419d834
Author: Alex Karle <alex@alexkarle.com>
Date: Sat, 13 Nov 2021 14:46:27 -0500
ui: Add fully functioning UI with prompt!
Specifically, rather than donly run once / force you to run `gc` again,
it now runs in a while-loop prompting you. Even better, it has support
for numbered links that can be used to quickly traverse menus!
Diffstat:
M | TODO | | | 3 | ++- |
M | gc | | | 86 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- |
2 files changed, 66 insertions(+), 23 deletions(-)
diff --git a/TODO b/TODO
@@ -1,6 +1,7 @@
TODO:
* Support for non 0/1 types (h, specifically)
-* Looping UI, if stdin is a tty
* Support for other protocol:// strings
* Man page!
+* TLS support (openssl s_client?)
+* history?
diff --git a/gc b/gc
@@ -8,42 +8,84 @@ die() {
[ -z "$1" ] && die "usage: gc URL"
pretty() {
- awk -F" " '
-/^[^01i\.]/ { sub("^.", "", $1); printf " ???| %s\n", $1 }
-/^i/ { sub("^i", "", $1); printf " | %s\n", $1 }
-/^0/ { sub("^0", "", $1); links[n++] = sprintf("%s/0%s", $3, $2); printf "%2d TXT| %s\n", n, $1 }
-/^1/ { sub("^1", "", $1); links[n++] = sprintf("%s/1%s", $3, $2); printf "%2d DIR| %s\n", n, $1 }
+ awk -F" " "
+/^[^01i\.]/ { sub(\"^.\", \"\", \$1); printf \" ???| %s\\n\", \$1 }
+/^i/ { sub(\"^i\", \"\", \$1); printf \" | %s\\n\", \$1 }
+/^0/ { sub(\"^0\", \"\", \$1); links[n++] = sprintf(\"%s/0%s\", \$3, \$2); printf \"%2d TXT| %s\\n\", n, \$1 }
+/^1/ { sub(\"^1\", \"\", \$1); links[n++] = sprintf(\"%s/1%s\", \$3, \$2); printf \"%2d DIR| %s\\n\", n, \$1 }
END {
- printf "\n"
- for (i=0; i < length(links); i++) {
- printf "[%d]: %s\n", i, links[i]
- }
+ printf \"\" > \"$LINKS\"
+ for (i=0; i < length(links); i++) {
+ printf \"[%d]: %s\\n\", i + 1, links[i] >>\"$LINKS\"
+ }
}
-'
+"
+}
+
+parseurl() {
+ bare=${URL##gopher://}
+ host=${bare%%/*}
+ target=${bare##$host}
}
catlike() {
- case "$TARGET" in
- /0/*) echo "${TARGET##/0}" | nc "$HOST" 70 ;;
- /1/*) echo "${TARGET##/1}" | nc "$HOST" 70 | pretty ;;
- *) echo "$TARGET" | nc "$HOST" 70 | pretty ;; # TODO: handle other types?
+ parseurl
+ case "$target" in
+ /0/*) echo "${target##/0}" | nc "$host" 70 ;;
+ /1/*) echo "${target##/1}" | nc "$host" 70 | pretty ;;
+ *) echo "$target" | nc "$host" 70 | pretty ;; # TODO: handle other types?
esac
}
+goto() {
+ printf "goto> "
+ read -r URL
+}
+
+graburl() {
+ N="$1"
+ link=$(grep "^\[$N\]:" "$LINKS")
+ URL=${link##\[*\]: }
+}
+
ui() {
- case "$TARGET" in
- /0/*) echo "${TARGET##/0}" | nc "$HOST" 70 | ${PAGER:-less} ;;
- /1/*) echo "${TARGET##/1}" | nc "$HOST" 70 | pretty ;;
- *) echo "$TARGET" | nc "$HOST" 70 | pretty ;; # TODO: handle other types?
- esac
+ while [ -n "$URL" ]; do
+ parseurl
+ case "$target" in
+ /0/*) echo "${target##/0}" | nc "$host" 70 | ${PAGER:-less} ;;
+ /1/*) echo "${target##/1}" | nc "$host" 70 | pretty ;;
+ *) echo "$target" | nc "$host" 70 | pretty ;; # TODO: handle other types?
+ esac
+
+ URL=""
+ while true; do
+ printf "> "
+ read -r opt
+ case $opt in
+ [0-9]*) graburl "$opt" && if [ -n "$URL" ]; then break; else echo "no such link"; fi ;;
+ l*) cat "$LINKS" ;;
+ g*) goto ; break ;;
+ h*) cat <<EOM ;;
+NUM -- go to this target
+g[oto] -- specify new URL
+h[elp] -- print this message
+l[ist] -- list targets
+q[uit] -- quit
+EOM
+ q*) break;;
+ *) echo "no such command; 'h' for help, 'q' to quit" ;;
+ esac
+ done
+ done
}
-uri=${1##gopher://}
-HOST=${uri%%/*}
-TARGET=${uri##$HOST}
+URL=$1
+LINKS=$(mktemp)
if ! tty >/dev/null; then
catlike
else
ui
fi
+
+rm -f "$LINKS"