Sharkey/src/services/chart/drive.ts

151 lines
3.3 KiB
TypeScript
Raw Normal View History

2018-10-22 23:36:35 +03:00
import autobind from 'autobind-decorator';
import Chart, { Obj } from './';
import DriveFile, { IDriveFile } from '../../models/drive-file';
import { isLocalUser } from '../../models/user';
2019-02-24 10:28:51 +02:00
import { SchemaType } from '../../misc/schema';
2018-10-22 23:36:35 +03:00
2019-02-24 03:00:24 +02:00
const logSchema = {
/**
*
*/
totalCount: {
type: 'number' as 'number',
description: '集計期間時点での、全ドライブファイル数'
},
2018-10-22 23:36:35 +03:00
2019-02-24 03:00:24 +02:00
/**
*
*/
totalSize: {
type: 'number' as 'number',
description: '集計期間時点での、全ドライブファイルの合計サイズ'
},
2018-10-22 23:36:35 +03:00
2019-02-24 03:00:24 +02:00
/**
*
*/
incCount: {
type: 'number' as 'number',
description: '増加したドライブファイル数'
},
2018-10-22 23:36:35 +03:00
2019-02-24 03:00:24 +02:00
/**
* 使
*/
incSize: {
type: 'number' as 'number',
description: '増加したドライブ使用量'
},
2018-10-22 23:36:35 +03:00
2019-02-24 03:00:24 +02:00
/**
*
*/
decCount: {
type: 'number' as 'number',
description: '減少したドライブファイル数'
},
2018-10-22 23:36:35 +03:00
2019-02-24 03:00:24 +02:00
/**
* 使
*/
decSize: {
type: 'number' as 'number',
description: '減少したドライブ使用量'
},
};
2018-10-22 23:36:35 +03:00
2019-02-24 03:00:24 +02:00
export const driveLogSchema = {
type: 'object' as 'object',
properties: {
local: {
type: 'object' as 'object',
properties: logSchema
},
remote: {
type: 'object' as 'object',
properties: logSchema
},
}
2018-10-22 23:36:35 +03:00
};
2019-02-24 03:00:24 +02:00
type DriveLog = SchemaType<typeof driveLogSchema>;
2018-10-22 23:36:35 +03:00
class DriveChart extends Chart<DriveLog> {
constructor() {
super('drive');
}
@autobind
protected async getTemplate(init: boolean, latest?: DriveLog): Promise<DriveLog> {
const calcSize = (local: boolean) => DriveFile
.aggregate([{
$match: {
'metadata._user.host': local ? null : { $ne: null },
'metadata.deletedAt': { $exists: false }
}
}, {
$project: {
length: true
}
}, {
$group: {
_id: null,
usage: { $sum: '$length' }
}
}])
.then(res => res.length > 0 ? res[0].usage : 0);
const [localCount, remoteCount, localSize, remoteSize] = init ? await Promise.all([
DriveFile.count({ 'metadata._user.host': null }),
DriveFile.count({ 'metadata._user.host': { $ne: null } }),
calcSize(true),
calcSize(false)
]) : [
latest ? latest.local.totalCount : 0,
latest ? latest.remote.totalCount : 0,
latest ? latest.local.totalSize : 0,
latest ? latest.remote.totalSize : 0
];
return {
local: {
totalCount: localCount,
totalSize: localSize,
incCount: 0,
incSize: 0,
decCount: 0,
decSize: 0
},
remote: {
totalCount: remoteCount,
totalSize: remoteSize,
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({
[isLocalUser(file.metadata._user) ? 'local' : 'remote']: update
});
}
}
export default new DriveChart();