wip: auto note removal

This commit is contained in:
아르페 2024-02-16 06:41:21 +09:00 committed by 무라쿠모
parent f30c95e51a
commit 74c7b5fe70
No known key found for this signature in database
GPG key ID: 139D6573F92DA9F7
12 changed files with 270 additions and 2 deletions

View file

@ -0,0 +1,106 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey, cherrypick contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import { And, In, MoreThan, Not } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { MiUserNotePining, NotesRepository, UserNotePiningsRepository, UsersRepository } from '@/models/_.js';
import type Logger from '@/logger.js';
import type { MiNote } from '@/models/Note.js';
import { bindThis } from '@/decorators.js';
import { NoteDeleteService } from '@/core/NoteDeleteService.js';
import { IdService } from '@/core/IdService.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
@Injectable()
export class AutoNoteRemovalProcessorService {
private logger: Logger;
constructor(
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
private usersRepository: UsersRepository,
private userNotePiningsRepository: UserNotePiningsRepository,
private idService: IdService,
private noteDeleteService: NoteDeleteService,
private queueLoggerService: QueueLoggerService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('auto-note-removal');
}
@bindThis
public async process(): Promise<void> {
this.logger.info('Checking notes that to remove automatically...');
this.logger.info('Checking users that enabled note auto-removal');
const users = await this.usersRepository.find({ where: { autoRemoval: true } });
if (users.length < 1) {
this.logger.info('Does not have any user that enabled autoRemoval');
return;
}
const now = Date.now();
for (const user of users) {
if (user.autoRemovalCondition === null) {
continue;
}
const pinings: MiUserNotePining[] = await this.userNotePiningsRepository.findBy({ userId: user.id });
const piningNoteIds: string[] = pinings.map(pining => pining.noteId); // pining.note always undefined (bug?)
const specifiedNotes: MiNote[] = await this.notesRepository.findBy({
userId: user.id,
visibility: Not(In(['public', 'home', 'followers'])),
});
const specifiedNoteIds: string[] = specifiedNotes.map(note => note.id);
const deleteAfter: number = user.autoRemovalCondition.deleteAfter * 86400000;
// Delete notes
let cursor: MiNote['id'] | null = null;
let condition: string[] = [];
if (user.autoRemovalCondition.noSpecifiedNotes === true) {
condition = [...condition, ...specifiedNoteIds];
}
if (user.autoRemovalCondition.noPiningNotes === true) {
condition = [...condition, ...piningNoteIds];
}
while (true) {
const notes = await this.notesRepository.find({
where: {
userId: user.id,
...(cursor ? {
id: And(Not(In(condition)), MoreThan(cursor)),
} : {
id: Not(In(condition)),
}),
},
take: 100,
order: {
id: 1,
},
}) as MiNote[];
if (notes.length === 0) {
break;
}
cursor = notes.at(-1)?.id ?? null;
for (const note of notes) {
const createdAt: number = this.idService.parse(note.id).date.getTime();
const delta: number = now - createdAt;
if (delta > deleteAfter) {
await Promise.bind(this.noteDeleteService.delete(user, note, false, user));
}
}
}
this.logger.succ('All of auto-removable notes deleted');
}
this.logger.succ('All notes to auto-remove has beed removed.');
}
}