1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-01-17 01:06:46 +01:00

refactor: deprecate /server-info and replace with /server-info/storage (#9645)

This commit is contained in:
Zack Pollard 2024-05-22 10:25:55 +01:00 committed by GitHub
parent a341ab0050
commit a3e7e8cc31
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 131 additions and 74 deletions

View file

@ -32,7 +32,7 @@ class ServerDiskInfo {
return 'ServerDiskInfo(diskAvailable: $diskAvailable, diskSize: $diskSize, diskUse: $diskUse, diskUsagePercentage: $diskUsagePercentage)'; return 'ServerDiskInfo(diskAvailable: $diskAvailable, diskSize: $diskSize, diskUse: $diskUse, diskUsagePercentage: $diskUsagePercentage)';
} }
ServerDiskInfo.fromDto(ServerInfoResponseDto dto) ServerDiskInfo.fromDto(ServerStorageResponseDto dto)
: diskAvailable = dto.diskAvailable, : diskAvailable = dto.diskAvailable,
diskSize = dto.diskSize, diskSize = dto.diskSize,
diskUse = dto.diskUse, diskUse = dto.diskUse,

View file

@ -374,7 +374,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
if (state.backupProgress != BackUpProgressEnum.inBackground) { if (state.backupProgress != BackUpProgressEnum.inBackground) {
await _getBackupAlbumsInfo(); await _getBackupAlbumsInfo();
await updateServerInfo(); await updateDiskInfo();
await _updateBackupAssetCount(); await _updateBackupAssetCount();
} else { } else {
log.warning("cannot get backup info - background backup is in progress!"); log.warning("cannot get backup info - background backup is in progress!");
@ -542,7 +542,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
_updatePersistentAlbumsSelection(); _updatePersistentAlbumsSelection();
} }
updateServerInfo(); updateDiskInfo();
} }
void _onUploadProgress(int sent, int total) { void _onUploadProgress(int sent, int total) {
@ -579,13 +579,13 @@ class BackupNotifier extends StateNotifier<BackUpState> {
); );
} }
Future<void> updateServerInfo() async { Future<void> updateDiskInfo() async {
final serverInfo = await _serverInfoService.getServerInfo(); final diskInfo = await _serverInfoService.getDiskInfo();
// Update server info // Update server info
if (serverInfo != null) { if (diskInfo != null) {
state = state.copyWith( state = state.copyWith(
serverInfo: serverInfo, serverInfo: diskInfo,
); );
} }
} }

View file

