From 466496650e86d38d8b0e60a0b366fe6533f5b852 Mon Sep 17 00:00:00 2001 From: "Patrik J. Braun" Date: Mon, 24 May 2021 14:56:23 +0200 Subject: [PATCH] Supporting date before epoch (1970) #245, #294 --- src/backend/model/threading/MetadataLoader.ts | 12 +++-- .../edge_case_exif_data/before_epoch.jpg | Bin 0 -> 19145 bytes .../edge_case_exif_data/before_epoch.json | 46 ++++++++++++++++++ .../edge_case_exif_data/date_error.json | 2 +- .../edge_case_exif_data/no_metadata.jpg | Bin 0 -> 5860 bytes .../edge_case_exif_data/no_metadata.json | 9 ++++ 6 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 test/backend/assets/edge_case_exif_data/before_epoch.jpg create mode 100644 test/backend/assets/edge_case_exif_data/before_epoch.json create mode 100644 test/backend/assets/edge_case_exif_data/no_metadata.jpg create mode 100644 test/backend/assets/edge_case_exif_data/no_metadata.json diff --git a/src/backend/model/threading/MetadataLoader.ts b/src/backend/model/threading/MetadataLoader.ts index 137c1186..c4208cb4 100644 --- a/src/backend/model/threading/MetadataLoader.ts +++ b/src/backend/model/threading/MetadataLoader.ts @@ -199,15 +199,21 @@ export class MetadataLoader { if (iptcData.caption) { metadata.caption = iptcData.caption.replace(/\0/g, '').trim(); } - metadata.keywords = iptcData.keywords || []; + if (Array.isArray(iptcData.keywords)) { + metadata.keywords = iptcData.keywords; + } - metadata.creationDate = ((iptcData.date_time ? iptcData.date_time.getTime() : metadata.creationDate) as number); + if (iptcData.date_time) { + metadata.creationDate = iptcData.date_time.getTime(); + } } catch (err) { // Logger.debug(LOG_TAG, 'Error parsing iptc data', fullPath, err); } - metadata.creationDate = Math.max(metadata.creationDate || 0, 0); + if (!metadata.creationDate) { // creationDate can be negative, when it was created before epoch (1970) + metadata.creationDate = 0; + } try { // TODO: clean up the three different exif readers, diff --git a/test/backend/assets/edge_case_exif_data/before_epoch.jpg b/test/backend/assets/edge_case_exif_data/before_epoch.jpg new file mode 100644 index 0000000000000000000000000000000000000000..17f9d3018afe8fb2c64075fceb2184b7b34ce5a6 GIT binary patch literal 19145 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 O3?Ds1zk5K_>Hh`$lpuTn literal 0 HcmV?d00001 diff --git a/test/backend/assets/edge_case_exif_data/before_epoch.json b/test/backend/assets/edge_case_exif_data/before_epoch.json new file mode 100644 index 00000000..e4722492 --- /dev/null +++ b/test/backend/assets/edge_case_exif_data/before_epoch.json @@ -0,0 +1,46 @@ +{ + "cameraData": { + "ISO": 800, + "exposure": 0.008, + "fStop": 5.6, + "focalLength": 85, + "lens": "EF-S15-85mm f/3.5-5.6 IS USM", + "make": "Canon", + "model": "Canon EOS 600D" + }, + "caption": "Bambi Caption", + "creationDate": -11630935227000, + "faces": [ + { + "box": { + "height": 2, + "left": 4, + "top": 2, + "width": 2 + }, + "name": "Bambi" + } + ], + "fileSize": 19145, + "keywords": [ + "USA", + "USA Road trip", + "Yosemite" + ], + "orientation": 1, + "positionData": { + "GPSData": { + "altitude": 1960, + "latitude": 37.74805833333333, + "longitude": -119.51402333333333 + }, + "city": "Yosemite Nemzeti Park", + "country": "United States", + "state": "California" + }, + "rating": 2, + "size": { + "height": 7, + "width": 10 + } +} diff --git a/test/backend/assets/edge_case_exif_data/date_error.json b/test/backend/assets/edge_case_exif_data/date_error.json index 364c0d0f..a5f34a3e 100644 --- a/test/backend/assets/edge_case_exif_data/date_error.json +++ b/test/backend/assets/edge_case_exif_data/date_error.json @@ -7,7 +7,7 @@ "make": "NIKON", "model": "E880" }, - "creationDate": 0, + "creationDate": -2211753600000, "fileSize": 72850, "orientation": 1, "size": { diff --git a/test/backend/assets/edge_case_exif_data/no_metadata.jpg b/test/backend/assets/edge_case_exif_data/no_metadata.jpg new file mode 100644 index 0000000000000000000000000000000000000000..13ac4b1b63d8562aff2d52ea052c104d794c2838 GIT binary patch literal 5860 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 Jfe6dhe*)dg(9{3` literal 0 HcmV?d00001 diff --git a/test/backend/assets/edge_case_exif_data/no_metadata.json b/test/backend/assets/edge_case_exif_data/no_metadata.json new file mode 100644 index 00000000..9801ee72 --- /dev/null +++ b/test/backend/assets/edge_case_exif_data/no_metadata.json @@ -0,0 +1,9 @@ +{ + "creationDate": 1621859678578, + "fileSize": 5860, + "orientation": 1, + "size": { + "height": 7, + "width": 10 + } +}