Microsoft cognitive services face API call - json

I've build an application on the Azure (microsoft) emotion API, but that was just merged with their cognitive services face API. I'm using a webcam to send an image (in binary data) to their server for analysis, and used to get an xml in return. (I've already commented out some old code, in this example. Trying to get it fixed).
function saveSnap(data){
// Convert Webcam IMG to BASE64BINARY to send to EmotionAPI
var file = data.substring(23).replace(' ', '+');
var img = Base64Binary.decodeArrayBuffer(file);
var ajax = new XMLHttpRequest();
// On return of data call uploadcomplete function.
ajax.addEventListener("load", function(event) {
uploadcomplete(event);
}, false);
// AJAX POST request
ajax.open("POST", "https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=emotion","image/jpg");
ajax.setRequestHeader("Content-Type","application/json");
//ajax.setRequestHeader("Accept","text/html,application/xhtml+xml,application/xml");
ajax.setRequestHeader("Ocp-Apim-Subscription-Key","subscription_key");
ajax.send(img);
}
now I understood from their website the call returns a JSON. But I just can't get it to work. I can see there is data coming back, but how do I even get the JSON out of it. I'm probably missing something essential, and hope someone can help me out. :) the program was working when I could still use the Emotion API.
function uploadcomplete(event){
console.log("complete");
console.log(event);
//var xmlDoc = event.target.responseXML;
//var list = xmlDoc.getElementsByTagName("scores");
console.log(JSON.stringify(event));

A few issues to address:
You'll want to wait for the POST response, not just for the upload
completion.
You'll want to set the content type to be application/octet-stream if you are uploading a binary as you are.
You'll want to set the subscription key to the real value (you probably did before pasting your code here.)
.
function saveSnap(data) {
// Convert Webcam IMG to BASE64BINARY to send to EmotionAPI
var file = data.substring(23).replace(' ', '+');
var img = Base64Binary.decodeArrayBuffer(file);
ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (ajax.readyState == XMLHttpRequest.DONE) {
console.log(JSON.stringify(ajax.response));
}
}
ajax.open('post', 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=emotion');
ajax.setRequestHeader('Content-Type', 'application/octet-stream');
ajax.setRequestHeader('Ocp-Apim-Subscription-Key', key);
ajax.send(img);
}

Related

How to Add a file to Google Drive via Docs Add On using App Script? [duplicate]

This question already has answers here:
Uploading Multiple Files to Google Drive with Google App Script
(5 answers)
Closed 6 years ago.
Here is my scenario. I've created an Add-On for Google Docs that acts as a video toolbox.
A feature I'm trying to add is the ability to record a video using the built in web cam (using videojs-recorder) and then link to that video within the doc. I've got the video part working, but not sure how to get the webm JS Blob converted into a Google Blob so I can create a file on the users Google Drive for sharing and linking.
Just to figure out how this might work this is what I've done so far without any luck.
CLIENT SIDE CODE
//event handler for video recording finish
vidrecorder.on('finishRecord', function()
{
// the blob object contains the recorded data that
// can be downloaded by the user, stored on server etc.
console.log('finished recording: ', vidrecorder.recordedData);
google.script.run.withSuccessHandler(function(){
console.log("winning");
}).saveBlob(vidrecorder.recordedData);
});
SERVER SIDE CODE
function saveBlob(blob) {
Logger.log("Uploaded %s of type %s and size %s.",
blob.name,
blob.size,
blob.type);
}
The errors I get seem to be related to serialization of the blob. But really the exceptions aren't very useful - and just point to some minimized code.
EDIT: Note that there is no FORM object involved here, hence no form POST, and no FileUpload objects, as others have indicated that this might be a duplicate, however it's slightly different in that we are getting a Blob object and need to save it to the server.
Thanks goes to Zig Mandel and Steve Webster who provided some insight from the G+ discussion regarding this.
I finally pieced together enough bits to get this working.
CLIENT CODE
vidrecorder.on('finishRecord', function()
{
// the blob object contains the recorded data that
// can be downloaded by the user, stored on server etc.
console.log('finished recording: ', vidrecorder.recordedData.video);
var blob = vidrecorder.recordedData.video;
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
b64Blob = reader.result;
google.script.run.withSuccessHandler(function(state){
console.log("winning: ", state);
}).saveB64Blob(b64Blob);
};
});
SERVER CODE
function saveB64Blob(b64Blob) {
var success = { success: false, url: null};
Logger.log("Got blob: %s", b64Blob);
try {
var blob = dataURItoBlob(b64Blob);
Logger.log("GBlob: %s", blob);
var file = DriveApp.createFile(blob);
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.COMMENT);
success = { success: true, url: file.getUrl() };
} catch (error) {
Logger.log("Error: %s", error);
}
return success;
}
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = Utilities.base64Decode(dataURI.split(',')[1]);
else
byteString = decodeURI(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
return Utilities.newBlob(byteString, mimeString, "video.webm");
}

