diff --git a/.gitignore b/.gitignore index 496ee2ca6a..0ed240d5ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -.DS_Store \ No newline at end of file +.DS_Store +.vscode +.idea \ No newline at end of file diff --git a/server/package-lock.json b/server/package-lock.json index 5da375075d..9b061d8a47 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -28,6 +28,7 @@ "bull": "^4.4.0", "class-transformer": "^0.5.1", "class-validator": "^0.13.2", + "diskusage": "^1.1.3", "dotenv": "^14.2.0", "exifr": "^7.1.3", "joi": "^17.5.0", @@ -4258,6 +4259,16 @@ "node": ">=8" } }, + "node_modules/diskusage": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/diskusage/-/diskusage-1.1.3.tgz", + "integrity": "sha512-EAyaxl8hy4Ph07kzlzGTfpbZMNAAAHXSZtNEMwdlnSd1noHzvA6HsgKt4fEMSvaEXQYLSphe5rPMxN4WOj0hcQ==", + "hasInstallScript": true, + "dependencies": { + "es6-promise": "^4.2.5", + "nan": "^2.14.0" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -4444,6 +4455,11 @@ "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", "dev": true }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -7712,8 +7728,7 @@ "node_modules/nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -14098,6 +14113,15 @@ "path-type": "^4.0.0" } }, + "diskusage": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/diskusage/-/diskusage-1.1.3.tgz", + "integrity": "sha512-EAyaxl8hy4Ph07kzlzGTfpbZMNAAAHXSZtNEMwdlnSd1noHzvA6HsgKt4fEMSvaEXQYLSphe5rPMxN4WOj0hcQ==", + "requires": { + "es6-promise": "^4.2.5", + "nan": "^2.14.0" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -14246,6 +14270,11 @@ "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", "dev": true }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -16753,8 +16782,7 @@ "nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "natural-compare": { "version": "1.4.0", diff --git a/server/package.json b/server/package.json index afbaebc697..ce99f36d58 100644 --- a/server/package.json +++ b/server/package.json @@ -41,6 +41,7 @@ "bull": "^4.4.0", "class-transformer": "^0.5.1", "class-validator": "^0.13.2", + "diskusage": "^1.1.3", "dotenv": "^14.2.0", "exifr": "^7.1.3", "joi": "^17.5.0", diff --git a/server/src/api-v1/asset/asset.controller.ts b/server/src/api-v1/asset/asset.controller.ts index 2158ade31c..e37fd4642d 100644 --- a/server/src/api-v1/asset/asset.controller.ts +++ b/server/src/api-v1/asset/asset.controller.ts @@ -55,7 +55,7 @@ export class AssetController { @UploadedFiles() uploadFiles: { assetData: Express.Multer.File[]; thumbnailData?: Express.Multer.File[] }, @Body(ValidationPipe) assetInfo: CreateAssetDto, ) { - uploadFiles.assetData.forEach(async (file) => { + for (const file of uploadFiles.assetData) { const savedAsset = await this.assetService.createUserAsset(authUser, assetInfo, file.path, file.mimetype); if (uploadFiles.thumbnailData != null) { @@ -66,7 +66,7 @@ export class AssetController { await this.backgroundTaskService.extractExif(savedAsset, file.originalname, file.size); this.wsCommunicateionGateway.server.to(savedAsset.userId).emit('on_upload_success', JSON.stringify(savedAsset)); - }); + } return 'ok'; } @@ -125,10 +125,10 @@ export class AssetController { async deleteAssetById(@GetAuthUser() authUser: AuthUserDto, @Body(ValidationPipe) assetIds: DeleteAssetDto) { const deleteAssetList: AssetEntity[] = []; - assetIds.ids.forEach(async (id) => { + for (const id of assetIds.ids) { const assets = await this.assetService.getAssetById(authUser, id); deleteAssetList.push(assets); - }); + } const result = await this.assetService.deleteAssetById(authUser, assetIds); diff --git a/server/src/api-v1/server-info/server-info.controller.ts b/server/src/api-v1/server-info/server-info.controller.ts index 211d743763..54894dd66e 100644 --- a/server/src/api-v1/server-info/server-info.controller.ts +++ b/server/src/api-v1/server-info/server-info.controller.ts @@ -1,10 +1,7 @@ -import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards } from '@nestjs/common'; +import { Controller, Get, UseGuards } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator'; import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard'; import { ServerInfoService } from './server-info.service'; -import mapboxGeocoding, { GeocodeService } from '@mapbox/mapbox-sdk/services/geocoding'; -import { MapiResponse } from '@mapbox/mapbox-sdk/lib/classes/mapi-response'; import { serverVersion } from '../../constants/server_version.constant'; @Controller('server-info') diff --git a/server/src/api-v1/server-info/server-info.service.ts b/server/src/api-v1/server-info/server-info.service.ts index b5ae866139..9e3b0fb4df 100644 --- a/server/src/api-v1/server-info/server-info.service.ts +++ b/server/src/api-v1/server-info/server-info.service.ts @@ -1,31 +1,27 @@ import { Injectable } from '@nestjs/common'; -import systemInformation from 'systeminformation'; import { ServerInfoDto } from './dto/server-info.dto'; +import diskusage from 'diskusage'; @Injectable() export class ServerInfoService { - constructor() {} async getServerInfo() { - const res = await systemInformation.fsSize(); + const diskInfo = await diskusage.check('./upload'); - const size = res[0].size; - const used = res[0].used; - const available = res[0].available; - const percentageUsage = res[0].use; + const usagePercentage = (((diskInfo.total - diskInfo.free) / diskInfo.total) * 100).toFixed(2); const serverInfo = new ServerInfoDto(); - serverInfo.diskAvailable = this.getHumanReadableString(available); - serverInfo.diskSize = this.getHumanReadableString(size); - serverInfo.diskUse = this.getHumanReadableString(used); - serverInfo.diskAvailableRaw = available; - serverInfo.diskSizeRaw = size; - serverInfo.diskUseRaw = used; - serverInfo.diskUsagePercentage = percentageUsage; + serverInfo.diskAvailable = ServerInfoService.getHumanReadableString(diskInfo.available); + serverInfo.diskSize = ServerInfoService.getHumanReadableString(diskInfo.total); + serverInfo.diskUse = ServerInfoService.getHumanReadableString(diskInfo.total - diskInfo.free); + serverInfo.diskAvailableRaw = diskInfo.available; + serverInfo.diskSizeRaw = diskInfo.total; + serverInfo.diskUseRaw = diskInfo.total - diskInfo.free; + serverInfo.diskUsagePercentage = parseFloat(usagePercentage); return serverInfo; } - private getHumanReadableString(sizeInByte: number) { + private static getHumanReadableString(sizeInByte: number) { const pepibyte = 1.126 * Math.pow(10, 15); const tebibyte = 1.1 * Math.pow(10, 12); const gibibyte = 1.074 * Math.pow(10, 9);