Resizing image error with gm package of node js - javascript

I've been trying this for a while, but I keep getting the error:
Error: Command failed: Invalid Parameter - /images
I installed ImageMagick and the gm package, so that's definitely not the problem.
gm(imageLocation)
.resize(100) // use your own width and height
.write('here.jpg', function (err) {
if (!err) console.log(' hooray! ');
else console.log(err);
});
imageLocation being ./images/3.jpg. Why does this error keep happening? I looked at the documentation
I'm on a Windows 32 bit machine. My server is supposed to get an image from a folder, resize it, and then display it. It seems like I have to write the resized photo and then display that, but the writing process always errors out and the image ends up being empty.
If there's a way to skip the writing part and just displaying the photo directly, that would be awesome too.
Thanks!
URL Query I used: http://localhost:8123/images/3.jpg
Complete code:
var querystring = require('querystring'); //used for parsing parts of urls
url = require('url');
http = require('http');
fs = require('fs');
gm = require('gm').subClass({ imageMagick: true });;
var server = http.createServer();
server.on('request', function(request, response){
var parsed_url = url.parse(request.url, true); //true gets the query as well
imageLocation = '.' + parsed_url.pathname;
gm(imageLocation)
.resize(100) // use your own width and height
.write('here.jpg', function (err) {
if (!err) console.log(' hooray! ');
else console.log(err);
});
if (getImage('here.jpg', response)){
//image is displayed
}
else{
respond404(parsed_url.pathname, response);
}
})
function respond404(path, response){
respond(404, "The requested path " + path + " was not found", response)
}
function getImage(location, response)
{
try{
var img = fs.readFileSync(location);
response.writeHead(200, {'Content-Type':'image/jpg'}); //parse this end
response.end(img, 'binary');
return true;
}catch(e){
return false;
}
}
server.listen(8123);

The answer Svbaker put can be used in Linux (maybe Mac as well?)
For Windows I got it to work by opening the command line in administrator mode and starting my server there.

I was able to get your code to work by changing how you required gm as follows:
var gm = require('gm');
I also had to remember to execute node with the correct permissions in my case:
sudo node server.js

Related

Formidable multi-file upload - ENOENT, no such file or directory

I know this question has been asked but my mind has been blown by my inability to get this working. I am trying to upload multiple images to my server with the following code:
var formidable = require('formidable');
var fs = require('fs');
...
router.post('/add_images/:showcase_id', function(req, res){
if(!admin(req, res)) return;
var form = new formidable.IncomingForm(),
files = [];
form.uploadDir = global.__project_dirname+"/tmp";
form.on('file', function(field, file) {
console.log(file);
file.image_id = global.s4()+global.s4();
file.endPath = "/img/"+file.image_id+"."+file.type.replace("image/","");
files.push({field:field, file:file});
});
form.on('end', function() {
console.log('done');
console.log(files);
db.get("SOME SQL", function(err, image_number){
if(err){
console.log(err);
}
var db_index = 0;
if(image_number) db_index = image_number.image_order;
files.forEach(function(file, index){
try{
//this line opens the image in my computer (testing)
require("sys").exec("display " + file.file.path);
console.log(file.file.path);
fs.renameSync(file.file.path, file.file.endPath);
}catch (e){
console.log(e);
}
db.run( "SOME MORE SQL"')", function(err){
if(index == files.length)
res.redirect("/admin/gallery"+req.params.showcase_id);
});
});
});
});
form.parse(req);
});
The line that opens the image via system calls works just fine, however I continue to get:
Error: ENOENT, no such file or directory '/home/[username]/[project name]/tmp/285ef5276581cb3b8ea950a043c6ed51'
by the rename statement.
the value of file.file.path is:
/home/[username]/[project name]/tmp/285ef5276581cb3b8ea950a043c6ed51
I am so confused and have tried everything. What am I doing wrong?
Probably you get this error because the target path does not exist or you don't have write permissions.
The error you get is misleading due to a bug in nodejs, see:
https://github.com/joyent/node/issues/5287
https://github.com/joyent/node/issues/685
Consider adding:
console.log(file.file.endPath);
before the fs.renameSync call and check if the target path exist and is writable by your application
You stated form. Therefore note that Formidable doesn't work out of the box with just NodeJS. Unless you were to use something like the prompt module for input. If you are using HTML, you'll need something like Angular, React or Browserify to be able to give it access to your interface.

