aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/ircbot/Sourcehut
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
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')
-rw-r--r--contrib/ircbot/Sourcehut/README.md1
-rw-r--r--contrib/ircbot/Sourcehut/__init__.py21
-rw-r--r--contrib/ircbot/Sourcehut/config.py14
-rw-r--r--contrib/ircbot/Sourcehut/local/__init__.py1
-rw-r--r--contrib/ircbot/Sourcehut/plugin.py80
-rw-r--r--contrib/ircbot/Sourcehut/setup.py3
6 files changed, 120 insertions, 0 deletions
diff --git a/contrib/ircbot/Sourcehut/README.md b/contrib/ircbot/Sourcehut/README.md
new file mode 100644
index 00000000..dbc4311d
--- /dev/null
+++ b/contrib/ircbot/Sourcehut/README.md
@@ -0,0 +1 @@
+Supybot plugin to receive Sourcehut webhooks
diff --git a/contrib/ircbot/Sourcehut/__init__.py b/contrib/ircbot/Sourcehut/__init__.py
new file mode 100644
index 00000000..39a9beef
--- /dev/null
+++ b/contrib/ircbot/Sourcehut/__init__.py
@@ -0,0 +1,21 @@
+"""
+Sourcehut: Supybot plugin to receive Sourcehut webhooks
+"""
+
+import sys
+import supybot
+
+__version__ = "0.1"
+__author__ = supybot.authors.unknown
+__contributors__ = {}
+__url__ = ''
+
+from . import config
+from . import plugin
+from importlib import reload
+
+reload(config)
+reload(plugin)
+
+Class = plugin.Class
+configure = config.configure
diff --git a/contrib/ircbot/Sourcehut/config.py b/contrib/ircbot/Sourcehut/config.py
new file mode 100644
index 00000000..38e55427
--- /dev/null
+++ b/contrib/ircbot/Sourcehut/config.py
@@ -0,0 +1,14 @@
+from supybot import conf, registry
+try:
+ from supybot.i18n import PluginInternationalization
+ _ = PluginInternationalization('Sourcehut')
+except:
+ _ = lambda x: x
+
+
+def configure(advanced):
+ from supybot.questions import expect, anything, something, yn
+ conf.registerPlugin('Sourcehut', True)
+
+
+Sourcehut = conf.registerPlugin('Sourcehut')
diff --git a/contrib/ircbot/Sourcehut/local/__init__.py b/contrib/ircbot/Sourcehut/local/__init__.py
new file mode 100644
index 00000000..e86e97b8
--- /dev/null
+++ b/contrib/ircbot/Sourcehut/local/__init__.py
@@ -0,0 +1 @@
+# Stub so local is a module, used for third-party modules
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
diff --git a/contrib/ircbot/Sourcehut/setup.py b/contrib/ircbot/Sourcehut/setup.py
new file mode 100644
index 00000000..11ba8772
--- /dev/null
+++ b/contrib/ircbot/Sourcehut/setup.py
@@ -0,0 +1,3 @@
+from supybot.setup import plugin_setup
+
+plugin_setup('Sourcehut')