mirror of
https://iceshrimp.dev/limepotato/jormungandr-bite.git
synced 2024-11-25 11:27:31 -07:00
[mastodon-client] GET /v1/instance
This commit is contained in:
parent
c90161189f
commit
2a64fe4ebf
3 changed files with 88 additions and 91 deletions
|
@ -1,70 +0,0 @@
|
|||
import { Entity } from "megalodon";
|
||||
import config from "@/config/index.js";
|
||||
import { fetchMeta } from "@/misc/fetch-meta.js";
|
||||
import { Notes, Users } from "@/models/index.js";
|
||||
import { IsNull } from "typeorm";
|
||||
import { FILE_TYPE_BROWSERSAFE, MAX_NOTE_TEXT_LENGTH } from "@/const.js";
|
||||
|
||||
// TODO: add iceshrimp features
|
||||
export async function getInstance(
|
||||
response: Entity.Instance,
|
||||
contact: Entity.Account,
|
||||
) {
|
||||
const [meta, totalUsers, totalStatuses] = await Promise.all([
|
||||
fetchMeta(true),
|
||||
Users.count({where: {host: IsNull()}}),
|
||||
Notes.count({where: {userHost: IsNull()}}),
|
||||
]);
|
||||
|
||||
return {
|
||||
uri: response.uri,
|
||||
title: response.title || "Iceshrimp",
|
||||
short_description:
|
||||
response.description?.substring(0, 50) || "See real server website",
|
||||
description:
|
||||
response.description ||
|
||||
"This is a vanilla Iceshrimp Instance. It doesn't seem to have a description.",
|
||||
email: response.email || "",
|
||||
version: `4.1.0 (compatible; Iceshrimp ${config.version})`,
|
||||
urls: response.urls,
|
||||
stats: {
|
||||
user_count: await totalUsers,
|
||||
status_count: await totalStatuses,
|
||||
domain_count: response.stats.domain_count,
|
||||
},
|
||||
thumbnail: response.thumbnail || "/static-assets/transparent.png",
|
||||
languages: meta.langs,
|
||||
registrations: !meta.disableRegistration || response.registrations,
|
||||
approval_required: !response.registrations,
|
||||
invites_enabled: response.registrations,
|
||||
configuration: {
|
||||
accounts: {
|
||||
max_featured_tags: 20,
|
||||
},
|
||||
statuses: {
|
||||
max_characters: MAX_NOTE_TEXT_LENGTH,
|
||||
max_media_attachments: 16,
|
||||
characters_reserved_per_url: response.uri.length,
|
||||
},
|
||||
media_attachments: {
|
||||
supported_mime_types: FILE_TYPE_BROWSERSAFE,
|
||||
image_size_limit: 10485760,
|
||||
image_matrix_limit: 16777216,
|
||||
video_size_limit: 41943040,
|
||||
video_frame_rate_limit: 60,
|
||||
video_matrix_limit: 2304000,
|
||||
},
|
||||
polls: {
|
||||
max_options: 10,
|
||||
max_characters_per_option: 50,
|
||||
min_expiration: 50,
|
||||
max_expiration: 2629746,
|
||||
},
|
||||
reactions: {
|
||||
max_reactions: 1,
|
||||
},
|
||||
},
|
||||
contact_account: contact,
|
||||
rules: [],
|
||||
};
|
||||
}
|
|
@ -5,6 +5,7 @@ import { convertAccount, convertAnnouncement, convertFilter } from "@/server/api
|
|||
import { Users } from "@/models/index.js";
|
||||
import { getInstance } from "@/server/api/mastodon/endpoints/meta.js";
|
||||
import { IsNull } from "typeorm";
|
||||
import { MiscHelpers } from "@/server/api/mastodon/helpers/misc.js";
|
||||
|
||||
export function setupEndpointsMisc(router: Router): void {
|
||||
router.get("/v1/custom_emojis", async (ctx) => {
|
||||
|
@ -22,30 +23,12 @@ export function setupEndpointsMisc(router: Router): void {
|
|||
});
|
||||
|
||||
router.get("/v1/instance", async (ctx) => {
|
||||
const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
|
||||
const accessTokens = ctx.request.headers.authorization;
|
||||
const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
|
||||
// displayed without being logged in
|
||||
try {
|
||||
const data = await client.getInstance();
|
||||
const admin = await Users.findOne({
|
||||
where: {
|
||||
host: IsNull(),
|
||||
isAdmin: true,
|
||||
isDeleted: false,
|
||||
isSuspended: false,
|
||||
},
|
||||
order: {id: "ASC"},
|
||||
});
|
||||
const contact =
|
||||
admin == null
|
||||
? null
|
||||
: convertAccount((await client.getAccount(admin.id)).data);
|
||||
ctx.body = await getInstance(data.data, contact);
|
||||
ctx.body = await MiscHelpers.getInstance();
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
ctx.status = 401;
|
||||
ctx.body = e.response.data;
|
||||
ctx.status = 500;
|
||||
ctx.body = { error: e.message };
|
||||
}
|
||||
});
|
||||
|
||||
|
|
84
packages/backend/src/server/api/mastodon/helpers/misc.ts
Normal file
84
packages/backend/src/server/api/mastodon/helpers/misc.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
import config from "@/config/index.js";
|
||||
import { FILE_TYPE_BROWSERSAFE, MAX_NOTE_TEXT_LENGTH } from "@/const.js";
|
||||
import { fetchMeta } from "@/misc/fetch-meta.js";
|
||||
import { Instances, Notes, Users } from "@/models/index.js";
|
||||
import { IsNull } from "typeorm";
|
||||
import { awaitAll } from "@/prelude/await-all.js";
|
||||
import { UserConverter } from "@/server/api/mastodon/converters/user.js";
|
||||
import { convertAccount } from "@/server/api/mastodon/converters.js";
|
||||
|
||||
export class MiscHelpers {
|
||||
public static async getInstance(): Promise<MastodonEntity.Instance> {
|
||||
const userCount = Users.count({where: {host: IsNull()}});
|
||||
const noteCount = Notes.count({where: {userHost: IsNull()}});
|
||||
const instanceCount = Instances.count({ cache: 3600000 });
|
||||
const contact = await Users.findOne({
|
||||
where: {
|
||||
host: IsNull(),
|
||||
isAdmin: true,
|
||||
isDeleted: false,
|
||||
isSuspended: false,
|
||||
},
|
||||
order: {id: "ASC"},
|
||||
})
|
||||
.then(p => p ? UserConverter.encode(p) : null)
|
||||
.then(p => p ? convertAccount(p) : null);
|
||||
const meta = await fetchMeta(true);
|
||||
|
||||
const res = {
|
||||
uri: config.domain,
|
||||
title: meta.name || "Iceshrimp",
|
||||
short_description:
|
||||
meta.description?.substring(0, 50) || "This is an Iceshrimp instance. It doesn't seem to have a description.",
|
||||
description:
|
||||
meta.description ||
|
||||
"This is an Iceshrimp instance. It doesn't seem to have a description.",
|
||||
email: meta.maintainerEmail || "",
|
||||
version: `4.1.0 (compatible; Iceshrimp ${config.version})`,
|
||||
urls: {
|
||||
streaming_api: `${config.url.replace(/^http(?=s?:\/\/)/, "ws")}/streaming`,
|
||||
},
|
||||
stats: awaitAll({
|
||||
user_count: userCount,
|
||||
status_count: noteCount,
|
||||
domain_count: instanceCount,
|
||||
}),
|
||||
thumbnail: meta.bannerUrl || "/static-assets/transparent.png",
|
||||
languages: meta.langs,
|
||||
registrations: !meta.disableRegistration,
|
||||
approval_required: meta.disableRegistration,
|
||||
invites_enabled: meta.disableRegistration,
|
||||
configuration: {
|
||||
accounts: {
|
||||
max_featured_tags: 20,
|
||||
},
|
||||
statuses: {
|
||||
max_characters: MAX_NOTE_TEXT_LENGTH,
|
||||
max_media_attachments: 16,
|
||||
characters_reserved_per_url: 23,
|
||||
},
|
||||
media_attachments: {
|
||||
supported_mime_types: FILE_TYPE_BROWSERSAFE,
|
||||
image_size_limit: 10485760,
|
||||
image_matrix_limit: 16777216,
|
||||
video_size_limit: 41943040,
|
||||
video_frame_limit: 60,
|
||||
video_matrix_limit: 2304000,
|
||||
},
|
||||
polls: {
|
||||
max_options: 10,
|
||||
max_characters_per_option: 50,
|
||||
min_expiration: 50,
|
||||
max_expiration: 2629746,
|
||||
},
|
||||
reactions: {
|
||||
max_reactions: 1,
|
||||
},
|
||||
},
|
||||
contact_account: contact,
|
||||
rules: [],
|
||||
};
|
||||
|
||||
return awaitAll(res);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue