fix(server): use exiftool decoded values and unify metadata extraction (#2908)

* refactor(server): metadata extraction

* chore: upgrade exiftool

* chore: remove log

* fix: other rotation cases

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Thomas
2023-09-18 14:06:03 +01:00
committed by GitHub
parent b6c6a7e403
commit 49ef86173f
8 changed files with 440 additions and 403 deletions

View File

@@ -1,36 +0,0 @@
import { describe, expect, it } from '@jest/globals';
import { ExifDateTime } from 'exiftool-vendored';
import { exifTimeZone, exifToDate } from './date-time';
describe('converts exif date to JS date', () => {
it('returns null for invalid inputs', () => {
expect(exifToDate(undefined)).toBeNull();
expect(exifToDate('invalid')).toBeNull();
expect(exifToDate(new Date('invalid'))).toBeNull();
expect(exifToDate(ExifDateTime.fromEXIF('invalid'))).toBeNull();
});
it('returns a valid date object for valid inputs', () => {
const date = new Date('2023');
expect(exifToDate(date)).toBeInstanceOf(Date);
expect(exifToDate(date)?.toISOString()).toBe('2023-01-01T00:00:00.000Z');
expect(exifToDate('2023')).toBeInstanceOf(Date);
const exifDateTime = ExifDateTime.fromISO('2023-01-01T00:00:00.000Z');
expect(exifToDate(exifDateTime)).toBeInstanceOf(Date);
expect(exifToDate(exifDateTime)?.toISOString()).toBe('2023-01-01T00:00:00.000Z');
});
});
describe('extracts the timezone from a date', () => {
it('returns null for invalid inputs', () => {
expect(exifTimeZone(undefined)).toBeNull();
expect(exifTimeZone('')).toBeNull();
expect(exifTimeZone(new Date('2023'))).toBeNull();
expect(exifTimeZone(ExifDateTime.fromEXIF('invalid'))).toBeNull();
});
it('returns the timezone for valid inputs', () => {
expect(exifTimeZone(ExifDateTime.fromEXIF('2020:12:29 14:24:45.700-05:00'))).toBe('UTC-5');
});
});

View File

@@ -1,24 +0,0 @@
import { ExifDateTime } from 'exiftool-vendored';
import { isDecimalNumber } from '../numbers';
export function exifToDate(exifDate: string | Date | ExifDateTime | undefined): Date | null {
if (!exifDate) {
return null;
}
const date = exifDate instanceof ExifDateTime ? exifDate.toDate() : new Date(exifDate);
if (!isDecimalNumber(date.valueOf())) {
return null;
}
return date;
}
export function exifTimeZone(exifDate: string | Date | ExifDateTime | undefined): string | null {
const isExifDate = exifDate instanceof ExifDateTime;
if (!isExifDate) {
return null;
}
return exifDate.zone ?? null;
}

View File

@@ -1,24 +0,0 @@
import { describe, expect, it } from '@jest/globals';
import { parseISO } from './iso';
describe('parsing ISO values', () => {
it('returns null for invalid values', () => {
expect(parseISO('')).toBeNull();
expect(parseISO(',,,')).toBeNull();
expect(parseISO('invalid')).toBeNull();
expect(parseISO('-5')).toBeNull();
expect(parseISO('99999999999999')).toBeNull();
});
it('returns the ISO number for valid inputs', () => {
expect(parseISO('0.0')).toBe(0);
expect(parseISO('32000.9')).toBe(32000);
});
it('returns the first valid ISO number in a comma separated list', () => {
expect(parseISO('400, 200, 100')).toBe(400);
expect(parseISO('-1600,800')).toBe(800);
expect(parseISO('-1, a., 1200')).toBe(1200);
expect(parseISO('NaN,50,100')).toBe(50);
});
});

View File

@@ -1,14 +0,0 @@
import { isNumberInRange } from '../numbers';
export function parseISO(input: string): number | null {
const values = input.split(',');
for (const value of values) {
const iso = Number.parseInt(value, 10);
if (isNumberInRange(iso, 0, 2 ** 32)) {
return iso;
}
}
return null;
}