79 lines
3.1 KiB
TypeScript
79 lines
3.1 KiB
TypeScript
import { APP_UPLOAD_LOCATION } from '@app/common/constants';
|
|
import { Injectable } from '@nestjs/common';
|
|
import { ServerInfoResponseDto } from './response-dto/server-info-response.dto';
|
|
import diskusage from 'diskusage';
|
|
import { ServerStatsResponseDto } from './response-dto/server-stats-response.dto';
|
|
import { UsageByUserDto } from './response-dto/usage-by-user-response.dto';
|
|
import { AssetEntity } from '@app/infra';
|
|
import { Repository } from 'typeorm';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { asHumanReadable } from '../../utils/human-readable.util';
|
|
|
|
@Injectable()
|
|
export class ServerInfoService {
|
|
constructor(
|
|
@InjectRepository(AssetEntity)
|
|
private assetRepository: Repository<AssetEntity>,
|
|
) {}
|
|
|
|
async getServerInfo(): Promise<ServerInfoResponseDto> {
|
|
const diskInfo = await diskusage.check(APP_UPLOAD_LOCATION);
|
|
|
|
const usagePercentage = (((diskInfo.total - diskInfo.free) / diskInfo.total) * 100).toFixed(2);
|
|
|
|
const serverInfo = new ServerInfoResponseDto();
|
|
serverInfo.diskAvailable = asHumanReadable(diskInfo.available);
|
|
serverInfo.diskSize = asHumanReadable(diskInfo.total);
|
|
serverInfo.diskUse = asHumanReadable(diskInfo.total - diskInfo.free);
|
|
serverInfo.diskAvailableRaw = diskInfo.available;
|
|
serverInfo.diskSizeRaw = diskInfo.total;
|
|
serverInfo.diskUseRaw = diskInfo.total - diskInfo.free;
|
|
serverInfo.diskUsagePercentage = parseFloat(usagePercentage);
|
|
return serverInfo;
|
|
}
|
|
|
|
async getStats(): Promise<ServerStatsResponseDto> {
|
|
const serverStats = new ServerStatsResponseDto();
|
|
|
|
type UserStatsQueryResponse = {
|
|
assetType: string;
|
|
assetCount: string;
|
|
totalSizeInBytes: string;
|
|
userId: string;
|
|
};
|
|
|
|
const userStatsQueryResponse: UserStatsQueryResponse[] = await this.assetRepository
|
|
.createQueryBuilder('a')
|
|
.select('COUNT(a.id)', 'assetCount')
|
|
.addSelect('SUM(ei.fileSizeInByte)', 'totalSizeInBytes')
|
|
.addSelect('a."userId"')
|
|
.addSelect('a.type', 'assetType')
|
|
.where('a.isVisible = true')
|
|
.leftJoin('a.exifInfo', 'ei')
|
|
.groupBy('a."userId"')
|
|
.addGroupBy('a.type')
|
|
.getRawMany();
|
|
|
|
const tmpMap = new Map<string, UsageByUserDto>();
|
|
const getUsageByUser = (id: string) => tmpMap.get(id) || new UsageByUserDto(id);
|
|
|
|
userStatsQueryResponse.forEach((r) => {
|
|
const usageByUser = getUsageByUser(r.userId);
|
|
usageByUser.photos += r.assetType === 'IMAGE' ? parseInt(r.assetCount) : 0;
|
|
usageByUser.videos += r.assetType === 'VIDEO' ? parseInt(r.assetCount) : 0;
|
|
usageByUser.usageRaw += parseInt(r.totalSizeInBytes);
|
|
usageByUser.usage = asHumanReadable(usageByUser.usageRaw);
|
|
|
|
serverStats.photos += r.assetType === 'IMAGE' ? parseInt(r.assetCount) : 0;
|
|
serverStats.videos += r.assetType === 'VIDEO' ? parseInt(r.assetCount) : 0;
|
|
serverStats.usageRaw += parseInt(r.totalSizeInBytes);
|
|
serverStats.usage = asHumanReadable(serverStats.usageRaw);
|
|
tmpMap.set(r.userId, usageByUser);
|
|
});
|
|
|
|
serverStats.usageByUser = Array.from(tmpMap.values());
|
|
|
|
return serverStats;
|
|
}
|
|
}
|