I am using Bluemix to develop a 'HTTP POST listener' with NodeJS. This server should be the link between an Android Application and a Watson Bluemix Service
This is my code
/*eslint-env node*/
// This application uses express as its web server
// for more info, see: http://expressjs.com
var express = require('express');
// cfenv provides access to your Cloud Foundry environment
// for more info, see: https://www.npmjs.com/package/cfenv
var cfenv = require('cfenv');
// create a new express server
var app = express();
// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));
// get the app environment from Cloud Foundry
var appEnv = cfenv.getAppEnv();
/* 'BODY PARSER - NOT WORKING' */
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); //Assuming JSON ENCODED INPUT
app.use(express.bodyParser({uploadDir:'/images'}));
// start server on the specified port and binding host
app.listen(appEnv.port, '0.0.0.0', function() {
// print a message when the server starts listening
console.log("server starting on " + appEnv.url);
app.post('/handle',function(request,response){
var image64=request.body.encoded_String;
var imageName=request.body.image_name;
/*OK LOG THIS (Encoded Base64 image)*/
console.log("IMG RECEIVED: " + imageName); //OK
console.log("ENCODED: " + image64); // = undefined (chunk problems?)
response.writeHead(200, { "Content-Type": "text/plain" });
response.write('Hello World - Example...\n');
response.end();
});
});
How can I receive a base64 encoded image and save it to a folder?
Thanks for you help!
String with image received in base64 has usually it's format written at the beginning which has to be removed (or at least I used to remove it).
var base64Data = str.replace(/^data:image\/png;base64,/, ""); // str - string with image
Then you have to save it with fs:
fs.writeFile("../dir/to/save/image.png", base64Data, 'base64', function(err) {});
And that's basically all.
Related
I'd like to send image from android app to node.js server to save into MongoDB on server side. I use AsyncHttpClient to post request.
My code is like this:
Android ->
RequestParams param = new RequestParams();
param.put("email", email);
param.put("image", file, "image/jpg");
System.out.println("Param : " + param);
HttpClient.post("uploadImg_Profile/", param, new AsyncHttpResponseHandler() {
Node.js ->
app.js->
app.post('/uploadImg_Profile/', function(req, res){
uploadImg_Profile.uploadImg_Profile(req, res);
})
uploadImg_Profile.js->
exports.uploadImg_Profile= function(req, res){
var User = new user({
email : req.body.email,
img : req.body.image
});
//
console.log("req : " + req);
console.log("email : "+ User.email);
console.log("image : " + User.img);
But console.log result is undefined. I respect that this is seen jhgdsfejdi734634jdhfdf like this BSON type result.
How can I get img data?
There is a way to get file's type from File object dynamically?
You need to use the right type of body parser in your node.js code - from the result you are getting, it looks as if you're not interpreting it as a multipart form.
You need to register the middleware to use to interpret the POST, for example, using the multer parser:
app.js:
var multer = require('multer');
app.use(bodyparser.json());
app.use(multer({ inMemory: true, putSingleFilesInArray: true }));
app.post('/uploadImg_Profile/', function(req, res){
uploadImg_Profile.uploadImg_Profile(req, res);
});
uploadImg_Profile.js:
exports.uploadImg_Profile= function(req, res){
var User = new user({
email : req.body.email,
img : req.files['image'][0].buffer
});
console.log("req : " + req);
console.log("email : "+ User.email);
console.log("image : " + User.img);
}
Multer will also populate various other properties about the file, so you should be able to retrieve the type of the image from that using:
req.files['image'][0].mimetype
See the multer page on github for all the goodness.
EDIT: Added bodyparser.json as well as multer.
It is solved.
It is possible that both app.use(bodyparser) and app.use(multer) are used simultaneously.
app.use(bodyparser.json())
app.use(multer())
Like this.
And my previous problem is another points.
I don't know exactly what make it doing. I just change express version from 3.x to 4.x and test various situation. In this progress, I find out that req has image buffer properly, and can get buffer data.
Thanks Mark and all of you intereted in my question.
i have an error with the Image Upload from Facebook in my Titanium Software, everytime i want to upload an image from my App i get this:
Fail: REST API is deprecated for versions v2.1 and higher
But if i try the same code in the KitchenSink example app, it works perfect:
var xhr = Titanium.Network.createHTTPClient({
onload: function() {
// first, grab a "handle" to the file where you'll store the downloaded data
var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'mygraphic.png');
f.write(this.responseData); // write to the file
var blob = f.read();
var data = {
caption: 'behold, a flower',
picture: blob
};
facebook.request('photos.upload', data, showRequestResult);
},
timeout: 10000
});
xhr.open('GET','http://www.pur-milch.de/files/www/motive/pm_motiv_kaese.jpg');
xhr.send();
And in my App:
function showRequestResult(e) {
var s = '';
if (e.success) {
s = "SUCCESS";
if (e.result) {
s += "; " + e.result;
}
} else {
s = "FAIL";
if (e.error) {
s += "; " + e.error;
}
}
alert(s);
}
Ti.App.hs_stats.addEventListener('touchend', function(e){
Ti.App.hs_stats.top = 255;
var xhr = Titanium.Network.createHTTPClient({
onload: function() {
// first, grab a "handle" to the file where you'll store the downloaded data
var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'mygraphic.png');
f.write(this.responseData); // write to the file
var blob = f.read();
var data = {
caption: 'behold, a flower',
picture: blob
};
Ti.App.fb.request('photos.upload', data, showRequestResult);
},
timeout: 10000
});
xhr.open('GET','http://www.pur-milch.de/files/www/motive/pm_motiv_kaese.jpg');
xhr.send();
});
Looks like you're using the 'old' Facebook module for Appcelerator? I have image uploads working for Profiles and Pages (although Pages is a bit different, I'll explain later). Here's some quick code (I assume you already authenticated with Facebook):
var fb = require('facebook');
fb.appid = "xxxxxxxxxxxxxxxxx";
var acc = fb.getAccessToken();
fb.requestWithGraphPath('me/photos?access_token='+ acc, {picture:image, message: data}, "POST", showRequestResult);
The image variable is just a blob - It comes directly from event.media from a gallery selection or camera intent. data is the text for your status update.
In your tiapp.xml add these lines:
<property name="ti.facebook.appid">xxxxxxxxxxxxxxxxx</property>
and (if you're using Android and iOS - add both or just the platform you're using)
<modules>
<module platform="android">facebook</module>
<module platform="iphone">facebook</module>
</modules>
Now Pages were a bit strange:
var endPoint = 'https://graph.facebook.com/v2.1/' + pid + '/photos?access_token='+ acc;
xhr.open('POST',endPoint);
xhr.send({
message: data,
picture: image
});
You have to use an HTTP Request, as I couldn't get the requestWithGraphPath() to work with pages no matter what I tried.
pid is your page ID and you can get it, or a list of pages you are an admin for like so (again, create a new HTTP Request (xhr) and use this):
xhr.open("GET","https://graph.facebook.com/v2.1/me?fields=accounts{access_token,global_brand_page_name,id,picture}&access_token=" +fb.getAccessToken());
This will return the access token for each page, the global brand name (basically a clean version of the page name), it's id and the profile picture. The access token in this URL is YOUR personal access token (the &access_token= part).
As far as I can tell, these access tokens don't expire for pages, so you can save it in your app somewhere or if you REALLY want to be safe, you could grab a token before each post, but that's a bit much.
BONUS:
If you want to do video posts to pages:
var xhr = Titanium.Network.createHTTPClient();
var endPoint = 'https://graph-video.facebook.com/'+ pid +'/videos?access_token='+ acc;
xhr.open('POST',endPoint);
xhr.setRequestHeader("enctype", "multipart/form-data");
xhr.send({source:video, description:data});
and for profiles:
var acc = fb.getAccessToken();
var xhr = Titanium.Network.createHTTPClient();
var endPoint = 'https://graph-video.facebook.com/me/videos?access_token='+ acc;
xhr.open('POST',endPoint);
xhr.setRequestHeader("enctype", "multipart/form-data");
xhr.send({source:video, description:data});
video is another blob from either your camera or gallery event.media intent and data is the text you want to use for the status update.
I am posting the data from Android to the Node.js. I am successfully able to call the Node.js post method and using restify able to get the Post data.
But when doing through express I am not able to get the post body in Node.js. I tried for many approaches from SO post but it seems none are working may be I am missing something.
The snippets are like:
Node.js
var express = require('express')
var request = require('request')
var http = require('http')
var bodyParser = require('body-parser')
var app = express();
app.set('port', (process.env.PORT || 5000))
app.use(express.static(__dirname + '/public'))
app.use(bodyParser.urlencoded())
app.use(bodyParser.json())
app.post('/search/addcomplaint',addComplaint)
function addComplaint(req,res,next){
console.log(req.body);
if (!req.body) return res.sendStatus(400)
res.send(201,user)
}
app.listen(app.get('port'), function() {
console.log("Node app is running at localhost:" + app.get('port'))
})
at Android Site I am making a retrofit call like this:
#Multipart
#POST("/search/addcomplaint")
public User search(#Part("complaint") String complaint);
when I used restify in Node.js I was able to get req.body but using express I am not getting the request body.
Question:
how can I make my sensor data come in as proper x,y,z coordinates or something more human readable??
Background:
I have packets of sensor data (eg. Gravity, Rotation etc..) coming from my android phone
Ok so I've a UDP server using nodeJS. It is open and listening for a message data.
server.js
var PORT = 33333;
var HOST = '0.0.0.0';
var dgram = require('dgram');
var server = dgram.createSocket('udp4');
server.on('listening', function () {
var address = server.address();
console.log('UDP Server listening on ' + address.address + ":" + address.port);
});
server.on('message', function (message, remote) {
console.log(message);
});
server.bind(PORT, HOST);
This message is formatted as a buffer((?) what is it really called binary?).
This is what happens when i do console.log(message.toString("utf8"));
I have implemented a app for android using phone Gap.
In the app I have two button one is Voice Enroll and another one is Voice Verification.
For Voice Enroll I implemented Record Function Using CaptureAudio in Phone Gap. It works Great.
Now I need to upload the Record file to server. I have Used Below Code.
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
alert(mediaFiles[i]);
uploadFile(mediaFiles[i]);
}
}
function captureError(error) {
var msg = 'An error occurred during capture: ' + error.code;
navigator.notification.alert(msg, null, 'Uh oh!');
}
function captureAudio() {
navigator.device.capture.captureAudio(captureSuccess, captureError, {limit: 3);
}
// Upload files to server
function uploadFile(mediaFile) {
var ft = new FileTransfer(),
recordingPath = mediaFile.fullPath,
name = mediaFile.name;
console.log('Path is: ' + recordingPath);
ft.upload(recordingPath,
"Webservice URL",
function(result) {
alert("Hi");
console.log('Upload success: ' + result.responseCode);
console.log(result.bytesSent + ' bytes sent');
},
function(error) {
alert("welcome");
console.log('Error uploading file ' + recordingPath + ': ' + error.code);
},
{ fileName: name });
alert(recordingPath);
}
When I alert that mediaFiles[i] is received "Object Object". I can't receive any response after uploading.
Once Success we receive some messages from server about the audio file.
I am also send the audio file name as 'utterence'. How can i done this using phonegap and jquery mobile?
I remember having a similar problem and in my case the problem was capture returned full path and upload required the file path in different format so I had to modify the full path in a format accepted by upload.
Also make sure you set mimeType in the upload function. It defaults to image/jpeg. I am not sure how your server behaves but if it has self signed certificates then you will have to set trustAllHosts to true.
Hope this helps