mirror of https://github.com/thumbsup/thumbsup
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
42 lines
1.3 KiB
JavaScript
42 lines
1.3 KiB
JavaScript
const os = require('node:os')
|
|
const stream = require('node:stream')
|
|
const _ = require('lodash')
|
|
const debug = require('debug')('thumbsup:debug')
|
|
const exiftool = require('./stream.js')
|
|
|
|
/*
|
|
Fans out the list of files to multiple exiftool processes (default = CPU count)
|
|
Returns a single stream of javascript objects, parsed from the JSON response
|
|
*/
|
|
exports.parse = (rootFolder, filePaths, concurrency) => {
|
|
// create several buckets of work
|
|
const workers = concurrency || os.cpus().length
|
|
const buckets = _.chunk(filePaths, Math.ceil(filePaths.length / workers))
|
|
debug(`Split files into ${buckets.length} batches for exiftool`)
|
|
// create several <exiftool> streams that can work in parallel
|
|
const streams = _.range(buckets.length).map(i => {
|
|
debug(`Calling exiftool with ${buckets[i].length} files`)
|
|
return exiftool.parse(rootFolder, buckets[i])
|
|
})
|
|
// merge the object streams
|
|
return merge(streams)
|
|
}
|
|
|
|
function merge (streams) {
|
|
let ended = 0
|
|
const merged = new stream.PassThrough({ objectMode: true })
|
|
streams.forEach(s => {
|
|
s.pipe(merged, { end: false })
|
|
s.once('end', () => {
|
|
++ended
|
|
if (ended === streams.length) {
|
|
merged.emit('end')
|
|
}
|
|
})
|
|
s.once('error', (err) => {
|
|
merged.emit('error', err)
|
|
})
|
|
})
|
|
return merged
|
|
}
|