瀏覽代碼

fix(server): add missing avi mime types and add tests (#3001)

See https://github.com/immich-app/immich/pull/2952#pullrequestreview-1497194041

Fixes: #2975
Thomas 2 年之前
父節點
當前提交
792ecc6cac

+ 21 - 0
server/src/domain/domain.constant.spec.ts

@@ -0,0 +1,21 @@
+import { validMimeTypes } from './domain.constant';
+
+describe('valid mime types', () => {
+  it('should be a sorted list', () => {
+    expect(validMimeTypes).toEqual(validMimeTypes.sort());
+  });
+
+  it('should contain only unique values', () => {
+    expect(validMimeTypes).toEqual([...new Set(validMimeTypes)]);
+  });
+
+  it('should contain only image or video mime types', () => {
+    expect(validMimeTypes).toEqual(
+      validMimeTypes.filter((mimeType) => mimeType.startsWith('image/') || mimeType.startsWith('video/')),
+    );
+  });
+
+  it('should contain only lowercase mime types', () => {
+    expect(validMimeTypes).toEqual(validMimeTypes.map((mimeType) => mimeType.toLowerCase()));
+  });
+});

+ 29 - 28
server/src/domain/domain.constant.ts

@@ -28,16 +28,40 @@ export function assertMachineLearningEnabled() {
   }
 }
 
