aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmed <git@gumx.cc>2026-06-14 16:39:16 +0300
committerAhmed <git@gumx.cc>2026-06-14 16:39:16 +0300
commit4cace2f42208bc54298894d4bc0988b165bd73da (patch)
tree2f4a2d181116fe63c00f168747cd7a73e753e321
parent5a8d568931d9b23ce0df1265d05259a7012081c9 (diff)
add: hooks, documentation, and other vibed edits
-rw-r--r--alfred/helpstrings.py31
-rw-r--r--dev-docs/alfred.md2
-rw-r--r--dev-docs/osterman.md1
-rw-r--r--docs/alfred.md13
-rw-r--r--hooks/post-receive7
-rw-r--r--scripts/gen_bots.py13
6 files changed, 54 insertions, 13 deletions
diff --git a/alfred/helpstrings.py b/alfred/helpstrings.py
index 6711340..90c7dbb 100644
--- a/alfred/helpstrings.py
+++ b/alfred/helpstrings.py
@@ -1,4 +1,4 @@
-TOPICS = "topics: srv, bot, files, irc, coffee. type !help <topic> for details"
+TOPICS = "topics: srv, bot, files, irc, coffee, vpn, list, git. type !help <topic> for details"
SRV_TOPIC = "srv: uptime disk mem load status net top topmem io conns who logs. type !help srv <cmd> for details"
SRV = {
@@ -52,15 +52,42 @@ COFFEE = {
"no": "coffee yes or no: confirm or cancel a pending change. usage: !coffee yes or !coffee no",
}
+VPN_TOPIC = "vpn: pubkey list add remove. type !help vpn <cmd> for details"
+VPN = {
+ "pubkey": "vpn pubkey: print the WireGuard server public key. usage: !vpn pubkey",
+ "list": "vpn list: list all peers with IP and pubkey. usage: !vpn list",
+ "add": "vpn add: add a peer, returns assigned IP and client config URL. usage: !vpn add name pubkey",
+ "remove": "vpn remove: remove a peer live and from wg0.conf. usage: !vpn remove name",
+}
+
+LIST_TOPIC = "list: members subscribe unsubscribe send. type !help list <cmd> for details"
+LIST = {
+ "members": "list members: show all subscribers. usage: !list members",
+ "subscribe": "list subscribe: subscribe an address. usage: !list subscribe email",
+ "unsubscribe": "list unsubscribe: unsubscribe an address. usage: !list unsubscribe email",
+ "send": "list send: send a message to the list. usage: !list send message",
+}
+
+GIT_TOPIC = "git: list desc hook remove. type !help git <cmd> for details"
+GIT = {
+ "list": "git list: list all repos with last commit time and description. usage: !git list",
+ "desc": "git desc: set a repo description. usage: !git desc repo text",
+ "hook": "git hook: install a post-receive hook template. usage: !git hook repo type",
+ "remove": "git remove: remove a repo, prompts for confirmation. usage: !git remove repo",
+}
+
TOPIC_MAP = {
"srv": (SRV_TOPIC, SRV),
"bot": (BOT_TOPIC, BOT),
"files": (FILES_TOPIC, FILES),
"irc": (IRC_TOPIC, IRC),
"coffee": (COFFEE_TOPIC, COFFEE),
+ "vpn": (VPN_TOPIC, VPN),
+ "list": (LIST_TOPIC, LIST),
+ "git": (GIT_TOPIC, GIT),
}
-_ALL = {**SRV, **BOT, **FILES, **IRC, **COFFEE}
+_ALL = {**SRV, **BOT, **FILES, **IRC, **COFFEE, **VPN, **LIST, **GIT}
def lookup(args):
diff --git a/dev-docs/alfred.md b/dev-docs/alfred.md
index 74876c5..49e2a08 100644
--- a/dev-docs/alfred.md
+++ b/dev-docs/alfred.md
@@ -153,9 +153,11 @@ These need proper parsing and formatted output.
These parse `top -b -n 1` output. The column indices are hardcoded to match
the Alpine Linux `top` format from busybox:
+
```
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
```
+
If the system uses a different `top` (procps-ng for example), the column
indices may be wrong. This is documented as a known platform dependency.
diff --git a/dev-docs/osterman.md b/dev-docs/osterman.md
index 7676def..75e058c 100644
--- a/dev-docs/osterman.md
+++ b/dev-docs/osterman.md
@@ -41,6 +41,7 @@ import helpstrings as h
```
Three-level hierarchy:
+
```
!help → TOPICS (list of topic names and commands)
!help <topic> → topic line listing commands
diff --git a/docs/alfred.md b/docs/alfred.md
index c2e6a7d..f86da83 100644
--- a/docs/alfred.md
+++ b/docs/alfred.md
@@ -118,6 +118,19 @@ Bots are discovered automatically from `~/.config/sopel/*.cfg`.
Manages the mlmmj list at `list@gumx.cc`. Web archive at `mail.gumx.cc/list/archive/`.
+### Git repos
+
+```
+!git list list all repos with last commit time and description
+!git desc <repo> <text> set a repo's description (shown on git.gumx.cc)
+!git hook <repo> <type> install a post-receive hook from the templates dir
+!git remove <repo> remove a repo (prompts for confirmation)
+```
+
+Repos auto-create on first push via the git-shell-wrapper. Use `!git hook` after pushing to a new repo to install a deploy hook. Available types depend on what's in `/home/ahmed/scripts/git-hooks/`.
+
+`!git remove` requires `!git yes` to confirm or `!git no` to cancel.
+
## Config keys
| Key | Description |
diff --git a/hooks/post-receive b/hooks/post-receive
new file mode 100644
index 0000000..b3164b0
--- /dev/null
+++ b/hooks/post-receive
@@ -0,0 +1,7 @@
+#!/bin/sh
+set -e
+WORK=/home/git/build/irc-bots
+OUT=/home/git/build/irc-bots-out
+python3 "$WORK/scripts/gen_bots.py" "$WORK" "$OUT"
+rsync -rlptD --delete "$OUT/" /var/www/irc.gumx.cc/bots/
+echo "irc-bots deployed"
diff --git a/scripts/gen_bots.py b/scripts/gen_bots.py
index ddb2d54..ed53bc6 100644
--- a/scripts/gen_bots.py
+++ b/scripts/gen_bots.py
@@ -37,17 +37,7 @@ a { color: inherit; }
@media (max-width: 400px) { body { font-size: 0.8em; } h1 { font-size: 1.6em; } }
@media (prefers-color-scheme: dark) { html { filter: invert(1); } img { filter: invert(1); } }"""
-FOOTER = """\
-<footer>
-<hr>
-<a href="https://gumx.cc">gumx.cc</a> /
-<a href="https://git.gumx.cc">git</a> /
-<a href="https://mail.gumx.cc">mail</a> /
-<a href="https://irc.gumx.cc">irc</a> /
-<a href="https://vpn.gumx.cc">vpn</a> /
-<a href="https://pgp.gumx.cc">pgp</a> /
-<a href="https://wk.fo">wk.fo</a>
-</footer>"""
+FOOTER = ""
def page(title, header_html, content_html):
@@ -56,6 +46,7 @@ def page(title, header_html, content_html):
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
+<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1IDUiPjxyZWN0IHg9IjEiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiLz48cmVjdCB4PSIyIiB5PSIxIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIi8+PHJlY3QgeD0iMCIgeT0iMiIgd2lkdGg9IjEiIGhlaWdodD0iMSIvPjxyZWN0IHg9IjEiIHk9IjIiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiLz48cmVjdCB4PSIyIiB5PSIyIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIi8+PC9zdmc+">
<title>{title}</title>
<style>
{STYLE}