From 99aa588ae74ed0440bbe5d2bc14ec59f33b2d4f6 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 22 Oct 2018 04:44:10 +0900 Subject: [PATCH] Implement per user drive stats --- src/services/drive/add-file.ts | 3 +- src/services/drive/delete-file.ts | 3 +- src/services/stats.ts | 100 ++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/services/drive/add-file.ts b/src/services/drive/add-file.ts index 830f5e043..77ee70db5 100644 --- a/src/services/drive/add-file.ts +++ b/src/services/drive/add-file.ts @@ -17,7 +17,7 @@ import { isLocalUser, IUser, IRemoteUser } from '../../models/user'; import delFile from './delete-file'; import config from '../../config'; import { getDriveFileThumbnailBucket } from '../../models/drive-file-thumbnail'; -import { driveStats } from '../stats'; +import { driveStats, perUserDriveStats } from '../stats'; const log = debug('misskey:drive:add-file'); @@ -394,6 +394,7 @@ export default async function( // 統計を更新 driveStats.update(driveFile, true); + perUserDriveStats.update(driveFile, true); return driveFile; } diff --git a/src/services/drive/delete-file.ts b/src/services/drive/delete-file.ts index e6aa1a064..761a5d6d4 100644 --- a/src/services/drive/delete-file.ts +++ b/src/services/drive/delete-file.ts @@ -2,7 +2,7 @@ import * as Minio from 'minio'; import DriveFile, { DriveFileChunk, IDriveFile } from '../../models/drive-file'; import DriveFileThumbnail, { DriveFileThumbnailChunk } from '../../models/drive-file-thumbnail'; import config from '../../config'; -import { driveStats } from '../stats'; +import { driveStats, perUserDriveStats } from '../stats'; export default async function(file: IDriveFile, isExpired = false) { if (file.metadata.storage == 'minio') { @@ -49,4 +49,5 @@ export default async function(file: IDriveFile, isExpired = false) { // 統計を更新 driveStats.update(file, false); + perUserDriveStats.update(file, false); } diff --git a/src/services/stats.ts b/src/services/stats.ts index 2a2dc848a..558e1786d 100644 --- a/src/services/stats.ts +++ b/src/services/stats.ts @@ -911,3 +911,103 @@ class PerUserNotesStats extends Stats { export const perUserNotesStats = new PerUserNotesStats(); //#endregion + +//#region Per user drive stats +/** + * ユーザーごとのドライブに関する統計 + */ +type PerUserDriveLog = { + /** + * 集計期間時点での、全ドライブファイル数 + */ + totalCount: number; + + /** + * 集計期間時点での、全ドライブファイルの合計サイズ + */ + totalSize: number; + + /** + * 増加したドライブファイル数 + */ + incCount: number; + + /** + * 増加したドライブ使用量 + */ + incSize: number; + + /** + * 減少したドライブファイル数 + */ + decCount: number; + + /** + * 減少したドライブ使用量 + */ + decSize: number; +}; + +class PerUserDriveStats extends Stats { + constructor() { + super('perUserDrive', true); + } + + @autobind + protected async getTemplate(init: boolean, latest?: PerUserDriveLog, group?: any): Promise { + const calcSize = () => DriveFile + .aggregate([{ + $match: { + 'metadata.userId': group, + 'metadata.deletedAt': { $exists: false } + } + }, { + $project: { + length: true + } + }, { + $group: { + _id: null, + usage: { $sum: '$length' } + } + }]) + .then(res => res.length > 0 ? res[0].usage : 0); + + const [count, size] = init ? await Promise.all([ + DriveFile.count({ 'metadata.userId': group }), + calcSize() + ]) : [ + latest ? latest.totalCount : 0, + latest ? latest.totalSize : 0 + ]; + + return { + totalCount: count, + totalSize: size, + incCount: 0, + incSize: 0, + decCount: 0, + decSize: 0 + }; + } + + @autobind + public async update(file: IDriveFile, isAdditional: boolean) { + const update: Obj = {}; + + update.totalCount = isAdditional ? 1 : -1; + update.totalSize = isAdditional ? file.length : -file.length; + if (isAdditional) { + update.incCount = 1; + update.incSize = file.length; + } else { + update.decCount = 1; + update.decSize = file.length; + } + + await this.inc(update, file.metadata.userId); + } +} + +export const perUserDriveStats = new PerUserDriveStats(); +//#endregion