From 085b1a8594ec5ee0338671ac859e68406bdf3934 Mon Sep 17 00:00:00 2001 From: Stephen Smith Date: Sat, 15 Jun 2024 15:24:19 -0400 Subject: [PATCH] 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 --- server/package-lock.json | 15 ++++++----- server/package.json | 2 +- .../src/repositories/metadata.repository.ts | 26 ++++++++++++------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/server/package-lock.json b/server/package-lock.json index 6cc3572ec4f9d8..1ca61d6ed7232d 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -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", diff --git a/server/package.json b/server/package.json index 6625555bb0daad..1633302ea3e7bb 100644 --- a/server/package.json +++ b/server/package.json @@ -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", diff --git a/server/src/repositories/metadata.repository.ts b/server/src/repositories/metadata.repository.ts index 0b32233f6a8f8f..52395fc3f4fbc9 100644 --- a/server/src/repositories/metadata.repository.ts +++ b/server/src/repositories/metadata.repository.ts @@ -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, exiftool } from 'exiftool-vendored'; import geotz from 'geo-tz'; import { DummyValue, GenerateSql } from 'src/decorators'; import { ExifEntity } from 'src/entities/exif.entity'; @@ -21,18 +21,22 @@ export class MetadataRepository implements IMetadataRepository { ) { this.logger.setContext(MetadataRepository.name); } + private exiftool: ExifTool = this.initExiftool(); async teardown() { - await exiftool.end(); + await this.exiftool.end(); } - readTags(path: string): Promise { - return exiftool - .read(path, undefined, { - ...DefaultReadTaskOptions, + private initExiftool() { + return new ExifTool({ + // Enable exiftool LFS to parse metadata for files larger than 2GB. + readArgs: ['-api', 'largefilesupport=1'], + }); + } - // Enable exiftool LFS to parse metadata for files larger than 2GB. - optionalArgs: ['-api', 'largefilesupport=1'], + readTags(path: string): Promise { + return this.exiftool + .read(path, { defaultVideosToUTC: true, backfillTimezones: true, inferTimezoneFromDatestamps: true, @@ -48,12 +52,14 @@ export class MetadataRepository implements IMetadataRepository { } extractBinaryTag(path: string, tagName: string): Promise { - return exiftool.extractBinaryTagToBuffer(tagName, path); + return this.exiftool.extractBinaryTagToBuffer(tagName, path); } async writeTags(path: string, tags: Partial): Promise { try { - await exiftool.write(path, tags, ['-overwrite_original']); + await this.exiftool.write(path, tags, { + writeArgs: ['-overwrite_original'], + }); } catch (error) { this.logger.warn(`Error writing exif data (${path}): ${error}`); }