[mastodon-client] Refactor converters

This commit is contained in:
Laura Hausmann 2023-09-15 12:14:36 +02:00
parent d258789c34
commit 2fe58b0017
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
6 changed files with 64 additions and 59 deletions

View file

@ -1,17 +1,19 @@
import { User } from "@/models/entities/user.js";
import config from "@/config/index.js";
export function convertMention(u: User): MastodonEntity.Mention {
let acct = u.username;
let acctUrl = `https://${u.host || config.host}/@${u.username}`;
if (u.host) {
acct = `${u.username}@${u.host}`;
acctUrl = `https://${u.host}/@${u.username}`;
}
return {
id: u.id,
username: u.username,
acct: acct,
url: u.uri ?? acctUrl,
};
export class MentionConverter {
public static encode(u: User): MastodonEntity.Mention {
let acct = u.username;
let acctUrl = `https://${u.host || config.host}/@${u.username}`;
if (u.host) {
acct = `${u.username}@${u.host}`;
acctUrl = `https://${u.host}/@${u.username}`;
}
return {
id: u.id,
username: u.username,
acct: acct,
url: u.uri ?? acctUrl,
};
}
}

View file

@ -4,14 +4,14 @@ import { Note } from "@/models/entities/note.js";
import config from "@/config/index.js";
import mfm from "mfm-js";
import { toHtml } from "@/mfm/to-html.js";
import { convertUser } from "@/server/api/mastodon/converters/user.js";
import { Visibility } from "@/server/api/mastodon/converters/visibility.js";
import { UserConverter } from "@/server/api/mastodon/converters/user.js";
import { VisibilityConverter } from "@/server/api/mastodon/converters/visibility.js";
import { escapeMFM } from "@/server/api/mastodon/converters/mfm.js";
import { populateEmojis } from "@/misc/populate-emojis.js";
import { EmojiConverter } from "@/server/api/mastodon/converters/emoji.js";
import { DriveFiles, NoteFavorites, NoteReactions, Notes, NoteThreadMutings } from "@/models/index.js";
import { decodeReaction } from "@/misc/reaction-lib.js";
import { convertMention } from "@/server/api/mastodon/converters/mention.js";
import { MentionConverter } from "@/server/api/mastodon/converters/mention.js";
import { PollConverter } from "@/server/api/mastodon/converters/poll.js";
import { populatePoll } from "@/models/repositories/note.js";
import { FileConverter } from "@/server/api/mastodon/converters/file.js";
@ -74,7 +74,7 @@ export class NoteConverter {
id: note.id,
uri: note.uri ? note.uri : `https://${config.host}/notes/${note.id}`,
url: note.uri ? note.uri : `https://${config.host}/notes/${note.id}`,
account: await convertUser(noteUser),
account: await UserConverter.encode(noteUser),
in_reply_to_id: note.replyId,
in_reply_to_account_id: reply?.userId ?? null,
reblog: note.renote ? await this.encode(note.renote, user) : null,
@ -93,9 +93,9 @@ export class NoteConverter {
muted: isMuted,
sensitive: files.length > 0 ? files.some((f) => f.isSensitive) : false,
spoiler_text: note.cw ? note.cw : "",
visibility: Visibility.encode(note.visibility),
visibility: VisibilityConverter.encode(note.visibility),
media_attachments: files.length > 0 ? files.map((f) => FileConverter.encode(f)) : [],
mentions: await Promise.all(note.mentions.map(async p => convertMention(await getUser(p)))),
mentions: await Promise.all(note.mentions.map(async p => MentionConverter.encode(await getUser(p)))),
tags: [], //FIXME
card: null, //FIXME
poll: note.hasPoll ? PollConverter.encode(await populatePoll(note, user.id), note.id) : null,

View file

@ -13,43 +13,46 @@ type Field = {
verified?: boolean;
};
export async function convertUser(u: User): Promise<MastodonEntity.Account> {
let acct = u.username;
let acctUrl = `https://${u.host || config.host}/@${u.username}`;
if (u.host) {
acct = `${u.username}@${u.host}`;
acctUrl = `https://${u.host}/@${u.username}`;
}
export class UserConverter {
public static async encode(u: User): Promise<MastodonEntity.Account> {
let acct = u.username;
let acctUrl = `https://${u.host || config.host}/@${u.username}`;
if (u.host) {
acct = `${u.username}@${u.host}`;
acctUrl = `https://${u.host}/@${u.username}`;
}
const profile = await UserProfiles.findOneBy({userId: u.id});
const bio = toHtml(mfm.parse(profile?.description ?? "")) ?? escapeMFM(profile?.description ?? "");
return {
id: u.id,
username: u.username,
acct: acct,
display_name: u.name || u.username,
locked: u.isLocked,
created_at: new Date().toISOString(),
followers_count: u.followersCount,
following_count: u.followingCount,
statuses_count: u.notesCount,
note: bio,
url: u.uri ?? acctUrl,
avatar: u.avatar?.url ?? Users.getIdenticonUrl(u.id),
avatar_static: u.avatar?.url ?? Users.getIdenticonUrl(u.id),
header: u.banner?.url ?? `${config.url}/static-assets/transparent.png`,
header_static: u.banner?.url ?? `${config.url}/static-assets/transparent.png`,
emojis: (await populateEmojis(u.emojis, u.host)).map((e) => EmojiConverter.encode(e)),
moved: null, //FIXME
fields: profile?.fields.map(p => convertField(p)) ?? [],
bot: u.isBot
};
}
function convertField(f: Field): MastodonEntity.Field {
return {
name: f.name,
value: toHtml(mfm.parse(f.value)) ?? escapeMFM(f.value),
verified_at: f.verified ? (new Date()).toISOString() : null,
return {
id: u.id,
username: u.username,
acct: acct,
display_name: u.name || u.username,
locked: u.isLocked,
created_at: new Date().toISOString(),
followers_count: u.followersCount,
following_count: u.followingCount,
statuses_count: u.notesCount,
note: bio,
url: u.uri ?? acctUrl,
avatar: u.avatar?.url ?? Users.getIdenticonUrl(u.id),
avatar_static: u.avatar?.url ?? Users.getIdenticonUrl(u.id),
header: u.banner?.url ?? `${config.url}/static-assets/transparent.png`,
header_static: u.banner?.url ?? `${config.url}/static-assets/transparent.png`,
emojis: (await populateEmojis(u.emojis, u.host)).map((e) => EmojiConverter.encode(e)),
moved: null, //FIXME
fields: profile?.fields.map(p => this.encodeField(p)) ?? [],
bot: u.isBot
};
}
private static encodeField(f: Field): MastodonEntity.Field {
return {
name: f.name,
value: toHtml(mfm.parse(f.value)) ?? escapeMFM(f.value),
verified_at: f.verified ? (new Date()).toISOString() : null,
}
}
}

View file

@ -1,7 +1,7 @@
type IceshrimpVisibility = "public" | "home" | "followers" | "specified" | "hidden";
type MastodonVisibility = "public" | "unlisted" | "private" | "direct";
export class Visibility {
export class VisibilityConverter {
public static encode (v: IceshrimpVisibility): MastodonVisibility {
switch (v) {
case "public":

View file

@ -13,7 +13,7 @@ import {
convertStatus,
} from "../converters.js";
import { getNote, getUser } from "@/server/api/common/getters.js";
import { convertUser } from "@/server/api/mastodon/converters/user.js";
import { UserConverter } from "@/server/api/mastodon/converters/user.js";
const relationshipModel = {
id: "",
@ -135,7 +135,7 @@ export function apiAccountMastodon(router: Router): void {
router.get<{ Params: { id: string } }>("/v1/accounts/:id", async (ctx) => {
try {
const userId = convertId(ctx.params.id, IdType.IceshrimpId);
const account = await convertUser(await getUser(userId));
const account = await UserConverter.encode(await getUser(userId));
ctx.body = convertAccount(account);
} catch (e: any) {
console.error(e);

View file

@ -12,8 +12,8 @@ import {
convertPoll,
convertStatus,
} from "../converters.js";
import {NoteConverter} from "@/server/api/mastodon/converters/note.js";
import {getNote} from "@/server/api/common/getters.js";
import { NoteConverter } from "@/server/api/mastodon/converters/note.js";
import { getNote } from "@/server/api/common/getters.js";
import authenticate from "@/server/api/authenticate.js";
import {Notes} from "@/models";