Improve instance list

This now returns the list of instances of multiple Fediverse projects.
Currently pretty slow because of the Mastodon and Pleroma being too big.
This commit is contained in:
Nikita Karamov 2023-03-18 15:05:53 +01:00
parent f5cbb082ed
commit 6d4eca0131
No known key found for this signature in database
GPG key ID: 41D6F71EE78E77CD
2 changed files with 51 additions and 5 deletions

14
src/constants.ts Normal file
View file

@ -0,0 +1,14 @@
/**
* Enumeration of the supported fediverse projects.
*
* The values of this enum are used as the keys for the fediverse.observer API,
* as the icon names, etc.
*/
export enum FediverseProject {
Friendica = "friendica",
GNUSocial = "gnusocial",
Hubzilla = "hubzilla",
Mastodon = "mastodon",
Misskey = "misskey",
Pleroma = "pleroma",
}

View file

@ -4,20 +4,52 @@
*/
import type { APIRoute } from "astro";
import { FediverseProject } from "../../constants";
interface MastodonServer {
[key: string]: unknown;
interface ProjectInstance {
domain: string;
score: number;
active_users_monthly: number;
status: number;
}
const PROJECTS = Object.values(FediverseProject);
export const fetchInstances = async (
projectId: string,
): Promise<ProjectInstance[]> => {
const response = await fetch("https://api.fediverse.observer/", {
headers: {
Accept: "*/*",
"Accept-Language": "en;q=1.0",
"Content-Type": "application/json",
},
referrer: "https://api.fediverse.observer/",
body: `{"query":"{\\n nodes(softwarename: \\"${projectId}\\") {\\n domain\\n score\\n active_users_monthly\\n status\\n }\\n}\\n"}`,
method: "POST",
});
const json = await response.json();
const instances: ProjectInstance[] = json.data.nodes;
return instances.filter(
(instance) => instance.score > 0 && instance.status === 1,
);
};
export const get: APIRoute = async () => {
try {
const response = await fetch("https://api.joinmastodon.org/servers");
const instances = await response.json();
const response = await Promise.all(
PROJECTS.map((projectId) => fetchInstances(projectId)),
);
const instances = response.flat();
instances.sort((a, b) => {
return b.active_users_monthly - a.active_users_monthly;
});
return new Response(
JSON.stringify(
instances.map((instance: MastodonServer) => instance.domain),
instances
.slice(0, 200)
.map((instance: ProjectInstance) => instance.domain),
),
{
headers: {