From da49c63526223fa3914e91cc2d42e7f6b0a11e24 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Thu, 20 Jul 2023 15:29:39 +0200 Subject: [PATCH] Continued: - FBA is now a Fediverse "instance" - outbound "rss" is supported as feeds are provided - peer list is available at `/api/v1/instance/peers`, but only instances with valid nodeinfo --- daemon.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/daemon.py b/daemon.py index 42a7276..9ccdc64 100755 --- a/daemon.py +++ b/daemon.py @@ -22,6 +22,7 @@ import re from datetime import datetime from email.utils import format_datetime from pathlib import Path +from urllib.parse import urlparse import fastapi from fastapi import Request, HTTPException, Query @@ -57,12 +58,12 @@ def api_info(): database.cursor.execute("SELECT (SELECT COUNT(domain) FROM instances), (SELECT COUNT(domain) FROM instances WHERE software IN ('pleroma', 'mastodon', 'lemmy', 'friendica', 'misskey', 'peertube', 'takahe', 'gotosocial', 'brighteon', 'wildebeest', 'bookwyrm')), (SELECT COUNT(blocker) FROM blocks), (SELECT COUNT(domain) FROM instances WHERE last_error_details IS NOT NULL)") row = database.cursor.fetchone() - return { + return JSONResponse(status_code=200, content={ "known_instances" : row[0], "supported_instances": row[1], "blocks_recorded" : row[2], "erroneous_instances": row[3], - } + }) @router.get(config.get("base_url") + "/api/scoreboard.json", response_class=JSONResponse) def api_scoreboard(mode: str, amount: int): @@ -102,7 +103,7 @@ def api_scoreboard(mode: str, amount: int): "score" : round(score) }) - return scores + return JSONResponse(status_code=200, content=scores) @router.get(config.get("base_url") + "/api/list.json", response_class=JSONResponse) def api_list(request: Request, mode: str, value: str, amount: int): @@ -122,7 +123,7 @@ LIMIT ?", [value, amount] domainlist = database.cursor.fetchall() - return domainlist + return JSONResponse(status_code=200, content=dict(domainlist)) @router.get(config.get("base_url") + "/api/top.json", response_class=JSONResponse) def api_index(request: Request, mode: str, value: str, amount: int): @@ -229,7 +230,7 @@ def api_domain(domain: str): if domain_data is None: raise HTTPException(status_code=404, detail=f"domain='{domain}' not found") - return domain_data + return JSONResponse(status_code=200, content=dict(domain_data)) @router.get(config.get("base_url") + "/api/mutual.json", response_class=JSONResponse) def api_mutual(domains: list[str] = Query()): @@ -254,6 +255,69 @@ def api_mutual(domains: list[str] = Query()): # No known blocks return JSONResponse(status_code=200, content={}) +@router.get(config.get("base_url") + "/.well-known/nodeinfo", response_class=JSONResponse) +def wellknown_nodeinfo(request: Request): + components = urlparse(str(request.url)) + + return JSONResponse(status_code=200, content={ + "links": ({ + "rel" : "http://nodeinfo.diaspora.software/ns/schema/1.0", + "href": f"{components.scheme}://{config.get('hostname')}{config.get('base_url')}/nodeinfo/1.0" + }) + }) + +@router.get(config.get("base_url") + "/nodeinfo/1.0", response_class=JSONResponse) +def nodeinfo_1_0(request: Request): + return JSONResponse(status_code=200, content={ + "version": "1.0", + "software": { + "name": "FBA", + "version": "0.1", + }, + "protocols": { + "inbound": (), + "outbound": ( + "rss", + ), + }, + "services": { + "inbound": (), + "outbound": ( + "rss", + ), + }, + "usage": { + "users": (), + }, + "openRegistrations": False, + "metadata": { + "nodeName": "Fedi Block API", + "protocols": { + "inbound": (), + "outbound": ( + "rss", + ), + }, + "services": { + "inbound": (), + "outbound": ( + "rss", + ), + }, + "explicitContent": False, + }, + }) + +@router.get(config.get("base_url") + "/api/v1/instance/peers", response_class=JSONResponse) +def api_peers(request: Request): + database.cursor.execute("SELECT domain FROM instances WHERE nodeinfo_url IS NOT NULL") + + peers = list() + for row in database.cursor.fetchall(): + peers.append(row["domain"]) + + return JSONResponse(status_code=200, content=peers) + @router.get(config.get("base_url") + "/scoreboard") def scoreboard(request: Request, mode: str, amount: int): response = None -- 2.39.5