enhance: 使われてないアンテナは自動停止されるように

Resolve #9373
This commit is contained in:
syuilo 2023-03-20 20:12:38 +09:00
parent eb5781465b
commit 54630edb0f
9 changed files with 59 additions and 4 deletions

View file

@ -22,6 +22,7 @@
- ロールの並び順を設定可能に - ロールの並び順を設定可能に
- カスタム絵文字にライセンス情報を付与できるように - カスタム絵文字にライセンス情報を付与できるように
- 指定した文字列を含む投稿の公開範囲をホームにできるように - 指定した文字列を含む投稿の公開範囲をホームにできるように
- 使われてないアンテナは自動停止されるように
### Client ### Client
- 設定から自分のロールを確認できるように - 設定から自分のロールを確認できるように

View file

@ -0,0 +1,17 @@
export class antennaActive1679309757174 {
name = 'antennaActive1679309757174'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "antenna" ADD "lastUsedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT 'now'`);
await queryRunner.query(`ALTER TABLE "antenna" ADD "isActive" boolean NOT NULL DEFAULT true`);
await queryRunner.query(`CREATE INDEX "IDX_084c2abb8948ef59a37dce6ac1" ON "antenna" ("lastUsedAt") `);
await queryRunner.query(`CREATE INDEX "IDX_36ef5192a1ce55ed0e40aa4db5" ON "antenna" ("isActive") `);
}
async down(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_36ef5192a1ce55ed0e40aa4db5"`);
await queryRunner.query(`DROP INDEX "public"."IDX_084c2abb8948ef59a37dce6ac1"`);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "isActive"`);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "lastUsedAt"`);
}
}

View file

@ -71,12 +71,14 @@ export class AntennaService implements OnApplicationShutdown {
this.antennas.push({ this.antennas.push({
...body, ...body,
createdAt: new Date(body.createdAt), createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt),
}); });
break; break;
case 'antennaUpdated': case 'antennaUpdated':
this.antennas[this.antennas.findIndex(a => a.id === body.id)] = { this.antennas[this.antennas.findIndex(a => a.id === body.id)] = {
...body, ...body,
createdAt: new Date(body.createdAt), createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt),
}; };
break; break;
case 'antennaDeleted': case 'antennaDeleted':
@ -217,7 +219,9 @@ export class AntennaService implements OnApplicationShutdown {
@bindThis @bindThis
public async getAntennas() { public async getAntennas() {
if (!this.antennasFetched) { if (!this.antennasFetched) {
this.antennas = await this.antennasRepository.find(); this.antennas = await this.antennasRepository.findBy({
isActive: true,
});
this.antennasFetched = true; this.antennasFetched = true;
} }

View file

@ -37,6 +37,7 @@ export class AntennaEntityService {
notify: antenna.notify, notify: antenna.notify,
withReplies: antenna.withReplies, withReplies: antenna.withReplies,
withFile: antenna.withFile, withFile: antenna.withFile,
isActive: antenna.isActive,
hasUnreadNote, hasUnreadNote,
}; };
} }

View file

@ -13,6 +13,10 @@ export class Antenna {
}) })
public createdAt: Date; public createdAt: Date;
@Index()
@Column('timestamp with time zone')
public lastUsedAt: Date;
@Index() @Index()
@Column({ @Column({
...id(), ...id(),
@ -83,4 +87,10 @@ export class Antenna {
@Column('boolean') @Column('boolean')
public notify: boolean; public notify: boolean;
@Index()
@Column('boolean', {
default: true,
})
public isActive: boolean;
} }

View file

@ -75,6 +75,10 @@ export const packedAntennaSchema = {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
}, },
isActive: {
type: 'boolean',
optional: false, nullable: false,
},
hasUnreadNote: { hasUnreadNote: {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,

View file

@ -1,7 +1,7 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { In, LessThan } from 'typeorm'; import { In, LessThan } from 'typeorm';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { AntennaNotesRepository, MutedNotesRepository, NotificationsRepository, RoleAssignmentsRepository, UserIpsRepository } from '@/models/index.js'; import type { AntennaNotesRepository, AntennasRepository, MutedNotesRepository, NotificationsRepository, RoleAssignmentsRepository, UserIpsRepository } from '@/models/index.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import type Logger from '@/logger.js'; import type Logger from '@/logger.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
@ -26,6 +26,9 @@ export class CleanProcessorService {
@Inject(DI.mutedNotesRepository) @Inject(DI.mutedNotesRepository)
private mutedNotesRepository: MutedNotesRepository, private mutedNotesRepository: MutedNotesRepository,
@Inject(DI.antennasRepository)
private antennasRepository: AntennasRepository,
@Inject(DI.antennaNotesRepository) @Inject(DI.antennaNotesRepository)
private antennaNotesRepository: AntennaNotesRepository, private antennaNotesRepository: AntennaNotesRepository,
@ -55,8 +58,16 @@ export class CleanProcessorService {
reason: 'word', reason: 'word',
}); });
this.antennaNotesRepository.delete({ this.mutedNotesRepository.delete({
id: LessThan(this.idService.genId(new Date(Date.now() - (1000 * 60 * 60 * 24 * 90)))), id: LessThan(this.idService.genId(new Date(Date.now() - (1000 * 60 * 60 * 24 * 90)))),
reason: 'word',
});
// 7日以上使われてないアンテナを停止
this.antennasRepository.update({
lastUsedAt: LessThan(new Date(Date.now() - (1000 * 60 * 60 * 24 * 7))),
}, {
isActive: false,
}); });
const expiredRoleAssignments = await this.roleAssignmentsRepository.createQueryBuilder('assign') const expiredRoleAssignments = await this.roleAssignmentsRepository.createQueryBuilder('assign')

View file

@ -103,9 +103,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
} }
} }
const now = new Date();
const antenna = await this.antennasRepository.insert({ const antenna = await this.antennasRepository.insert({
id: this.idService.genId(), id: this.idService.genId(),
createdAt: new Date(), createdAt: now,
lastUsedAt: now,
userId: me.id, userId: me.id,
name: ps.name, name: ps.name,
src: ps.src, src: ps.src,

View file

@ -101,6 +101,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
this.noteReadService.read(me.id, notes); this.noteReadService.read(me.id, notes);
} }
this.antennasRepository.update(antenna.id, {
lastUsedAt: new Date(),
});
return await this.noteEntityService.packMany(notes, me); return await this.noteEntityService.packMany(notes, me);
}); });
} }