diff --git a/server/apps/immich/src/config/asset-upload.config.ts b/server/apps/immich/src/config/asset-upload.config.ts index cbbb3a2c3d..1a9c086d5a 100644 --- a/server/apps/immich/src/config/asset-upload.config.ts +++ b/server/apps/immich/src/config/asset-upload.config.ts @@ -26,16 +26,18 @@ function fileFilter(req: Request, file: any, cb: any) { if (!req.user) { return cb(new UnauthorizedException()); } - if ( - file.mimetype.match( - /\/(jpg|jpeg|png|gif|mp4|webm|x-msvideo|quicktime|heic|heif|dng|x-adobe-dng|webp|tiff|3gpp|nef|x-nikon-nef)$/, - ) - ) { - cb(null, true); - } else { - logger.error(`Unsupported file type ${extname(file.originalname)} file MIME type ${file.mimetype}`); - cb(new BadRequestException(`Unsupported file type ${extname(file.originalname)}`), false); - } + // TODO: Create new API endpoint for mimetypes and use that here. + cb(null, true); + //if ( + // file.mimetype.match( + // /\/(jpg|jpeg|png|gif|mp4|webm|x-msvideo|quicktime|heic|heif|dng|x-adobe-dng|webp|tiff|3gpp|nef|x-nikon-nef)$/, + // ) + //) { + // cb(null, true); + //} else { + // logger.error(`Unsupported file type ${extname(file.originalname)} file MIME type ${filetype}`); + // cb(new BadRequestException(`Unsupported file type ${extname(file.originalname)}`), false); + // } } function destination(req: Request, file: Express.Multer.File, cb: any) { diff --git a/server/apps/microservices/src/processors/thumbnail.processor.ts b/server/apps/microservices/src/processors/thumbnail.processor.ts index 0d51981ba6..106ceccea2 100644 --- a/server/apps/microservices/src/processors/thumbnail.processor.ts +++ b/server/apps/microservices/src/processors/thumbnail.processor.ts @@ -14,6 +14,7 @@ import { Repository } from 'typeorm/repository/Repository'; import { join } from 'path'; import { CommunicationGateway } from 'apps/immich/src/api-v1/communication/communication.gateway'; import { IMachineLearningJob } from '@app/domain'; +import { exiftool } from 'exiftool-vendored'; @Processor(QueueName.THUMBNAIL_GENERATION) export class ThumbnailGeneratorProcessor { @@ -49,11 +50,19 @@ export class ThumbnailGeneratorProcessor { if (asset.type == AssetType.IMAGE) { try { - await sharp(asset.originalPath, { failOnError: false }) + await sharp(asset.originalPath, { failOnError: true }) .resize(1440, 2560, { fit: 'inside' }) .jpeg() .rotate() - .toFile(jpegThumbnailPath); + .toFile(jpegThumbnailPath) + .catch(() => { + this.logger.warn( + 'Failed to generate jpeg thumbnail for asset: ' + + asset.id + + ' using sharp, failing over to exiftool-vendored', + ); + exiftool.extractThumbnail(asset.originalPath, jpegThumbnailPath); + }); await this.assetRepository.update({ id: asset.id }, { resizePath: jpegThumbnailPath }); } catch (error: any) { this.logger.error('Failed to generate jpeg thumbnail for asset: ' + asset.id, error.stack);