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.
thumbsup/src/steps/step-album-zip.js

57 lines
1.9 KiB
JavaScript

const path = require('node:path')
const childProcess = require('node:child_process')
const async = require('async')
const Observable = require('zen-observable')
const trace = require('debug')('thumbsup:trace')
const debug = require('debug')('thumbsup:debug')
const error = require('debug')('thumbsup:error')
exports.run = function (rootAlbum, outputFolder) {
return new Observable(observer => {
const albums = flattenAlbums([rootAlbum])
const zippers = albums.filter(a => a.zip).map(album => {
return (done) => {
debug(`Zipping album ${album.zip} (${album.files.length} files)`)
const zipPath = path.join(outputFolder, album.zip)
const filenames = album.files.map(f => f.output.download.path)
createZip(zipPath, outputFolder, filenames, done)
}
})
async.series(zippers, err => {
if (err) {
observer.error(err)
} else {
observer.complete(err)
}
})
})
}
function flattenAlbums (albums, result) {
return albums.reduce((acc, album) => {
acc.push(album)
return flattenAlbums(album.albums, acc)
}, result || [])
}
// This function uses the Unix ZIP command, which supports "updating" a ZIP file
// In the future it could also delegate to 7zip on Windows
function createZip (targetZipPath, currentFolder, filesToInclude, done) {
const args = ['-FS', targetZipPath].concat(filesToInclude)
const startTime = Date.now()
trace(`Calling: zip ${args.join(' ')}`)
const child = childProcess.spawn('zip', args, {
cwd: currentFolder,
stdio: ['ignore', 'ignore', 'ignore']
})
child.on('error', (err) => {
error('Error: please verify that <zip> is installed on your system')
error(err.toString())
})
child.on('close', (code, signal) => {
const elapsed = Math.floor(Date.now() - startTime)
debug(`Zip exited with code ${code} in ${elapsed}ms`)
done(code === 0 ? null : new Error(`Error creating ZIP file ${targetZipPath}`))
})
}