Recursive directory search including files inside ZIP's and RAR's - javascript

i'm trying to find a solution for my problem. I need get all files inside a target directory, including files inside zip and rars. Is this possible? Currently i'm working with this version, that takes all files inside all directories, including zips and rars files, but not what is inside.
var fs = require('fs');
var path = require('path');
var walk = function(dir, done) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err) return done(err);
var pending = list.length;
if (!pending) return done(null, results);
list.forEach(function(file) {
file = path.resolve(dir, file);
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
results = results.concat(res);
if (!--pending) done(null, results);
});
} else {
results.push(file);
if (!--pending) done(null, results);
}
});
});
});
};
Thanks in advance.

While recursively looking for file,if you get a zip file you can use module like adm-zip to getEntries of zip file and do the recursive search again.

You may look into some external library:
Like jszip: https://stuk.github.io/jszip/
Install via npm and when you're looking for file, if you get a .zip or .rar file you can use jszip to get the list of files inside of the .zip or .rar folder

Related

How to fetch current filename that is being processed using gulp.src()

I have to run certain gulp task over multiple json files in a folder but the task would fetch files different location based on the filename.
I am able to run the task by passing the filename as an argument in cmd but I want to automate the script so that it would get executed for all the files in the src location.
gulp.task("writeJSON", function() {
dataObj = require("./src/data/" + argv["filename"] + ".json");
dataObjKeysList = require("./src/data/stats/" + argv["filename"] + ".json");
segregateData(dataObj, dataObjKeysList, tabspace, false);
gulp
.src("./src/metadata.html")
.pipe(rename(argv["filename"] + ".html"))
.pipe(gulp.dest("./src/output"));
});
Any help would be greatly appreciated.
I am able to resolve the above issue using node filestream. I found this useful article
Filewalker Source
Used the below utility function which take the directory path and callback as args.
function filewalker(dir, done) {
let results = [];
fs.readdir(dir, function(err, list) {
if (err) return done(err);
var pending = list.length;
if (!pending) return done(null, results);
list.forEach(function(file){
file = path.resolve(dir, file);
fs.stat(file, function(err, stat){
// If directory, execute a recursive call
if (stat && stat.isDirectory()) {
// Add directory to array [comment if you need to remove the directories from the array]
results.push(file);
filewalker(file, function(err, res){
results = results.concat(res);
if (!--pending) done(null, results);
});
} else {
results.push(file);
if (!--pending) done(null, results);
}
});
});
});
};
Added the below execution in my gulp task
filewalker("./src/data/stats/" , function(err, dataFilesList){
if(err){
throw err;
}
dataFilesList.map((name) => {
let fileName = path.basename(name);
fileName = fileName.split('.')[0];
gutil.log('Generating ' + fileName + '.html file.');
});
});

Extract Sketch file using JavaScript

The purpose is to extract the contents of a .sketch file.
I have a file with the name myfile.sketch. On renaming the file extension to myfile.zip and extracting the same in Finder, I'm able view the files within. I tried doing the same on the server using Node.js by renaming the file extension to .zip. I wasn't able to extract the files, rather I got some ZIP files within the files.
var oldPath = __dirname+'/uploads/myfile.sketch',
newPath = __dirname+'/uploads/myfile.zip';
fs.rename(oldPath, newPath, function (err) {
console.log('rename callback ', err);
});
Is it possible to extract a non-ZIP file using frameworks like JSzip?
As a .sketch file is essentially a ZIP file, the extension does not matter. Any tool that is capable of unpacking a ZIP file will work.
You can verify this with the file command:
$ file myfile.sketch
myfile.sketch: Zip archive data, at least v1.0 to extract
As you are working on the server already, there is nothing stopping you from just using the OS's command line tools like unzip.
Like this:
const util = require('util');
const exec = util.promisify(require('child_process').exec);
async function unzip() {
const filename = 'myfile.sketch'
const { stdout, stderr } = await exec('unzip ' + filename);
console.log('stdout:', stdout);
console.log('stderr:', stderr);
}
unzip();
Doing it with JSZip is straight-forward as well:
var fs = require('fs');
var JSZip = require('jszip');
new JSZip.external.Promise(function (resolve, reject) {
fs.readFile('myfile.sketch', function(err, data) {
if (err) {
reject(e);
} else {
resolve(data);
}
});
}).then(function (data) {
return JSZip.loadAsync(data);
})