-const validMimeTypes = [
+export const validMimeTypes = [
+  'image/3fr',
+  'image/ari',
+  'image/arw',
   'image/avif',
+  'image/cap',
+  'image/cin',
+  'image/cr2',
   'image/cr3',
+  'image/crw',
+  'image/dcr',
+  'image/dng',
+  'image/erf',
+  'image/fff',
   'image/gif',
   'image/heic',
   'image/heif',
+  'image/iiq',
   'image/jpeg',
   'image/jxl',
+  'image/k25',
+  'image/kdc',
+  'image/mrw',
+  'image/nef',
+  'image/orf',
+  'image/ori',
+  'image/pef',
   'image/png',
-  'image/dng',
+  'image/raf',
+  'image/raw',
+  'image/rwl',
+  'image/sr2',
+  'image/srf',
+  'image/srw',
   'image/tiff',
   'image/webp',
   'image/x-adobe-dng',
@@ -67,38 +91,15 @@ const validMimeTypes = [
   'image/x-sony-arw',
   'image/x-sony-sr2',
   'image/x-sony-srf',
-  'image/dng',
-  'image/ari',
-  'image/cr2',
-  'image/cr3',
-  'image/crw',
-  'image/erf',
-  'image/raf',
-  'image/3fr',
-  'image/fff',
-  'image/dcr',
-  'image/k25',
-  'image/kdc',
-  'image/rwl',
-  'image/mrw',
-  'image/nef',
-  'image/orf',
-  'image/ori',
-  'image/raw',
-  'image/pef',
-  'image/cin',
-  'image/cap',
-  'image/iiq',
-  'image/srw',
   'image/x3f',
-  'image/arw',
-  'image/sr2',
-  'image/srf',
   'video/3gpp',
+  'video/avi',
   'video/mp2t',
   'video/mp4',
   'video/mpeg',
+  'video/msvideo',
   'video/quicktime',
+  'video/vnd.avi',
   'video/webm',
   'video/x-flv',
   'video/x-matroska',

+ 30 - 27
server/src/immich/config/asset-upload.config.spec.ts

@@ -50,14 +50,41 @@ describe('assetUploadOption', () => {
     });
 
     for (const { mimetype, extension } of [
+      // Please ensure this list is sorted.
+      { mimetype: 'image/3fr', extension: '3fr' },
+      { mimetype: 'image/ari', extension: 'ari' },
+      { mimetype: 'image/arw', extension: 'arw' },
       { mimetype: 'image/avif', extension: 'avif' },
+      { mimetype: 'image/cap', extension: 'cap' },
+      { mimetype: 'image/cin', extension: 'cin' },
+      { mimetype: 'image/cr2', extension: 'cr2' },
+      { mimetype: 'image/cr3', extension: 'cr3' },
+      { mimetype: 'image/crw', extension: 'crw' },
+      { mimetype: 'image/dcr', extension: 'dcr' },
+      { mimetype: 'image/dng', extension: 'dng' },
+      { mimetype: 'image/erf', extension: 'erf' },
+      { mimetype: 'image/fff', extension: 'fff' },
       { mimetype: 'image/gif', extension: 'gif' },
       { mimetype: 'image/heic', extension: 'heic' },
       { mimetype: 'image/heif', extension: 'heif' },
+      { mimetype: 'image/iiq', extension: 'iiq' },
       { mimetype: 'image/jpeg', extension: 'jpeg' },
       { mimetype: 'image/jpeg', extension: 'jpg' },
       { mimetype: 'image/jxl', extension: 'jxl' },
+      { mimetype: 'image/k25', extension: 'k25' },
+      { mimetype: 'image/kdc', extension: 'kdc' },
+      { mimetype: 'image/mrw', extension: 'mrw' },
+      { mimetype: 'image/nef', extension: 'nef' },
+      { mimetype: 'image/orf', extension: 'orf' },
+      { mimetype: 'image/ori', extension: 'ori' },
+      { mimetype: 'image/pef', extension: 'pef' },
       { mimetype: 'image/png', extension: 'png' },
+      { mimetype: 'image/raf', extension: 'raf' },
+      { mimetype: 'image/raw', extension: 'raw' },
+      { mimetype: 'image/rwl', extension: 'rwl' },
+      { mimetype: 'image/sr2', extension: 'sr2' },
+      { mimetype: 'image/srf', extension: 'srf' },
+      { mimetype: 'image/srw', extension: 'srw' },
       { mimetype: 'image/tiff', extension: 'tiff' },
       { mimetype: 'image/webp', extension: 'webp' },
       { mimetype: 'image/x-adobe-dng', extension: 'dng' },
@@ -87,40 +114,16 @@ describe('assetUploadOption', () => {
       { mimetype: 'image/x-sony-arw', extension: 'arw' },
       { mimetype: 'image/x-sony-sr2', extension: 'sr2' },
       { mimetype: 'image/x-sony-srf', extension: 'srf' },
-
-      { mimetype: 'image/dng', extension: 'dng' },
-      { mimetype: 'image/ari', extension: 'ari' },
-      { mimetype: 'image/cr2', extension: 'cr2' },
-      { mimetype: 'image/cr3', extension: 'cr3' },
-      { mimetype: 'image/crw', extension: 'crw' },
-      { mimetype: 'image/erf', extension: 'erf' },
-      { mimetype: 'image/raf', extension: 'raf' },
-      { mimetype: 'image/3fr', extension: '3fr' },
-      { mimetype: 'image/fff', extension: 'fff' },
-      { mimetype: 'image/dcr', extension: 'dcr' },
-      { mimetype: 'image/k25', extension: 'k25' },
-      { mimetype: 'image/kdc', extension: 'kdc' },
-      { mimetype: 'image/rwl', extension: 'rwl' },
-      { mimetype: 'image/mrw', extension: 'mrw' },
-      { mimetype: 'image/nef', extension: 'nef' },
-      { mimetype: 'image/orf', extension: 'orf' },
-      { mimetype: 'image/ori', extension: 'ori' },
-      { mimetype: 'image/raw', extension: 'raw' },
-      { mimetype: 'image/pef', extension: 'pef' },
-      { mimetype: 'image/cin', extension: 'cin' },
-      { mimetype: 'image/cap', extension: 'cap' },
-      { mimetype: 'image/iiq', extension: 'iiq' },
-      { mimetype: 'image/srw', extension: 'srw' },
       { mimetype: 'image/x3f', extension: 'x3f' },
-      { mimetype: 'image/arw', extension: 'arw' },
-      { mimetype: 'image/sr2', extension: 'sr2' },
-      { mimetype: 'image/srf', extension: 'srf' },
       { mimetype: 'video/3gpp', extension: '3gp' },
+      { mimetype: 'video/avi', extension: 'avi' },
       { mimetype: 'video/mp2t', extension: 'm2ts' },
       { mimetype: 'video/mp2t', extension: 'mts' },
       { mimetype: 'video/mp4', extension: 'mp4' },
       { mimetype: 'video/mpeg', extension: 'mpg' },
+      { mimetype: 'video/msvideo', extension: 'avi' },
       { mimetype: 'video/quicktime', extension: 'mov' },
+      { mimetype: 'video/vnd.avi', extension: 'avi' },
       { mimetype: 'video/webm', extension: 'webm' },
       { mimetype: 'video/x-flv', extension: 'flv' },
       { mimetype: 'video/x-matroska', extension: 'mkv' },

+ 2 - 31
web/src/lib/utils/asset-utils.spec.ts

@@ -98,36 +98,8 @@ describe('get file mime type', () => {
 		{ mimetype: 'image/x-sony-arw', extension: 'arw' },
 		{ mimetype: 'image/x-sony-sr2', extension: 'sr2' },
 		{ mimetype: 'image/x-sony-srf', extension: 'srf' },
-		/*** The following MIME types are allowed for upload but not returned by getFileMimeType() ***
-		{ mimetype: 'image/dng', extension: 'dng' },
-		{ mimetype: 'image/ari', extension: 'ari' },
-		{ mimetype: 'image/cr2', extension: 'cr2' },
-		{ mimetype: 'image/cr3', extension: 'cr3' },
-		{ mimetype: 'image/crw', extension: 'crw' },
-		{ mimetype: 'image/erf', extension: 'erf' },
-		{ mimetype: 'image/raf', extension: 'raf' },
-		{ mimetype: 'image/3fr', extension: '3fr' },
-		{ mimetype: 'image/fff', extension: 'fff' },
-		{ mimetype: 'image/dcr', extension: 'dcr' },
-		{ mimetype: 'image/k25', extension: 'k25' },
-		{ mimetype: 'image/kdc', extension: 'kdc' },
-		{ mimetype: 'image/rwl', extension: 'rwl' },
-		{ mimetype: 'image/mrw', extension: 'mrw' },
-		{ mimetype: 'image/nef', extension: 'nef' },
-		{ mimetype: 'image/orf', extension: 'orf' },
-		{ mimetype: 'image/ori', extension: 'ori' },
-		{ mimetype: 'image/raw', extension: 'raw' },
-		{ mimetype: 'image/pef', extension: 'pef' },
-		{ mimetype: 'image/cin', extension: 'cin' },
-		{ mimetype: 'image/cap', extension: 'cap' },
-		{ mimetype: 'image/iiq', extension: 'iiq' },
-		{ mimetype: 'image/srw', extension: 'srw' },
-		{ mimetype: 'image/x3f', extension: 'x3f' },
-		{ mimetype: 'image/arw', extension: 'arw' },
-		{ mimetype: 'image/sr2', extension: 'sr2' },
-		{ mimetype: 'image/srf', extension: 'srf' },
-**/
 		{ mimetype: 'video/3gpp', extension: '3gp' },
+		{ mimetype: 'video/avi', extension: 'avi' },
 		{ mimetype: 'video/mp2t', extension: 'm2ts' },
 		{ mimetype: 'video/mp2t', extension: 'mts' },
 		{ mimetype: 'video/mp4', extension: 'mp4' },
@@ -136,8 +108,7 @@ describe('get file mime type', () => {
 		{ mimetype: 'video/webm', extension: 'webm' },
 		{ mimetype: 'video/x-flv', extension: 'flv' },
 		{ mimetype: 'video/x-matroska', extension: 'mkv' },
-		{ mimetype: 'video/x-ms-wmv', extension: 'wmv' },
-		{ mimetype: 'video/x-msvideo', extension: 'avi' }
+		{ mimetype: 'video/x-ms-wmv', extension: 'wmv' }
 	]) {
 		it(`returns the mime type for ${extension}`, () => {
 			expect(getFileMimeType({ name: `filename.${extension}` } as File)).toEqual(mimetype);

+ 1 - 1
web/src/lib/utils/asset-utils.ts

@@ -130,7 +130,7 @@ export function getFileMimeType(file: File): string {
 		'3gp': 'video/3gpp',
 		ari: 'image/x-arriflex-ari',
 		arw: 'image/x-sony-arw',
-		avi: 'video/x-msvideo',
+		avi: 'video/avi',
 		avif: 'image/avif',
 		cap: 'image/x-phaseone-cap',
 		cin: 'image/x-phantom-cin',