mirror of
https://github.com/immich-app/immich.git
synced 2024-12-25 10:43:13 +02:00
hotfix(server): skip exif extraction on duplicate file (#590)
* fix(server): skip exif extraction on duplicate file * fix(server): typo * chore(server): remvoe un-use code
This commit is contained in:
parent
a467936e73
commit
7f6837c751
@ -47,6 +47,7 @@ import { GetAssetThumbnailDto } from './dto/get-asset-thumbnail.dto';
|
||||
import { AssetCountByTimeBucketResponseDto } from './response-dto/asset-count-by-time-group-response.dto';
|
||||
import { GetAssetCountByTimeBucketDto } from './dto/get-asset-count-by-time-bucket.dto';
|
||||
import { GetAssetByTimeBucketDto } from './dto/get-asset-by-time-bucket.dto';
|
||||
import { QueryFailedError } from 'typeorm';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@ -74,8 +75,11 @@ export class AssetController {
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@Body(ValidationPipe) assetInfo: CreateAssetDto,
|
||||
): Promise<AssetFileUploadResponseDto> {
|
||||
const checksum = await this.assetService.calculateChecksum(file.path);
|
||||
|
||||
try {
|
||||
const savedAsset = await this.assetService.createUserAsset(authUser, assetInfo, file.path, file.mimetype);
|
||||
const savedAsset = await this.assetService.createUserAsset(authUser, assetInfo, file.path, file.mimetype, checksum);
|
||||
|
||||
if (!savedAsset) {
|
||||
await this.backgroundTaskService.deleteFileOnDisk([
|
||||
{
|
||||
@ -92,14 +96,20 @@ export class AssetController {
|
||||
);
|
||||
|
||||
return new AssetFileUploadResponseDto(savedAsset.id);
|
||||
} catch (e) {
|
||||
Logger.error(`Error uploading file ${e}`);
|
||||
} catch (err) {
|
||||
await this.backgroundTaskService.deleteFileOnDisk([
|
||||
{
|
||||
originalPath: file.path,
|
||||
} as any,
|
||||
]); // simulate asset to make use of delete queue (or use fs.unlink instead)
|
||||
throw new BadRequestException(`Error uploading file`, `${e}`);
|
||||
|
||||
if (err instanceof QueryFailedError && (err as any).constraint === 'UQ_userid_checksum') {
|
||||
const existedAsset = await this.assetService.getAssetByChecksum(authUser.id, checksum)
|
||||
return new AssetFileUploadResponseDto(existedAsset.id);
|
||||
}
|
||||
|
||||
Logger.error(`Error uploading file ${err}`);
|
||||
throw new BadRequestException(`Error uploading file`, `${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { QueryFailedError, Repository } from 'typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||
import { AssetEntity, AssetType } from '@app/database/entities/asset.entity';
|
||||
import { constants, createReadStream, ReadStream, stat } from 'fs';
|
||||
@ -53,31 +53,17 @@ export class AssetService {
|
||||
createAssetDto: CreateAssetDto,
|
||||
originalPath: string,
|
||||
mimeType: string,
|
||||
checksum: Buffer,
|
||||
): Promise<AssetEntity> {
|
||||
const checksum = await this.calculateChecksum(originalPath);
|
||||
const assetEntity = await this._assetRepository.create(
|
||||
createAssetDto,
|
||||
authUser.id,
|
||||
originalPath,
|
||||
mimeType,
|
||||
checksum,
|
||||
);
|
||||
|
||||
try {
|
||||
const assetEntity = await this._assetRepository.create(
|
||||
createAssetDto,
|
||||
authUser.id,
|
||||
originalPath,
|
||||
mimeType,
|
||||
checksum,
|
||||
);
|
||||
|
||||
return assetEntity;
|
||||
} catch (err) {
|
||||
if (err instanceof QueryFailedError && (err as any).constraint === 'UQ_userid_checksum') {
|
||||
const [assetEntity, _] = await Promise.all([
|
||||
this._assetRepository.getAssetByChecksum(authUser.id, checksum),
|
||||
fs.unlink(originalPath)
|
||||
]);
|
||||
|
||||
return assetEntity;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
return assetEntity;
|
||||
}
|
||||
|
||||
public async getUserAssetsByDeviceId(authUser: AuthUserDto, deviceId: string) {
|
||||
@ -478,7 +464,11 @@ export class AssetService {
|
||||
return mapAssetCountByTimeBucket(result);
|
||||
}
|
||||
|
||||
private calculateChecksum(filePath: string): Promise<Buffer> {
|
||||
getAssetByChecksum(userId: string, checksum: Buffer) {
|
||||
return this._assetRepository.getAssetByChecksum(userId, checksum);
|
||||
}
|
||||
|
||||
calculateChecksum(filePath: string): Promise<Buffer> {
|
||||
const fileReadStream = createReadStream(filePath);
|
||||
const sha1Hash = createHash('sha1');
|
||||
const deferred = new Promise<Buffer>((resolve, reject) => {
|
||||
|
Loading…
Reference in New Issue
Block a user