-
Notifications
You must be signed in to change notification settings - Fork 92
/
stream.js
64 lines (58 loc) · 1.97 KB
/
stream.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
const childProcess = require('child_process')
const trace = require('debug')('thumbsup:trace')
const debug = require('debug')('thumbsup:debug')
const error = require('debug')('thumbsup:error')
const es = require('event-stream')
const JSONStream = require('JSONStream')
const through2 = require('through2')
/*
Spawn a single <exiftool> process and send all the files to be parsed
Returns a stream which emits JS objects as they get returned
*/
exports.parse = (rootFolder, filePaths) => {
const args = [
'-a', // include duplicate tags
'-s', // use tag ID, not display name
'-g', // include group names, as nested structures
'-c', // specify format for GPS lat/long
'%+.6f', // lat/long = float values
'-struct', // preserve XMP structure
'-json', // JSON output
'-charset', // allow UTF8 filenames
'filename=utf8', // allow UTF8 filenames
'-@', // specify more arguments separately
'-' // read arguments from standard in
]
// create a new <exiftool> child process
const child = childProcess.spawn('exiftool', args, {
cwd: rootFolder,
stdio: ['pipe', 'pipe', 'pipe']
})
child.on('error', (err) => {
error('Error: please verify that <exiftool> is installed on your system')
error(err.toString())
})
child.on('close', (code, signal) => {
debug(`Exiftool exited with code ${code}`)
})
child.stderr.on('data', chunk => {
trace('Exiftool output:', chunk.toString())
})
// write all files to <stdin>
// exiftool will only start processing after <stdin> is closed
const allFiles = filePaths.join('\n')
child.stdin.write(allFiles + '\n')
child.stdin.end()
// stream <stdout> into a JSON parser
// parse every top-level object and emit it on the stream
return es.pipeline(
child.stdout,
through2(chunkToString),
JSONStream.parse([true])
)
}
function chunkToString (chunk, enc, callback) {
// convert to string to help JSONStream deal with odd encodings
this.push(chunk.toString())
callback()
}