Skip to content

Commit

Permalink
Merge pull request #58 from chughts/bugfixes
Browse files Browse the repository at this point in the history
Enabled Alchemy Language Emotion feature
  • Loading branch information
chughts committed May 12, 2016
2 parents e55426c + d26ae62 commit 4610616
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 26 deletions.
13 changes: 10 additions & 3 deletions services/alchemy_language/v1.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
Copyright 2013,2015 IBM Corp.
Copyright 2013,2015,2016 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -46,7 +46,8 @@
<input style="width: 30px; margin-left: 20px; margin-top: 0;" type="checkbox" id="node-input-author"><label style="width: auto;" for="node-input-author">Authors</label>
</div>
</div>
<div style="margin-left: -200px; float: right;">
<div style="margin-left: -200px; float: right;">

<div>
<input style="width: 30px; margin-left: 20px; margin-top: 0;" type="checkbox" id="node-input-keyword"><label style="width: auto;" for="node-input-keyword">Keywords</label>
</div>
Expand All @@ -65,6 +66,10 @@
<div>
<input style="width: 30px; margin-left: 20px; margin-top: 0;" type="checkbox" id="node-input-doc-sentiment"><label style="width: auto;" for="node-input-doc-sentiment">Document Sentiment</label>
</div>
<div>
<input style="width: 30px; margin-left: 20px; margin-top: 0;" type="checkbox" id="node-input-doc-emotion"><label style="width: auto;" for="node-input-doc-emotion">Document Emotion</label>
</div>

</div>
</div>
<div class="form-row" style="padding-top: 10px;">
Expand All @@ -89,6 +94,7 @@
<li><b>Relations</b>, identify Subject-Action-Object relations.</li>
<li><b>Publication Date</b>, extract available publication date.</li>
<li><b>Document Sentiment</b>, generate sentiment scores.</li>
<li><b>Document Emotion</b>, generate emotion scores.</li>
</ul>
<p>For full details on the feature details, please see the <a href="http://www.alchemyapi.com/api">Alchemy API documentation</a></p>
<p>The content to be analysed should be passed in on <code>msg.payload</code>.</p>
Expand All @@ -115,7 +121,8 @@
concept: {value: ""},
relation: {value: ""},
"pub-date": {value: ""},
"doc-sentiment": {value: ""}
"doc-sentiment": {value: ""},
"doc-emotion": {value: ""}
},
credentials: {
apikey: {type:"password"}
Expand Down
86 changes: 63 additions & 23 deletions services/alchemy_language/v1.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2013,2015 IBM Corp.
* Copyright 2013,2015, 2016 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
Expand All @@ -13,6 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/


// AlchemyAPI Text Analysis functions supported by this node
var FEATURES = {
'page-image': 'image',
'image-kw': 'imageKeywords',
Expand All @@ -25,77 +28,114 @@ var FEATURES = {
'concept': 'concepts',
'relation': 'relations',
'pub-date': 'publicationDate',
'doc-sentiment': 'docSentiment'
'doc-sentiment': 'docSentiment',
'doc-emotion': 'docEmotions'
};

module.exports = function (RED) {
var cfenv = require('cfenv'),
AlchemyAPI = require('alchemy-api');

var services = cfenv.getAppEnv().services,
service;
var cfenv = require('cfenv');
var watson = require('watson-developer-cloud');

// Require the Cloud Foundry Module to pull credentials from bound service
// If they are found then the api key is stored in the variable s_apikey.
//
// This separation between s_apikey and apikey is to allow
// the end user to modify the key redentials when the service is not bound.
// Otherwise, once set apikey is never reset, resulting in a frustrated
// user who, when he errenously enters bad credentials, can't figure out why
// the edited ones are not being taken.

var services = cfenv.getAppEnv().services;
var service;

var apikey;
var apikey, s_apikey;

var service = cfenv.getAppEnv().getServiceCreds(/alchemy/i);

if (service) {
apikey = service.apikey;
s_apikey = service.apikey;
}

RED.httpAdmin.get('/alchemy-feature-extract/vcap', function (req, res) {
res.json(service ? {bound_service: true} : null);
});


// This is the Alchemy Data Node

function AlchemyFeatureExtractNode (config) {
RED.nodes.createNode(this, config);
var node = this;

this.on('input', function (msg) {
if (!msg.payload) {
this.status({fill:'red', shape:'ring', text:'missing payload'});
var message = 'Missing property: msg.payload';
node.error(message, msg);
return;
}

apikey = apikey || this.credentials.apikey;
// If it is present the newly provided user entered key takes precedence over the existing one.
apikey = s_apikey || this.credentials.apikey;
this.status({});

if (!apikey) {
this.status({fill:'red', shape:'ring', text:'missing credentials'});
var message = 'Missing Alchemy API service credentials';
node.error(message, msg);
return;
}

var alchemy = new AlchemyAPI(apikey);
var alchemy_language = watson.alchemy_language( { api_key: apikey } );

// Check which features have been requested.

var enabled_features = Object.keys(FEATURES).filter(function (feature) {
return config[feature]
});


if (!enabled_features.length) {
this.status({fill:'red', shape:'ring', text:'no features selected'});
var message = 'AlchemyAPI node must have at least one selected feature.';
node.error(message, msg);
return;
}

alchemy.combined(msg.payload, enabled_features, msg.alchemy_options || {}, function (err, response) {
if (err || response.status === 'ERROR') {
var message = 'Alchemy API request error: ' + (err ? err : response.statusInfo);
node.error(message, msg);
return;
}
// The watson node-SDK expects the features as a single string.
var extract = "" ; //doc-sentiment";
enabled_features.forEach(function(entry){extract += (',' + entry)})

//console.log("Will be looking for ", extract)

msg.features = {};
Object.keys(FEATURES).forEach(function (feature) {
var answer_feature = FEATURES[feature];
msg.features[feature] = response[answer_feature];
});
var params = { text: msg.payload, extract: extract };

alchemy_language.combined(params, function (err, response) {
if (err || response.status === 'ERROR') {
node.status({fill:'red', shape:'ring', text:'call to alchmeyapi language service failed'});
console.log('Error:', msg, err);
node.error(err, msg);
}
else {
msg.features = {};
//msg.features['all'] = response;

Object.keys(FEATURES).forEach(function (feature) {
var answer_feature = FEATURES[feature];

msg.features[feature] = response[answer_feature] || {};
});

node.send(msg);
}
});

node.send(msg)
})
});
}


//Register the node as alchemy-feature-extract to nodeRED
RED.nodes.registerType('alchemy-feature-extract', AlchemyFeatureExtractNode, {
credentials: {
apikey: {type:"password"}
Expand Down

0 comments on commit 4610616

Please sign in to comment.