fs.stat never finds file - node.js

I'm trying to create a function in node that will generate an article page if it can find the requested article's json, but I can't even get fs.stat to tell me that a file exists. I've verified the directory and the filename of the script with the __dirname and __filename globals, but I can't even get my function to find a file that's in the same directory as the script, much less a different directory.
var express = require('express');
var fs = require('fs');
var router = express.Router();
var articlePage = function home(req, res) {
console.log(__dirname + __filename);
fs.stat('foo.txt', function(err, stat) {
if(err == null) {
console.log('File exists');
res.send("filefound"); //this never is triggered
} else if(err.code == 'ENOENT') {
console.log("file does not exist");
res.status(404).send('file not found');
} else {
console.log('Some error has occured');
}
});
};
router.get('/article/:articleName', articlePage);
module.exports = router;

Related

formidable handle no uploaded file errors

Everything is working as expected in my code except if the user has not uploaded a file it crashes my node app.
The error is arising at the fs.rename part, as there is nothing uploaded the app cant rename anything and causes the following:
Error:
EPERM: operation not permitted, rename 'C:\Users\xxx\AppData\Local\Temp\upload_0a145049089fa69e9df64f8d20abb362' -> 'C:\Users\xxx\Dropbox\Automate NodeJS\Login_Register+Submit - 0.01\data\5be13231807fe33f14b2834a\sdS9m'
Im having difficulty searching for my err and how to handle that, If anyone can point me to some resources for how to handle formidable errors and how to stop the process of the user hasn't uploaded anything it would be fantastic.
It's not a production app or anything of the like its just me learning how to deal with multiple functions and a database at once.
router.post('/submit', userisSubbed, userhasTime, (req, res, next0) => {
var userId = req.user._id;
var username = req.user.email;
var isCompleted = 'No'
var jobNumber = generator.generate({
length: 5,
numbers: true
});
// Validate
const errors = req.validationErrors();
if (errors) {
res.render('index', {
errors: errors
});}
else {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var userPath = req.user._id
var dir = './data/' + userPath + '/' + jobNumber + '/';
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}else
{
console.log("Directory already exist");
}
var oldpath = files.filetoupload.path;
var newpath = dir + files.filetoupload.name;
// copy the file to a new location
fs.rename(oldpath, newpath, function (err) {
if (err) throw err;
console.log('renamed complete');
const newJob = new Job({
userId: userId,
username: username,
isCompleted: isCompleted,
filepath: newpath,
jobNumber: jobNumber,
});
Job.createJob(newJob, function(err, job){
if (err) throw err;
console.log(job);
});
req.flash('success_msg', 'Job Submitted...');
res.redirect('/')
});
});
}
});

cannot pass learnyounode: is the callback function used uncorrectly?

