Skip to content

Commit

Permalink
refactor: asset v1, app.utils (#8152)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrasm91 committed Mar 21, 2024
1 parent 87ccba7 commit 382b639
Show file tree
Hide file tree
Showing 34 changed files with 517 additions and 547 deletions.
8 changes: 4 additions & 4 deletions server/package.json
Expand Up @@ -156,10 +156,10 @@
"coverageDirectory": "./coverage",
"coverageThreshold": {
"./src/": {
"branches": 75,
"functions": 80,
"lines": 85,
"statements": 85
"branches": 70,
"functions": 75,
"lines": 80,
"statements": 80
}
},
"testEnvironment": "node",
Expand Down
5 changes: 2 additions & 3 deletions server/src/apps/api.main.ts
Expand Up @@ -6,12 +6,11 @@ import { existsSync } from 'node:fs';
import sirv from 'sirv';
import { ApiModule } from 'src/apps/api.module';
import { ApiService } from 'src/apps/api.service';
import { excludePaths } from 'src/config';
import { WEB_ROOT, envName, isDev, serverVersion } from 'src/constants';
import { useSwagger } from 'src/immich/app.utils';
import { WEB_ROOT, envName, excludePaths, isDev, serverVersion } from 'src/constants';
import { WebSocketAdapter } from 'src/middleware/websocket.adapter';
import { otelSDK } from 'src/utils/instrumentation';
import { ImmichLogger } from 'src/utils/logger';
import { useSwagger } from 'src/utils/misc';

const logger = new ImmichLogger('ImmichServer');
const port = Number(process.env.SERVER_PORT) || 3001;
Expand Down
18 changes: 5 additions & 13 deletions server/src/apps/api.module.ts
@@ -1,13 +1,13 @@
import { Module, OnModuleInit, ValidationPipe } from '@nestjs/common';
import { APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core';
import { ScheduleModule } from '@nestjs/schedule';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ApiService } from 'src/apps/api.service';
import { AppModule } from 'src/apps/app.module';
import { ActivityController } from 'src/controllers/activity.controller';
import { AlbumController } from 'src/controllers/album.controller';
import { APIKeyController } from 'src/controllers/api-key.controller';
import { AppController } from 'src/controllers/app.controller';
import { AssetControllerV1 } from 'src/controllers/asset-v1.controller';
import { AssetController, AssetsController } from 'src/controllers/asset.controller';
import { AuditController } from 'src/controllers/audit.controller';
import { AuthController } from 'src/controllers/auth.controller';
Expand All @@ -25,11 +25,6 @@ import { SystemConfigController } from 'src/controllers/system-config.controller
import { TagController } from 'src/controllers/tag.controller';
import { TrashController } from 'src/controllers/trash.controller';
import { UserController } from 'src/controllers/user.controller';
import { AssetEntity } from 'src/entities/asset.entity';
import { ExifEntity } from 'src/entities/exif.entity';
import { AssetRepositoryV1, IAssetRepositoryV1 } from 'src/immich/api-v1/asset/asset-repository';
import { AssetController as AssetControllerV1 } from 'src/immich/api-v1/asset/asset.controller';
import { AssetService as AssetServiceV1 } from 'src/immich/api-v1/asset/asset.service';
import { AuthGuard } from 'src/middleware/auth.guard';
import { ErrorInterceptor } from 'src/middleware/error.interceptor';
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
Expand All @@ -39,7 +34,6 @@ import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
//
AppModule,
ScheduleModule.forRoot(),
TypeOrmModule.forFeature([AssetEntity, ExifEntity]),
],
controllers: [
ActivityController,
Expand Down Expand Up @@ -67,19 +61,17 @@ import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
PersonController,
],
providers: [
ApiService,
FileUploadInterceptor,
{ provide: APP_PIPE, useValue: new ValidationPipe({ transform: true, whitelist: true }) },
{ provide: APP_INTERCEPTOR, useClass: ErrorInterceptor },
{ provide: APP_GUARD, useClass: AuthGuard },
{ provide: IAssetRepositoryV1, useClass: AssetRepositoryV1 },
ApiService,
AssetServiceV1,
FileUploadInterceptor,
],
})
export class ApiModule implements OnModuleInit {
constructor(private appService: ApiService) {}
constructor(private apiService: ApiService) {}

async onModuleInit() {
await this.appService.init();
await this.apiService.init();
}
}
5 changes: 5 additions & 0 deletions server/src/apps/app.module.ts
Expand Up @@ -13,6 +13,7 @@ import { IActivityRepository } from 'src/interfaces/activity.interface';
import { IAlbumRepository } from 'src/interfaces/album.interface';
import { IKeyRepository } from 'src/interfaces/api-key.interface';
import { IAssetStackRepository } from 'src/interfaces/asset-stack.interface';
import { IAssetRepositoryV1 } from 'src/interfaces/asset-v1.interface';
import { IAssetRepository } from 'src/interfaces/asset.interface';
import { IAuditRepository } from 'src/interfaces/audit.interface';
import { ICommunicationRepository } from 'src/interfaces/communication.interface';
Expand Down Expand Up @@ -40,6 +41,7 @@ import { ActivityRepository } from 'src/repositories/activity.repository';
import { AlbumRepository } from 'src/repositories/album.repository';
import { ApiKeyRepository } from 'src/repositories/api-key.repository';
import { AssetStackRepository } from 'src/repositories/asset-stack.repository';
import { AssetRepositoryV1 } from 'src/repositories/asset-v1.repository';
import { AssetRepository } from 'src/repositories/asset.repository';
import { AuditRepository } from 'src/repositories/audit.repository';
import { CommunicationRepository } from 'src/repositories/communication.repository';
Expand All @@ -65,6 +67,7 @@ import { UserRepository } from 'src/repositories/user.repository';
import { ActivityService } from 'src/services/activity.service';
import { AlbumService } from 'src/services/album.service';
import { APIKeyService } from 'src/services/api-key.service';
import { AssetServiceV1 } from 'src/services/asset-v1.service';
import { AssetService } from 'src/services/asset.service';
import { AuditService } from 'src/services/audit.service';
import { AuthService } from 'src/services/auth.service';
Expand Down Expand Up @@ -94,6 +97,7 @@ const services: Provider[] = [
ActivityService,
AlbumService,
AssetService,
AssetServiceV1,
AuditService,
AuthService,
DatabaseService,
Expand Down Expand Up @@ -122,6 +126,7 @@ const repositories: Provider[] = [
{ provide: IAccessRepository, useClass: AccessRepository },
{ provide: IAlbumRepository, useClass: AlbumRepository },
{ provide: IAssetRepository, useClass: AssetRepository },
{ provide: IAssetRepositoryV1, useClass: AssetRepositoryV1 },
{ provide: IAssetStackRepository, useClass: AssetStackRepository },
{ provide: IAuditRepository, useClass: AuditRepository },
{ provide: ICommunicationRepository, useClass: CommunicationRepository },
Expand Down
2 changes: 0 additions & 2 deletions server/src/config.ts
Expand Up @@ -69,5 +69,3 @@ export const bullConfig: QueueOptions = {
};

export const bullQueues: RegisterQueueOptions[] = Object.values(QueueName).map((name) => ({ name }));

export const excludePaths = ['/.well-known/immich', '/custom.css', '/favicon.ico'];
2 changes: 2 additions & 0 deletions server/src/constants.ts
Expand Up @@ -35,6 +35,8 @@ export enum AuthType {
OAUTH = 'oauth',
}

export const excludePaths = ['/.well-known/immich', '/custom.css', '/favicon.ico'];

export const FACE_THUMBNAIL_SIZE = 250;

export const supportedYearTokens = ['y', 'yy'];
Expand Down
Expand Up @@ -16,22 +16,26 @@ import {
import { ApiBody, ApiConsumes, ApiHeader, ApiTags } from '@nestjs/swagger';
import { NextFunction, Response } from 'express';
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
import {
AssetBulkUploadCheckResponseDto,
AssetFileUploadResponseDto,
CheckExistingAssetsResponseDto,
CuratedLocationsResponseDto,
CuratedObjectsResponseDto,
} from 'src/dtos/asset-v1-response.dto';
import {
AssetBulkUploadCheckDto,
AssetSearchDto,
CheckExistingAssetsDto,
CreateAssetDto,
GetAssetThumbnailDto,
ServeFileDto,
} from 'src/dtos/asset-v1.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import { AssetService as AssetServiceV1 } from 'src/immich/api-v1/asset/asset.service';
import { AssetBulkUploadCheckDto } from 'src/immich/api-v1/asset/dto/asset-check.dto';
import { AssetSearchDto } from 'src/immich/api-v1/asset/dto/asset-search.dto';
import { CheckExistingAssetsDto } from 'src/immich/api-v1/asset/dto/check-existing-assets.dto';
import { CreateAssetDto } from 'src/immich/api-v1/asset/dto/create-asset.dto';
import { GetAssetThumbnailDto } from 'src/immich/api-v1/asset/dto/get-asset-thumbnail.dto';
import { ServeFileDto } from 'src/immich/api-v1/asset/dto/serve-file.dto';
import { AssetBulkUploadCheckResponseDto } from 'src/immich/api-v1/asset/response-dto/asset-check-response.dto';
import { AssetFileUploadResponseDto } from 'src/immich/api-v1/asset/response-dto/asset-file-upload-response.dto';
import { CheckExistingAssetsResponseDto } from 'src/immich/api-v1/asset/response-dto/check-existing-assets-response.dto';
import { CuratedLocationsResponseDto } from 'src/immich/api-v1/asset/response-dto/curated-locations-response.dto';
import { CuratedObjectsResponseDto } from 'src/immich/api-v1/asset/response-dto/curated-objects-response.dto';
import { sendFile } from 'src/immich/app.utils';
import { Auth, Authenticated, FileResponse, SharedLinkRoute } from 'src/middleware/auth.guard';
import { FileUploadInterceptor, ImmichFile, Route, mapToUploadFile } from 'src/middleware/file-upload.interceptor';
import { AssetServiceV1 } from 'src/services/asset-v1.service';
import { sendFile } from 'src/utils/file';
import { FileNotEmptyValidator, UUIDParamDto } from 'src/validation';

interface UploadFiles {
Expand All @@ -43,8 +47,8 @@ interface UploadFiles {
@ApiTags('Asset')
@Controller(Route.ASSET)
@Authenticated()
export class AssetController {
constructor(private serviceV1: AssetServiceV1) {}
export class AssetControllerV1 {
constructor(private service: AssetServiceV1) {}

@SharedLinkRoute()
@Post('upload')
Expand Down Expand Up @@ -73,7 +77,7 @@ export class AssetController {
sidecarFile = mapToUploadFile(_sidecarFile);
}

const responseDto = await this.serviceV1.uploadFile(auth, dto, file, livePhotoFile, sidecarFile);
const responseDto = await this.service.uploadFile(auth, dto, file, livePhotoFile, sidecarFile);
if (responseDto.duplicate) {
res.status(HttpStatus.OK);
}
Expand All @@ -91,7 +95,7 @@ export class AssetController {
@Param() { id }: UUIDParamDto,
@Query() dto: ServeFileDto,
) {
await sendFile(res, next, () => this.serviceV1.serveFile(auth, id, dto));
await sendFile(res, next, () => this.service.serveFile(auth, id, dto));
}

@SharedLinkRoute()
Expand All @@ -104,22 +108,22 @@ export class AssetController {
@Param() { id }: UUIDParamDto,
@Query() dto: GetAssetThumbnailDto,
) {
await sendFile(res, next, () => this.serviceV1.serveThumbnail(auth, id, dto));
await sendFile(res, next, () => this.service.serveThumbnail(auth, id, dto));
}

@Get('/curated-objects')
getCuratedObjects(@Auth() auth: AuthDto): Promise<CuratedObjectsResponseDto[]> {
return this.serviceV1.getCuratedObject(auth);
return this.service.getCuratedObject(auth);
}

@Get('/curated-locations')
getCuratedLocations(@Auth() auth: AuthDto): Promise<CuratedLocationsResponseDto[]> {
return this.serviceV1.getCuratedLocation(auth);
return this.service.getCuratedLocation(auth);
}

@Get('/search-terms')
getAssetSearchTerms(@Auth() auth: AuthDto): Promise<string[]> {
return this.serviceV1.getAssetSearchTerm(auth);
return this.service.getAssetSearchTerm(auth);
}

/**
Expand All @@ -133,7 +137,7 @@ export class AssetController {
schema: { type: 'string' },
})
getAllAssets(@Auth() auth: AuthDto, @Query() dto: AssetSearchDto): Promise<AssetResponseDto[]> {
return this.serviceV1.getAllAssets(auth, dto);
return this.service.getAllAssets(auth, dto);
}

/**
Expand All @@ -145,7 +149,7 @@ export class AssetController {
@Auth() auth: AuthDto,
@Body() dto: CheckExistingAssetsDto,
): Promise<CheckExistingAssetsResponseDto> {
return this.serviceV1.checkExistingAssets(auth, dto);
return this.service.checkExistingAssets(auth, dto);
}

/**
Expand All @@ -157,6 +161,6 @@ export class AssetController {
@Auth() auth: AuthDto,
@Body() dto: AssetBulkUploadCheckDto,
): Promise<AssetBulkUploadCheckResponseDto> {
return this.serviceV1.bulkUploadCheck(auth, dto);
return this.service.bulkUploadCheck(auth, dto);
}
}
2 changes: 1 addition & 1 deletion server/src/controllers/download.controller.ts
Expand Up @@ -4,9 +4,9 @@ import { NextFunction, Response } from 'express';
import { AssetIdsDto } from 'src/dtos/asset.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import { DownloadInfoDto, DownloadResponseDto } from 'src/dtos/download.dto';
import { asStreamableFile, sendFile } from 'src/immich/app.utils';
import { Auth, Authenticated, FileResponse, SharedLinkRoute } from 'src/middleware/auth.guard';
import { DownloadService } from 'src/services/download.service';
import { asStreamableFile, sendFile } from 'src/utils/file';
import { UUIDParamDto } from 'src/validation';

@ApiTags('Download')
Expand Down
2 changes: 1 addition & 1 deletion server/src/controllers/person.controller.ts
Expand Up @@ -15,9 +15,9 @@ import {
PersonStatisticsResponseDto,
PersonUpdateDto,
} from 'src/dtos/person.dto';
import { sendFile } from 'src/immich/app.utils';
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
import { PersonService } from 'src/services/person.service';
import { sendFile } from 'src/utils/file';
import { UUIDParamDto } from 'src/validation';

@ApiTags('Person')
Expand Down
2 changes: 1 addition & 1 deletion server/src/controllers/user.controller.ts
Expand Up @@ -19,10 +19,10 @@ import { NextFunction, Response } from 'express';
import { AuthDto } from 'src/dtos/auth.dto';
import { CreateProfileImageDto, CreateProfileImageResponseDto } from 'src/dtos/user-profile.dto';
import { CreateUserDto, DeleteUserDto, UpdateUserDto, UserResponseDto } from 'src/dtos/user.dto';
import { sendFile } from 'src/immich/app.utils';
import { AdminRoute, Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
import { FileUploadInterceptor, Route } from 'src/middleware/file-upload.interceptor';
import { UserService } from 'src/services/user.service';
import { sendFile } from 'src/utils/file';
import { UUIDParamDto } from 'src/validation';

@ApiTags('User')
Expand Down
45 changes: 45 additions & 0 deletions server/src/dtos/asset-v1-response.dto.ts
@@ -0,0 +1,45 @@
export class AssetBulkUploadCheckResult {
id!: string;
action!: AssetUploadAction;
reason?: AssetRejectReason;
assetId?: string;
}

export class AssetBulkUploadCheckResponseDto {
results!: AssetBulkUploadCheckResult[];
}

export enum AssetUploadAction {
ACCEPT = 'accept',
REJECT = 'reject',
}

export enum AssetRejectReason {
DUPLICATE = 'duplicate',
UNSUPPORTED_FORMAT = 'unsupported-format',
}

export class AssetFileUploadResponseDto {
id!: string;
duplicate!: boolean;
}

export class CheckExistingAssetsResponseDto {
existingIds!: string[];
}

export class CuratedLocationsResponseDto {
id!: string;
city!: string;
resizePath!: string;
deviceAssetId!: string;
deviceId!: string;
}

export class CuratedObjectsResponseDto {
id!: string;
object!: string;
resizePath!: string;
deviceAssetId!: string;
deviceId!: string;
}

0 comments on commit 382b639

Please sign in to comment.