Comparing version 0.3.3 to 0.4.0
64
index.js
@@ -26,2 +26,32 @@ var _ = require('lodash') | ||
var _boundary = 'clarifai_multipart_boundary' | ||
var _partForParameter = function(name, value) { | ||
var part = '--' + _boundary + '\r\nContent-Disposition: form-data; name="' + name + '"\r\n\r\n' + value + '\r\n' | ||
return new Buffer(part, 'utf8'); | ||
} | ||
var _buildMultipart = function(buffers, lang) { | ||
// Build a multipart payload. We can't use needle's support for this because needle expects all | ||
// parts to have distinct names while Clarifai requires multiple parts to have the same name. | ||
var chunks = [] | ||
for (var buffer of _array(buffers)) { | ||
var header = '--' + _boundary + '\r\n' + | ||
'Content-Disposition: form-data; name="encoded_data"; filename="data"\r\n' + | ||
'Content-Transfer-Encoding: binary\r\n' + | ||
'Content-Type: application/octet-stream\r\n\r\n' | ||
chunks.push(new Buffer(header, 'ascii')) | ||
chunks.push(buffer) | ||
} | ||
if (lang) { | ||
chunks.push(_partForParameter('language', lang)) | ||
} | ||
chunks.push(new Buffer('--' + _boundary + '--\r\n', 'ascii')) | ||
return Buffer.concat(chunks) | ||
} | ||
var _parseErr = function(err, resp, body, cb) { | ||
@@ -37,2 +67,6 @@ if(err) { | ||
var _withAccessToken = function(_this, options) { | ||
return _.merge(options, { headers: { 'Authorization': _this.tokenType + ' ' + _this.accessToken }}); | ||
} | ||
var _request = function(verb, type, data, options, _this, cb) { | ||
@@ -58,3 +92,3 @@ var url = 'https://api.clarifai.com' | ||
needle.request(verb, url, data, options, function(err, resp, body) { | ||
needle.request(verb, url, data, _withAccessToken(_this, options), function(err, resp, body) { | ||
if (body.status_code === 'TOKEN_INVALID' || body.status_code === 'TOKEN_NONE') { | ||
@@ -65,4 +99,3 @@ _this.getAccessToken(function(err) { | ||
} else { | ||
options = { headers: _this.headers() } | ||
needle.request(verb, url, data, options, function(err, resp, body) { | ||
needle.request(verb, url, data, _withAccessToken(_this, options), function(err, resp, body) { | ||
_parseErr(err, resp, body, cb) | ||
@@ -134,6 +167,2 @@ }) | ||
Clarifai.prototype.headers = function() { | ||
return { 'Authorization': this.tokenType + ' ' + this.accessToken } | ||
} | ||
Clarifai.prototype.getAccessToken = function(cb) { | ||
@@ -152,3 +181,2 @@ var _this = this | ||
_this.tokenType = body.token_type | ||
_this.options = { headers: _this.headers() } | ||
cb(err, _this.accessToken) | ||
@@ -218,2 +246,21 @@ }) | ||
Clarifai.prototype.tagFromBuffers = function(type, buffers, cb, lang) { | ||
var data = _buildMultipart(buffers, lang) | ||
var options = _.cloneDeep(this.options || {}) | ||
options.headers = options.headers || {} | ||
options.headers['Content-Type'] = 'multipart/form-data; boundary=' + _boundary | ||
options.headers['Content-Length'] = data.length | ||
_request('post', 'tag', data, options, this, function(err, body) { | ||
if (err) { | ||
return cb(err) | ||
} else if (type === 'image') { | ||
return cb(err, formatImageResults(body)) | ||
} else { | ||
return cb(err, formatVideoResults(body)) | ||
} | ||
}) | ||
} | ||
function Clarifai (opts) { | ||
@@ -227,4 +274,5 @@ opts = opts || { | ||
this.secret = opts.secret | ||
this.options = {} | ||
} | ||
module.exports = Clarifai |
{ | ||
"name": "clarifai", | ||
"version": "0.3.3", | ||
"version": "0.4.0", | ||
"description": "A Node integration library for clarifai", | ||
"main": "index.js", | ||
"engines": { | ||
"node": "5.5.0" | ||
"node": "5.6.0" | ||
}, | ||
@@ -33,12 +33,12 @@ "scripts": { | ||
"devDependencies": { | ||
"chai": "3.4.1", | ||
"chai": "3.5.0", | ||
"codacy-coverage": "1.1.3", | ||
"istanbul": "0.4.2", | ||
"mocha": "2.3.4", | ||
"mocha-lcov-reporter": "1.0.0", | ||
"mocha": "2.4.5", | ||
"mocha-lcov-reporter": "1.2.0", | ||
"publish": "0.5.0" | ||
}, | ||
"dependencies": { | ||
"lodash": "4.0.0", | ||
"needle": "0.11.0" | ||
"lodash": "4.5.1", | ||
"needle": "1.0.0" | ||
}, | ||
@@ -45,0 +45,0 @@ "config": { |
[![Circle CI](https://circleci.com/gh/ctartist621/clarifai/tree/master.svg?style=svg&circle-token=e15ad7ff3e856e1b86fb002868fb4c9e98d4e22e)](https://circleci.com/gh/ctartist621/clarifai/tree/master) [![npm version](https://badge.fury.io/js/clarifai.svg)](https://badge.fury.io/js/clarifai) [![Codacy Badge](https://api.codacy.com/project/badge/grade/fd34502ca14c4c0ba556e90a81d77991)](https://www.codacy.com/app/ctartist621/clarifai) [![Codacy Badge](https://api.codacy.com/project/badge/coverage/fd34502ca14c4c0ba556e90a81d77991)](https://www.codacy.com/app/ctartist621/clarifai) [![Dependency Status](https://david-dm.org/ctartist621/clarifai.svg)](https://david-dm.org/ctartist621/clarifai) [![devDependency Status](https://david-dm.org/ctartist621/clarifai/dev-status.svg)](https://david-dm.org/ctartist621/clarifai#info=devDependencies) | ||
# clarifai | ||
A Node integration library for [clarifai](http://clarifai.com/), a very cool content tagging api. | ||
A Node integration library for [Clarifai](http://clarifai.com/), a very cool content tagging api. | ||
@@ -19,4 +19,4 @@ | ||
client = new Clarifai({ | ||
id: <clarafai id>, | ||
secret: <clarafai secret> | ||
id: <clarifai id>, | ||
secret: <clarifai secret> | ||
}) | ||
@@ -45,3 +45,3 @@ ``` | ||
### Image Tagging via url | ||
### Image Tagging via URL | ||
``` | ||
@@ -52,5 +52,5 @@ client.tagFromUrls('image', url, function(err, results) { | ||
``` | ||
This function will take one image url, or many image urls as an array. The language parameter is optional, and will request tags from clarifai in the appropriate language. | ||
This function will take one image URL, or many image URLs as an array. The language parameter is optional, and will request tags from Clarifai in the appropriate language. | ||
The callback returns the standard error / results. The results object returned has the following structure: | ||
The callback returns the standard error/results. The results object returned has the following structure: | ||
``` | ||
@@ -164,5 +164,5 @@ { | ||
``` | ||
If one image was passed in, the results object will be the single object representing the results for that image. If more than one was passed in, it will be an array of results objects. | ||
If one image was passed in, the `results` object will be the single object representing the results for that image. If more than one was passed in, it will be an array of `results` objects. | ||
### Video Tagging via url | ||
### Video Tagging via URL | ||
``` | ||
@@ -173,5 +173,5 @@ client.tagFromUrls('video', url, function(err, results) { | ||
``` | ||
This function will take one video url, or many video urls as an array. The language parameter is optional, and will request tags from clarifai in the appropriate language. | ||
This function will take one video URL, or many video URLs as an array. The language parameter is optional, and will request tags from Clarifai in the appropriate language. | ||
The callback returns the standard error / results. The results object returned has the following structure: | ||
The callback returns the standard error/results. The `results` object returned has the following structure: | ||
``` | ||
@@ -249,7 +249,19 @@ { | ||
``` | ||
Each classification is taken at 1 second keyframes by clarifai, so each keyframe has a set of tags associated with it. So the document results object will have a timestamps array, and each timestamp will have an array of tags associated with that timestamp. | ||
Each classification is taken at 1 second keyframes by Clarifai, so each keyframe has a set of tags associated with it. So the document's `results` object will have a timestamps array, and each timestamp will have an array of tags associated with that timestamp. | ||
If one video was passed in, the results object will be the single object representing the results for that image. If more than one was passed in, it will be an array of results objects. | ||
If one video was passed in, the `results` object will be the single object representing the results for that image. If more than one was passed in, it will be an array of `results` objects. | ||
### Image and Video Tagging from Buffers | ||
``` | ||
client.tagFromBuffers('image', buffer, function(err, results) { | ||
// Callback code here | ||
}, [language]) | ||
``` | ||
This function will take one Buffer containing image or video data, or many Buffers as an array. The language parameter is optional, and will request tags from clarifai in the appropriate language. | ||
The response format is the same as for image or video URLs, as described in the previous sections. | ||
## Feedback | ||
@@ -256,0 +268,0 @@ For all the feedback functions, any input parameters can be a single string, or an array of strings. |
@@ -1,2 +0,4 @@ | ||
var should = require('chai').should(), | ||
var fs = require('fs'), | ||
path = require('path'), | ||
should = require('chai').should(), | ||
Clarifai = require('../index'), | ||
@@ -141,2 +143,57 @@ client | ||
}); | ||
describe('#Buffers', function() { | ||
it('should tag an image from a buffer', function(done) { | ||
var buffer = fs.readFileSync(path.join(__dirname, 'sky.jpg')); | ||
client.tagFromBuffers('image', buffer, function(err, resp) { | ||
should.not.exist(err) | ||
resp.should.have.property('docId') | ||
resp.should.have.property('docIdStr') | ||
resp.should.have.property('tags').with.length.above(0) | ||
resp.tags[0].should.have.property('class') | ||
resp.tags[0].should.have.property('conceptId') | ||
resp.tags[0].should.have.property('probability') | ||
done() | ||
}) | ||
}); | ||
it('should tag an image from a buffer in another language', function(done) { | ||
var buffer = fs.readFileSync(path.join(__dirname, 'sky.jpg')); | ||
client.tagFromBuffers('image', buffer, function(err, resp) { | ||
should.not.exist(err) | ||
resp.should.have.property('docId') | ||
resp.should.have.property('docIdStr') | ||
resp.should.have.property('tags').with.length.above(0) | ||
resp.tags[0].should.have.property('class') | ||
resp.tags[0].should.have.property('conceptId') | ||
resp.tags[0].should.have.property('probability') | ||
done() | ||
}, 'es') | ||
}); | ||
it('should tag multiple images from a set of buffers', function(done) { | ||
var buffers = [ | ||
fs.readFileSync(path.join(__dirname, 'sky.jpg')), | ||
fs.readFileSync(path.join(__dirname, 'sky.jpg')) | ||
]; | ||
client.tagFromBuffers('image', buffers, function(err, resp) { | ||
should.not.exist(err) | ||
resp.should.have.length(2) | ||
resp[0].should.have.property('docId') | ||
resp[0].should.have.property('docIdStr') | ||
resp[0].should.have.property('tags').with.length.above(0) | ||
resp[0].tags[0].should.have.property('class') | ||
resp[0].tags[0].should.have.property('conceptId') | ||
resp[0].tags[0].should.have.property('probability') | ||
resp[1].should.have.property('docId') | ||
resp[1].should.have.property('docIdStr') | ||
resp[1].should.have.property('tags').with.length.above(0) | ||
resp[1].tags[0].should.have.property('class') | ||
resp[1].tags[0].should.have.property('conceptId') | ||
resp[1].tags[0].should.have.property('probability') | ||
done() | ||
}) | ||
}); | ||
}); | ||
}); | ||
@@ -143,0 +200,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
9
342
0
110263
2537
4
+ Addedlodash@4.5.1(transitive)
+ Addedneedle@1.0.0(transitive)
- Removedlodash@4.0.0(transitive)
- Removedneedle@0.11.0(transitive)
Updatedlodash@4.5.1
Updatedneedle@1.0.0