Get file path with dynamic path inside

I need to create file from directory like following
application/userxxx.txt/manifest.txt
The path is constant except the userxxx which can be any alpha numeric
/application/
user12.txt
newfile.txt
newFile2.txt
There is only one file which start with user...
I think of using the which is currently not working..
fs.readdir('c://application', function (err, files) {
if (err) {
throw err;
}
and then get all the files under the application
and search for file which start with userabcd1234.txt and when I find it do the read file like following
readFile('application/userabcd1234/manifest.txt')
There is no two files inside application which start with /user. just one but after the user. and before the third '/manifest.txt' can be any random alpha numeric.
You can do something like
var filePath = path.join(__dirname, '../your path to application folder');
fs.readdir(filePath, function (err, files) {
if (err) {
return console.error(err);
}
files.forEach(function (file) {
if (file.indexOf('user') === 0) {
var relFilePath = filePath + '/' + file + '/manifest.txt';
fs.readFile(relFilePath,'utf8', function read(err, data) {
if (err) {
throw err;
}
console.log(data);
});
}
});
});

Node.js possible callback endless call?

I'm actually trying to learn a bit about node.js
At the moment I try to understand the principles about callbacks.
I've written a module that should filter me files from a given directory by a specified file extension. But it won't work. I've tested a bit and I noticed that the function 'getFiles' will be called more the ones. But why? I can't find the mistake, can someone help me, to understood my problem? If someone thinks my code is ugly, please give me a better example, thanks.
So here's my code:
//Returns a list of filtered files from a specified directory and extension
function getFilteredFiles(dir, ext, callback)
{
getFiles(dir, function(error, data){
if(error)
{
callback(error);
}
else
{
var result = getFilteredFiles(data, ext);
callback(null, result);
}
});
}
//Reading files from a given directory
function getFiles(dir, callback)
{
var fs = require('fs');
console.log(typeof dir);
fs.readdir(dir, function(err, data){
if(err)
{
callback(err);
}
else
{
callback(null, data);
}
});
}
//Filters a file by a specified extension
function filterFiles(data, extension)
{
var path = require('path');
return data.filter(function(file){
return path.extname(file) == '.' + extension;
});
}

Creating a zip archive from a folder and preserving structure with Node.js

I'm trying to use Node.js to create a zip file from an existing folder, and preserve the structure.
I was hoping there would be a simple module to allow this kind of thing:
archiver.create("../folder", function(zipFile){
console.log('et viola');
});
but I can't find anything of the sort!
I've been googling around, and the best I've found so far is zipstream, but as far as I can tell there's no way to do what I want. I don't really want to call into commandline utilities, as the the app has to be cross platform.
Any help would be greatly appreciated.
Thanks.
It's not entirely code free, but you can use node-native-zip in conjunction with folder.js. Usage:
function zipUpAFolder (dir, callback) {
var archive = new zip();
// map all files in the approot thru this function
folder.mapAllFiles(dir, function (path, stats, callback) {
// prepare for the .addFiles function
callback({
name: path.replace(dir, "").substr(1),
path: path
});
}, function (err, data) {
if (err) return callback(err);
// add the files to the zip
archive.addFiles(data, function (err) {
if (err) return callback(err);
// write the zip file
fs.writeFile(dir + ".zip", archive.toBuffer(), function (err) {
if (err) return callback(err);
callback(null, dir + ".zip");
});
});
});
}
This can be done even simpler using node's built-in execfile function. It spawns a process and executes the zip command through the os, natively. Everything just works.
var execFile = require('child_process').execFile;
execFile('zip', ['-r', '-j', zipName, pathToFolder], function(err, stdout) {
console.log(err);
logZipFile(localPath);
});
The -j flag 'junks' the file path, if you are zipping a sibdirectory, and don't want excessive nesting within the zip file.
Here's some documentation on execfile.
Here's a man page for zip.
Using Easy-zip, npm install easy-zip, you can do:
var zip5 = new EasyZip();
zip5.zipFolder('../easy-zip',function(){
zip5.writeToFile('folderall.zip');
});

Categories