aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/ircbot/Sourcehut/plugin.py
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2023-06-25 13:33:44 +0200
committerRobin Jarry <robin@jarry.cc>2023-07-01 18:26:35 +0200
commit91dbd6078192e017b88bf061bb730e9d16ed5088 (patch)
treeedc2f7fcf65b699cc048b5aa5476afea02ae2aed /contrib/ircbot/Sourcehut/plugin.py
parent69094e332779a71ddd47b88bced0992c290d67e7 (diff)
downloadaerc-91dbd6078192e017b88bf061bb730e9d16ed5088.tar.gz
contrib: add irc bot stuff
Add a small script to install a sourcehut webhook that triggers on patchset reception. Add a limnoria (supybot fork) plugin to receive the webhook requests and send IRC NOTICE messages on the proper channels. Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Bence Ferdinandy <bence@ferdinandy.com>
Diffstat (limited to 'contrib/ircbot/Sourcehut/plugin.py')
-rw-r--r--contrib/ircbot/Sourcehut/plugin.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/contrib/ircbot/Sourcehut/plugin.py b/contrib/ircbot/Sourcehut/plugin.py
new file mode 100644
index 00000000..d66c1029
--- /dev/null
+++ b/contrib/ircbot/Sourcehut/plugin.py
@@ -0,0 +1,80 @@
+import json
+
+from supybot import ircmsgs, callbacks, httpserver, log, world
+from supybot.ircutils import bold, italic, underline
+
+
+class Sourcehut(callbacks.Plugin):
+ """
+ Supybot plugin to receive Sourcehut webhooks
+ """
+ def __init__(self, irc):
+ super().__init__(irc)
+ httpserver.hook("sourcehut", SourcehutServerCallback(self))
+
+ def die(self):
+ httpserver.unhook("sourcehut")
+ super().die()
+
+ def announce(self, channel, message):
+ libera = world.getIrc("libera")
+ if libera is None:
+ print("error: no irc libera")
+ return
+ if channel not in libera.state.channels:
+ print(f"error: not in {channel} channel")
+ return
+ libera.sendMsg(ircmsgs.notice(channel, message))
+
+
+class SourcehutServerCallback(httpserver.SupyHTTPServerCallback):
+ name = "Sourcehut"
+ defaultResponse = "Bad request\n"
+
+ def __init__(self, plugin: Sourcehut):
+ super().__init__()
+ self.plugin = plugin
+
+ SUBJECT = "[PATCH {prefix} v{version}] {subject}"
+ URL = "https://lists.sr.ht/{list[owner][canonicalName]}/{list[name]}/patches/{id}"
+ CHANS = {
+ "#public-inbox": "##rjarry",
+ "#aerc-devel": "#aerc",
+ }
+
+ def doPost(self, handler, path, form=None):
+ if hasattr(form, "decode"):
+ form = form.decode("utf-8")
+ print(f"POST {path} {form}")
+ try:
+ body = json.loads(form)
+ hook = body["data"]["webhook"]
+ if hook["event"] == "PATCHSET_RECEIVED":
+ patchset = hook["patchset"]
+ subject = self.SUBJECT.format(**patchset)
+ url = self.URL.format(**patchset)
+ if not url.startswith("https://lists.sr.ht/~rjarry/"):
+ raise ValueError("unknown list")
+ channel = f"#{patchset['list']['name']}"
+ channel = self.CHANS.get(channel, channel)
+ submitter = patchset["submitter"]["canonicalName"]
+ msg = f"received {bold(subject)} from {italic(submitter)}: {underline(url)}"
+ self.plugin.announce(channel, msg)
+ handler.send_response(200)
+ handler.end_headers()
+ handler.wfile.write(b"")
+ return
+
+ raise ValueError("unsupported webhook: %r" % hook)
+
+ except Exception as e:
+ print("ERROR", e)
+ handler.send_response(400)
+ handler.end_headers()
+ handler.wfile.write(b"Bad request\n")
+
+ def log_message(self, format, *args):
+ pass
+
+
+Class = Sourcehut