refactor: remove note.mentionedRemoteUsers column

The column mentionedRemoteUsers on the note table in the database is
firstly in the wrong type since it contains JSON data but is typed as
text. Secondly it seems redundant, since that data can be acquired by
using the note.mentions column to fetch the respective data instead.

Co-authored-by: Francis Dinh <normandy@biribiri.dev>
This commit is contained in:
Johann150 2022-08-24 23:57:34 +02:00 committed by naskya
parent 9bce737f67
commit 65797a934a
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
6 changed files with 50 additions and 64 deletions

View file

@ -0,0 +1,20 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class RemoveMentionedUsersColumn1710688552234
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "note" DROP COLUMN "mentionedRemoteUsers"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "note" ADD "mentionedRemoteUsers" TEXT NOT NULL DEFAULT '[]'::text`,
);
await queryRunner.query(
`UPDATE "note" SET "mentionedRemoteUsers" = (SELECT COALESCE(json_agg(row_to_json("data"))::text, '[]') FROM (SELECT "url", "uri", "username", "host" FROM "user" JOIN "user_profile" ON "user"."id" = "user_profile". "userId" WHERE "user"."host" IS NOT NULL AND "user"."id" = ANY("note"."mentions")) AS "data")`,
);
}
}

View file

@ -172,12 +172,6 @@ export class Note {
})
public mentions: User["id"][];
// FIXME: WHAT IS THIS
@Column("text", {
default: "[]",
})
public mentionedRemoteUsers: string;
@Column("varchar", {
length: 128,
array: true,
@ -307,10 +301,3 @@ export class Note {
}
}
}
export type IMentionedRemoteUsers = {
uri: string;
url?: string;
username: string;
host: string;
}[];

View file

@ -1,6 +1,6 @@
import { In, IsNull } from "typeorm";
import config from "@/config/index.js";
import type { Note, IMentionedRemoteUsers } from "@/models/entities/note.js";
import type { Note } from "@/models/entities/note.js";
import type { DriveFile } from "@/models/entities/drive-file.js";
import { DriveFiles, Notes, Users, Emojis, Polls } from "@/models/index.js";
import type { Emoji } from "@/models/entities/emoji.js";
@ -61,26 +61,6 @@ export default async function renderNote(
const attributedTo = `${config.url}/users/${note.userId}`;
const mentions = (
JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers
).map((x) => x.uri);
let to: string[] = [];
let cc: string[] = [];
if (note.visibility === "public") {
to = ["https://www.w3.org/ns/activitystreams#Public"];
cc = [`${attributedTo}/followers`].concat(mentions);
} else if (note.visibility === "home") {
to = [`${attributedTo}/followers`];
cc = ["https://www.w3.org/ns/activitystreams#Public"].concat(mentions);
} else if (note.visibility === "followers") {
to = [`${attributedTo}/followers`];
cc = mentions;
} else {
to = mentions;
}
const mentionedUsers =
note.mentions.length > 0
? await Users.findBy({
@ -88,6 +68,27 @@ export default async function renderNote(
})
: [];
const mentionUris = mentionedUsers
// only remote users
.filter((user) => Users.isRemoteUser(user))
.map((user) => user.uri);
let to: string[] = [];
let cc: string[] = [];
if (note.visibility === "public") {
to = ["https://www.w3.org/ns/activitystreams#Public"];
cc = [`${attributedTo}/followers`].concat(mentionUris);
} else if (note.visibility === "home") {
to = [`${attributedTo}/followers`];
cc = ["https://www.w3.org/ns/activitystreams#Public"].concat(mentionUris);
} else if (note.visibility === "followers") {
to = [`${attributedTo}/followers`];
cc = mentionUris;
} else {
to = mentionUris;
}
const hashtagTags = (note.tags || []).map((tag) => renderHashtag(tag));
const mentionTags = mentionedUsers.map((u) => renderMention(u));

View file

@ -134,13 +134,6 @@ export async function createMessage(
userId: message.userId,
visibility: "specified",
mentions: [recipientUser].map((u) => u.id),
mentionedRemoteUsers: JSON.stringify(
[recipientUser].map((u) => ({
uri: u.uri,
username: u.username,
host: u.host,
})),
),
} as Note;
let renderedNote: Record<string, unknown> = await renderNote(

View file

@ -18,7 +18,6 @@ import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instanc
import { extractMentions } from "@/misc/extract-mentions.js";
import { extractCustomEmojisFromMfm } from "@/misc/extract-custom-emojis-from-mfm.js";
import { extractHashtags } from "@/misc/extract-hashtags.js";
import type { IMentionedRemoteUsers } from "@/models/entities/note.js";
import { Note } from "@/models/entities/note.js";
import {
Mutings,
@ -751,21 +750,6 @@ async function insertNote(
// Append mentions data
if (mentionedUsers.length > 0) {
insert.mentions = mentionedUsers.map((u) => u.id);
const profiles = await UserProfiles.findBy({ userId: In(insert.mentions) });
insert.mentionedRemoteUsers = JSON.stringify(
mentionedUsers
.filter((u) => Users.isRemoteUser(u))
.map((u) => {
const profile = profiles.find((p) => p.userId === u.id);
const url = profile != null ? profile.url : null;
return {
uri: u.uri,
url: url == null ? undefined : url,
username: u.username,
host: u.host,
} as IMentionedRemoteUsers[0];
}),
);
}
// 投稿を作成

View file

@ -1,4 +1,4 @@
import { Brackets, In } from "typeorm";
import { Brackets, In, IsNull, Not } from "typeorm";
import { publishNoteStream } from "@/services/stream.js";
import renderDelete from "@/remote/activitypub/renderer/delete.js";
import renderAnnounce from "@/remote/activitypub/renderer/announce.js";
@ -7,7 +7,7 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js";
import renderTombstone from "@/remote/activitypub/renderer/tombstone.js";
import config from "@/config/index.js";
import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js";
import type { Note, IMentionedRemoteUsers } from "@/models/entities/note.js";
import type { Note } from "@/models/entities/note.js";
import { Notes, Users, Instances } from "@/models/index.js";
import {
deliverToFollowers,
@ -147,11 +147,12 @@ async function getMentionedRemoteUsers(note: Note) {
const where = [] as any[];
// mention / reply / dm
const uris = (
JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers
).map((x) => x.uri);
if (uris.length > 0) {
where.push({ uri: In(uris) });
if (note.mentions.length > 0) {
where.push({
id: In(note.mentions),
// only remote users, local users are on the server and do not need to be notified
host: Not(IsNull()),
});
}
// renote / quote