how to update existing json object in java script with titanium studio

var args = arguments[0] || {};
$.atn.text=args.attendance;
Ti.API.info('attendance:'+args.attendance);
function doClick(e){
$.atn.value=$.atn.value+1;
Ti.API.info('atn is'+$.atn.value);
var url = "api.usergrid.com/PRI_95616/LOGIN/attendances?";
var client = Ti.Network.createHTTPClient({
onload : function(e) {},
onerror : function(e) {
Ti.API.debug(e.error);
alert('error');
},
timeout : 5000 // in milliseconds
});
client.setRequestHeader('content-type', 'JSON');
client.open("PUT", url);
client.send(JSON.stringify(jsonobject));
}
I want to fetch and then update the attendance value then insert the updated value in database. How can I do it?
If by "update the database" you mean PUT to the Restful API, then you have one small error.
client.send(JSON.stringify(jsonobject));
jsonobject is not defined. It must be the json (JavaScript) object you just built. if $.atn is the object you're pushing values into then try:
client.send(JSON.stringify($.atn));
I don't know the REST API specs for usergrid.com, but if all you have to do is PUT a json object with .text and .value defined, the URL "api.usergrid.com/PRI_95616/LOGIN/attendances?" then this should do it. However, you'll have to put http:// before the URL like:
"http://api.usergrid.com/PRI_95616/LOGIN/attendances?"

Using backgrounddownloader and savefilepicker together?

Hello everyone I have a small winrt aplication that downloads video from internet and I was trying to implement backgrounddownloader and filesavepicker together but I run on errors for every type of implementation I searched google and I searched microsoft documentation but nothing.I implemented download via HttpClient class but what I want is to get download progress and HttpClient doesn't offer it.Thx in advance
Here's a quick sample, how to do it:
// set download URI
var uri = new Uri("http://s3.amazonaws.com/thetabletshow/thetabletshow_0072_lhotka.mp3");
// get destination file
var picker = new FileSavePicker();
// set allowed extensions
picker.FileTypeChoices.Add("MP3", new List<string> { ".mp3" });
var file = await picker.PickSaveFileAsync();
// create a background download
var downloader = new BackgroundDownloader();
var download = downloader.CreateDownload(uri, file);
// create progress object
var progress = new Progress<DownloadOperation>();
// attach an event handler to get notified on progress
progress.ProgressChanged += (o, operation) =>
{
// use the progress info in Progress.BytesReceived and Progress.TotalBytesToReceive
ProgressText.Text = operation.Progress.BytesReceived.ToString();
};
// start the actual download
await download.StartAsync().AsTask(progress);
You should be able to modify it for your needs from here on.

Upload a file to Google Drive API using HTML5