Node js working on second or third call

I have written a node.js server which creates a server and prints the output when done with an asynchronous function. While I am able to get the correct output always in the console.log. The same is not getting reflected in my response. Here is my code snippet :-
var request = require('request');
var http = require('http');
var cheerio = require('cheerio');
var url = require('url');
var Curl = require( 'node-libcurl' ).Curl;
var sleep = require('sleep');
isDone = 0;
globalImage = "";
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
var url_parts = url.parse(req.url, true);
var query = url_parts.query;
var main_url = query["link"];
if (req.url != '/favicon.ico') {
res.writeHead(200);
if(main_url != undefined ){
var position = parseInt(query["position"]);
// web_scrap()
web_scrap(main_url,position, function(image) {
console.log("Console log : " + image);
globalImage = image;
});
res.write(globalImage);
res.end("HEY");
}
}
else {//For favicon and other requests just write 404s
res.writeHead(404);
res.write('This URL does nothing interesting');
res.end();
}
}).listen(3000, '127.0.0.1');
console.log('Server running at http://127.0.0.1:3000/');
function web_scrap(url, position, callback){
// do something
callback(JSON.stringify(product));
}
Now on starting the server and accessing it in browser with parameters link and position as get, I am getting output on second or third refresh. I am getting perfect output in console.log though !
Can anyone help or guide me in this regard ?
Thanks !
From what I understand, you're loading an image from an external source, asynchronously.
Thus, your function continues to run, even though the load is not finished yet. And as your globalImage is a global variable, once it is loaded, it stays in memory, that's why you get the data after some tries.
Just move your res.write and res.end in the callback function, this way the content will be sent once the image is loaded.
web_scrap(main_url,position, function(image) {
console.log("Console log : " + image);
globalImage = image;
res.write(globalImage);
res.end("HEY");
});
Anyway, except if you want to cache your image, you should not have a globalImage variable, as it would stay in memory even though you would want it to be garbage collected. You can remove the variable and just make this:
web_scrap(main_url,position, function(image) {
console.log("Console log : " + image);
res.write(image);
res.end("HEY");
});

How to load webpage as response to request

I would like to load a webpage in response to a request for a path,I have figured it out till here:
var http=require('http');
var mysql=require('./mysql');
var fs=require('fs');
var app=http.createServer();
app.listen(8000);
app.on('request',function(req,res){
var _path=req.url;
if(path==='/')
{ res.writeHead(200,{'Content-Type':'text/plain'});
res.end('Hello World \n');
}
if(path==='/demo')
{
//this is bad,we could use streams to improve this(although this is non-blocking too)
fs.readFile('../maps/google_maps.html',function(err,contents){
if(err)
{
console.log('did not work');
res.writeHead(500);
}
else
{
res.setHeader("Content-Length", contents.length);
res.setHeader("Content-Type", mimeType);
res.statusCode = 200;
res.write(contents);
}
res.end();
});
}
});
Server does not work for /demo path,it throws the error:
{ [Error: ENOENT, open '../maps/google_maps.html'] errno: 34, code: 'ENOENT', path: '../maps/google_maps.html' }
var _path=req.url;
if(path==='/')
you create _path but then compare path, which is always undefined
change it to var path=req.url;
error:
ENOENT means file not found
../maps/google_maps.html is a path relative to where you're calling node from, so make sure file exists, or specify full path
To make a path relative to the script, you must use the __dirname variable.
__dirname + '/path/to/file'
You should better use Express.js along with Jade which is a templating engine for Node.js. You can easily render html pages to client and serve static content

Meteor.http.get request -> Error: Hostname/IP doesn't match certificate's altnames

