1
0
mirror of https://github.com/immich-app/immich.git synced 2025-01-12 15:32:36 +02:00

chore(server): remove import file endpoint (#5093)

* chore(server): remove import file endpoint

* chore: open api
This commit is contained in:
Jason Rasmussen 2023-11-17 00:44:59 -05:00 committed by GitHub
parent c7b3039a1a
commit 82f12b8ee6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 7 additions and 614 deletions

View File

@ -1773,97 +1773,6 @@ export interface FileReportItemDto {
} }
/**
*
* @export
* @interface ImportAssetDto
*/
export interface ImportAssetDto {
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'assetPath': string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'deviceAssetId': string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'deviceId': string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'duration'?: string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'fileCreatedAt': string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'fileModifiedAt': string;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isArchived'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isExternal'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isFavorite'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isOffline'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isReadOnly'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isVisible'?: boolean;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'libraryId'?: string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'sidecarPath'?: string;
}
/** /**
* *
* @export * @export
@ -7609,50 +7518,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
options: localVarRequestOptions, options: localVarRequestOptions,
}; };
}, },
/**
*
* @param {ImportAssetDto} importAssetDto
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
importFile: async (importAssetDto: ImportAssetDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'importAssetDto' is not null or undefined
assertParamExists('importFile', 'importAssetDto', importAssetDto)
const localVarPath = `/asset/import`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication cookie required
// authentication api_key required
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
// authentication bearer required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(importAssetDto, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/** /**
* *
* @param {BulkIdsDto} bulkIdsDto * @param {BulkIdsDto} bulkIdsDto
@ -8602,16 +8467,6 @@ export const AssetApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.getUserAssetsByDeviceId(deviceId, options); const localVarAxiosArgs = await localVarAxiosParamCreator.getUserAssetsByDeviceId(deviceId, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
}, },
/**
*
* @param {ImportAssetDto} importAssetDto
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async importFile(importAssetDto: ImportAssetDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AssetFileUploadResponseDto>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.importFile(importAssetDto, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/** /**
* *
* @param {BulkIdsDto} bulkIdsDto * @param {BulkIdsDto} bulkIdsDto
@ -8945,15 +8800,6 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
getUserAssetsByDeviceId(requestParameters: AssetApiGetUserAssetsByDeviceIdRequest, options?: AxiosRequestConfig): AxiosPromise<Array<string>> { getUserAssetsByDeviceId(requestParameters: AssetApiGetUserAssetsByDeviceIdRequest, options?: AxiosRequestConfig): AxiosPromise<Array<string>> {
return localVarFp.getUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(axios, basePath)); return localVarFp.getUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(axios, basePath));
}, },
/**
*
* @param {AssetApiImportFileRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
importFile(requestParameters: AssetApiImportFileRequest, options?: AxiosRequestConfig): AxiosPromise<AssetFileUploadResponseDto> {
return localVarFp.importFile(requestParameters.importAssetDto, options).then((request) => request(axios, basePath));
},
/** /**
* *
* @param {AssetApiRestoreAssetsRequest} requestParameters Request parameters. * @param {AssetApiRestoreAssetsRequest} requestParameters Request parameters.
@ -9527,20 +9373,6 @@ export interface AssetApiGetUserAssetsByDeviceIdRequest {
readonly deviceId: string readonly deviceId: string
} }
/**
* Request parameters for importFile operation in AssetApi.
* @export
* @interface AssetApiImportFileRequest
*/
export interface AssetApiImportFileRequest {
/**
*
* @type {ImportAssetDto}
* @memberof AssetApiImportFile
*/
readonly importAssetDto: ImportAssetDto
}
/** /**
* Request parameters for restoreAssets operation in AssetApi. * Request parameters for restoreAssets operation in AssetApi.
* @export * @export
@ -10282,17 +10114,6 @@ export class AssetApi extends BaseAPI {
return AssetApiFp(this.configuration).getUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(this.axios, this.basePath)); return AssetApiFp(this.configuration).getUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(this.axios, this.basePath));
} }
/**
*
* @param {AssetApiImportFileRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof AssetApi
*/
public importFile(requestParameters: AssetApiImportFileRequest, options?: AxiosRequestConfig) {
return AssetApiFp(this.configuration).importFile(requestParameters.importAssetDto, options).then((request) => request(this.axios, this.basePath));
}
/** /**
* *
* @param {AssetApiRestoreAssetsRequest} requestParameters Request parameters. * @param {AssetApiRestoreAssetsRequest} requestParameters Request parameters.

View File

@ -66,7 +66,6 @@ doc/FileChecksumResponseDto.md
doc/FileReportDto.md doc/FileReportDto.md
doc/FileReportFixDto.md doc/FileReportFixDto.md
doc/FileReportItemDto.md doc/FileReportItemDto.md
doc/ImportAssetDto.md
doc/JobApi.md doc/JobApi.md
doc/JobCommand.md doc/JobCommand.md
doc/JobCommandDto.md doc/JobCommandDto.md
@ -255,7 +254,6 @@ lib/model/file_checksum_response_dto.dart
lib/model/file_report_dto.dart lib/model/file_report_dto.dart
lib/model/file_report_fix_dto.dart lib/model/file_report_fix_dto.dart
lib/model/file_report_item_dto.dart lib/model/file_report_item_dto.dart
lib/model/import_asset_dto.dart
lib/model/job_command.dart lib/model/job_command.dart
lib/model/job_command_dto.dart lib/model/job_command_dto.dart
lib/model/job_counts_dto.dart lib/model/job_counts_dto.dart
@ -413,7 +411,6 @@ test/file_checksum_response_dto_test.dart
test/file_report_dto_test.dart test/file_report_dto_test.dart
test/file_report_fix_dto_test.dart test/file_report_fix_dto_test.dart
test/file_report_item_dto_test.dart test/file_report_item_dto_test.dart
test/import_asset_dto_test.dart
test/job_api_test.dart test/job_api_test.dart
test/job_command_dto_test.dart test/job_command_dto_test.dart
test/job_command_test.dart test/job_command_test.dart

BIN
mobile/openapi/README.md generated

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1485,48 +1485,6 @@
] ]
} }
}, },
"/asset/import": {
"post": {
"operationId": "importFile",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ImportAssetDto"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AssetFileUploadResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Asset"
]
}
},
"/asset/jobs": { "/asset/jobs": {
"post": { "post": {
"operationId": "runAssetJobs", "operationId": "runAssetJobs",
@ -7540,64 +7498,6 @@
], ],
"type": "object" "type": "object"
}, },
"ImportAssetDto": {
"properties": {
"assetPath": {
"type": "string"
},
"deviceAssetId": {
"type": "string"
},
"deviceId": {
"type": "string"
},
"duration": {
"type": "string"
},
"fileCreatedAt": {
"format": "date-time",
"type": "string"
},
"fileModifiedAt": {
"format": "date-time",
"type": "string"
},
"isArchived": {
"type": "boolean"
},
"isExternal": {
"type": "boolean"
},
"isFavorite": {
"type": "boolean"
},
"isOffline": {
"type": "boolean"
},
"isReadOnly": {
"default": true,
"type": "boolean"
},
"isVisible": {
"type": "boolean"
},
"libraryId": {
"format": "uuid",
"type": "string"
},
"sidecarPath": {
"type": "string"
}
},
"required": [
"assetPath",
"deviceAssetId",
"deviceId",
"fileCreatedAt",
"fileModifiedAt"
],
"type": "object"
},
"JobCommand": { "JobCommand": {
"enum": [ "enum": [
"start", "start",

View File

@ -24,7 +24,7 @@ import { AssetService } from './asset.service';
import { AssetBulkUploadCheckDto } from './dto/asset-check.dto'; import { AssetBulkUploadCheckDto } from './dto/asset-check.dto';
import { AssetSearchDto } from './dto/asset-search.dto'; import { AssetSearchDto } from './dto/asset-search.dto';
import { CheckExistingAssetsDto } from './dto/check-existing-assets.dto'; import { CheckExistingAssetsDto } from './dto/check-existing-assets.dto';
import { CreateAssetDto, ImportAssetDto } from './dto/create-asset.dto'; import { CreateAssetDto } from './dto/create-asset.dto';
import { DeviceIdDto } from './dto/device-id.dto'; import { DeviceIdDto } from './dto/device-id.dto';
import { GetAssetThumbnailDto } from './dto/get-asset-thumbnail.dto'; import { GetAssetThumbnailDto } from './dto/get-asset-thumbnail.dto';
import { ServeFileDto } from './dto/serve-file.dto'; import { ServeFileDto } from './dto/serve-file.dto';
@ -81,20 +81,6 @@ export class AssetController {
return responseDto; return responseDto;
} }
@Post('import')
async importFile(
@AuthUser() authUser: AuthUserDto,
@Body(new ValidationPipe({ transform: true })) dto: ImportAssetDto,
@Response({ passthrough: true }) res: Res,
): Promise<AssetFileUploadResponseDto> {
const responseDto = await this.assetService.importFile(authUser, dto);
if (responseDto.duplicate) {
res.status(200);
}
return responseDto;
}
@SharedLinkRoute() @SharedLinkRoute()
@Get('/file/:id') @Get('/file/:id')
@ApiOkResponse({ @ApiOkResponse({

View File

@ -2,7 +2,7 @@ import { AuthUserDto, IJobRepository, JobName, mimeTypes, UploadFile } from '@ap
import { AssetEntity } from '@app/infra/entities'; import { AssetEntity } from '@app/infra/entities';
import { parse } from 'node:path'; import { parse } from 'node:path';
import { IAssetRepository } from './asset-repository'; import { IAssetRepository } from './asset-repository';
import { CreateAssetDto, ImportAssetDto } from './dto/create-asset.dto'; import { CreateAssetDto } from './dto/create-asset.dto';
export class AssetCore { export class AssetCore {
constructor( constructor(
@ -12,7 +12,7 @@ export class AssetCore {
async create( async create(
authUser: AuthUserDto, authUser: AuthUserDto,
dto: (CreateAssetDto | ImportAssetDto) & { libraryId: string }, dto: CreateAssetDto & { libraryId: string },
file: UploadFile, file: UploadFile,
livePhotoAssetId?: string, livePhotoAssetId?: string,
sidecarPath?: string, sidecarPath?: string,

View File

@ -1,4 +1,4 @@
import { ICryptoRepository, IJobRepository, ILibraryRepository, IStorageRepository, JobName } from '@app/domain'; import { IJobRepository, ILibraryRepository, JobName } from '@app/domain';
import { ASSET_CHECKSUM_CONSTRAINT, AssetEntity, AssetType, ExifEntity } from '@app/infra/entities'; import { ASSET_CHECKSUM_CONSTRAINT, AssetEntity, AssetType, ExifEntity } from '@app/infra/entities';
import { BadRequestException } from '@nestjs/common'; import { BadRequestException } from '@nestjs/common';
import { import {
@ -7,10 +7,8 @@ import {
authStub, authStub,
fileStub, fileStub,
newAccessRepositoryMock, newAccessRepositoryMock,
newCryptoRepositoryMock,
newJobRepositoryMock, newJobRepositoryMock,
newLibraryRepositoryMock, newLibraryRepositoryMock,
newStorageRepositoryMock,
} from '@test'; } from '@test';
import { when } from 'jest-when'; import { when } from 'jest-when';
import { QueryFailedError } from 'typeorm'; import { QueryFailedError } from 'typeorm';
@ -87,9 +85,7 @@ describe('AssetService', () => {
let sut: AssetService; let sut: AssetService;
let accessMock: IAccessRepositoryMock; let accessMock: IAccessRepositoryMock;
let assetRepositoryMock: jest.Mocked<IAssetRepository>; let assetRepositoryMock: jest.Mocked<IAssetRepository>;
let cryptoMock: jest.Mocked<ICryptoRepository>;
let jobMock: jest.Mocked<IJobRepository>; let jobMock: jest.Mocked<IJobRepository>;
let storageMock: jest.Mocked<IStorageRepository>;
let libraryMock: jest.Mocked<ILibraryRepository>; let libraryMock: jest.Mocked<ILibraryRepository>;
beforeEach(() => { beforeEach(() => {
@ -109,12 +105,10 @@ describe('AssetService', () => {
}; };
accessMock = newAccessRepositoryMock(); accessMock = newAccessRepositoryMock();
cryptoMock = newCryptoRepositoryMock();
jobMock = newJobRepositoryMock(); jobMock = newJobRepositoryMock();
storageMock = newStorageRepositoryMock();
libraryMock = newLibraryRepositoryMock(); libraryMock = newLibraryRepositoryMock();
sut = new AssetService(accessMock, assetRepositoryMock, cryptoMock, jobMock, libraryMock, storageMock); sut = new AssetService(accessMock, assetRepositoryMock, jobMock, libraryMock);
when(assetRepositoryMock.get) when(assetRepositoryMock.get)
.calledWith(assetStub.livePhotoStillAsset.id) .calledWith(assetStub.livePhotoStillAsset.id)
@ -164,7 +158,6 @@ describe('AssetService', () => {
name: JobName.DELETE_FILES, name: JobName.DELETE_FILES,
data: { files: ['fake_path/asset_1.jpeg', undefined, undefined] }, data: { files: ['fake_path/asset_1.jpeg', undefined, undefined] },
}); });
expect(storageMock.moveFile).not.toHaveBeenCalled();
}); });
it('should handle a live photo', async () => { it('should handle a live photo', async () => {
@ -237,47 +230,6 @@ describe('AssetService', () => {
}); });
}); });
describe('importFile', () => {
it('should handle a file import', async () => {
assetRepositoryMock.create.mockResolvedValue(assetStub.image);
storageMock.checkFileExists.mockResolvedValue(true);
accessMock.library.hasOwnerAccess.mockResolvedValue(true);
await expect(
sut.importFile(authStub.external1, {
..._getCreateAssetDto(),
assetPath: '/data/user1/fake_path/asset_1.jpeg',
isReadOnly: true,
libraryId: 'library-id',
}),
).resolves.toEqual({ duplicate: false, id: 'asset-id' });
expect(assetRepositoryMock.create).toHaveBeenCalled();
});
it('should handle a duplicate if originalPath already exists', async () => {
const error = new QueryFailedError('', [], '');
(error as any).constraint = ASSET_CHECKSUM_CONSTRAINT;
assetRepositoryMock.create.mockRejectedValue(error);
assetRepositoryMock.getAssetsByChecksums.mockResolvedValue([assetStub.image]);
storageMock.checkFileExists.mockResolvedValue(true);
accessMock.library.hasOwnerAccess.mockResolvedValue(true);
cryptoMock.hashFile.mockResolvedValue(Buffer.from('file hash', 'utf8'));
await expect(
sut.importFile(authStub.external1, {
..._getCreateAssetDto(),
assetPath: '/data/user1/fake_path/asset_1.jpeg',
isReadOnly: true,
libraryId: 'library-id',
}),
).resolves.toEqual({ duplicate: true, id: 'asset-id' });
expect(assetRepositoryMock.create).toHaveBeenCalled();
});
});
describe('getAssetById', () => { describe('getAssetById', () => {
it('should allow owner access', async () => { it('should allow owner access', async () => {
accessMock.asset.hasOwnerAccess.mockResolvedValue(true); accessMock.asset.hasOwnerAccess.mockResolvedValue(true);

View File

@ -4,10 +4,8 @@ import {
AuthUserDto, AuthUserDto,
getLivePhotoMotionFilename, getLivePhotoMotionFilename,
IAccessRepository, IAccessRepository,
ICryptoRepository,
IJobRepository, IJobRepository,
ILibraryRepository, ILibraryRepository,
IStorageRepository,
JobName, JobName,
mapAsset, mapAsset,
mimeTypes, mimeTypes,
@ -16,14 +14,7 @@ import {
UploadFile, UploadFile,
} from '@app/domain'; } from '@app/domain';
import { ASSET_CHECKSUM_CONSTRAINT, AssetEntity, AssetType, LibraryType } from '@app/infra/entities'; import { ASSET_CHECKSUM_CONSTRAINT, AssetEntity, AssetType, LibraryType } from '@app/infra/entities';
import { import { Inject, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common';
BadRequestException,
Inject,
Injectable,
InternalServerErrorException,
Logger,
NotFoundException,
} from '@nestjs/common';
import { Response as Res, Response } from 'express'; import { Response as Res, Response } from 'express';
import { constants } from 'fs'; import { constants } from 'fs';
import fs from 'fs/promises'; import fs from 'fs/promises';
@ -34,7 +25,7 @@ import { AssetCore } from './asset.core';
import { AssetBulkUploadCheckDto } from './dto/asset-check.dto'; import { AssetBulkUploadCheckDto } from './dto/asset-check.dto';
import { AssetSearchDto } from './dto/asset-search.dto'; import { AssetSearchDto } from './dto/asset-search.dto';
import { CheckExistingAssetsDto } from './dto/check-existing-assets.dto'; import { CheckExistingAssetsDto } from './dto/check-existing-assets.dto';
import { CreateAssetDto, ImportAssetDto } from './dto/create-asset.dto'; import { CreateAssetDto } from './dto/create-asset.dto';
import { GetAssetThumbnailDto, GetAssetThumbnailFormatEnum } from './dto/get-asset-thumbnail.dto'; import { GetAssetThumbnailDto, GetAssetThumbnailFormatEnum } from './dto/get-asset-thumbnail.dto';
import { SearchPropertiesDto } from './dto/search-properties.dto'; import { SearchPropertiesDto } from './dto/search-properties.dto';
import { ServeFileDto } from './dto/serve-file.dto'; import { ServeFileDto } from './dto/serve-file.dto';
@ -60,10 +51,8 @@ export class AssetService {
constructor( constructor(
@Inject(IAccessRepository) accessRepository: IAccessRepository, @Inject(IAccessRepository) accessRepository: IAccessRepository,
@Inject(IAssetRepository) private _assetRepository: IAssetRepository, @Inject(IAssetRepository) private _assetRepository: IAssetRepository,
@Inject(ICryptoRepository) private cryptoRepository: ICryptoRepository,
@Inject(IJobRepository) private jobRepository: IJobRepository, @Inject(IJobRepository) private jobRepository: IJobRepository,
@Inject(ILibraryRepository) private libraryRepository: ILibraryRepository, @Inject(ILibraryRepository) private libraryRepository: ILibraryRepository,
@Inject(IStorageRepository) private storageRepository: IStorageRepository,
) { ) {
this.assetCore = new AssetCore(_assetRepository, jobRepository); this.assetCore = new AssetCore(_assetRepository, jobRepository);
this.access = AccessCore.create(accessRepository); this.access = AccessCore.create(accessRepository);
@ -121,59 +110,6 @@ export class AssetService {
} }
} }
public async importFile(authUser: AuthUserDto, dto: ImportAssetDto): Promise<AssetFileUploadResponseDto> {
dto = {
...dto,
assetPath: path.resolve(dto.assetPath),
sidecarPath: dto.sidecarPath ? path.resolve(dto.sidecarPath) : undefined,
};
if (!mimeTypes.isAsset(dto.assetPath)) {
throw new BadRequestException(`Unsupported file type ${dto.assetPath}`);
}
if (dto.sidecarPath && !mimeTypes.isSidecar(dto.sidecarPath)) {
throw new BadRequestException(`Unsupported sidecar file type`);
}
for (const filepath of [dto.assetPath, dto.sidecarPath]) {
if (!filepath) {
continue;
}
const exists = await this.storageRepository.checkFileExists(filepath, constants.R_OK);
if (!exists) {
throw new BadRequestException('File does not exist');
}
}
if (!authUser.externalPath || !dto.assetPath.match(new RegExp(`^${authUser.externalPath}`))) {
throw new BadRequestException("File does not exist within user's external path");
}
const assetFile: UploadFile = {
checksum: await this.cryptoRepository.hashFile(dto.assetPath),
originalPath: dto.assetPath,
originalName: path.parse(dto.assetPath).name,
};
try {
const libraryId = await this.getLibraryId(authUser, dto.libraryId);
await this.access.requirePermission(authUser, Permission.ASSET_UPLOAD, libraryId);
const asset = await this.assetCore.create(authUser, { ...dto, libraryId }, assetFile, undefined, dto.sidecarPath);
return { id: asset.id, duplicate: false };
} catch (error: QueryFailedError | Error | any) {
// handle duplicates with a success response
if (error instanceof QueryFailedError && (error as any).constraint === ASSET_CHECKSUM_CONSTRAINT) {
const [duplicate] = await this._assetRepository.getAssetsByChecksums(authUser.id, [assetFile.checksum]);
return { id: duplicate.id, duplicate: true };
}
this.logger.error(`Error importing file ${error}`, error?.stack);
throw new BadRequestException(`Error importing file`, `${error}`);
}
}
public async getUserAssetsByDeviceId(authUser: AuthUserDto, deviceId: string) { public async getUserAssetsByDeviceId(authUser: AuthUserDto, deviceId: string) {
return this._assetRepository.getAllByDeviceId(authUser.id, deviceId); return this._assetRepository.getAllByDeviceId(authUser.id, deviceId);
} }

View File

@ -70,23 +70,3 @@ export class CreateAssetDto extends CreateAssetBase {
@ApiProperty({ type: 'string', format: 'binary', required: false }) @ApiProperty({ type: 'string', format: 'binary', required: false })
[UploadFieldName.SIDECAR_DATA]?: any; [UploadFieldName.SIDECAR_DATA]?: any;
} }
export class ImportAssetDto extends CreateAssetBase {
@Optional()
@IsBoolean()
@Transform(toBoolean)
isReadOnly?: boolean = true;
@ValidateUUID()
@Optional()
libraryId?: string;
@IsString()
@IsNotEmpty()
assetPath!: string;
@IsString()
@Optional()
@IsNotEmpty()
sidecarPath?: string;
}

View File

@ -1773,97 +1773,6 @@ export interface FileReportItemDto {
} }
/**
*
* @export
* @interface ImportAssetDto
*/
export interface ImportAssetDto {
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'assetPath': string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'deviceAssetId': string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'deviceId': string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'duration'?: string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'fileCreatedAt': string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'fileModifiedAt': string;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isArchived'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isExternal'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isFavorite'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isOffline'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isReadOnly'?: boolean;
/**
*
* @type {boolean}
* @memberof ImportAssetDto
*/
'isVisible'?: boolean;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'libraryId'?: string;
/**
*
* @type {string}
* @memberof ImportAssetDto
*/
'sidecarPath'?: string;
}
/** /**
* *
* @export * @export
@ -7609,50 +7518,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
options: localVarRequestOptions, options: localVarRequestOptions,
}; };
}, },
/**
*
* @param {ImportAssetDto} importAssetDto
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
importFile: async (importAssetDto: ImportAssetDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'importAssetDto' is not null or undefined
assertParamExists('importFile', 'importAssetDto', importAssetDto)
const localVarPath = `/asset/import`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication cookie required
// authentication api_key required
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
// authentication bearer required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(importAssetDto, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/** /**
* *
* @param {BulkIdsDto} bulkIdsDto * @param {BulkIdsDto} bulkIdsDto
@ -8602,16 +8467,6 @@ export const AssetApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.getUserAssetsByDeviceId(deviceId, options); const localVarAxiosArgs = await localVarAxiosParamCreator.getUserAssetsByDeviceId(deviceId, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
}, },
/**
*
* @param {ImportAssetDto} importAssetDto
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async importFile(importAssetDto: ImportAssetDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AssetFileUploadResponseDto>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.importFile(importAssetDto, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/** /**
* *
* @param {BulkIdsDto} bulkIdsDto * @param {BulkIdsDto} bulkIdsDto
@ -8945,15 +8800,6 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
getUserAssetsByDeviceId(requestParameters: AssetApiGetUserAssetsByDeviceIdRequest, options?: AxiosRequestConfig): AxiosPromise<Array<string>> { getUserAssetsByDeviceId(requestParameters: AssetApiGetUserAssetsByDeviceIdRequest, options?: AxiosRequestConfig): AxiosPromise<Array<string>> {
return localVarFp.getUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(axios, basePath)); return localVarFp.getUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(axios, basePath));
}, },
/**
*
* @param {AssetApiImportFileRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
importFile(requestParameters: AssetApiImportFileRequest, options?: AxiosRequestConfig): AxiosPromise<AssetFileUploadResponseDto> {
return localVarFp.importFile(requestParameters.importAssetDto, options).then((request) => request(axios, basePath));
},
/** /**
* *
* @param {AssetApiRestoreAssetsRequest} requestParameters Request parameters. * @param {AssetApiRestoreAssetsRequest} requestParameters Request parameters.
@ -9527,20 +9373,6 @@ export interface AssetApiGetUserAssetsByDeviceIdRequest {
readonly deviceId: string readonly deviceId: string
} }
/**
* Request parameters for importFile operation in AssetApi.
* @export
* @interface AssetApiImportFileRequest
*/
export interface AssetApiImportFileRequest {
/**
*
* @type {ImportAssetDto}
* @memberof AssetApiImportFile
*/
readonly importAssetDto: ImportAssetDto
}
/** /**
* Request parameters for restoreAssets operation in AssetApi. * Request parameters for restoreAssets operation in AssetApi.
* @export * @export
@ -10282,17 +10114,6 @@ export class AssetApi extends BaseAPI {
return AssetApiFp(this.configuration).getUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(this.axios, this.basePath)); return AssetApiFp(this.configuration).getUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(this.axios, this.basePath));
} }
/**
*
* @param {AssetApiImportFileRequest} requestParameters Request parameters.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof AssetApi
*/
public importFile(requestParameters: AssetApiImportFileRequest, options?: AxiosRequestConfig) {
return AssetApiFp(this.configuration).importFile(requestParameters.importAssetDto, options).then((request) => request(this.axios, this.basePath));
}
/** /**
* *
* @param {AssetApiRestoreAssetsRequest} requestParameters Request parameters. * @param {AssetApiRestoreAssetsRequest} requestParameters Request parameters.