I'm creating a Google Chrome extension which use Google Drive API.
I have to upload a file with HTML5.
For text files, there is no problem. But when I want to upload a binary file, there are always errors.
So when I upload a file using the FileReader in HTML5 as BinaryString, my image is corrupted, I can't read it.
And when I use Base64 encoding (with the header in the body part "Content-Transfer-Encoding: base64"), I have a 400 Bad Request -> Malformed multipart body.
Can you help me please ?
Thanks :)
PS: I don't want to use Google Drive SDK, I prefer write all the code.
var bb, reader;
var meta = {
"title": "mozilla.png",
"mimeType": "image/png",
"description": "Mozilla Official logo"
};
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://developer.mozilla.org/media/img/mdn-logo-sm.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e){
if(this.status == 200){
bb = new WebKitBlobBuilder();
bb.append(this.response);
console.log('Download OK');
reader = new FileReader();
reader.readAsDataURL(bb.getBlob('image/png'));
reader.onloadend = function(e){
console.log('Reader OK');
var bound = 287032396531387;
var parts = [];
parts.push('--' + bound);
parts.push('Content-Type: application/json');
parts.push('');
parts.push(JSON.stringify(meta));
parts.push('--' + bound);
parts.push('Content-Type: image/png');
parts.push('Content-Transfer-Encoding: base64');
parts.push('');
parts.push(reader.result);
parts.push('--' + bound + '--');
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart", true);
xhr.setRequestHeader("Authorization", "Bearer token123456");
xhr.setRequestHeader("Content-Type", "multipart/mixed; boundary=" + bound);
xhr.onload = function(e){
console.log("DRIVE OK", this, e);
};
xhr.send(parts.join("\r\n"));
}
}
};
xhr.send();
For Binary Upload, just modify this line :
reader.readAsDataURL(bb.getBlob('image/png'));
by that
reader.readAsBinaryString(bb.getBlob('image/png'));
and delete this line :
parts.push('Content-Transfer-Encoding: base64');
I tried to create a file by sending the metadata first and upload the content after like in this post and I always get a 404 error for uploading the content, but this is another story...
An empty line which consists of only \r\n and no other whitespace need to be added at the end of your request. Try to add another parts.push(''); after parts.push('--' + bound + '--');
Edit:
First, I want to say that you should not upload file as raw Binary String because your binary data contains control characters which may screw up your request and results in corrupted file. Data should be encoded in Base64. You can read more here
If you check reader.result in debug, it will contain:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABHCAMAAABoMgR/AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJlQTFRFAAAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAEgICExAQIAQFIyAgLwYHMjAwPggJQkBATAoLUlBQWwwOYmBgaQ4QcXBweBASgYCAhxIUkIKCkY+PlRQXoZ+fpBYZrYaGsK+vsxgbwL+/wRod0Bwg0M/P3h4i4N/f7SAk7+/v9pCS////7yG8VgAAAA90Uk5TABAgMEBQYHCAn6+/z9/vBoviEQAABBtJREFUWMOtmA13mzoMhumWdd3uWpuPACUEWIkXA3HI+P8/7kq2AYOBNj1Tz2nA9oOl10KAHUfZw+7p4/b41ZnY7j9yn708PQzww09yv7186+lf5FP2qHBJJ1y0H7am9JCR8z/BAa3bOy1B/zH+lzW6KJt3+CfHeYSfYqGboX9eylRMC5FB/7Pj/IBRdicPoTkOMMIgZWlAEmtIBn1fHFjx0JIGPQt40wiWSZGoZ/Mc2ncLuMgoABAQpXCWEi9hraAWv4KXFP1G1dIYBVSy1ha/iHOM12PzmdLU4hfwBhUj6VRKnqA/GfBxvYWLVCbjMDVLwrBoUOM9/JXAw0rWazgqhp63LMTIa4+mjBdeCiMl2IoyNq4wxWWaoGUwGzjASKxiKALwq6gHj+AK5RyXaaIMZoaxgga9AmlipWu5LJ1ISKwZNYVsnEmeeR66Z+O45KzPaBF7ujkkibkWRSiC0MbVkusxhLShbOesxcCCjI+J1WYWLhItXI9DAy5ASNtel3C4hIUXtBeOyduXkpKTgPGYZI3qqU6R319ihgtIELCABBi1ktcTMvvTNtZ4lXent1fpRRIuSVfj7Jzrw6ARnDcYlEyJox9dSHeqLsdXlyzimVF4CqyfWZYCmkBtxHzz96RyT+djl5PUxmXexaO+ZEhDfdfJ4nNwo4qQeo43Wt/WiERaahZodMJ1UaIJLrJ+LmZ6rxesqM1bn6oQTbzm0goyJii4ystErydN+qqNpSwUK9WGDmkndAbWKuS+akN+6Fpk4zKEelCud4SNzzVQNxMr1UY9ubTQsSEDRFCXiewN16pNraUPWsFl0tP5Hd6USbla61A6Jp9YWG2YIaIZyGalDWXe1BCennCQkX4Ah0rrieEBaJQIU4hVnI2612b6yhR69xnX0PGOyUbfOWVts+D9DBeBMWMw+s7wmsHgl41TXSuGwHG2YP4w98KpBT3e2/iOUszfOOrll6sJXppKN9aryBru59J+/x1sciLtTz63Q49H3Wes+nf4Fby59h2nPD+pJmln1QHnZ8VBWzXF8fig6SsZmrRFFz0b/kKdJSS3cVIp/NXCiXtR5/stPBpimuPkVZ/nGziRsUUGjhes9tjQD7ls4D7qRma41AIwPeS2jpO3rvMtvFO66CHHDdy95eQdnFTrODzB3sX94zLu9/3ruBziLuORctw9r+N5pKdYwm/y4m/VBn5113G5aPtuC+/OGzimTGXhp3Hdc5XSa/gF7xsD31fV+eiOWQfUzV3Hu/w2wQc7DPiQ+wrHL6mbEegivr+NeKfX/Si/pL7Jk03cR59GHBcol/+f1Veke7m/VmGl/A74d0yV6jP0s/yGl5X+cL7eUSXffFXl/8H3u/Pw4zO7Bztj7+Le7YdnY+9C7Zw8fnznZDfsnPwP488L21waSrUAAAAASUVORK5CYII=
As you can see, the readAsDataURL method DID encode your data to base64 but because it is used to produce Data URI , a string with format as data:[<MIME-type>][;charset=<encoding>][;base64], is added at the begin of your encoded data. This is the culprit cause 400 Bad Request error (Malformed multipart body).The solution is to eliminate this string before adding it to the request body:
parts.push(reader.result.replace(/^data:image\/(png|jpg);base64,/, ""));
I have tested and it works fine.

