mirror of
https://github.com/MbinOrg/mbin-website.git
synced 2025-06-29 22:58:56 +00:00
Add fedidb.org as server list source, add title to webpages
This commit is contained in:
parent
e118d9d5cd
commit
ed7d5303a0
5 changed files with 119 additions and 59 deletions
|
@ -1,4 +1,3 @@
|
|||
import { clientOnly } from '@solidjs/start';
|
||||
import { ParentComponent } from 'solid-js';
|
||||
import { SolidMarkdown } from 'solid-markdown';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @refresh reload
|
||||
import { createHandler, StartServer } from "@solidjs/start/server";
|
||||
import { createHandler, StartServer } from '@solidjs/start/server';
|
||||
|
||||
export default createHandler(() => (
|
||||
<StartServer
|
||||
|
@ -9,6 +9,7 @@ export default createHandler(() => (
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<title>Join Mbin</title>
|
||||
{assets}
|
||||
</head>
|
||||
<body>
|
||||
|
|
162
src/initdata.js
162
src/initdata.js
|
@ -3,7 +3,14 @@ import fs from 'node:fs/promises';
|
|||
await fs.rm('./.output/data', { recursive: true, force: true });
|
||||
await fs.mkdir('./.output/data', { recursive: true });
|
||||
|
||||
const initServerData = async () => {
|
||||
/**
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
const fetchServerList = async () => {
|
||||
/** @type Set<string> */
|
||||
const servers = new Set();
|
||||
|
||||
// Fetch Mbin servers from fediverse.observer
|
||||
const fediverseObserver = await (
|
||||
await fetch('https://api.fediverse.observer/', {
|
||||
body: '{"query":"{nodes(softwarename:\\"mbin\\" status: \\"UP\\"){domain}}"}',
|
||||
|
@ -11,65 +18,118 @@ const initServerData = async () => {
|
|||
})
|
||||
).json();
|
||||
|
||||
/** @type string[] */
|
||||
const servers = fediverseObserver.data.nodes.map((v) => v.domain);
|
||||
for (const server of fediverseObserver.data.nodes) {
|
||||
servers.add(server.domain);
|
||||
}
|
||||
|
||||
const serversJson = (
|
||||
await Promise.allSettled(
|
||||
servers.map(async (serverHost) => {
|
||||
console.log('START:', serverHost);
|
||||
// Fetch Mbin servers from fedidb.org. The api used below is not documented and is subject to change;
|
||||
// this is used due to the current publicized api not being sufficient for fetching Mbin server lists.
|
||||
// Once issue #3 (https://github.com/fedidb/issues/issues/3) is complete, then we can move to api v1.
|
||||
const fedidbCookies = (await fetch('https://fedidb.org')).headers
|
||||
.getSetCookie()
|
||||
.map((c) => c.split(';')[0]);
|
||||
|
||||
const jsonNodeInfo = await (
|
||||
await fetch(`https://${serverHost}/nodeinfo/2.1.json`)
|
||||
).json();
|
||||
const fedidbHeaders = {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'X-XSRF-TOKEN': decodeURIComponent(
|
||||
fedidbCookies
|
||||
.find((c) => c.startsWith('XSRF-TOKEN='))
|
||||
.substring('XSRF-TOKEN='.length),
|
||||
),
|
||||
Cookie: fedidbCookies.join('; '),
|
||||
};
|
||||
|
||||
if (jsonNodeInfo.software.name != 'mbin') {
|
||||
throw new Error(
|
||||
`${serverHost} software does not match mbin (skipped)`,
|
||||
);
|
||||
}
|
||||
let fedidbNextCursor = '';
|
||||
|
||||
const jsonApiInfo = await (
|
||||
await fetch(`https://${serverHost}/api/info`)
|
||||
).json();
|
||||
if (jsonApiInfo.websiteDomain != serverHost) {
|
||||
throw new Error(`${serverHost} api not setup correctly (skipped)`);
|
||||
}
|
||||
const jsonApiInstance = await (
|
||||
await fetch(`https://${serverHost}/api/instance`)
|
||||
).json();
|
||||
const jsonApiDefederated = await (
|
||||
await fetch(`https://${serverHost}/api/defederated`)
|
||||
).json();
|
||||
do {
|
||||
const fedidbServers = await (
|
||||
await fetch(
|
||||
`https://fedidb.org/api/web/network/software/servers${
|
||||
fedidbNextCursor ? `?cursor=` + fedidbNextCursor : ''
|
||||
}`,
|
||||
{
|
||||
headers: fedidbHeaders,
|
||||
body: '{"slug":"mbin"}',
|
||||
method: 'POST',
|
||||
},
|
||||
)
|
||||
).json();
|
||||
|
||||
console.log('FINISH:', serverHost);
|
||||
for (const server of fedidbServers.data) {
|
||||
servers.add(server.domain);
|
||||
}
|
||||
|
||||
/** @type import('./routes/servers').Server */
|
||||
const server = {
|
||||
domain: serverHost,
|
||||
version: jsonNodeInfo.software.version,
|
||||
name: jsonNodeInfo.metadata.nodeName,
|
||||
description: jsonNodeInfo.metadata.nodeDescription,
|
||||
openRegistrations: jsonNodeInfo.openRegistrations,
|
||||
federationEnabled: jsonApiInfo.websiteFederationEnabled,
|
||||
language: jsonApiInfo.websiteDefaultLang ?? 'en',
|
||||
contactEmail: jsonApiInfo.websiteContactEmail,
|
||||
totalUsers: jsonNodeInfo.usage.users.total,
|
||||
activeHalfyearUsers: jsonNodeInfo.usage.users.activeHalfyear,
|
||||
activeMonthUsers: jsonNodeInfo.usage.users.activeMonth,
|
||||
localPosts: jsonNodeInfo.usage.localPosts,
|
||||
localComments: jsonNodeInfo.usage.localComments,
|
||||
pages: jsonApiInstance,
|
||||
defederated: jsonApiDefederated.instances ?? [],
|
||||
};
|
||||
fedidbNextCursor = fedidbServers.meta.next_cursor;
|
||||
} while (fedidbNextCursor);
|
||||
|
||||
return server;
|
||||
}),
|
||||
)
|
||||
)
|
||||
.filter((v) => v.status == 'fulfilled')
|
||||
return [...servers];
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} domain
|
||||
* @returns {Promise<import('./routes/servers').Server>}
|
||||
*/
|
||||
const fetchServerInfo = async (domain) => {
|
||||
console.log('START:', domain);
|
||||
|
||||
const jsonNodeInfo = await (
|
||||
await fetch(`https://${domain}/nodeinfo/2.1.json`)
|
||||
).json();
|
||||
|
||||
if (jsonNodeInfo.software.name != 'mbin') {
|
||||
throw new Error(`${domain} software does not match mbin (skipped)`);
|
||||
}
|
||||
|
||||
const jsonApiInfo = await (await fetch(`https://${domain}/api/info`)).json();
|
||||
if (jsonApiInfo.websiteDomain != domain) {
|
||||
throw new Error(`${domain} api not setup correctly (skipped)`);
|
||||
}
|
||||
const jsonApiInstance = await (
|
||||
await fetch(`https://${domain}/api/instance`)
|
||||
).json();
|
||||
const jsonApiDefederated = await (
|
||||
await fetch(`https://${domain}/api/defederated`)
|
||||
).json();
|
||||
|
||||
console.log('FINISH:', domain);
|
||||
|
||||
return {
|
||||
domain: domain,
|
||||
version: jsonNodeInfo.software.version,
|
||||
name: jsonNodeInfo.metadata.nodeName,
|
||||
description: jsonNodeInfo.metadata.nodeDescription,
|
||||
openRegistrations: jsonNodeInfo.openRegistrations,
|
||||
federationEnabled: jsonApiInfo.websiteFederationEnabled,
|
||||
language: jsonApiInfo.websiteDefaultLang ?? 'en',
|
||||
contactEmail: jsonApiInfo.websiteContactEmail,
|
||||
totalUsers: jsonNodeInfo.usage.users.total,
|
||||
activeHalfyearUsers: jsonNodeInfo.usage.users.activeHalfyear,
|
||||
activeMonthUsers: jsonNodeInfo.usage.users.activeMonth,
|
||||
localPosts: jsonNodeInfo.usage.localPosts,
|
||||
localComments: jsonNodeInfo.usage.localComments,
|
||||
pages: jsonApiInstance,
|
||||
defederated: jsonApiDefederated.instances ?? [],
|
||||
};
|
||||
};
|
||||
|
||||
const initServerData = async () => {
|
||||
const servers = await fetchServerList();
|
||||
|
||||
const serversJson = (await Promise.allSettled(servers.map(fetchServerInfo)))
|
||||
.filter((v) => {
|
||||
const isOk = v.status == 'fulfilled';
|
||||
|
||||
if (!isOk) {
|
||||
console.error(v.reason);
|
||||
}
|
||||
|
||||
return isOk;
|
||||
})
|
||||
.map((v) => v.value);
|
||||
|
||||
console.log('Successful Mbin servers found:', serversJson.length);
|
||||
|
||||
fs.writeFile(
|
||||
'./.output/data/servers.json',
|
||||
JSON.stringify(serversJson),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { ClassValue } from "clsx"
|
||||
import { clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import type { ClassValue } from 'clsx';
|
||||
import { clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ export default function Home() {
|
|||
Mbin
|
||||
</h1>
|
||||
<p class="my-10 text-2xl text-gray-400 block mx-auto">
|
||||
a federated content aggregator, voting, discussion and microblogging
|
||||
A federated content aggregator, voting, discussion and microblogging
|
||||
platform
|
||||
<br />
|
||||
(By the community, for the community)
|
||||
|
|
Loading…
Add table
Reference in a new issue