refactor: remove note.mentionedRemoteUsers column
All checks were successful
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/push/lint-foundkey-js Pipeline was successful
ci/woodpecker/push/lint-backend Pipeline was successful
ci/woodpecker/push/lint-client Pipeline was successful
ci/woodpecker/push/test Pipeline was successful

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
parent 3bdbbcadd9
commit 7a981de883
Signed by: Johann150
GPG key ID: 9EE6577A2A06F8F1
6 changed files with 34 additions and 45 deletions

View file

@ -0,0 +1,12 @@
export class removeMentionedRemoteUsersColumn1661376843000 {
name = 'removeMentionedRemoteUsersColumn1661376843000';
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "mentionedRemoteUsers"`);
}
async down(queryRunner) {
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

@ -155,11 +155,6 @@ export class Note {
})
public mentions: User['id'][];
@Column('text', {
default: '[]',
})
public mentionedRemoteUsers: string;
@Column('varchar', {
length: 128, array: true, default: '{}',
})
@ -233,10 +228,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 { Note, IMentionedRemoteUsers } from '@/models/entities/note.js';
import { Note } from '@/models/entities/note.js';
import { DriveFile } from '@/models/entities/drive-file.js';
import { DriveFiles, Notes, Users, Emojis, Polls } from '@/models/index.js';
import { Emoji } from '@/models/entities/emoji.js';
@ -55,28 +55,31 @@ export default async function renderNote(note: Note, dive = true, isTalk = false
const attributedTo = `${config.url}/users/${note.userId}`;
const mentions = (JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers).map(x => x.uri);
const mentionedUsers = note.mentions.length > 0 ? await Users.findBy({
id: In(note.mentions),
}) : [];
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(mentions);
cc = [`${attributedTo}/followers`].concat(mentionUris);
} else if (note.visibility === 'home') {
to = [`${attributedTo}/followers`];
cc = ['https://www.w3.org/ns/activitystreams#Public'].concat(mentions);
cc = ['https://www.w3.org/ns/activitystreams#Public'].concat(mentionUris);
} else if (note.visibility === 'followers') {
to = [`${attributedTo}/followers`];
cc = mentions;
cc = mentionUris;
} else {
to = mentions;
to = mentionUris;
}
const mentionedUsers = note.mentions.length > 0 ? await Users.findBy({
id: In(note.mentions),
}) : [];
const hashtagTags = (note.tags || []).map(tag => renderHashtag(tag));
const mentionTags = mentionedUsers.map(u => renderMention(u));

View file

@ -93,11 +93,6 @@ export async function createMessage(user: { id: User['id']; host: User['host'];
userId: message.userId,
visibility: 'specified',
mentions: [ recipientUser.id ],
mentionedRemoteUsers: JSON.stringify([ recipientUser ].map(u => ({
uri: u.uri,
username: u.username,
host: u.host,
}))),
} as Note;
const activity = renderActivity(renderCreate(await renderNote(note, false, true), note));

View file

@ -15,7 +15,7 @@ import { insertNoteUnread } from '@/services/note/unread.js';
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 { Note, IMentionedRemoteUsers } from '@/models/entities/note.js';
import { Note } from '@/models/entities/note.js';
import { Mutings, Users, NoteWatchings, Notes, Instances, UserProfiles, MutedNotes, Channels, ChannelFollowings, NoteThreadMutings } from '@/models/index.js';
import { DriveFile } from '@/models/entities/drive-file.js';
import { App } from '@/models/entities/app.js';
@ -537,16 +537,6 @@ async function insertNote(user: { id: User['id']; host: User['host']; }, data: O
// 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);
return {
uri: u.uri,
url: profile?.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 { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js';
import { Note, IMentionedRemoteUsers } from '@/models/entities/note.js';
import { Note } from '@/models/entities/note.js';
import { Notes, Users, Instances } from '@/models/index.js';
import { notesChart, perUserNotesChart, instanceChart } from '@/services/chart/index.js';
import { deliverToFollowers, deliverToUser } from '@/remote/activitypub/deliver-manager.js';
@ -109,11 +109,12 @@ async function getMentionedRemoteUsers(note: Note): Promise<IRemoteUser[]> {
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 > 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