@ -121,7 +121,7 @@ class ManualUploadNotifier extends StateNotifier<ManualUploadState> {
bool isDuplicated, bool isDuplicated,
) { ) {
state = state.copyWith(successfulUploads: state.successfulUploads + 1); state = state.copyWith(successfulUploads: state.successfulUploads + 1);
_backupProvider.updateServerInfo(); _backupProvider.updateDiskInfo();
} }
void _onAssetUploadError(ErrorUploadAsset errorAssetInfo) { void _onAssetUploadError(ErrorUploadAsset errorAssetInfo) {

View file

@ -18,14 +18,14 @@ class ServerInfoService {
ServerInfoService(this._apiService); ServerInfoService(this._apiService);
Future<ServerDiskInfo?> getServerInfo() async { Future<ServerDiskInfo?> getDiskInfo() async {
try { try {
final dto = await _apiService.serverInfoApi.getServerInfo(); final dto = await _apiService.serverInfoApi.getStorage();
if (dto != null) { if (dto != null) {
return ServerDiskInfo.fromDto(dto); return ServerDiskInfo.fromDto(dto);
} }
} catch (e) { } catch (e) {
debugPrint("Error [getServerInfo] ${e.toString()}"); debugPrint("Error [getDiskInfo] ${e.toString()}");
} }
return null; return null;
} }

View file

@ -31,7 +31,7 @@ class ImmichAppBarDialog extends HookConsumerWidget {
useEffect( useEffect(
() { () {
ref.read(backupProvider.notifier).updateServerInfo(); ref.read(backupProvider.notifier).updateDiskInfo();
ref.read(currentUserProvider.notifier).refresh(); ref.read(currentUserProvider.notifier).refresh();
return null; return null;
}, },

BIN
mobile/openapi/README.md generated

Binary file not shown.

Binary file not shown.

BIN
mobile/openapi/lib/api/deprecated_api.dart generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -4337,6 +4337,8 @@
}, },
"/server-info": { "/server-info": {
"get": { "get": {
"deprecated": true,
"description": "This property was deprecated in v1.106.0",
"operationId": "getServerInfo", "operationId": "getServerInfo",
"parameters": [], "parameters": [],
"responses": { "responses": {
@ -4344,7 +4346,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/ServerInfoResponseDto" "$ref": "#/components/schemas/ServerStorageResponseDto"
} }
} }
}, },
@ -4363,8 +4365,12 @@
} }
], ],
"tags": [ "tags": [
"Server Info" "Server Info",
] "Deprecated"
],
"x-immich-lifecycle": {
"deprecatedAt": "v1.106.0"
}
} }
}, },
"/server-info/config": { "/server-info/config": {
@ -4483,6 +4489,38 @@
] ]
} }
}, },
"/server-info/storage": {
"get": {
"operationId": "getStorage",
"parameters": [],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ServerStorageResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Server Info"
]
}
},
"/server-info/theme": { "/server-info/theme": {
"get": { "get": {
"operationId": "getTheme", "operationId": "getTheme",
@ -9487,45 +9525,6 @@
], ],
"type": "object" "type": "object"
}, },
"ServerInfoResponseDto": {
"properties": {
"diskAvailable": {
"type": "string"
},
"diskAvailableRaw": {
"format": "int64",
"type": "integer"
},
"diskSize": {
"type": "string"
},
"diskSizeRaw": {
"format": "int64",
"type": "integer"
},
"diskUsagePercentage": {
"format": "float",
"type": "number"
},
"diskUse": {
"type": "string"
},
"diskUseRaw": {
"format": "int64",
"type": "integer"
}
},
"required": [
"diskAvailable",
"diskAvailableRaw",
"diskSize",
"diskSizeRaw",
"diskUsagePercentage",
"diskUse",
"diskUseRaw"
],
"type": "object"
},
"ServerMediaTypesResponseDto": { "ServerMediaTypesResponseDto": {
"properties": { "properties": {
"image": { "image": {
@ -9606,6 +9605,45 @@
], ],
"type": "object" "type": "object"
}, },
"ServerStorageResponseDto": {
"properties": {
"diskAvailable": {
"type": "string"
},
"diskAvailableRaw": {
"format": "int64",
"type": "integer"
},
"diskSize": {
"type": "string"
},
"diskSizeRaw": {
"format": "int64",
"type": "integer"
},
"diskUsagePercentage": {
"format": "float",
"type": "number"
},
"diskUse": {
"type": "string"
},
"diskUseRaw": {
"format": "int64",
"type": "integer"
}
},
"required": [
"diskAvailable",
"diskAvailableRaw",
"diskSize",
"diskSizeRaw",
"diskUsagePercentage",
"diskUse",
"diskUseRaw"
],
"type": "object"
},
"ServerThemeDto": { "ServerThemeDto": {
"properties": { "properties": {
"customCss": { "customCss": {

View file

@ -732,7 +732,7 @@ export type SmartSearchDto = {
withDeleted?: boolean; withDeleted?: boolean;
withExif?: boolean; withExif?: boolean;
}; };
export type ServerInfoResponseDto = { export type ServerStorageResponseDto = {
diskAvailable: string; diskAvailable: string;
diskAvailableRaw: number; diskAvailableRaw: number;
diskSize: string; diskSize: string;
@ -2245,10 +2245,13 @@ export function getSearchSuggestions({ country, make, model, state, $type }: {
...opts ...opts
})); }));
} }
/**
* This property was deprecated in v1.106.0
*/
export function getServerInfo(opts?: Oazapfts.RequestOpts) { export function getServerInfo(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{ return oazapfts.ok(oazapfts.fetchJson<{
status: 200; status: 200;
data: ServerInfoResponseDto; data: ServerStorageResponseDto;
}>("/server-info", { }>("/server-info", {
...opts ...opts
})); }));
@ -2293,6 +2296,14 @@ export function getServerStatistics(opts?: Oazapfts.RequestOpts) {
...opts ...opts
})); }));
} }
export function getStorage(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: ServerStorageResponseDto;
}>("/server-info/storage", {
...opts
}));
}
export function getTheme(opts?: Oazapfts.RequestOpts) { export function getTheme(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{ return oazapfts.ok(oazapfts.fetchJson<{
status: 200; status: 200;

View file

@ -1,12 +1,13 @@
import { Controller, Get } from '@nestjs/common'; import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger'; import { ApiTags } from '@nestjs/swagger';
import { EndpointLifecycle } from 'src/decorators';
import { import {
ServerConfigDto, ServerConfigDto,
ServerFeaturesDto, ServerFeaturesDto,
ServerInfoResponseDto,
ServerMediaTypesResponseDto, ServerMediaTypesResponseDto,
ServerPingResponse, ServerPingResponse,
ServerStatsResponseDto, ServerStatsResponseDto,
ServerStorageResponseDto,
ServerThemeDto, ServerThemeDto,
ServerVersionResponseDto, ServerVersionResponseDto,
} from 'src/dtos/server-info.dto'; } from 'src/dtos/server-info.dto';
@ -23,9 +24,16 @@ export class ServerInfoController {
) {} ) {}
@Get() @Get()
@EndpointLifecycle({ deprecatedAt: 'v1.106.0' })
@Authenticated() @Authenticated()
getServerInfo(): Promise<ServerInfoResponseDto> { getServerInfo(): Promise<ServerStorageResponseDto> {
return this.service.getInfo(); return this.service.getStorage();
}
@Get('storage')
@Authenticated()
getStorage(): Promise<ServerStorageResponseDto> {
return this.service.getStorage();
} }
@Get('ping') @Get('ping')

View file

@ -7,7 +7,7 @@ export class ServerPingResponse {
res!: string; res!: string;
} }
export class ServerInfoResponseDto { export class ServerStorageResponseDto {
diskSize!: string; diskSize!: string;
diskUse!: string; diskUse!: string;
diskAvailable!: string; diskAvailable!: string;

View file

@ -29,11 +29,11 @@ describe(ServerInfoService.name, () => {
expect(sut).toBeDefined(); expect(sut).toBeDefined();
}); });
describe('getInfo', () => { describe('getStorage', () => {
it('should return the disk space as B', async () => { it('should return the disk space as B', async () => {
storageMock.checkDiskUsage.mockResolvedValue({ free: 200, available: 300, total: 500 }); storageMock.checkDiskUsage.mockResolvedValue({ free: 200, available: 300, total: 500 });
await expect(sut.getInfo()).resolves.toEqual({ await expect(sut.getStorage()).resolves.toEqual({
diskAvailable: '300 B', diskAvailable: '300 B',
diskAvailableRaw: 300, diskAvailableRaw: 300,
diskSize: '500 B', diskSize: '500 B',
@ -49,7 +49,7 @@ describe(ServerInfoService.name, () => {
it('should return the disk space as KiB', async () => { it('should return the disk space as KiB', async () => {
storageMock.checkDiskUsage.mockResolvedValue({ free: 200_000, available: 300_000, total: 500_000 }); storageMock.checkDiskUsage.mockResolvedValue({ free: 200_000, available: 300_000, total: 500_000 });
await expect(sut.getInfo()).resolves.toEqual({ await expect(sut.getStorage()).resolves.toEqual({
diskAvailable: '293.0 KiB', diskAvailable: '293.0 KiB',
diskAvailableRaw: 300_000, diskAvailableRaw: 300_000,
diskSize: '488.3 KiB', diskSize: '488.3 KiB',
@ -65,7 +65,7 @@ describe(ServerInfoService.name, () => {
it('should return the disk space as MiB', async () => { it('should return the disk space as MiB', async () => {
storageMock.checkDiskUsage.mockResolvedValue({ free: 200_000_000, available: 300_000_000, total: 500_000_000 }); storageMock.checkDiskUsage.mockResolvedValue({ free: 200_000_000, available: 300_000_000, total: 500_000_000 });
await expect(sut.getInfo()).resolves.toEqual({ await expect(sut.getStorage()).resolves.toEqual({
diskAvailable: '286.1 MiB', diskAvailable: '286.1 MiB',
diskAvailableRaw: 300_000_000, diskAvailableRaw: 300_000_000,
diskSize: '476.8 MiB', diskSize: '476.8 MiB',
@ -85,7 +85,7 @@ describe(ServerInfoService.name, () => {
total: 500_000_000_000, total: 500_000_000_000,
}); });
await expect(sut.getInfo()).resolves.toEqual({ await expect(sut.getStorage()).resolves.toEqual({
diskAvailable: '279.4 GiB', diskAvailable: '279.4 GiB',
diskAvailableRaw: 300_000_000_000, diskAvailableRaw: 300_000_000_000,
diskSize: '465.7 GiB', diskSize: '465.7 GiB',
@ -105,7 +105,7 @@ describe(ServerInfoService.name, () => {
total: 500_000_000_000_000, total: 500_000_000_000_000,
}); });
await expect(sut.getInfo()).resolves.toEqual({ await expect(sut.getStorage()).resolves.toEqual({
diskAvailable: '272.8 TiB', diskAvailable: '272.8 TiB',
diskAvailableRaw: 300_000_000_000_000, diskAvailableRaw: 300_000_000_000_000,
diskSize: '454.7 TiB', diskSize: '454.7 TiB',
@ -125,7 +125,7 @@ describe(ServerInfoService.name, () => {
total: 500_000_000_000_000_000, total: 500_000_000_000_000_000,
}); });
await expect(sut.getInfo()).resolves.toEqual({ await expect(sut.getStorage()).resolves.toEqual({
diskAvailable: '266.5 PiB', diskAvailable: '266.5 PiB',
diskAvailableRaw: 300_000_000_000_000_000, diskAvailableRaw: 300_000_000_000_000_000,
diskSize: '444.1 PiB', diskSize: '444.1 PiB',

View file

@ -4,10 +4,10 @@ import { SystemConfigCore } from 'src/cores/system-config.core';
import { import {
ServerConfigDto, ServerConfigDto,
ServerFeaturesDto, ServerFeaturesDto,
ServerInfoResponseDto,
ServerMediaTypesResponseDto, ServerMediaTypesResponseDto,
ServerPingResponse, ServerPingResponse,
ServerStatsResponseDto, ServerStatsResponseDto,
ServerStorageResponseDto,
UsageByUserDto, UsageByUserDto,
} from 'src/dtos/server-info.dto'; } from 'src/dtos/server-info.dto';
import { SystemMetadataKey } from 'src/entities/system-metadata.entity'; import { SystemMetadataKey } from 'src/entities/system-metadata.entity';
@ -42,13 +42,13 @@ export class ServerInfoService {
} }
} }
async getInfo(): Promise<ServerInfoResponseDto> { async getStorage(): Promise<ServerStorageResponseDto> {
const libraryBase = StorageCore.getBaseFolder(StorageFolder.LIBRARY); const libraryBase = StorageCore.getBaseFolder(StorageFolder.LIBRARY);
const diskInfo = await this.storageRepository.checkDiskUsage(libraryBase); const diskInfo = await this.storageRepository.checkDiskUsage(libraryBase);
const usagePercentage = (((diskInfo.total - diskInfo.free) / diskInfo.total) * 100).toFixed(2); const usagePercentage = (((diskInfo.total - diskInfo.free) / diskInfo.total) * 100).toFixed(2);
const serverInfo = new ServerInfoResponseDto(); const serverInfo = new ServerStorageResponseDto();
serverInfo.diskAvailable = asHumanReadable(diskInfo.available); serverInfo.diskAvailable = asHumanReadable(diskInfo.available);
serverInfo.diskSize = asHumanReadable(diskInfo.total); serverInfo.diskSize = asHumanReadable(diskInfo.total);
serverInfo.diskUse = asHumanReadable(diskInfo.total - diskInfo.free); serverInfo.diskUse = asHumanReadable(diskInfo.total - diskInfo.free);

View file

@ -1,4 +1,4 @@
import type { ServerInfoResponseDto } from '@immich/sdk'; import type { ServerStorageResponseDto } from '@immich/sdk';
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
export const serverInfo = writable<ServerInfoResponseDto>(); export const serverInfo = writable<ServerStorageResponseDto>();

View file

@ -1,7 +1,7 @@
import { browser } from '$app/environment'; import { browser } from '$app/environment';
import { serverInfo } from '$lib/stores/server-info.store'; import { serverInfo } from '$lib/stores/server-info.store';
import { user } from '$lib/stores/user.store'; import { user } from '$lib/stores/user.store';
import { getMyUserInfo, getServerInfo } from '@immich/sdk'; import { getMyUserInfo, getStorage } from '@immich/sdk';
import { redirect } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit';
import { get } from 'svelte/store'; import { get } from 'svelte/store';
import { AppRoute } from '../constants'; import { AppRoute } from '../constants';
@ -58,7 +58,7 @@ export const authenticate = async (options?: AuthOptions) => {
export const requestServerInfo = async () => { export const requestServerInfo = async () => {
if (get(user)) { if (get(user)) {
const data = await getServerInfo(); const data = await getStorage();
serverInfo.set(data); serverInfo.set(data);
} }
}; };