diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..58e9f3f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +env/ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7469669 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +fastcgi==0.0.3 diff --git a/services/mentions.pickle b/services/mentions.pickle new file mode 100644 index 0000000..7f0a25a Binary files /dev/null and b/services/mentions.pickle differ diff --git a/services/webmention.py b/services/webmention.py new file mode 100644 index 0000000..55139bb --- /dev/null +++ b/services/webmention.py @@ -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") diff --git a/services/webmention_nginx.conf b/services/webmention_nginx.conf new file mode 100644 index 0000000..deb80ce --- /dev/null +++ b/services/webmention_nginx.conf @@ -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 "; 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; + } +} diff --git a/www/index.html b/www/index.html index a9df694..d5dcc53 100644 --- a/www/index.html +++ b/www/index.html @@ -1,19 +1,21 @@ - + Libre Internet Club - + - + + @ University of Alberta +
Webmention us at https://webmention.libreinternet.club