Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding photo & video storage space to server stats #14125

Merged
merged 10 commits into from
Nov 15, 2024
6 changes: 6 additions & 0 deletions e2e/src/api/specs/server.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,15 @@ describe('/server', () => {
expect(body).toEqual({
photos: 0,
usage: 0,
usagePhotos: 0,
usageVideos: 0,
usageByUser: [
{
quotaSizeInBytes: null,
photos: 0,
usage: 0,
usagePhotos: 0,
usageVideos: 0,
userName: 'Immich Admin',
userId: admin.userId,
videos: 0,
Expand All @@ -176,6 +180,8 @@ describe('/server', () => {
quotaSizeInBytes: null,
photos: 0,
usage: 0,
usagePhotos: 0,
usageVideos: 0,
userName: 'User 1',
userId: nonAdmin.userId,
videos: 0,
Expand Down
18 changes: 17 additions & 1 deletion mobile/openapi/lib/model/server_stats_response_dto.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 17 additions & 1 deletion mobile/openapi/lib/model/usage_by_user_dto.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 25 additions & 1 deletion open-api/immich-openapi-specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -10966,7 +10966,9 @@
{
"photos": 1,
"videos": 1,
"diskUsageRaw": 1
"diskUsageRaw": 2,
"usagePhotos": 1,
"usageVideos": 1
}
],
"items": {
Expand All @@ -10975,6 +10977,16 @@
"title": "Array of usage for each user",
"type": "array"
},
"usagePhotos": {
"default": 0,
"format": "int64",
"type": "integer"
},
"usageVideos": {
"default": 0,
"format": "int64",
"type": "integer"
},
"videos": {
"default": 0,
"type": "integer"
Expand All @@ -10984,6 +10996,8 @@
"photos",
"usage",
"usageByUser",
"usagePhotos",
"usageVideos",
"videos"
],
"type": "object"
Expand Down Expand Up @@ -12503,6 +12517,14 @@
"format": "int64",
"type": "integer"
},
"usagePhotos": {
"format": "int64",
"type": "integer"
},
"usageVideos": {
"format": "int64",
"type": "integer"
},
"userId": {
"type": "string"
},
Expand All @@ -12517,6 +12539,8 @@
"photos",
"quotaSizeInBytes",
"usage",
"usagePhotos",
"usageVideos",
"userId",
"userName",
"videos"
Expand Down
4 changes: 4 additions & 0 deletions open-api/typescript-sdk/src/fetch-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,8 @@ export type UsageByUserDto = {
photos: number;
quotaSizeInBytes: number | null;
usage: number;
usagePhotos: number;
usageVideos: number;
userId: string;
userName: string;
videos: number;
Expand All @@ -977,6 +979,8 @@ export type ServerStatsResponseDto = {
photos: number;
usage: number;
usageByUser: UsageByUserDto[];
usagePhotos: number;
usageVideos: number;
videos: number;
};
export type ServerStorageResponseDto = {
Expand Down
14 changes: 13 additions & 1 deletion server/src/dtos/server.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ export class UsageByUserDto {
@ApiProperty({ type: 'integer', format: 'int64' })
usage!: number;
@ApiProperty({ type: 'integer', format: 'int64' })
usagePhotos!: number;
@ApiProperty({ type: 'integer', format: 'int64' })
usageVideos!: number;
@ApiProperty({ type: 'integer', format: 'int64' })
quotaSizeInBytes!: number | null;
}

Expand All @@ -99,6 +103,12 @@ export class ServerStatsResponseDto {
@ApiProperty({ type: 'integer', format: 'int64' })
usage = 0;

@ApiProperty({ type: 'integer', format: 'int64' })
usagePhotos = 0;

@ApiProperty({ type: 'integer', format: 'int64' })
usageVideos = 0;

@ApiProperty({
isArray: true,
type: UsageByUserDto,
Expand All @@ -107,7 +117,9 @@ export class ServerStatsResponseDto {
{
photos: 1,
videos: 1,
diskUsageRaw: 1,
diskUsageRaw: 2,
usagePhotos: 1,
usageVideos: 1,
},
],
})
Expand Down
2 changes: 2 additions & 0 deletions server/src/interfaces/user.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export interface UserStatsQueryResponse {
photos: number;
videos: number;
usage: number;
usagePhotos: number;
usageVideos: number;
quotaSizeInBytes: number | null;
}

Expand Down
18 changes: 17 additions & 1 deletion server/src/queries/user.repository.sql
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,23 @@ SELECT
"assets"."libraryId" IS NULL
),
0
) AS "usage"
) AS "usage",
COALESCE(
SUM("exif"."fileSizeInByte") FILTER (
WHERE
"assets"."libraryId" IS NULL
AND "assets"."type" = 'IMAGE'
),
0
) AS "usagePhotos",
COALESCE(
SUM("exif"."fileSizeInByte") FILTER (
WHERE
"assets"."libraryId" IS NULL
AND "assets"."type" = 'VIDEO'
),
0
) AS "usageVideos"
FROM
"users" "users"
LEFT JOIN "assets" "assets" ON "assets"."ownerId" = "users"."id"
Expand Down
10 changes: 10 additions & 0 deletions server/src/repositories/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ export class UserRepository implements IUserRepository {
.addSelect(`COUNT(assets.id) FILTER (WHERE assets.type = 'IMAGE' AND assets.isVisible)`, 'photos')
.addSelect(`COUNT(assets.id) FILTER (WHERE assets.type = 'VIDEO' AND assets.isVisible)`, 'videos')
.addSelect('COALESCE(SUM(exif.fileSizeInByte) FILTER (WHERE assets.libraryId IS NULL), 0)', 'usage')
.addSelect(
`COALESCE(SUM(exif.fileSizeInByte) FILTER (WHERE assets.libraryId IS NULL AND assets.type = 'IMAGE'), 0)`,
'usagePhotos',
)
.addSelect(
`COALESCE(SUM(exif.fileSizeInByte) FILTER (WHERE assets.libraryId IS NULL AND assets.type = 'VIDEO'), 0)`,
'usageVideos',
)
.addSelect('users.quotaSizeInBytes', 'quotaSizeInBytes')
.leftJoin('users.assets', 'assets')
.leftJoin('assets.exifInfo', 'exif')
Expand All @@ -119,6 +127,8 @@ export class UserRepository implements IUserRepository {
stat.photos = Number(stat.photos);
stat.videos = Number(stat.videos);
stat.usage = Number(stat.usage);
stat.usagePhotos = Number(stat.usagePhotos);
stat.usageVideos = Number(stat.usageVideos);
stat.quotaSizeInBytes = stat.quotaSizeInBytes;
}

Expand Down
14 changes: 14 additions & 0 deletions server/src/services/server.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ describe(ServerService.name, () => {
photos: 10,
videos: 11,
usage: 12_345,
usagePhotos: 1,
usageVideos: 11_345,
quotaSizeInBytes: 0,
},
{
Expand All @@ -193,6 +195,8 @@ describe(ServerService.name, () => {
photos: 10,
videos: 20,
usage: 123_456,
usagePhotos: 100,
usageVideos: 23_456,
quotaSizeInBytes: 0,
},
{
Expand All @@ -201,6 +205,8 @@ describe(ServerService.name, () => {
photos: 100,
videos: 0,
usage: 987_654,
usagePhotos: 900,
usageVideos: 87_654,
quotaSizeInBytes: 0,
},
]);
Expand All @@ -209,11 +215,15 @@ describe(ServerService.name, () => {
photos: 120,
videos: 31,
usage: 1_123_455,
usagePhotos: 1001,
usageVideos: 122_455,
usageByUser: [
{
photos: 10,
quotaSizeInBytes: 0,
usage: 12_345,
usagePhotos: 1,
usageVideos: 11_345,
userName: '1 User',
userId: 'user1',
videos: 11,
Expand All @@ -222,6 +232,8 @@ describe(ServerService.name, () => {
photos: 10,
quotaSizeInBytes: 0,
usage: 123_456,
usagePhotos: 100,
usageVideos: 23_456,
userName: '2 User',
userId: 'user2',
videos: 20,
Expand All @@ -230,6 +242,8 @@ describe(ServerService.name, () => {
photos: 100,
quotaSizeInBytes: 0,
usage: 987_654,
usagePhotos: 900,
usageVideos: 87_654,
userName: '3 User',
userId: 'user3',
videos: 0,
Expand Down
Loading
Loading