wip: auto note removal
This commit is contained in:
parent
f30c95e51a
commit
74c7b5fe70
12 changed files with 270 additions and 2 deletions
|
@ -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.');
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue