Add rudimentary webmention service

This commit is contained in:
Spencer Killen 2026-07-14 00:15:08 -06:00
parent f5ef6d3b5e
commit 6616a748c0
6 changed files with 85 additions and 3 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
__pycache__
env/

1
requirements.txt Normal file
View file

@ -0,0 +1 @@
fastcgi==0.0.3

BIN
services/mentions.pickle Normal file

Binary file not shown.

63
services/webmention.py Normal file
View file

@ -0,0 +1,63 @@
import sys
import os
from fastcgi import fastcgi
from urllib.parse import parse_qs
from pathlib import Path
import pickle
from dataclasses import dataclass
CACHE_PATH = Path(__file__).parent / "mentions.pickle"
print("FastCGI server starting... unix socket to be located at")
print(Path.cwd()/"fcgi.sock")
@dataclass
class Mention:
source: str
target: str
@staticmethod
def load_past_mentions() -> list["Mention"]:
if CACHE_PATH.exists():
with open(CACHE_PATH, "rb") as fo:
return pickle.load(fo)
return []
@staticmethod
def save_past_mentions(mentions: list["Mention"]):
with open(CACHE_PATH, "wb") as fo:
return pickle.dump(mentions, fo)
@classmethod
def add_mention(cls, mention: "Mention"):
cache = cls.load_past_mentions()
if mention not in cache:
cache.append(mention)
cls.save_past_mentions(cache)
@fastcgi()
def handler():
try:
url = os.environ["REQUEST_URL"]
method = os.environ["REQUEST_METHOD"]
if method == "POST":
payload = sys.stdin.read()
data = parse_qs(payload)
source = data["source"][-1]
target = data["target"][-1]
Mention.add_mention(Mention(source, target))
if source == target:
raise Exception()
print("Status: 202 Accepted\r")
print("Content-Type: text/plain; charset=utf-8\r\n\r")
print("Thanks for mentioning us!")
print(source)
elif method == "GET":
print("Status: 200 OK\r")
print("Content-Type: text/plain; charset=utf-8\r\n\r")
for mention in Mention.load_past_mentions():
print(f"<{mention.source}> mentioned <{mention.target}>")
else:
raise Exception()
except Exception as e:
print("Status: 400 Bad Request\r\n\r")

View file

@ -0,0 +1,14 @@
# A basic nginx configuration to test webmention.py
# Update unix: path to be the correct file
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
add_header Link "<https://webmention.libreinternet.club>; rel=\"webmention\"" always;
fastcgi_pass unix:/home/gopher/libreinternet.club/services/fcgi.sock;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param REQUEST_URL $request_uri;
}
}

View file

@ -1,19 +1,21 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en-ca" typeof="Organization"> <html lang="en-ca" typeof="Organization">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8">
<title property="http://schema.org/name">Libre Internet Club</title> <title property="http://schema.org/name">Libre Internet Club</title>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css">
<script type="module" src="editor.js" defer></script> <script type="module" src="editor.js" defer></script>
<script type="module" src="tictactoe.js" defer></script> <script type="module" src="tictactoe.js" defer></script>
<script type="module" src="crawler.js" defer></script> <script type="module" src="crawler.js" defer></script>
<link rel="stylesheet" href="tictactoe.css" /> <link rel="stylesheet" href="tictactoe.css">
<link vocab="https://www.w3.org/ns/webmention#" rel="webmention" href="https://webmention.libreinternet.club">
</head> </head>
<body vocab="https://schema.org/"> <body vocab="https://schema.org/">
<div id="banner"> <div id="banner">
<img property="logo" src="banner.gif" alt="Libre Internet Club" /> <img property="logo" src="banner.gif" alt="Libre Internet Club" />
</div> </div>
<span property="location">@ <span typeof="CollegeOrUniversity" property="name">University of Alberta</span></span> <span property="location">@ <span typeof="CollegeOrUniversity" property="name">University of Alberta</span></span>
<div><a href="https://www.w3.org/TR/webmention">Webmention</a> us at <a vocab="https://www.w3.org/ns/webmention#" rel="webmention" href="https://webmention.libreinternet.club">https://webmention.libreinternet.club</a></div>
<ul> <ul>
<li><a href="https://discord.gg/U9MQTv952">Join Discord</a></li> <li><a href="https://discord.gg/U9MQTv952">Join Discord</a></li>
<li><a href="https://matrix.to/#/#Libre_Internet:matrix.org">Matrix</a></li> <li><a href="https://matrix.to/#/#Libre_Internet:matrix.org">Matrix</a></li>