I'm trying to use meteor.http module and I'm getting the following error on the server side.
"Error: Hostname/IP doesn't match certificate's altnames" since I'm new in Meteor and in Node.js and its javaScript debugging is hard (btw how can I debug server side scripts ? client side it's easy), I'm using MAC OS X 10.9 not sure if it's relevent...
Thanks
Ronen
client side code:
'click #buildButton' : function () {
console.log("Jenkins job request");
$('#buildButton').attr('disabled','true').val('loading...');
var userName = "Ronen";
Meteor.call('jenkinsServiceBuild', function(err, respJson) {
if(err) {
window.alert("Error: " + err.reason);
console.log("error occured on receiving data on server. ", err );
} else {
window.alert("Success: ");
console.log("respJson: ", respJson);
//window.alert(respJson.length + ' tweets received.');
Session.set("recentTweets",respJson);
}
$('#buildButton').removeAttr('disabled').val('build');
});
}
Server Side Code:
Meteor.methods({jenkinsServiceBuild: function(userName) {
var url = "https://www.ynet.co.il";
//synchronous GET
var result = Meteor.http.get(url, {timeout:30000});
if(result.statusCode==200) {
var respJson = JSON.parse(result.content);
console.log("response received.");
return respJson;
} else {
console.log("Response issue: ", result.statusCode);
var errorJson = JSON.parse(result.content);
throw new Meteor.Error(result.statusCode, errorJson.error);
}
}
});
The site 'https://www.ynet.co.il' has an incorrectly installed SSL certficate for that domain. It's using akamai's certificate.
If you know and trust the site and its for nothing too secure just remove the s in https
var url = "http://www.ynet.co.il";
Also I'm not sure the code will work, looking at the site it serves html content but this line:
var respJson = JSON.parse(result.content);
Suggests it serves JSON content. If it does server json content use this instead:
var respJson = result.data;

Node.js copy remote file to server

Right now I'm using this script in PHP. I pass it the image and size (large/medium/small) and if it's on my server it returns the link, otherwise it copies it from a remote server then returns the local link.
function getImage ($img, $size) {
if (#filesize("./images/".$size."/".$img.".jpg")) {
return './images/'.$size.'/'.$img.'.jpg';
} else {
copy('http://www.othersite.com/images/'.$size.'/'.$img.'.jpg', './images/'.$size.'/'.$img.'.jpg');
return './images/'.$size.'/'.$img.'.jpg';
}
}
It works fine, but I'm trying to do the same thing in Node.js and I can't seem to figure it out. The filesystem seems to be unable to interact with any remote servers so I'm wondering if I'm just messing something up, or if it can't be done natively and a module will be required.
Anyone know of a way in Node.js?
You should check out http.Client and http.ClientResponse. Using those you can make a request to the remote server and write out the response to a local file using fs.WriteStream.
Something like this:
var http = require('http');
var fs = require('fs');
var google = http.createClient(80, 'www.google.com');
var request = google.request('GET', '/',
{'host': 'www.google.com'});
request.end();
out = fs.createWriteStream('out');
request.on('response', function (response) {
response.setEncoding('utf8');
response.on('data', function (chunk) {
out.write(chunk);
});
});
I haven't tested that, and I'm not sure it'll work out of the box. But I hope it'll guide you to what you need.
To give a more updated version (as the most recent answer is 4 years old, and http.createClient is now deprecated), here is a solution using the request method:
var fs = require('fs');
var request = require('request');
function getImage (img, size, filesize) {
var imgPath = size + '/' + img + '.jpg';
if (filesize) {
return './images/' + imgPath;
} else {
request('http://www.othersite.com/images/' + imgPath).pipe(fs.createWriteStream('./images/' + imgPath))
return './images/' + imgPath;
}
}
If you can't use remote user's password for some reasons and need to use the identity key (RSA) for authentication, then programmatically executing the scp with child_process is good to go
const { exec } = require('child_process');
exec(`scp -i /path/to/key username#example.com:/remote/path/to/file /local/path`,
(error, stdout, stderr) => {
if (error) {
console.log(`There was an error ${error}`);
}
console.log(`The stdout is ${stdout}`);
console.log(`The stderr is ${stderr}`);
});

Categories

Resources