mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:29:32 -05:00 
			
		
		
		
	chore(server): update exiftool and migrate off deprecated method signatures (#10367)
* chore(server): update exiftool and migrate off deprecated method signatures * chore(server): update exiftool-vendored to 27.0.0 * chore(server): switch away from deprecated exiftool method signatures - options now includes read/writeArgs making the deprecated signatures with args array redundant - switch read call from file,args,options to file,options - switch write call from file,tags,args to file,tags,options * chore(server): move largefilesupport flags into exiftool constructor - options now includes read/writeArgs making it available to be set globally in constructor - switches back to instantiating an instance of exiftool * chore(server): consolidate exiftool config into constructor along with writeArgs * chore(server): move exiftool instantiation into MetadataRepository constructor
This commit is contained in:
		
							parent
							
								
									38e26fd67c
								
							
						
					
					
						commit
						1b67ea2d91
					
				
							
								
								
									
										15
									
								
								server/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										15
									
								
								server/package-lock.json
									
									
									
										generated
									
									
									
								
							@ -34,7 +34,7 @@
 | 
			
		||||
        "class-transformer": "^0.5.1",
 | 
			
		||||
        "class-validator": "^0.14.0",
 | 
			
		||||
        "cookie-parser": "^1.4.6",
 | 
			
		||||
        "exiftool-vendored": "~26.2.0",
 | 
			
		||||
        "exiftool-vendored": "~27.0.0",
 | 
			
		||||
        "fast-glob": "^3.3.2",
 | 
			
		||||
        "fluent-ffmpeg": "^2.1.2",
 | 
			
		||||
        "geo-tz": "^8.0.0",
 | 
			
		||||
@ -9127,9 +9127,10 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/exiftool-vendored": {
 | 
			
		||||
      "version": "26.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-26.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-7P6jQ944or7ic2SJzW+uaWK4TLDXlaCppHrBayl4MpIrVcEeQjiQTez4/oOH0wULIRu4j4H6Xruz4SLrDaafUg==",
 | 
			
		||||
      "version": "27.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-27.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-/jHX8Jjadj0YJzpqnuBo1Yy2ln2hnRbBIc+3jcVOLQ6qhHEKsLRlfJ145Ghn7k/EcnfpDzVX3V8AUCTC8juTow==",
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@photostructure/tz-lookup": "^10.0.0",
 | 
			
		||||
        "@types/luxon": "^3.4.2",
 | 
			
		||||
@ -22600,9 +22601,9 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "exiftool-vendored": {
 | 
			
		||||
      "version": "26.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-26.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-7P6jQ944or7ic2SJzW+uaWK4TLDXlaCppHrBayl4MpIrVcEeQjiQTez4/oOH0wULIRu4j4H6Xruz4SLrDaafUg==",
 | 
			
		||||
      "version": "27.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-27.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-/jHX8Jjadj0YJzpqnuBo1Yy2ln2hnRbBIc+3jcVOLQ6qhHEKsLRlfJ145Ghn7k/EcnfpDzVX3V8AUCTC8juTow==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "@photostructure/tz-lookup": "^10.0.0",
 | 
			
		||||
        "@types/luxon": "^3.4.2",
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@
 | 
			
		||||
    "class-transformer": "^0.5.1",
 | 
			
		||||
    "class-validator": "^0.14.0",
 | 
			
		||||
    "cookie-parser": "^1.4.6",
 | 
			
		||||
    "exiftool-vendored": "~26.2.0",
 | 
			
		||||
    "exiftool-vendored": "~27.0.0",
 | 
			
		||||
    "fast-glob": "^3.3.2",
 | 
			
		||||
    "fluent-ffmpeg": "^2.1.2",
 | 
			
		||||
    "geo-tz": "^8.0.0",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
 | 
			
		||||
import { DefaultReadTaskOptions, Tags, exiftool } from 'exiftool-vendored';
 | 
			
		||||
import { DefaultReadTaskOptions, ExifTool, Tags } from 'exiftool-vendored';
 | 
			
		||||
import geotz from 'geo-tz';
 | 
			
		||||
import { DummyValue, GenerateSql } from 'src/decorators';
 | 
			
		||||
import { ExifEntity } from 'src/entities/exif.entity';
 | 
			
		||||
@ -20,19 +20,7 @@ export class MetadataRepository implements IMetadataRepository {
 | 
			
		||||
    @Inject(ILoggerRepository) private logger: ILoggerRepository,
 | 
			
		||||
  ) {
 | 
			
		||||
    this.logger.setContext(MetadataRepository.name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async teardown() {
 | 
			
		||||
    await exiftool.end();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  readTags(path: string): Promise<ImmichTags | null> {
 | 
			
		||||
    return exiftool
 | 
			
		||||
      .read(path, undefined, {
 | 
			
		||||
        ...DefaultReadTaskOptions,
 | 
			
		||||
 | 
			
		||||
        // Enable exiftool LFS to parse metadata for files larger than 2GB.
 | 
			
		||||
        optionalArgs: ['-api', 'largefilesupport=1'],
 | 
			
		||||
    this.exiftool = new ExifTool({
 | 
			
		||||
      defaultVideosToUTC: true,
 | 
			
		||||
      backfillTimezones: true,
 | 
			
		||||
      inferTimezoneFromDatestamps: true,
 | 
			
		||||
@ -40,20 +28,31 @@ export class MetadataRepository implements IMetadataRepository {
 | 
			
		||||
      numericTags: [...DefaultReadTaskOptions.numericTags, 'FocalLength'],
 | 
			
		||||
      /* eslint unicorn/no-array-callback-reference: off, unicorn/no-array-method-this-argument: off */
 | 
			
		||||
      geoTz: (lat, lon) => geotz.find(lat, lon)[0],
 | 
			
		||||
      })
 | 
			
		||||
      .catch((error) => {
 | 
			
		||||
      // Enable exiftool LFS to parse metadata for files larger than 2GB.
 | 
			
		||||
      readArgs: ['-api', 'largefilesupport=1'],
 | 
			
		||||
      writeArgs: ['-api', 'largefilesupport=1', '-overwrite_original'],
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  private exiftool: ExifTool;
 | 
			
		||||
 | 
			
		||||
  async teardown() {
 | 
			
		||||
    await this.exiftool.end();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  readTags(path: string): Promise<ImmichTags | null> {
 | 
			
		||||
    return this.exiftool.read(path).catch((error) => {
 | 
			
		||||
      this.logger.warn(`Error reading exif data (${path}): ${error}`, error?.stack);
 | 
			
		||||
      return null;
 | 
			
		||||
    }) as Promise<ImmichTags | null>;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  extractBinaryTag(path: string, tagName: string): Promise<Buffer> {
 | 
			
		||||
    return exiftool.extractBinaryTagToBuffer(tagName, path);
 | 
			
		||||
    return this.exiftool.extractBinaryTagToBuffer(tagName, path);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async writeTags(path: string, tags: Partial<Tags>): Promise<void> {
 | 
			
		||||
    try {
 | 
			
		||||
      await exiftool.write(path, tags, ['-overwrite_original']);
 | 
			
		||||
      await this.exiftool.write(path, tags);
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      this.logger.warn(`Error writing exif data (${path}): ${error}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user