Skip to content

Instantly share code, notes, and snippets.

@MadLittleMods
Last active November 20, 2018 12:07
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MadLittleMods/7eedb4001c52acec104e91dbd80618b5 to your computer and use it in GitHub Desktop.
Save MadLittleMods/7eedb4001c52acec104e91dbd80618b5 to your computer and use it in GitHub Desktop.
Stream .tar.gz of some glob (directory, etc). See .zip equivalent, https://gist.github.com/MadLittleMods/72bc11761e05a2658d0be13fa8c27fef
const Promise = require('bluebird');
const path = require('path');
const fs = require('fs-extra');
const stat = Promise.promisify(fs.stat);
const glob = Promise.promisify(require('glob'));
const tarstream = require('tar-stream');
const zlib = require('zlib');
const express = require('express');
function targzGlobStream(globString, options) {
const stream = tarstream.pack();
const addFileToStream = (filePath, size) => {
return new Promise((resolve, reject) => {
const entry = stream.entry({
name: path.relative(options.base || '', filePath),
size: size
}, (err) => {
if(err) reject(err);
resolve();
});
fs.createReadStream(filePath)
.pipe(entry);
});
};
const getFileMap = glob(globString, Object.assign({ nodir: true }, options))
.then((files) => {
const fileMap = {};
const stattingFilePromises = files.map((file) => {
return stat(file)
.then((fileStats) => {
fileMap[file] = fileStats;
});
});
return Promise.all(stattingFilePromises)
.then(() => fileMap);
});
getFileMap.then((fileMap) => {
// We can only add one file at a time
return Object.keys(fileMap).reduce((promiseChain, file) => {
return promiseChain.then(() => {
return addFileToStream(file, fileMap[file].size);
});
}, Promise.resolve());
})
.then(() => {
stream.finalize();
});
return stream.pipe(zlib.createGzip());
}
const app = express();
app.get('/logs.tar.gz', function (req, res) {
const logDirPath = path.join(process.cwd(), './logs/');
const tarGzStream = targzGlobStream(path.join(logDirPath, '**/*'), {
base: logDirPath
});
res
.set('Content-Type', 'application/gzip')
.set('Content-Disposition', 'attachment; filename="logs.tar.gz"');
tarGzStream.pipe(res);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment