aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-05-21 18:56:19 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-05-21 18:56:19 +0200
commit688779fbc61d48046199d1f45549720e289ce417 (patch)
tree4ea8c13d96428176f97c0c27f665391c09a93098 /cmd
parentfb0fd67d6e7e55548c7a0a1ec67f608efffe3a94 (diff)
downloadxmppcb-688779fbc61d48046199d1f45549720e289ce417.tar.gz
xmppcb-688779fbc61d48046199d1f45549720e289ce417.zip
Added support for user generated shell scripts:
- create a director with shell scripts - call them within the chat with @<script-name> - four sample scripts
Diffstat (limited to 'cmd')
-rwxr-xr-xcmd/fx44
-rwxr-xr-xcmd/todo16
-rwxr-xr-xcmd/uptime29
-rwxr-xr-xcmd/weather38
4 files changed, 127 insertions, 0 deletions
diff --git a/cmd/fx b/cmd/fx
new file mode 100755
index 0000000..407c2d0
--- /dev/null
+++ b/cmd/fx
@@ -0,0 +1,44 @@
+#!/bin/sh
+# @fx - exchange rates between USD, EUR, PLN and THB (no arguments)
+#
+# One keyless request to open.er-api.com (base USD); the six cross-rates
+# are derived from it. JSON is parsed with awk so no 'jq' is needed.
+
+json=$(curl -fsS --max-time 8 "https://open.er-api.com/v6/latest/USD" \
+ | tr -d '\n\r') || { echo "fx: rate lookup failed"; exit 1; }
+
+case "$json" in
+ *'"result":"success"'*) ;;
+ *) echo "fx: rate service returned an error"; exit 1 ;;
+esac
+
+printf '%s' "$json" | awk '
+function rate(cur, s) {
+ if (match($0, "\"" cur "\":[0-9.]+")) {
+ s = substr($0, RSTART, RLENGTH)
+ sub(/^.*:/, "", s)
+ return s + 0
+ }
+ return -1
+}
+{
+ e = rate("EUR"); p = rate("PLN"); t = rate("THB")
+ if (e <= 0 || p <= 0 || t <= 0) {
+ print "fx: incomplete rate data"
+ exit 1
+ }
+ if (match($0, /"time_last_update_utc":"[^"]*"/)) {
+ d = substr($0, RSTART, RLENGTH)
+ sub(/^.*:"/, "", d)
+ sub(/"$/, "", d)
+ split(d, w, " ")
+ print "FX rates " w[1] " " w[2] " " w[3] " " w[4]
+ }
+ printf "1 USD = %.4g EUR\n", e
+ printf "1 USD = %.4g PLN\n", p
+ printf "1 USD = %.4g THB\n", t
+ printf "1 EUR = %.4g PLN\n", p / e
+ printf "1 EUR = %.4g THB\n", t / e
+ printf "1 PLN = %.4g THB\n", t / p
+}
+'
diff --git a/cmd/todo b/cmd/todo
new file mode 100755
index 0000000..7fb796b
--- /dev/null
+++ b/cmd/todo
@@ -0,0 +1,16 @@
+#!/bin/sh
+# @todo - print the shared to-do list
+#
+# The list lives in todo.md next to this script (cmd/todo.md). Edit that
+# file directly - on the server or by scp - to change it; @todo only
+# reads it, and the next call reflects the edit (no restart).
+
+file="$(dirname "$0")/todo.md"
+
+if [ ! -f "$file" ]; then
+ echo "todo: no list yet - create $file"
+elif [ ! -s "$file" ]; then
+ echo "todo: the list is empty"
+else
+ cat "$file"
+fi
diff --git a/cmd/uptime b/cmd/uptime
new file mode 100755
index 0000000..fef74a8
--- /dev/null
+++ b/cmd/uptime
@@ -0,0 +1,29 @@
+#!/bin/sh
+# @uptime - how long the xmppcb bot has been running
+#
+# The bot exec's this script directly, so its parent process ($PPID) is
+# the xmppcb process itself; ps tells us how long that process has run.
+
+secs=$(ps -o etimes= -p "$PPID" 2>/dev/null | tr -cd '0-9')
+
+if [ -n "$secs" ]; then
+ d=$(( secs / 86400 ))
+ h=$(( secs % 86400 / 3600 ))
+ m=$(( secs % 3600 / 60 ))
+ s=$(( secs % 60 ))
+ if [ "$d" -gt 0 ]; then up="${d}d ${h}h ${m}m ${s}s"
+ elif [ "$h" -gt 0 ]; then up="${h}h ${m}m ${s}s"
+ elif [ "$m" -gt 0 ]; then up="${m}m ${s}s"
+ else up="${s}s"
+ fi
+ echo "xmppcb up: $up"
+else
+ # fallback for a ps without 'etimes': raw elapsed string [dd-]hh:mm:ss
+ et=$(ps -o etime= -p "$PPID" 2>/dev/null | tr -d ' ')
+ if [ -n "$et" ]; then
+ echo "xmppcb up: $et"
+ else
+ echo "uptime: cannot read bot process (pid $PPID)"
+ exit 1
+ fi
+fi
diff --git a/cmd/weather b/cmd/weather
new file mode 100755
index 0000000..ee21233
--- /dev/null
+++ b/cmd/weather
@@ -0,0 +1,38 @@
+#!/bin/sh
+# @weather [location] - condition, temperature and local time
+#
+# In chat: @weather -> default: Bangkok and Warsaw
+# @weather Wroclaw -> just that location
+# @weather New York -> the whole argument arrives as "$1"
+#
+# Weather comes from wttr.in. Its %T (time) field is served from a cache
+# and goes stale, so we take only the timezone name (%Z, which is
+# static) from wttr.in and compute the current local time with date.
+
+fmt='%l:+%c+%t+%Z'
+
+one() {
+ loc=$(printf '%s' "$1" | tr ' ' '+')
+ out=$(curl -fsS --max-time 8 "https://wttr.in/${loc}?format=${fmt}") || {
+ printf 'weather: lookup failed for %s\n' "$1"
+ return
+ }
+ tz=${out##* } # last token: timezone name, e.g. Asia/Bangkok
+ wx=${out% *} # the rest: location, condition, temperature
+ case "$tz" in
+ */*)
+ now=$(TZ="$tz" date '+%H:%M')
+ printf '%s, %s\n' "$wx" "$now"
+ ;;
+ *)
+ printf '%s\n' "$out" # no usable timezone: show as-is
+ ;;
+ esac
+}
+
+if [ -n "$1" ]; then
+ one "$1"
+else
+ one Bangkok
+ one Warsaw
+fi