Binding JSON string to ListView in Metro apps?

I have a metro application(HTML5 & WinJS) in which am trying to display service data . Actually here am retrieving JSON data from my service but am unable to bind this data into listview . Anyone give me some working example.
Thank you.
You can use the WinJS.xhr() for this. You can read more about it on this link https://msdn.microsoft.com/pt-br/library/windows/apps/br229787.aspx and here is an example:
var path = "data/file.json";
function getData(path) {
WinJS.xhr({ url: path }).then(
function (response) {
var json = JSON.parse(response.responseText);
// Since this is an asynchronous function, you can't
// return the data, so you can:
// 1) retrieve the data to a namespace once the app loads.
var list = new WinJS.Binding.List(json);
Somenomespace.data = list;
// 2) or do all the binding inside the function.
var listView = document.getElementById("listViewID");
listView.winControl.itemDataSource = list.dataSource;
});
}
If you use the built in JSON.parse(jsonString) function you can loop through the content using a normal for loop as it then is a normal object and add it as usuall. Just remember to process or render the data.
Her is an example from code i had in a search page using listview:
var response = JSON.parse(data) ;
var originalResults = new WinJS.Binding.List();
for (x in response) {
originalResults.push(response[x]);
}
this.populateFilterBar(element, originalResults);
this.applyFilter(this.filters[0], originalResults);