I am trying to solve the sixth problem of learnyounode which needs a module file to print file list. Here are my two files:
The main file program.js:
var mymodule = require('./module.js');
mymodule(process.argv[2], process.argv[3], function(err, file){
if(err){
console.log(err);
return;
}
console.log(file);
});
The module file module.js:
var fs = require('fs');
var path = require('path');
var fileExt;
module.exports = function(dir, ext, callback) {
fs.readdir(dir, function(err, files){
if(err){
callback(err);
return;
}
files.forEach(function(file){
fileExt = path.extname(file).substring(1);
if(fileExt === ext){
callback(null, file);
}
});
});
}
But it throws an error:
processors[i].call(self, mode, function (err, pass) {
TypeError: Cannot read property 'call' of undefined
What am I doing wrong?
The instructions state that you need to call callback only once, with an array containing of all the matching files. In your case, you are calling callback once for every matching file.

Node.JS downloading hundreds of files simultaneously

I am trying to download more that 100 files at the same time. But when I execute the downloading function my macbook freezes(unable to execute new tasks) in windows also no download(but doesn't freeze) and no download progress in both case(idle network).
Here is my download module:
var express = require('express');
var router = express.Router();
var fs = require('fs');
var youtubedl = require('youtube-dl');
var links = require('../models/Links');
router.get('/', function (req, res, next) {
links.find({dlStatus: false}, function (err, docs) {
if (err) {
console.log(err);
res.end();
} else if (!docs) {
console.log('No incomplete downloads!');
res.end();
} else {
for (var i = 0; i < docs.length; i++) {
//todo scraping
var video = youtubedl(docs[i].url, [], {cwd: __dirname});
// Will be called when the download starts.
video.on('info', function (info) {
console.log('Download started');
console.log(info);
});
video.pipe(fs.createWriteStream('./downloads/' + docs[i].id + '-' + i + '.mp4'));
video.on('complete', function complete(info) {
links.findOneAndUpdate({url: info.webpage_url}, {dlStatus: true}, function (err, doc) {
if (err)console.log(err);
else console.log('Download completed!')
});
});
}
}
});
});
module.exports = router;
Now can anyone please help me here? I am using this module for downloading files.
The solution is using async in this case.
Try it this way....with async.each()
var express = require('express');
var router = express.Router();
var fs = require('fs');
var youtubedl = require('youtube-dl');
var links = require('../models/Links');
var async = require('async')
router.get('/', function (req, res, next) {
links.find({dlStatus: false}, function (err, docs) {
if (err) {
console.log(err);
res.end();
} else if (!docs) {
console.log('No incomplete downloads!');
res.end();
} else {
async.each(docs,function(doc,cb){
var video = youtubedl(doc.url, [], {cwd: __dirname});
// Will be called when the download starts.
video.on('info', function (info) {
console.log('Download started');
console.log(info);
});
video.pipe(fs.createWriteStream('./downloads/' + docs.id + '-' + i + '.mp4'));
video.on('complete', function complete(info) {
links.findOneAndUpdate({url: info.webpage_url}, {dlStatus: true}, function (err, doc) {
if (err){
console.log(err);
cb(err);
}
else {
console.log('Download completed!');
cb()
}
});
});
},function(err){
if(err)
return console.log(err);
console.log("Every thing is done,Here!!");
})
}
});
});
module.exports = router;
And you can process every thing in batch too using async.eachLimits().

Parse Objects not created from node in heroku

I have the following code running on a node server # heroku. The trouble I am having is that the application frequently fails to create a new parse.com object on post. What is strange is that this code works 100% of the time on my local machine. running through heroku introduces the issue.
I run a heroku log trail when the application posts and it does not throw any exceptions/errors, so I'm stumped as to what to look for.
BTW - I realize this code isn't the prettiest, this is my first attempt to get a node/heroku/parse application up and running.
var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
var Parse = require('parse/node').Parse;
var mime = require('mime');
var server = http.createServer(router).listen(process.env.PORT || 5000);
Parse.initialize("key", "key");
console.log("Parse initialized");
function router (req, res) {
var pathname = url.parse(req.url, true).pathname;
if (pathname.slice(0, 4) === '/api') {
apiHandler(req, res);
} else {
if (pathname[pathname.length - 1] === '/')
pathname += 'index.html';
staticFileHandler(pathname, res);
}
}
function staticFileHandler (pathname, res) {
fs.readFile(__dirname + '/public_html' + pathname, function (err, data) {
if (err) return errHandler(err, res);
console.log('[200]: ' + pathname);
res.setHeader('Content-Type', mime.lookup(path.extname(pathname)));
res.end(data);
});
}
function errHandler (err, res) {
if (err.code === 'ENOENT') {
res.statusCode = 404;
res.end('File not found!');
console.log('[404]: File not found: ' + err.path);
} else {
console.error(err);
}
}
function apiHandler (req, res) {
if (req.method === 'GET') {
//send back a list of todos
// var toDo = new Parse.Object("ToDo");
var parseQuery = new Parse.Query("ToDo");
parseQuery.find({
success: function(toDoList){
res.setHeader('Content-Type', mime.lookup('json'));
res.end(JSON.stringify(toDoList));
},
error: function(toDoList, error) {
// error is an instance of Parse.Error.
console.log('Error encountered while getting Parse objects: ' + error.message);
}
});
} else if (req.method === "POST"){
var body = "";
req.on('data', function (chunk) {
body += chunk;
});
var today = new Date();
req.on('end', function () {
var toDo = new Parse.Object("ToDo");
toDo.set('Description', body);
toDo.set('Done', false);
toDo.set('DueDate',today )
toDo.save(null, {
success: function(toDo) {
// Execute any logic that should take place after the object is saved.
console.log('New object created with objectId: ' + toDo.id);
},
error: function(toDo, error) {
// Execute any logic that should take place if the save fails.
// error is a Parse.Error with an error code and message.
console.log('Failed to create new object, with error code: ' + error.message);
}
});
});
res.end();
}
}

Change the name of uploaded file in node.js

I am using node.js to upload a file. But it uploads the file in the /tmp folder with a random like name (such as: 132d439bb31ee13daaf6ce02e223738f). I want the node to upload the file in a given directory with a given name. How can I make it? here is my code:
var http = require("http"),
url = require("url"),
sys = require("sys"),
events = require("events"),
fs = require("fs"),
formidable = require('formidable'),
util = require('util');
var server = http.createServer(function(req, res) {
switch (url.parse(req.url).pathname) {
case '/':
display_form(req, res);
break;
case '/upload':
upload_file(req,res);
break;
default:
show_404(req, res);
break;
}
});
server.listen(8124);
function display_form(req, res) {
//displays an html form with an upload and a submit button
}
function upload_file(req, res) {
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
// Instantiate a new formidable form for processing.
var form = new formidable.IncomingForm();
// form.parse analyzes the incoming stream data, picking apart the different fields and files for you.
form.parse(req, function(err, fields, files) {
if (err) {
// Check for and handle any errors here.
console.error(err.message);
return;
}
form.on('fileBegin', function(name, files) {
files.name="./guake.up";
});
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
console.log(files.name);
// This last line responds to the form submission with a list of the parsed data and files.
res.end(util.inspect({fields: fields, files: files}));
});
return;
}
}
function show_404(req, res) {
//shows a 404 page
}
I found the answer and I only need to add the following code before my form.parse method:
form.on('error', function(err) {
throw err;
})
/* this is where the renaming happens */
.on ('fileBegin', function(name, file){
//rename the incoming file to the file's name
file.path = form.uploadDir + file.name;
});
and the problem is solved

Resources