Nodejs illegal operation on a directory - node.js

Im trying to compile a folder of markdown files into a single PDF with markdown-pdf NPM package.
I have a simple script to do the job:
var mpdf = require('markdown-pdf');
var fs = require('fs');
var mDocs = fs.readdirSync('./understandinges6/manuscript/');
mDocs = mDocs.map(function(d) { return 'understandinges6/manuscript/' + d });
var Book = 'understandinges6.pdf';
mpdf().concat.from(mDocs).to(Book, function() {
console.log("Created", Book);
});
But when i execute the script, this error appears:
events.js:154
throw er; // Unhandled 'error' event
^
Error: EISDIR: illegal operation on a directory, read
at Error (native)
It's weird because i'm in my home folder with the respective permissions. I'm specifying the output folder/file in the script and just reading with fs.readdirSync.
Any idea about this?

mDocs = mDocs.map(function(d) { return 'understandinges6/manuscript/' + d }); you forgot to add "./". Rewrite to mDocs = mDocs.map(function(d) { return './understandinges6/manuscript/' + d });

Cool, i get the problem here:
In the manuscripts/ folder are a images/ sub-folder with some png's. When the scripts tryed to read and transform images/ from .md to .pdf the error was fired.
Here is the array with the images/ inside:
[ 'understandinges6/manuscript/00-Introduction.md',
'understandinges6/manuscript/01-Block-Bindings.md',
'understandinges6/manuscript/02-Strings-and-Regular-Expressions.md',
'understandinges6/manuscript/03-Functions.md',
'understandinges6/manuscript/04-Objects.md',
'understandinges6/manuscript/05-Destructuring.md',
'understandinges6/manuscript/06-Symbols.md',
'understandinges6/manuscript/07-Sets-And-Maps.md',
'understandinges6/manuscript/08-Iterators-And-Generators.md',
'understandinges6/manuscript/09-Classes.md',
'understandinges6/manuscript/10-Arrays.md',
'understandinges6/manuscript/11-Promises.md',
'understandinges6/manuscript/12-Proxies-and-Reflection.md',
'understandinges6/manuscript/13-Modules.md',
'understandinges6/manuscript/A-Other-Changes.md',
'understandinges6/manuscript/B-ECMAScript-7.md',
'understandinges6/manuscript/Book.txt',
'understandinges6/manuscript/images' ]
Solution? Just pop() the mDocs array (now just docs):
var mpdf = require('markdown-pdf');
var fs = require('fs');
var mDocs = fs.readdirSync('understandinges6/manuscript/');
var docs = mDocs.map(function(d) { return 'understandinges6/manuscript/' + d });
docs.pop();
var Book = 'understandinges6.pdf';
mpdf().concat.from(docs).to(Book, function() {
console.log("Created", Book);
});

Related

Node search for file upwards

I'm looking for a function in node.js to search upwards in the filesystem to check if a given file exists and if so get its content.
For example, if I have the following folder structure:
* root
|--dir1
| |-dir2
| |-dir3
|...
If I'm in dir3 I want to search for a given file that could be in any folder if I go up .. but not in their subfolders. So what I want is a simple way to check in current folder for the file if it doesn't exist go up one folder and search there, until you find the file or you are in the root folder.
I think it's easy to write by yourself. You can use fs.readdir or fs.readdirSync.
Synchronous solution might look like this: (not tested)
var fs = require('fs');
var process = require('process');
var path = require('path');
function findFile(filename, startdir) {
if(!startdir) statdir = process.cwd();
while(true) {
var list = fs.readdirSync(startdir);
if((index = list.indexOf(filename)) != -1)
// found
return fs.readFileSync(path.join([startdir, filename]));
else if(startdir == '/')
// root dir, file not found
return null;
else
startdir = path.normalize(path.join([startdir, '..']));
}
}
There is also an NPM package - fileUp that does this.
From the Readme:
const path = require('path');
const findUp = require('find-up');
(async () => {
console.log(await findUp('unicorn.png'));
//=> '/Users/sindresorhus/unicorn.png'
console.log(await findUp(['rainbow.png', 'unicorn.png']));
//=> '/Users/sindresorhus/unicorn.png'
console.log(await findUp(async directory => {
const hasUnicorns = await findUp.exists(path.join(directory, 'unicorn.png'));
return hasUnicorns && directory;
}, {type: 'directory'}));
//=> '/Users/sindresorhus'
})();

Get all files with specified extension node.js

I am using node.js. I want to loop through all files with extension .coffee,
but I have nowhere found an example.
Following function will return all the files in the specified directory with the regex provided.
Function
var path = require('path'), fs=require('fs');
function fromDir(startPath,filter,callback){
//console.log('Starting from dir '+startPath+'/');
if (!fs.existsSync(startPath)){
console.log("no dir ",startPath);
return;
}
var files=fs.readdirSync(startPath);
for(var i=0;i<files.length;i++){
var filename=path.join(startPath,files[i]);
var stat = fs.lstatSync(filename);
if (stat.isDirectory()){
fromDir(filename,filter,callback); //recurse
}
else if (filter.test(filename)) callback(filename);
};
};
Usage
fromDir('../LiteScript',/\.coffee$/,function(filename){
console.log('-- found: ',filename);
});

Unhandled 'error' event when extracting zip file with nodejs

I want to download a zip file and extract it with nodejs. This is what I have done so far:
var fs = require('fs');
var wget = require('wget-improved');
var filesizeHumanReadable = require('filesize');
var unzip = require('unzip');
var downloadCSS = function() {
var src = 'http://7-zip.org/a/7za920.zip';
var output = '/tmp/7z.zip';
var options = {};
var download = wget.download(src, output, options);
download.on('error', function(err) {
console.log(err);
});
download.on('start', function(fileSize) {
console.log(filesizeHumanReadable(fileSize));
});
download.on('end', function(outputMessage) {
console.log(outputMessage);
console.log(output);
fs.createReadStream(output).pipe(unzip.Extract({ path: '/tmp/' }));
});
download.on('progress', function(progress) {
// code to show progress bar
});
}
The error message I get when running it:
mles-MacBook-Pro:test-api mles$ node index.js
375.83 KB
Finished writing to disk
/tmp/7z.zip
events.js:85
throw er; // Unhandled 'error' event
^
Error: EPERM, unlink '/tmp'
at Error (native)
Now I'm a bit baffled how to handle the error event and what my actual error is?
Does the process have enough permission to write to /tmp? Does /tmp already have some files?
Because unlink is a node.js function to delete directories. Apparently, unzip.Extract calls it. So, unlink fails if the folder isn't empty (in your case /tmp).
Setting the unzip location to a specific directory fixes it
fs.createReadStream(output).pipe(unzip.Extract({ path: '/tmp/7zip' }));
I'm marking mostruash answer as correct since he brought me on the right track.

Create an archive and add files in it before sending to client

I'd like to create an archive with archiver and put some files in it. Client's side, an user will click on a button and it'll generate the archive (server's side).
I'm using Express.js, this is my server side code where the archive will be generated. I did something like this :
app.get('/export/siteoccupancy', function(req,res){
if(_.isEmpty(req.query)){
res.status(404).send('requires a start and end date');
}else{
//getting paramas
var sDate = req.query.startDate;
var eDate = req.query.endDate;
}
var fs = require('fs');
var archiver = require('archiver');
var archive = archiver('zip');
archive.on('err',function(err){
res.status(500).send({error : err.message});
});
res.on('close',function(){
console.log('Archive size : %d b',archive.pointer());
return res.status(200).send('OK').end();
});
res.attachment('data-export.zip');
archive.pipe(res);
var stream = fs.createWriteStream("data-report.txt')");
stream.once('open',function(fd) {
stream.write('test1');
stream.write('\n test2');
stream.write('\n test3');
stream.end();
});
archive.append(stream);
archive.finalize();
});
This is totally new for me and I'd like to understand why the console tells me the stream file is empty ?
Error: append: entry name must be a non-empty string value
at Archiver.append
Regards
you can only append a readStream, because an archive can only take data from readstreams. You can use the method named archive.append, and you should pass as a second argument with the name property to name the file. Like so :
archive.append(myReadStream,{ name : 'myTest.txt'});

jsRender and node.js

I am a complete beginner with node.js.
What I try to do is to parse a jsrender template on server side
I donwloaded jsrender.js from git
this is my attempt ... saved as render.js:
var data = [
{id:1, name:"tom"},
{id:2, name:"jack"},
]
require('./jsrender.js', function(jsrender){
console.log('test');
var result = jsrender.render['<p>{{:id}} <b>{{:name}}</p>']( data );
console.log(result);
} );
and then runned it (node render.js)
and I get NOTHING
what am I doing wrong?
======================================================
tried this way too:
var data = [
{id:1, name:"tom"},
{id:2, name:"jack"},
]
var jsrender = require('./jsrender.js');
var result = jsrender.render('<p>{{:id}} <b>{{:name}}</p>',data );
console.log(result);
and I am getting
var result = jsrender.render('<p>{{:id}} <b>{{:name}}</p>',data );
^
TypeError: Object #<Object> has no method 'render'
========================================================================
tried also installing this node_jsrender module
and this syntax:
var jsrender = require('./jsrender');
process.on('start', function () {
jsrender.template("yourtemplate", "{{:myvar}}");
var result = jsrender.render("yourtemplate", {myvar:"Hello World!"});
console.log(result);
});
ALSO EMPTY result :(
So first you need to install the Node.js module.
npm install node_jsrender
This will create a node_modules directory with node_jsrender directory inside. Next you need to require.
var jsrender = require('node_jsrender');
If the first parameters of the require method starts with ./ it means that you want to import a local file. Without it Node.js will look at the node_modules directory.
jsrender.template("yourtemplate", "{{=myvar}}");
var result = jsrender.render("yourtemplate", {myvar:"Hello World!"});
I checked the syntax of that template engine and it's {{= and not {{:?

Resources