-
Notifications
You must be signed in to change notification settings - Fork 0
/
fileProcessor.js
87 lines (85 loc) · 3.18 KB
/
fileProcessor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import exifr from 'exifr'
import ExifImage from 'exif'
import { flatten } from 'flat'
import { DateTime, IANAZone } from 'luxon'
/**
* Attempts to read EXIF data from given file.
*
* @param {*} filename of image to attempt to read EXIF data from
* @param {string} (optional) IANA timezone string to display full date times as
* @param {boolean} whether to output all exif data or just dates
* @returns {Array} contains Arrays of extracted EXIF data keys, values, and optional timezone
*/
export async function processFileExif (filename, zone, all) {
if (zone && !IANAZone.isValidZone(zone)) {
throw new Error(zone + ' is not a valid IANA zone')
}
const exif = await exifr.parse(filename)
if (exif) {
return logExifDates(exif, zone, all)
} else {
try {
/* eslint-disable */
new ExifImage({ image: filename }, function (error, exifData) {
/* eslint-enable */
if (error) {
console.log('Error: ' + error.message)
} else {
return logExifDates(exifData, zone, all)
}
})
} catch (error) {
console.log('Error: ' + error)
}
}
}
/**
* Logs to console all EXIF attributes that include the word 'date'
* @param {*} exif output from one of the exif metadata extraction modules
* @param {string} (optional) IANA timezone string to display full date times as
* @param {boolean} whether to output all exif data
* @returns {Array} contains Arrays of extracted EXIF data keys, values, and optional timezone
*/
function logExifDates (exif, zone, all) {
const exifValues = []
if (exif) {
// we flatten as ExifImage provides nested objects in output, whereas exifr does not.
const flatExif = flatten(exif)
Object.keys(flatExif)
.sort()
.forEach(function (key, i) {
if (key.toUpperCase().indexOf('DATE') > -1) {
const dateVal = flatExif[key]
let lDT, lD
if (Object.prototype.toString.call(dateVal) === '[object Date]') {
lDT = DateTime.fromJSDate(dateVal)
} else if (typeof dateVal === 'string') {
if (key === 'GPSDateStamp') {
// TODO append GPSTimeStamp if present
lD = DateTime.fromFormat(dateVal, 'yyyy:MM:dd')
} else {
// we might get lucky and find it is an ISO format string
lDT = DateTime.fromISO(dateVal)
}
}
if (lDT) {
if (zone) {
exifValues.push([key, lDT.toLocaleString(DateTime.DATETIME_MED_WITH_SECONDS), 'NO ZONE'])
exifValues.push([key, lDT.toUTC().toLocaleString(DateTime.DATETIME_MED_WITH_SECONDS), 'UTC'])
exifValues.push([key, lDT.setZone(zone).toLocaleString(DateTime.DATETIME_MED_WITH_SECONDS), zone])
} else {
exifValues.push([key, lDT.toLocaleString(DateTime.DATETIME_MED_WITH_SECONDS), null])
}
} else if (lD) {
exifValues.push([key, lD.toLocaleString(DateTime.DATE_FULL), null])
}
exifValues.push([key, dateVal, null])
} else {
if (all) exifValues.push([key, flatExif[key], null])
}
})
} else {
console.log('Error - null exif')
}
return exifValues
}