Last active
July 19, 2018 12:57
-
-
Save dev-drprasad/17a1ce327f5254b6ce3af823adac6e73 to your computer and use it in GitHub Desktop.
Extract specific child zips from zip file using node and express
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express'); | |
const fs = require('fs'); | |
const extract = require('extract-zip') | |
const formidable = require('formidable'); | |
const path = require('path'); | |
const uploadDir = path.join(__dirname, '/uploads/'); | |
const extractDir = path.join(__dirname, '/app/'); | |
if (!fs.existsSync(uploadDir)) { | |
fs.mkdirSync(uploadDir); | |
} | |
if (!fs.existsSync(extractDir)) { | |
fs.mkdirSync(extractDir); | |
} | |
const server = express(); | |
const uploadMedia = (req, res, next) => { | |
const form = new formidable.IncomingForm(); | |
// file size limit 100MB. change according to your needs | |
form.maxFileSize = 100 * 1024 * 1024; | |
form.keepExtensions = true; | |
form.multiples = true; | |
form.uploadDir = uploadDir; | |
// collect all form files and fileds and pass to its callback | |
form.parse(req, (err, fields, files) => { | |
// when form parsing fails throw error | |
if (err) return res.status(500).json({ error: err }); | |
if (Object.keys(files).length === 0) return res.status(400).json({ message: "no files uploaded" }); | |
// Iterate all uploaded files and get their path, extension, final extraction path | |
const filesInfo = Object.keys(files).map((key) => { | |
const file = files[key]; | |
const filePath = file.path; | |
const fileExt = path.extname(file.name); | |
const fileName = path.basename(file.name, fileExt); | |
return { filePath, fileExt, fileName }; | |
}); | |
// Check whether uploaded files are zip files | |
const validFiles = filesInfo.every(({ fileExt }) => fileExt === '.zip'); | |
// if uploaded files are not zip files, return error | |
if (!validFiles) return res.status(400).json({ message: "unsupported file type" }); | |
res.status(200).json({ uploaded: true }); | |
// iterate through each file path and extract them | |
filesInfo.forEach(({ filePath, fileName }) => { | |
extract(filePath, { dir: extractDir }, (err) => { | |
if (!err) { | |
fs.readdirSync(path.join(extractDir, fileName)).forEach((file) => { | |
const filePath = path.join(extractDir, fileName, file); | |
if (fs.statSync(filePath).isFile()) { | |
if (path.extname(file) === '.zip') { | |
extract(filePath, { dir: path.join(extractDir, fileName) }, (err) => { | |
if (err) { | |
console.error('extraction failed.'); | |
} else { | |
fs.unlinkSync(filePath); | |
} | |
}); | |
} | |
} | |
}); | |
} | |
}); | |
}); | |
}); | |
// runs when new file detected in upload stream | |
form.on('fileBegin', function (name, file) { | |
// get the file base name `index.css.zip` => `index.html` | |
const fileName = path.basename(file.name, path.extname(file.name)); | |
const fileExt = path.extname(file.name); | |
// create files with timestamp to prevent overwrite same file names | |
file.path = path.join(uploadDir, `${fileName}_${new Date().getTime()}${fileExt}`); | |
}); | |
} | |
server.post('/upload', uploadMedia); | |
server.listen(3000, (err) => { | |
if (err) throw err; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment