From 73a6b2ec41fed45d43771532bbb69a285b07c3bc Mon Sep 17 00:00:00 2001 From: chughts Date: Mon, 17 Dec 2018 10:12:56 +0000 Subject: [PATCH 01/53] Additional languages for Visual Recognition --- README.md | 6 ++++++ package.json | 4 ++-- services/visual_recognition/v3.html | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e1123692..f7030441 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,12 @@ Node-RED Watson Nodes for IBM Cloud CLA assistant +### New in version 0.7.5 +- Bump SDK Dependency to 3.15.0 +- Added Portuguese (Brazilian) and Chinese (Simplified and Traditional) as output languages +for Visual Recognition node. +- Disable SSL Verification option for Assistant Node. + ### New in version 0.7.4 - Bump SDK Dependency to 3.11.0 - Bump Assistant version to 2018-09-20 diff --git a/package.json b/package.json index 863ebd2b..c757a91b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-node-watson", - "version": "0.7.4", + "version": "0.7.5", "description": "A collection of Node-RED nodes for IBM Watson services", "dependencies": { "async": "^1.5.2", @@ -10,7 +10,7 @@ "temp": "^0.8.3", "qs": "6.x", "image-type": "^2.0.2", - "watson-developer-cloud": "^3.11.0", + "watson-developer-cloud": "^3.15.0", "kuromoji": "^0.1.1", "word-count": "^0.2.2", "is-docx": "^0.0.3", diff --git a/services/visual_recognition/v3.html b/services/visual_recognition/v3.html index e21818bb..0bc3a7e6 100644 --- a/services/visual_recognition/v3.html +++ b/services/visual_recognition/v3.html @@ -51,6 +51,9 @@ + + + From cf5918735c8a1c265f1ee3e8761e321cd48691e5 Mon Sep 17 00:00:00 2001 From: chughts Date: Mon, 17 Dec 2018 14:59:15 +0000 Subject: [PATCH 02/53] Fix STT Streaming when using IAM Tokens --- README.md | 5 + services/speech_to_text/stt-utils.js | 2 +- services/speech_to_text/v1.js | 126 ++++-------------- .../text_to_speech/v1-corpus-builder.html | 3 + services/text_to_speech/v1-corpus-builder.js | 33 ++++- 5 files changed, 67 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index f7030441..3ed2c78d 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,11 @@ Node-RED Watson Nodes for IBM Cloud - Bump SDK Dependency to 3.15.0 - Added Portuguese (Brazilian) and Chinese (Simplified and Traditional) as output languages for Visual Recognition node. +- Added list voices and delete customisation methods to TTS Corpus Builder node. +- Allowing SDK to manage IAM Tokens for STT Node. +- Streaming mode for STT using IAM key now working +- Allow Start and End data packets to be specified as JSON objects, as well as +a stringified JSON objects. - Disable SSL Verification option for Assistant Node. ### New in version 0.7.4 diff --git a/services/speech_to_text/stt-utils.js b/services/speech_to_text/stt-utils.js index 00602fdf..fa57fdd0 100644 --- a/services/speech_to_text/stt-utils.js +++ b/services/speech_to_text/stt-utils.js @@ -74,7 +74,7 @@ class STTUtils { if (endpoint) { serviceSettings.url = endpoint; } - + return new STTV1(serviceSettings); } diff --git a/services/speech_to_text/v1.js b/services/speech_to_text/v1.js index 1f9793ad..771b6db1 100644 --- a/services/speech_to_text/v1.js +++ b/services/speech_to_text/v1.js @@ -241,8 +241,9 @@ module.exports = function (RED) { if ('string' === typeof msg.payload) { msg.payload = JSON.parse(tmp); - if ( msg.payload.action && - 'start' === msg.payload.action) { + } + if (msg.payload.action) { + if ('start' === msg.payload.action) { startPacket = msg.payload; } } else { @@ -307,7 +308,6 @@ module.exports = function (RED) { //tokenService = new iamutils(apikey); } else { - // console.log('Standard Key'); tokenService = new AuthV1(stt.getCredentials()); } @@ -338,79 +338,6 @@ module.exports = function (RED) { return clone; } - function buildRequestSettings(params, t) { - let requestSettings = { - qs : cloneQS(params), - method : 'POST', - uri : endpoint + '/v1/recognize', - headers : { - //Authorization: "Bearer " + t, - 'Content-Type': params.content_type, - 'User-Agent': pkg.name + '-' + pkg.version, - 'Accept': 'application/json', - }, - iam_apikey: apikey, - auth: { - 'bearer': t - }, - body : params.audio - }; - - return Promise.resolve(requestSettings); - } - - function executePostRequest(requestSettings) { - var p = new Promise(function resolver(resolve, reject){ - request(requestSettings, (error, response, body) => { - //console.log('--------- request has been executed ---------------'); - - if (!error && response.statusCode === 200) { - let data = JSON.parse(body); - resolve(data); - } else if (error) { - reject(error); - } else { - let errordata = JSON.parse(body); - console.log(errordata); - if (errordata.errors && - Array.isArray(errordata.errors) && - errordata.errors.length && - errordata.errors[0].message) { - reject('Error ' + response.statusCode + ' ' + errordata.errors[0].message); - } else if (errordata.error) { - reject('Error performing request ' + errordata.error); - } else { - reject('Error performing request ' + response.statusCode); - } - } - - }); - }); - return p; - } - - function iamRecognize(params) { - var p = new Promise(function resolver(resolve, reject){ - //console.log('qs params look like ', qs); - // The token may have expired so test for it. - //getToken(speech_to_text) - iamutils.getIAMToken(apikey) - .then((t) => { - //console.log('We should now have a token ', token); - return buildRequestSettings(params, t); - }) - .then((requestSettings) => { - return executePostRequest(requestSettings); - }) - .then((data) => { - resolve(data); - }) - .catch((err) => { - reject(err); - }); - }); - return p; - } function performSTT(speech_to_text, audioData) { var p = new Promise(function resolver(resolve, reject){ @@ -437,23 +364,13 @@ module.exports = function (RED) { } // Everything is now in place to invoke the service - if (apikey) { - iamRecognize(params) - .then((data) => { - resolve(data); - }) - .catch((err) => { + speech_to_text.recognize(params, function (err, res) { + if (err) { reject(err); - }); - } else { - speech_to_text.recognize(params, function (err, res) { - if (err) { - reject(err); - } else { - resolve(res); - } + } else { + resolve(res); + } }); - } }); return p; @@ -483,7 +400,7 @@ module.exports = function (RED) { tokenPending = false; tokenTime = now; token = res; - //console.log('We have the token ', token); + // console.log('We have the token ', token); resolve(); } }); @@ -505,22 +422,31 @@ module.exports = function (RED) { if (endpoint) { var tmp = endpoint.replace('https', 'wss'); - wsURI = tmp + '/v1/recognize' - + '?watson-token=' + token + '&model=' + model; + wsURI = tmp + '/v1/recognize'; } else { - wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize' - + '?watson-token=' + token + '&model=' + model; + wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize'; + } + + if (apikey) { + wsURI += '?model=' + model; + } else { + wsURI += '?watson-token=' + token + '&model=' + model; } //console.log('wsURI is : ', wsURI); if (!websocket && !socketCreationInProcess) { socketCreationInProcess = true; - // console.log('Attempting creation of web socket'); - var ws = new WebSocket(wsURI); - // console.log('Setting up listeners'); + //console.log('Attempting creation of web socket'); + var authHeader = {}; + if (apikey) { + authHeader.headers = { authorization: 'Bearer ' + token }; + } + + var ws = new WebSocket(wsURI, authHeader); + //console.log('Setting up listeners'); ws.on('open', () => { - // console.log('Socket is open'); + //console.log('Socket is open'); ws.send(JSON.stringify(startPacket)); websocket = ws; socketCreationInProcess = false; diff --git a/services/text_to_speech/v1-corpus-builder.html b/services/text_to_speech/v1-corpus-builder.html index ba2e7261..1cab219a 100644 --- a/services/text_to_speech/v1-corpus-builder.html +++ b/services/text_to_speech/v1-corpus-builder.html @@ -59,6 +59,8 @@ + + @@ -281,6 +283,7 @@ + ', #node-input-tts-custom-id'); break; case 'getCustomisation': + case 'deleteCustomisation': case 'addWords': case 'getWords': fields.push('#node-input-tts-custom-id'); diff --git a/services/text_to_speech/v1-corpus-builder.js b/services/text_to_speech/v1-corpus-builder.js index 410c1c3d..c719c6b8 100644 --- a/services/text_to_speech/v1-corpus-builder.js +++ b/services/text_to_speech/v1-corpus-builder.js @@ -72,6 +72,18 @@ module.exports = function (RED) { }); } + function executeListVoices(node, tts, params, msg) { + tts.listVoices(params, function (err, response) { + node.status({}); + if (err) { + payloadutils.reportError(node, msg, err); + } else { + msg['voices'] = response.voices ? response.voices: response; + } + node.send(msg); + }); + } + function executeGetCustomisation(node, tts, params, msg) { tts.getVoiceModel(params, function (err, response) { node.status({}); @@ -84,6 +96,18 @@ module.exports = function (RED) { }); } + function executeDeleteCustomisation(node, tts, params, msg) { + tts.deleteVoiceModel(params, function (err, response) { + node.status({}); + if (err) { + payloadutils.reportError(node, msg, err); + } else { + msg['response'] = response ; + } + node.send(msg); + }); + } + function executeGetPronounce(node, tts, params, msg) { tts.getPronunciation(params, function (err, response) { node.status({}); @@ -152,9 +176,15 @@ module.exports = function (RED) { case 'listCustomisations': executeListCustomisations(node, tts, params, msg); break; + case 'listVoices': + executeListVoices(node, tts, params, msg); + break; case 'getCustomisation': executeGetCustomisation(node, tts, params, msg); break; + case 'deleteCustomisation': + executeDeleteCustomisation(node, tts, params, msg); + break; case 'getPronounce': executeGetPronounce(node, tts, params, msg); break; @@ -282,8 +312,9 @@ module.exports = function (RED) { params['word'] = config['tts-custom-word']; } // No break here as want the custom id also - case 'listCustomisations': + //case 'listCustomisations': case 'getCustomisation': + case 'deleteCustomisation': case 'addWords': case 'getWords': if (config['tts-custom-id']) { From bf744844b495782e73369a5a1a8e8a04611d31b8 Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 18 Dec 2018 10:40:40 +0000 Subject: [PATCH 03/53] Keywords and customisation weight support for STT Node --- README.md | 10 +++-- services/speech_to_text/v1-corpus-builder.js | 2 +- services/speech_to_text/v1.html | 32 +++++++++++++++- services/speech_to_text/v1.js | 40 +++++++++++++++++++- 4 files changed, 78 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3ed2c78d..11dc127b 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,14 @@ Node-RED Watson Nodes for IBM Cloud - Added Portuguese (Brazilian) and Chinese (Simplified and Traditional) as output languages for Visual Recognition node. - Added list voices and delete customisation methods to TTS Corpus Builder node. -- Allowing SDK to manage IAM Tokens for STT Node. -- Streaming mode for STT using IAM key now working -- Allow Start and End data packets to be specified as JSON objects, as well as +- STT Node Changes + - Allowing SDK to manage IAM Tokens. + - Streaming mode for STT using IAM key now working. + - Fix to stream mode for max alternatives and smart formatting options + - Keywords and Customization Weight can now be specified + - Allow Start and End data packets to be specified as JSON objects, as well as a stringified JSON objects. + - In line with SDK change use createLanguageModel() to create custom model - Disable SSL Verification option for Assistant Node. ### New in version 0.7.4 diff --git a/services/speech_to_text/v1-corpus-builder.js b/services/speech_to_text/v1-corpus-builder.js index 1d0cb406..246a32fe 100644 --- a/services/speech_to_text/v1-corpus-builder.js +++ b/services/speech_to_text/v1-corpus-builder.js @@ -48,7 +48,7 @@ module.exports = function (RED) { } function executeCreateCustomisation(node, stt, params, msg) { - stt.createCustomization(params, function (err, response) { + stt.createLanguageModel(params, function (err, response) { node.status({}); if (err) { payloadutils.reportError(node, msg, err); diff --git a/services/speech_to_text/v1.html b/services/speech_to_text/v1.html index 6a42eb80..7616f7ba 100644 --- a/services/speech_to_text/v1.html +++ b/services/speech_to_text/v1.html @@ -71,6 +71,11 @@ +
+ + +
+
+
+ + +
+ +
+ + +
@@ -166,6 +180,9 @@ two character code from Language Indentification, but the language will default. eg. en will default to en-US

+ Keywords to identify should be entered as a comma separted list. If keywords are specified + then keyword threshold must also be set. +

The returned audio transcription will be returned on msg.transcription.

The full response, including alternative transcriptions can be found on msg.fullresult.

@@ -239,11 +256,14 @@ fields.push('#node-label-message' + ', #node-input-alternatives' + + ', #node-input-keywords' + + ', #node-input-keywords-threshold' + ', #node-input-speakerlabels' + ', #node-input-smartformatting' + ', #node-input-lang' + ', #node-input-band' - + ', #node-input-langcustom'); + + ', #node-input-langcustom' + + ', #node-input-custom-weight'); stt.hideSelectedFields(fields); } } @@ -255,6 +275,8 @@ var hideFields = []; if (stt.models) { showFields.push('#node-input-alternatives' + + ', #node-input-keywords' + + ', #node-input-keywords-threshold' + ', #node-input-speakerlabels' + ', #node-input-smartformatting' + ', #node-input-lang' @@ -264,9 +286,12 @@ } else { hideFields.push('#node-label-message' + ', #node-input-alternatives' + + ', #node-input-keywords' + + ', #node-input-keywords-threshold' + ', #node-input-speakerlabels' + ', #node-input-smartformatting' + ', #node-input-langcustom' + + ', #node-input-custom-weight' + ', #node-input-lang' + ', #node-input-band'); } @@ -370,8 +395,10 @@ if (showit) { $('select#node-input-langcustom').parent().show(); + $('#node-input-custom-weight').parent().show(); } else { $('select#node-input-langcustom').parent().hide(); + $('#node-input-custom-weight').parent().hide(); } } @@ -608,8 +635,11 @@ langhidden: {value: ''}, langcustom: {value: ''}, langcustomhidden: {value: ''}, + 'custom-weight': {value: '0.5'}, band: {value: ''}, bandhidden: {value: ''}, + keywords: {value: ''}, + 'keywords-threshold': {value: '0.5'}, password: {value: ''}, apikey: {value: ''}, 'payload-response' :{value: false}, diff --git a/services/speech_to_text/v1.js b/services/speech_to_text/v1.js index 771b6db1..b035f0cf 100644 --- a/services/speech_to_text/v1.js +++ b/services/speech_to_text/v1.js @@ -339,6 +339,26 @@ module.exports = function (RED) { } + function keywordParams(params) { + // Check for keywords, which might already be an array + if (config['keywords'] && 'string' === typeof config['keywords']) { + // Trim any [] from edges of string + var keywords = config['keywords']; + var start = 0; + var end = keywords.length; + var threshold = parseFloat(config['keywords_threshold']); + + if ('[' === keywords[start]) { + start++; + } + if (']' === keywords[end]) { + end--; + } + params.keywords = keywords.substring(start, end).split(','); + params['keywords_threshold'] = isNaN(threshold) ? 0 : threshold; + } + } + function performSTT(speech_to_text, audioData) { var p = new Promise(function resolver(resolve, reject){ var model = config.lang + '_' + config.band, @@ -358,9 +378,13 @@ module.exports = function (RED) { smart_formatting: config.smartformatting ? config.smartformatting : false }; + keywordParams(params); + // Check the params for customisation options if (config.langcustom && 'NoCustomisationSetting' !== config.langcustom) { + var weight = parseFloat(config['custom-weight']); params.customization_id = config.langcustom; + params.customization_weight = isNaN(weight) ? 0 : weight; } // Everything is now in place to invoke the service @@ -447,7 +471,21 @@ module.exports = function (RED) { //console.log('Setting up listeners'); ws.on('open', () => { //console.log('Socket is open'); - ws.send(JSON.stringify(startPacket)); + var streamStartPacket = startPacket; + + if (config['alternatives']) { + streamStartPacket.max_alternatives = parseInt(config['alternatives']); + } + if (config.speakerlabels) { + streamStartPacket.speakerlabels = config.speakerlabels; + } + if (config.smart_formatting) { + streamStartPacket.smartformatting = config.smartformatting; + } + + keywordParams(streamStartPacket); + + ws.send(JSON.stringify(streamStartPacket)); websocket = ws; socketCreationInProcess = false; // resolve(); From 332cec0e6f50ff0f9b6a687313c3524a5b1f6ba0 Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 18 Dec 2018 11:10:46 +0000 Subject: [PATCH 04/53] word confidence flag added to STT Node config --- README.md | 2 +- services/speech_to_text/v1.html | 47 ++++++++++++++++++++++----------- services/speech_to_text/v1.js | 8 ++++-- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 11dc127b..159f0734 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ for Visual Recognition node. - Allowing SDK to manage IAM Tokens. - Streaming mode for STT using IAM key now working. - Fix to stream mode for max alternatives and smart formatting options - - Keywords and Customization Weight can now be specified + - Keywords, Word Confidence and Customization Weight can now be specified - Allow Start and End data packets to be specified as JSON objects, as well as a stringified JSON objects. - In line with SDK change use createLanguageModel() to create custom model diff --git a/services/speech_to_text/v1.html b/services/speech_to_text/v1.html index 7616f7ba..4b3c668d 100644 --- a/services/speech_to_text/v1.html +++ b/services/speech_to_text/v1.html @@ -102,50 +102,56 @@
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + + +
+ +
+ + +
@@ -183,6 +189,11 @@ Keywords to identify should be entered as a comma separted list. If keywords are specified then keyword threshold must also be set.

+ Keywords to identify should be entered as a comma separted list. If keywords are specified + then keyword threshold must also be set. +

+ Check the word confidence setting if you want confidence scores for each word. +

The returned audio transcription will be returned on msg.transcription.

The full response, including alternative transcriptions can be found on msg.fullresult.

@@ -258,6 +269,7 @@ + ', #node-input-alternatives' + ', #node-input-keywords' + ', #node-input-keywords-threshold' + + ', #node-input-word-confidence' + ', #node-input-speakerlabels' + ', #node-input-smartformatting' + ', #node-input-lang' @@ -277,6 +289,7 @@ showFields.push('#node-input-alternatives' + ', #node-input-keywords' + ', #node-input-keywords-threshold' + + ', #node-input-word-confidence' + ', #node-input-speakerlabels' + ', #node-input-smartformatting' + ', #node-input-lang' @@ -288,6 +301,7 @@ + ', #node-input-alternatives' + ', #node-input-keywords' + ', #node-input-keywords-threshold' + + ', #node-input-word-confidence' + ', #node-input-speakerlabels' + ', #node-input-smartformatting' + ', #node-input-langcustom' @@ -640,6 +654,7 @@ bandhidden: {value: ''}, keywords: {value: ''}, 'keywords-threshold': {value: '0.5'}, + 'word-confidence': {value: false}, password: {value: ''}, apikey: {value: ''}, 'payload-response' :{value: false}, diff --git a/services/speech_to_text/v1.js b/services/speech_to_text/v1.js index b035f0cf..3b34e3d3 100644 --- a/services/speech_to_text/v1.js +++ b/services/speech_to_text/v1.js @@ -375,7 +375,8 @@ module.exports = function (RED) { model: model, max_alternatives: config['alternatives'] ? parseInt(config['alternatives']) : 1, speaker_labels: config.speakerlabels ? config.speakerlabels : false, - smart_formatting: config.smartformatting ? config.smartformatting : false + smart_formatting: config.smartformatting ? config.smartformatting : false, + word_confidence: config['word-confidence'] ? config['word-confidence'] : false }; keywordParams(params); @@ -384,7 +385,7 @@ module.exports = function (RED) { if (config.langcustom && 'NoCustomisationSetting' !== config.langcustom) { var weight = parseFloat(config['custom-weight']); params.customization_id = config.langcustom; - params.customization_weight = isNaN(weight) ? 0 : weight; + params.customization_weight = isNaN(weight) ? 0 : weight; } // Everything is now in place to invoke the service @@ -482,6 +483,9 @@ module.exports = function (RED) { if (config.smart_formatting) { streamStartPacket.smartformatting = config.smartformatting; } + if (config['word-confidence']) { + streamStartPacket.word_confidence = config['word-confidence']; + } keywordParams(streamStartPacket); From 5c31ddc1882dc4b035c7fe2fef5332f33cd7471f Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 18 Dec 2018 11:59:06 +0000 Subject: [PATCH 05/53] Added categorie limit option to NLU node config --- README.md | 2 ++ services/natural_language_understanding/v1.html | 10 ++++++++++ services/natural_language_understanding/v1.js | 10 +++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 159f0734..164e8836 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ for Visual Recognition node. a stringified JSON objects. - In line with SDK change use createLanguageModel() to create custom model - Disable SSL Verification option for Assistant Node. +- Bump Natural Language Understanding to 2018-11-16 +- Add Limit Categories option on Natural Language Understanding node ### New in version 0.7.4 - Bump SDK Dependency to 3.11.0 diff --git a/services/natural_language_understanding/v1.html b/services/natural_language_understanding/v1.html index 407fc133..36564e07 100644 --- a/services/natural_language_understanding/v1.html +++ b/services/natural_language_understanding/v1.html @@ -58,6 +58,11 @@ type="checkbox" id="node-input-categories" />
+
+ + +
Date: Tue, 18 Dec 2018 13:11:23 +0000 Subject: [PATCH 06/53] Add limit text characters as config option for NLU Node --- README.md | 6 ++++-- .../natural_language_understanding/v1.html | 20 +++++++++++++++---- services/natural_language_understanding/v1.js | 14 +++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 164e8836..a6a5a69d 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,10 @@ for Visual Recognition node. a stringified JSON objects. - In line with SDK change use createLanguageModel() to create custom model - Disable SSL Verification option for Assistant Node. -- Bump Natural Language Understanding to 2018-11-16 -- Add Limit Categories option on Natural Language Understanding node +- Natural Language Understanding Node Changes + - Bump Natural Language Understanding to 2018-11-16 + - Add Limit Categories and limit_text_characters options + ### New in version 0.7.4 - Bump SDK Dependency to 3.11.0 diff --git a/services/natural_language_understanding/v1.html b/services/natural_language_understanding/v1.html index 36564e07..2c05405a 100644 --- a/services/natural_language_understanding/v1.html +++ b/services/natural_language_understanding/v1.html @@ -21,6 +21,11 @@
+
+ + +
+ + - -
- - +
+ +
+ + + + + + + diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js new file mode 100644 index 00000000..2faabfba --- /dev/null +++ b/services/language_translator/v3-doc.js @@ -0,0 +1,37 @@ +/** + * Copyright 2018 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function (RED) { + + + function Node (config) { + var node = this; + RED.nodes.createNode(this, config); + + this.on('input', function (msg) { + msg.payload = 'Node does nothing yet'; + node.send(msg); + }); + } + + RED.nodes.registerType('watson-doc-translator', Node, { + credentials: { + username: {type:'text'}, + password: {type:'password'}, + apikey: {type:'password'} + } + }); +}; From c3ec0b8ac37ffffec716a88e8a73cb5afdee27f3 Mon Sep 17 00:00:00 2001 From: chughts Date: Wed, 19 Dec 2018 11:30:42 +0000 Subject: [PATCH 12/53] Added Credential Checking --- services/language_translator/v3-doc.html | 135 ++++++++++++++++++++++- services/language_translator/v3-doc.js | 21 ++++ 2 files changed, 153 insertions(+), 3 deletions(-) diff --git a/services/language_translator/v3-doc.html b/services/language_translator/v3-doc.html index 50efc159..6abb5f39 100644 --- a/services/language_translator/v3-doc.html +++ b/services/language_translator/v3-doc.html @@ -15,10 +15,55 @@ --> - diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 2faabfba..54e55f14 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -15,6 +15,27 @@ **/ module.exports = function (RED) { + const SERVICE_IDENTIFIER = 'language-translator'; + var serviceutils = require('../../utilities/service-utils'), + username = null, + password = null, + sUsername = null, + sPassword = null, + apikey = null, + sApikey = null, + service = serviceutils.getServiceCreds(SERVICE_IDENTIFIER); + + if (service) { + sUsername = service.username ? service.username : ''; + sPassword = service.password ? service.password : ''; + sApikey = service.apikey ? service.apikey : ''; + sEndpoint = service.url; + } + + // Node RED Admin - fetch and set vcap services + RED.httpAdmin.get('/watson-doc-translator/vcap', function (req, res) { + res.json(service ? {bound_service: true} : null); + }); function Node (config) { From d3c691fbd5d44831252a14271ebfd572aaf7c205 Mon Sep 17 00:00:00 2001 From: chughts Date: Wed, 19 Dec 2018 11:35:47 +0000 Subject: [PATCH 13/53] wrapped credential check into a promise --- services/language_translator/v3-doc.html | 28 +++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/services/language_translator/v3-doc.html b/services/language_translator/v3-doc.html index 6abb5f39..a72b417f 100644 --- a/services/language_translator/v3-doc.html +++ b/services/language_translator/v3-doc.html @@ -145,15 +145,18 @@ } doctor.checkCredentials = function() { - $.getJSON('watson-doc-translator/vcap/') - .done(function (service) { - $('.credentials').toggle(!service); - }) - .fail(function () { - $('.credentials').show(); - }).always(function () { - $('#credentials-check').hide(); - }) + return new Promise(function resolver(resolve, reject){ + $.getJSON('watson-doc-translator/vcap/') + .done(function (service) { + $('.credentials').toggle(!service); + }) + .fail(function () { + $('.credentials').show(); + }).always(function () { + $('#credentials-check').hide(); + resolve(); + }) + }); } // This is the on edit prepare function, which will be invoked everytime @@ -161,7 +164,12 @@ function oneditprepare() { //doctor.hideAll(); doctor.UIListeners(); - doctor.checkCredentials(); + doctor.checkCredentials() + .then(() => { + }) + .catch(function(err){ + console.log('Error in oneditprepare for doc translator node ', err); + }); } // Save the values in the dyanmic lists to the hidden fields. From afd8825c4b4649f2eb923b2fb0c92ccee4c49aa5 Mon Sep 17 00:00:00 2001 From: chughts Date: Wed, 19 Dec 2018 12:21:31 +0000 Subject: [PATCH 14/53] Move Credential Check into utils class --- .../language_translator/translator-utils.js | 32 +++++++++++++++++++ services/language_translator/v3-doc.js | 31 +++++++++++++++++- services/language_translator/v3.js | 11 ++----- 3 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 services/language_translator/translator-utils.js diff --git a/services/language_translator/translator-utils.js b/services/language_translator/translator-utils.js new file mode 100644 index 00000000..e23de113 --- /dev/null +++ b/services/language_translator/translator-utils.js @@ -0,0 +1,32 @@ +/** + * Copyright 2018 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + + +class TranslatorUtils { + constructor() { + } + + credentialCheck(u, p, k) { + if (!k && (!u || !p)) { + return Promise.reject('Missing Watson Language Translator service credentials'); + } + return Promise.resolve(); + } + +} + +var translatorutils = new TranslatorUtils(); +module.exports = translatorutils ; diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 54e55f14..654367a7 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -17,12 +17,16 @@ module.exports = function (RED) { const SERVICE_IDENTIFIER = 'language-translator'; var serviceutils = require('../../utilities/service-utils'), + payloadutils = require('../../utilities/payload-utils'), + translatorutils = require('./translator-utils'), username = null, password = null, sUsername = null, sPassword = null, apikey = null, sApikey = null, + endpoint = '', + sEndpoint = 'https://gateway.watsonplatform.net/language-translator/api', service = serviceutils.getServiceCreds(SERVICE_IDENTIFIER); if (service) { @@ -43,7 +47,32 @@ module.exports = function (RED) { RED.nodes.createNode(this, config); this.on('input', function (msg) { - msg.payload = 'Node does nothing yet'; + msg.payload = 'Node does nothing yet - 001'; + + var action = msg.action || config.action; + + // The dynamic nature of this node has caused problems with the password field. it is + // hidden but not a credential. If it is treated as a credential, it gets lost when there + // is a request to refresh the model list. + // Credentials are needed for each of the modes. + username = sUsername || this.credentials.username; + password = sPassword || this.credentials.password || config.password; + apikey = sApikey || this.credentials.apikey || config.apikey; + + endpoint = sEndpoint; + if ((!config['default-endpoint']) && config['service-endpoint']) { + endpoint = config['service-endpoint']; + } + + node.status({}); + translatorutils.credentialCheck(username, password, apikey) + .then(function(){ + return Promise.reject('Not working yet - 001'); + }) + .catch(function(err){ + payloadutils.reportError(node, msg, err); + node.send(msg); + }); node.send(msg); }); } diff --git a/services/language_translator/v3.js b/services/language_translator/v3.js index 469d733d..064444ab 100644 --- a/services/language_translator/v3.js +++ b/services/language_translator/v3.js @@ -28,6 +28,7 @@ module.exports = function (RED) { //cfenv = require('cfenv'), payloadutils = require('../../utilities/payload-utils'), serviceutils = require('../../utilities/service-utils'), + translatorutils = require('./translator-utils'), fs = require('fs'), temp = require('temp'), username = null, @@ -112,14 +113,6 @@ module.exports = function (RED) { RED.nodes.createNode(this, config); var node = this; - - function initialCheck(u, p, k) { - if (!k && (!u || !p)) { - return Promise.reject('Missing Watson Language Translator service credentials'); - } - return Promise.resolve(); - } - function payloadCheck(msg) { if (!msg.payload) { return Promise.reject('Missing property: msg.payload'); @@ -456,7 +449,7 @@ module.exports = function (RED) { node.status({}); - initialCheck(username, password, apikey) + translatorutils.credentialCheck(username, password, apikey) .then(function(){ return payloadCheck(msg); }) From 050af22bea5bebd6e86ed85568dedfd2061e3e77 Mon Sep 17 00:00:00 2001 From: chughts Date: Wed, 19 Dec 2018 12:30:16 +0000 Subject: [PATCH 15/53] Move action check into utils --- services/language_translator/translator-utils.js | 7 +++++++ services/language_translator/v3-doc.js | 5 ++++- services/language_translator/v3.js | 9 +-------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/services/language_translator/translator-utils.js b/services/language_translator/translator-utils.js index e23de113..1752dc10 100644 --- a/services/language_translator/translator-utils.js +++ b/services/language_translator/translator-utils.js @@ -26,6 +26,13 @@ class TranslatorUtils { return Promise.resolve(); } + checkForAction(action) { + if (!action) { + return Promise.reject('Missing action, please select one'); + } + return Promise.resolve(); + } + } var translatorutils = new TranslatorUtils(); diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 654367a7..6fb2af49 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -67,7 +67,10 @@ module.exports = function (RED) { node.status({}); translatorutils.credentialCheck(username, password, apikey) .then(function(){ - return Promise.reject('Not working yet - 001'); + return translatorutils.checkForAction(action); + }) + .then(function(){ + return Promise.reject('Not working yet - 002'); }) .catch(function(err){ payloadutils.reportError(node, msg, err); diff --git a/services/language_translator/v3.js b/services/language_translator/v3.js index 064444ab..abce9d87 100644 --- a/services/language_translator/v3.js +++ b/services/language_translator/v3.js @@ -120,13 +120,6 @@ module.exports = function (RED) { return Promise.resolve(); } - function checkForAction(action) { - if (!action) { - return Promise.reject('Missing action, please select one'); - } - return Promise.resolve(); - } - function checkForGlobalOverides(msg) { // If the selection is to use global overrides then // look for them @@ -454,7 +447,7 @@ module.exports = function (RED) { return payloadCheck(msg); }) .then(function(){ - return checkForAction(action); + return translatorutils.checkForAction(action); }) .then(function(){ return checkForGlobalOverides(msg); From c28a3a37bc672ef7fb50263fc033349eb0cd94b5 Mon Sep 17 00:00:00 2001 From: chughts Date: Wed, 19 Dec 2018 12:41:57 +0000 Subject: [PATCH 16/53] Added Paylod check --- services/language_translator/v3-doc.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 6fb2af49..3cead85c 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -46,6 +46,26 @@ module.exports = function (RED) { var node = this; RED.nodes.createNode(this, config); + function payloadCheck(msg, mode) { + var message = null; + switch (mode) { + case 'listDocuments': + break; + case 'translateDocument': + if (!msg.payload) { + message = 'Missing property: msg.payload'; + } + break; + default: + message = 'Unexpected Mode'; + break; + } + if (message) { + return Promise.reject(message); + } + return Promise.resolve(); + } + this.on('input', function (msg) { msg.payload = 'Node does nothing yet - 001'; @@ -70,7 +90,10 @@ module.exports = function (RED) { return translatorutils.checkForAction(action); }) .then(function(){ - return Promise.reject('Not working yet - 002'); + return payloadCheck(msg, action); + }) + .then(function(){ + return Promise.reject('Not working yet - 003'); }) .catch(function(err){ payloadutils.reportError(node, msg, err); From 3152198ebff97d79da9eef998343344acb7db68d Mon Sep 17 00:00:00 2001 From: chughts Date: Wed, 19 Dec 2018 14:26:08 +0000 Subject: [PATCH 17/53] List Translation Documents method --- services/language_translator/v3-doc.js | 72 ++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 3cead85c..8d21ad28 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -15,7 +15,10 @@ **/ module.exports = function (RED) { - const SERVICE_IDENTIFIER = 'language-translator'; + const request = require('request'); + SERVICE_IDENTIFIER = 'language-translator', + SERVICE_VERSION = '2018-05-01'; + var serviceutils = require('../../utilities/service-utils'), payloadutils = require('../../utilities/payload-utils'), translatorutils = require('./translator-utils'), @@ -66,6 +69,61 @@ module.exports = function (RED) { return Promise.resolve(); } + + function executeRequest(uriAddress) { + return new Promise(function resolver(resolve, reject){ + var authSettings = {}; + + if (apikey) { + authSettings.user = 'apikey'; + authSettings.pass = apikey; + } else { + authSettings.user = username; + authSettings.pass = password; + } + + request({ + uri: uriAddress, + method: 'GET', + auth: authSettings + }, (error, response, body) => { + if (!error && response.statusCode == 200) { + data = JSON.parse(body); + resolve(data); + } else if (error) { + reject(error); + } else { + reject('Error performing request ' + response.statusCode); + } + }); + }); + } + + function executeUnknownMethod() { + return Promise.reject('Unable to process as unknown mode has been specified'); + } + + function executeListDocuments() { + let uriAddress = endpoint + '/v3/documents?version=' + SERVICE_VERSION; + return executeRequest(uriAddress); + } + + function executeAction(msg, action) { + var f = null; + + const execute = { + 'listDocuments' : executeListDocuments + } + + f = execute[action] || executeUnknownMethod; + return f(); + } + + function processResponse(msg, data) { + msg.payload = data; + return Promise.resolve(); + } + this.on('input', function (msg) { msg.payload = 'Node does nothing yet - 001'; @@ -93,13 +151,21 @@ module.exports = function (RED) { return payloadCheck(msg, action); }) .then(function(){ - return Promise.reject('Not working yet - 003'); + node.status({fill:'blue', shape:'dot', text:'executing'}); + return executeAction(msg, action); + }) + .then( (data) => { + node.status({ fill: 'blue', shape: 'dot', text: 'processing response' }); + return processResponse(msg, data); + }) + .then(function(){ + node.status({}); + node.send(msg); }) .catch(function(err){ payloadutils.reportError(node, msg, err); node.send(msg); }); - node.send(msg); }); } From 953c08ca66b60cdd892b3189b2f1ecd589a9aab8 Mon Sep 17 00:00:00 2001 From: chughts Date: Thu, 20 Dec 2018 00:36:24 +0000 Subject: [PATCH 18/53] Preparation for translation fields --- services/language_translator/v3-doc.html | 100 ++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/services/language_translator/v3-doc.html b/services/language_translator/v3-doc.html index a72b417f..6e7ef0c7 100644 --- a/services/language_translator/v3-doc.html +++ b/services/language_translator/v3-doc.html @@ -64,6 +64,25 @@
+
+ + +
+
+ +
+ +
+ + +
+
+ +
+ + @@ -185,10 +190,14 @@ tor.action = $('#node-input-action').val(); switch (tor.action) { case 'translateDocument': - showFields.push('#node-input-srclang' + ', #node-input-destlang'); + showFields.push('#node-input-srclang' + + ', #node-input-destlang' + + ', #node-input-filename'); break; case 'listDocuments': - hideFields.push('#node-input-srclang' + ', #node-input-destlang'); + hideFields.push('#node-input-srclang' + + ', #node-input-destlang' + + ', #node-input-filename'); break; default: break; @@ -416,6 +425,7 @@ destlang: {value: 'fr'}, srclanghidden: {value: ''}, destlanghidden: {value: ''}, + filename: {value: ''}, 'default-endpoint' :{value: true}, 'service-endpoint' :{value: 'https://gateway.watsonplatform.net/language-translator/api'} }, diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index a6ba7e4c..1f92c4a9 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -21,7 +21,9 @@ module.exports = function (RED) { var pkg = require('../../package.json'), LanguageTranslatorV3 = require('watson-developer-cloud/language-translator/v3'), + fs = require('fs'), fileType = require('file-type'), + temp = require('temp'), serviceutils = require('../../utilities/service-utils'), payloadutils = require('../../utilities/payload-utils'), translatorutils = require('./translator-utils'), @@ -104,18 +106,21 @@ module.exports = function (RED) { return Promise.resolve(); } + function buildAuthSettings () { + var authSettings = {}; + if (apikey) { + authSettings.user = 'apikey'; + authSettings.pass = apikey; + } else { + authSettings.user = username; + authSettings.pass = password; + } + return authSettings; + } function executeGetRequest(uriAddress) { return new Promise(function resolver(resolve, reject){ - var authSettings = {}; - - if (apikey) { - authSettings.user = 'apikey'; - authSettings.pass = apikey; - } else { - authSettings.user = username; - authSettings.pass = password; - } + var authSettings = buildAuthSettings(); request({ uri: uriAddress, @@ -151,8 +156,6 @@ module.exports = function (RED) { if (msg.payload instanceof Buffer) { var ft = fileType(msg.payload); - console.log('File Type is ', ft); - if (ft && ft.ext) { ext = '.' + ft.ext; } else { @@ -164,11 +167,74 @@ module.exports = function (RED) { return Promise.resolve(ext); } - function loadFile() { - return Promise.reject('Load File Functionality is incomplete'); + function loadFile(suffix) { + return new Promise(function resolver(resolve, reject){ + var options = {}; + if (suffix) { + options.suffix = suffix; + } + temp.open(options, function(err, info) { + if (err) { + reject('Error opening temp file'); + } else { + resolve(info); + } + }); + }); + } + + function syncTheFile(info, msg) { + return new Promise(function resolver(resolve, reject){ + fs.writeFile(info.path, msg.payload, function(err) { + if (err) { + reject('Error processing buffer'); + } + resolve(); + }); + + }); + } + + function createStream(info) { + //var theStream = fs.createReadStream(info.path, 'utf8'); + var theStream = fs.readFileSync(info.path, 'utf8'); + return Promise.resolve(theStream); + } + + function whatName(msg, suffix){ + var name = 'Doc ' + (new Date()).toString(); // + suffix; + if (msg && msg.filename) { + name = msg.filename; + } else if (config && config.filename ) { + name = config.filename + } + name = name.replace(/[^0-9a-z]/gi, ''); + return (name + suffix); + } + + function executePostRequest(uriAddress, params, msg, fileSuffix) { + return new Promise(function resolver(resolve, reject){ + var authSettings = buildAuthSettings(); + + request({ + uri: uriAddress, + method: 'POST', + auth: authSettings, + formData: params + }, (error, response, body) => { + if (!error && response.statusCode == 200) { + data = JSON.parse(body); + resolve(data); + } else if (error) { + reject(error); + } else { + reject('Error performing request ' + response.statusCode + ' ' + body); + } + }); + }); } - function executeUnknownMethod() { + function executeUnknownMethod(msg) { return Promise.reject('Unable to process as unknown mode has been specified'); } @@ -178,19 +244,49 @@ module.exports = function (RED) { } function executeTranslateDocument(msg) { - var p = null; + var p = null, + fileInfo = null, + fileSuffix = ''; let uriAddress = endpoint + '/v3/documents?version=' + SERVICE_VERSION; p = verifyDocumentPayload(msg) .then (() => { return determineSuffix(msg); }) - .then ((ext) => { - return loadFile(); - }); + .then ((suffix) => { + //return loadFile(uriAddress, msg, ext); + fileSuffix = suffix; + return loadFile(suffix); + }) + .then ((info) => { + fileInfo = info; + return syncTheFile(fileInfo, msg); + }) + .then(function(){ + return createStream(fileInfo); + }) + .then(function(theStream){ + //params.file = theStream; + //var fname = 'temp' + fileSuffix; + var params = { + 'source' : msg.srclang ? msg.srclang : config.srclang, + 'target' : msg.destlang ? msg.destlang : config.destlang + }; + var fname = whatName(msg, fileSuffix); + + params.file = { + value: theStream, + options: { + filename: fname + } + }; + + node.status({ fill: 'blue', shape: 'dot', text: 'processing' }); + //return Promise.reject('temp disabled'); + return executePostRequest(uriAddress, params, msg, fileSuffix); + }) return p; - //return executeGetRequest(uriAddress); } @@ -228,6 +324,8 @@ module.exports = function (RED) { } node.status({}); + temp.track(); + translatorutils.credentialCheck(username, password, apikey) .then(function(){ return translatorutils.checkForAction(action); @@ -244,10 +342,12 @@ module.exports = function (RED) { return processResponse(msg, data); }) .then(function(){ + temp.cleanup(); node.status({}); node.send(msg); }) .catch(function(err){ + temp.cleanup(); payloadutils.reportError(node, msg, err); node.send(msg); }); From 10e64d0791a45c9d65661c16e1f8f75dbcd9b4a2 Mon Sep 17 00:00:00 2001 From: chughts Date: Fri, 21 Dec 2018 18:58:36 +0000 Subject: [PATCH 22/53] Implement get document status --- services/language_translator/v3-doc.html | 16 ++++++++++- services/language_translator/v3-doc.js | 36 +++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/services/language_translator/v3-doc.html b/services/language_translator/v3-doc.html index 2b287451..c99d83c2 100644 --- a/services/language_translator/v3-doc.html +++ b/services/language_translator/v3-doc.html @@ -61,6 +61,7 @@ @@ -87,6 +88,11 @@ +
+ + +
+ @@ -193,12 +199,19 @@ showFields.push('#node-input-srclang' + ', #node-input-destlang' + ', #node-input-filename'); + hideFields.push('#node-input-document-id'); break; case 'listDocuments': hideFields.push('#node-input-srclang' + ', #node-input-destlang' + - ', #node-input-filename'); + ', #node-input-filename' + + ', #node-input-document-id'); break; + case 'documentStatus' : + hideFields.push('#node-input-srclang' + + ', #node-input-destlang' + + ', #node-input-filename'); + showFields.push('#node-input-document-id'); default: break; } @@ -426,6 +439,7 @@ srclanghidden: {value: ''}, destlanghidden: {value: ''}, filename: {value: ''}, + 'document-id': {value: ''}, 'default-endpoint' :{value: true}, 'service-endpoint' :{value: 'https://gateway.watsonplatform.net/language-translator/api'} }, diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 1f92c4a9..4015d748 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -90,6 +90,7 @@ module.exports = function (RED) { var message = null; switch (mode) { case 'listDocuments': + case 'documentStatus': break; case 'translateDocument': if (!msg.payload) { @@ -106,6 +107,27 @@ module.exports = function (RED) { return Promise.resolve(); } + function paramCheck(msg, mode) { + var message = null; + switch (mode) { + case 'listDocuments': + case 'translateDocument': + break; + case 'documentStatus' : + if (!msg.docID && !(config['document-id'])) { + message = 'Document ID is required to fetch document status'; + } + break; + default: + break; + } + if (message) { + return Promise.reject(message); + } + return Promise.resolve(); + } + + function buildAuthSettings () { var authSettings = {}; if (apikey) { @@ -243,6 +265,14 @@ module.exports = function (RED) { return executeGetRequest(uriAddress); } + function executeGetDocumentStatus(msg) { + var docid = msg.documentID ? msg.documentID : config['document-id']; + //let uriAddress = endpoint + '/v3/documents/' + docid + '?version=' + SERVICE_VERSION; + let uriAddress = `${endpoint}/v3/documents/${docid}?version=${SERVICE_VERSION}`; + + return executeGetRequest(uriAddress); + } + function executeTranslateDocument(msg) { var p = null, fileInfo = null, @@ -295,7 +325,8 @@ module.exports = function (RED) { const execute = { 'listDocuments' : executeListDocuments, - 'translateDocument' : executeTranslateDocument + 'translateDocument' : executeTranslateDocument, + 'documentStatus' : executeGetDocumentStatus } f = execute[action] || executeUnknownMethod; @@ -333,6 +364,9 @@ module.exports = function (RED) { .then(function(){ return payloadCheck(msg, action); }) + .then(function(){ + return paramCheck(msg, action); + }) .then(function(){ node.status({fill:'blue', shape:'dot', text:'executing'}); return executeAction(msg, action); From 56aa12d6e56bec52897cf6d2700021d5085291ee Mon Sep 17 00:00:00 2001 From: chughts Date: Fri, 21 Dec 2018 19:57:45 +0000 Subject: [PATCH 23/53] Implement delete document method --- services/language_translator/v3-doc.html | 4 +- services/language_translator/v3-doc.js | 52 +++++++++++++++++++----- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/services/language_translator/v3-doc.html b/services/language_translator/v3-doc.html index c99d83c2..7d79bad0 100644 --- a/services/language_translator/v3-doc.html +++ b/services/language_translator/v3-doc.html @@ -62,6 +62,7 @@ + @@ -207,7 +208,8 @@ ', #node-input-filename' + ', #node-input-document-id'); break; - case 'documentStatus' : + case 'documentStatus': + case 'deleteDocument': hideFields.push('#node-input-srclang' + ', #node-input-destlang' + ', #node-input-filename'); diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 4015d748..51271455 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -91,6 +91,7 @@ module.exports = function (RED) { switch (mode) { case 'listDocuments': case 'documentStatus': + case 'deleteDocument': break; case 'translateDocument': if (!msg.payload) { @@ -113,7 +114,8 @@ module.exports = function (RED) { case 'listDocuments': case 'translateDocument': break; - case 'documentStatus' : + case 'documentStatus': + case 'deleteDocument': if (!msg.docID && !(config['document-id'])) { message = 'Document ID is required to fetch document status'; } @@ -140,27 +142,46 @@ module.exports = function (RED) { return authSettings; } - function executeGetRequest(uriAddress) { + function executeRequest(uriAddress, method) { return new Promise(function resolver(resolve, reject){ var authSettings = buildAuthSettings(); request({ uri: uriAddress, - method: 'GET', + method: method, auth: authSettings }, (error, response, body) => { - if (!error && response.statusCode == 200) { - data = JSON.parse(body); - resolve(data); - } else if (error) { + if (error) { reject(error); } else { - reject('Error performing request ' + response.statusCode); + switch (response.statusCode) { + case 200: + data = JSON.parse(body); + resolve(data); + break; + case 204: + resolve(body); + break; + case 404: + reject('Document not found ' + response.statusCode); + default: + reject('Error Invoking API ' + response.statusCode); + break; + } } }); + }); } + function executeGetRequest(uriAddress) { + return executeRequest(uriAddress, 'GET'); + } + + function executeDeleteRequest(uriAddress) { + return executeRequest(uriAddress, 'DELETE'); + } + function verifyDocumentPayload (msg) { if (!msg.payload) { return Promise.reject('Missing property: msg.payload'); @@ -261,7 +282,7 @@ module.exports = function (RED) { } function executeListDocuments(msg) { - let uriAddress = endpoint + '/v3/documents?version=' + SERVICE_VERSION; + let uriAddress = `${endpoint}/v3/documents?version=${SERVICE_VERSION}` return executeGetRequest(uriAddress); } @@ -273,11 +294,19 @@ module.exports = function (RED) { return executeGetRequest(uriAddress); } + function executeDeleteDocument(msg) { + var docid = msg.documentID ? msg.documentID : config['document-id']; + //let uriAddress = endpoint + '/v3/documents/' + docid + '?version=' + SERVICE_VERSION; + let uriAddress = `${endpoint}/v3/documents/${docid}?version=${SERVICE_VERSION}`; + + return executeDeleteRequest(uriAddress); + } + function executeTranslateDocument(msg) { var p = null, fileInfo = null, fileSuffix = ''; - let uriAddress = endpoint + '/v3/documents?version=' + SERVICE_VERSION; + let uriAddress = `${endpoint}/v3/documents?version=${SERVICE_VERSION}` p = verifyDocumentPayload(msg) .then (() => { @@ -326,7 +355,8 @@ module.exports = function (RED) { const execute = { 'listDocuments' : executeListDocuments, 'translateDocument' : executeTranslateDocument, - 'documentStatus' : executeGetDocumentStatus + 'documentStatus' : executeGetDocumentStatus, + 'deleteDocument' : executeDeleteDocument } f = execute[action] || executeUnknownMethod; From a643f2a179ae63c371dd9a016f096604a00103bb Mon Sep 17 00:00:00 2001 From: chughts Date: Fri, 21 Dec 2018 20:15:49 +0000 Subject: [PATCH 24/53] Allow msg.payload to override document id --- services/language_translator/v3-doc.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 51271455..a65ed22e 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -116,8 +116,10 @@ module.exports = function (RED) { break; case 'documentStatus': case 'deleteDocument': - if (!msg.docID && !(config['document-id'])) { - message = 'Document ID is required to fetch document status'; + if (!(config['document-id'])) { + if (!msg.payload || 'string' !== typeof msg.payload) { + message = 'Document ID is required to fetch document status'; + } } break; default: @@ -255,6 +257,14 @@ module.exports = function (RED) { return (name + suffix); } + function docID(msg) { + if (msg.payload && 'string' == typeof msg.payload) { + return msg.payload; + } else { + return config['document-id']; + } + } + function executePostRequest(uriAddress, params, msg, fileSuffix) { return new Promise(function resolver(resolve, reject){ var authSettings = buildAuthSettings(); @@ -287,7 +297,7 @@ module.exports = function (RED) { } function executeGetDocumentStatus(msg) { - var docid = msg.documentID ? msg.documentID : config['document-id']; + var docid = docID(msg); //let uriAddress = endpoint + '/v3/documents/' + docid + '?version=' + SERVICE_VERSION; let uriAddress = `${endpoint}/v3/documents/${docid}?version=${SERVICE_VERSION}`; @@ -295,7 +305,7 @@ module.exports = function (RED) { } function executeDeleteDocument(msg) { - var docid = msg.documentID ? msg.documentID : config['document-id']; + var docid = docID(msg); //let uriAddress = endpoint + '/v3/documents/' + docid + '?version=' + SERVICE_VERSION; let uriAddress = `${endpoint}/v3/documents/${docid}?version=${SERVICE_VERSION}`; From 3188e58bd6a8a5535c080abfec7591a32904d915 Mon Sep 17 00:00:00 2001 From: chughts Date: Fri, 21 Dec 2018 23:25:02 +0000 Subject: [PATCH 25/53] Implement get translated document --- services/language_translator/v3-doc.html | 13 +++++++ services/language_translator/v3-doc.js | 49 +++++++++++++++++++----- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/services/language_translator/v3-doc.html b/services/language_translator/v3-doc.html index 7d79bad0..76ce069d 100644 --- a/services/language_translator/v3-doc.html +++ b/services/language_translator/v3-doc.html @@ -60,9 +60,11 @@ @@ -202,6 +204,12 @@ ', #node-input-filename'); hideFields.push('#node-input-document-id'); break; + case 'translateSubmittedDocument': + showFields.push('#node-input-srclang' + + ', #node-input-destlang' + + ', #node-input-document-id'); + hideFields.push('#node-input-filename'); + break; case 'listDocuments': hideFields.push('#node-input-srclang' + ', #node-input-destlang' + @@ -210,6 +218,7 @@ break; case 'documentStatus': case 'deleteDocument': + case 'getDocument': hideFields.push('#node-input-srclang' + ', #node-input-destlang' + ', #node-input-filename'); @@ -337,6 +346,10 @@ // For Some reason this gets lost in the JSON get doctor.srclang_selected = $('#node-input-srclanghidden').val(); + //if (!doctor.srclang_seleted) { + // doctor.srclang_selected = 'en'; + //} + if (doctor.models) { var input_lang = doctor.models.map(function (a) { return a.source; diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index a65ed22e..8fac7a55 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -92,6 +92,8 @@ module.exports = function (RED) { case 'listDocuments': case 'documentStatus': case 'deleteDocument': + case 'getDocument': + case 'translateSubmittedDocument': break; case 'translateDocument': if (!msg.payload) { @@ -116,9 +118,11 @@ module.exports = function (RED) { break; case 'documentStatus': case 'deleteDocument': + case 'getDocument': + case 'translateSubmittedDocument': if (!(config['document-id'])) { if (!msg.payload || 'string' !== typeof msg.payload) { - message = 'Document ID is required to fetch document status'; + message = 'Document ID is required'; } } break; @@ -145,6 +149,7 @@ module.exports = function (RED) { } function executeRequest(uriAddress, method) { + console.log('uri is ', uriAddress); return new Promise(function resolver(resolve, reject){ var authSettings = buildAuthSettings(); @@ -158,7 +163,12 @@ module.exports = function (RED) { } else { switch (response.statusCode) { case 200: - data = JSON.parse(body); + let data = null; + try { + data = JSON.parse(body); + } catch(e) { + data = body + } resolve(data); break; case 204: @@ -167,6 +177,7 @@ module.exports = function (RED) { case 404: reject('Document not found ' + response.statusCode); default: + console.log(body); reject('Error Invoking API ' + response.statusCode); break; } @@ -265,7 +276,7 @@ module.exports = function (RED) { } } - function executePostRequest(uriAddress, params, msg, fileSuffix) { + function executePostRequest(uriAddress, params, msg) { return new Promise(function resolver(resolve, reject){ var authSettings = buildAuthSettings(); @@ -276,7 +287,7 @@ module.exports = function (RED) { formData: params }, (error, response, body) => { if (!error && response.statusCode == 200) { - data = JSON.parse(body); + let data = JSON.parse(body); resolve(data); } else if (error) { reject(error); @@ -292,18 +303,24 @@ module.exports = function (RED) { } function executeListDocuments(msg) { - let uriAddress = `${endpoint}/v3/documents?version=${SERVICE_VERSION}` + let uriAddress = `${endpoint}/v3/documents?version=${SERVICE_VERSION}`; return executeGetRequest(uriAddress); } function executeGetDocumentStatus(msg) { var docid = docID(msg); - //let uriAddress = endpoint + '/v3/documents/' + docid + '?version=' + SERVICE_VERSION; let uriAddress = `${endpoint}/v3/documents/${docid}?version=${SERVICE_VERSION}`; return executeGetRequest(uriAddress); } + function executeGetDocument(msg) { + var docid = docID(msg); + let uriAddress = `${endpoint}/v3/documents/${docid}/translated_document?version=${SERVICE_VERSION}`; + + return executeGetRequest(uriAddress); + } + function executeDeleteDocument(msg) { var docid = docID(msg); //let uriAddress = endpoint + '/v3/documents/' + docid + '?version=' + SERVICE_VERSION; @@ -312,11 +329,21 @@ module.exports = function (RED) { return executeDeleteRequest(uriAddress); } + function executeTranslateSubmittedDocument(msg) { + let uriAddress = `${endpoint}/v3/documents?version=${SERVICE_VERSION}`; + var params = { + 'source' : msg.srclang ? msg.srclang : config.srclang, + 'target' : msg.destlang ? msg.destlang : config.destlang, + 'document_id' : docID(msg) + }; + return executePostRequest(uriAddress, params, msg); + } + function executeTranslateDocument(msg) { var p = null, fileInfo = null, fileSuffix = ''; - let uriAddress = `${endpoint}/v3/documents?version=${SERVICE_VERSION}` + let uriAddress = `${endpoint}/v3/documents?version=${SERVICE_VERSION}`; p = verifyDocumentPayload(msg) .then (() => { @@ -350,9 +377,8 @@ module.exports = function (RED) { } }; - node.status({ fill: 'blue', shape: 'dot', text: 'processing' }); //return Promise.reject('temp disabled'); - return executePostRequest(uriAddress, params, msg, fileSuffix); + return executePostRequest(uriAddress, params, msg); }) return p; @@ -365,11 +391,14 @@ module.exports = function (RED) { const execute = { 'listDocuments' : executeListDocuments, 'translateDocument' : executeTranslateDocument, + 'translateSubmittedDocument' : executeTranslateSubmittedDocument, 'documentStatus' : executeGetDocumentStatus, - 'deleteDocument' : executeDeleteDocument + 'deleteDocument' : executeDeleteDocument, + 'getDocument' : executeGetDocument } f = execute[action] || executeUnknownMethod; + node.status({ fill: 'blue', shape: 'dot', text: 'processing' }); return f(msg); } From b0ddc8f9eed749eeac60fe6ec840e285233d7201 Mon Sep 17 00:00:00 2001 From: chughts Date: Sat, 22 Dec 2018 13:22:50 +0000 Subject: [PATCH 26/53] Allow output from docstatus to be input into doc translation node --- services/language_translator/v3-doc.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 8fac7a55..54454947 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -120,10 +120,13 @@ module.exports = function (RED) { case 'deleteDocument': case 'getDocument': case 'translateSubmittedDocument': - if (!(config['document-id'])) { - if (!msg.payload || 'string' !== typeof msg.payload) { + if (!docID(msg)) { + + //if (!(config['document-id'])) { + // if (!msg.payload || + // !('string' === typeof msg.payload || 'object' === typeof msg.payload)) { message = 'Document ID is required'; - } + // } } break; default: @@ -269,8 +272,12 @@ module.exports = function (RED) { } function docID(msg) { - if (msg.payload && 'string' == typeof msg.payload) { + if (msg.payload && 'string' === typeof msg.payload) { return msg.payload; + } else if (msg.payload && + 'object' === typeof msg.payload && + msg.payload.document_id) { + return msg.payload.document_id; } else { return config['document-id']; } From 1e66a6d1e6fcd5f5988ad9860ed59ff91375283c Mon Sep 17 00:00:00 2001 From: chughts Date: Sat, 22 Dec 2018 14:06:21 +0000 Subject: [PATCH 27/53] Let output of list documents be optional input into doc translate node --- services/language_translator/v3-doc.js | 59 ++++++++++++++++---------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 54454947..7940c870 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -121,12 +121,7 @@ module.exports = function (RED) { case 'getDocument': case 'translateSubmittedDocument': if (!docID(msg)) { - - //if (!(config['document-id'])) { - // if (!msg.payload || - // !('string' === typeof msg.payload || 'object' === typeof msg.payload)) { message = 'Document ID is required'; - // } } break; default: @@ -414,24 +409,8 @@ module.exports = function (RED) { return Promise.resolve(); } - this.on('input', function (msg) { - var action = msg.action || config.action; - - // The dynamic nature of this node has caused problems with the password field. it is - // hidden but not a credential. If it is treated as a credential, it gets lost when there - // is a request to refresh the model list. - // Credentials are needed for each of the modes. - username = sUsername || this.credentials.username; - password = sPassword || this.credentials.password || config.password; - apikey = sApikey || this.credentials.apikey || config.apikey; - - endpoint = sEndpoint; - if ((!config['default-endpoint']) && config['service-endpoint']) { - endpoint = config['service-endpoint']; - } - - node.status({}); - temp.track(); + function doit(msg) { + let action = msg.action || config.action; translatorutils.credentialCheck(username, password, apikey) .then(function(){ @@ -461,6 +440,40 @@ module.exports = function (RED) { payloadutils.reportError(node, msg, err); node.send(msg); }); + } + + this.on('input', function (msg) { + // The dynamic nature of this node has caused problems with the password field. it is + // hidden but not a credential. If it is treated as a credential, it gets lost when there + // is a request to refresh the model list. + // Credentials are needed for each of the modes. + username = sUsername || this.credentials.username; + password = sPassword || this.credentials.password || config.password; + apikey = sApikey || this.credentials.apikey || config.apikey; + + endpoint = sEndpoint; + if ((!config['default-endpoint']) && config['service-endpoint']) { + endpoint = config['service-endpoint']; + } + + node.status({}); + temp.track(); + + if ('object' === typeof msg.payload && + msg.payload.documents && + Array.isArray(msg.payload.documents)) { + let len = msg.payload.documents.length; + + msg.payload.documents.forEach((e, i) => { + let msgClone = Object.assign({}, msg), + pos = i+1; + node.status({ fill: 'blue', shape: 'dot', text: `Processing document ${pos} of ${len}` }); + msgClone.payload = e; + doit(msgClone); + }) + } else { + doit(msg); + } }); } From 7206502a0008217efe289cf7e0c5e42ff3878430 Mon Sep 17 00:00:00 2001 From: chughts Date: Sat, 22 Dec 2018 22:52:59 +0000 Subject: [PATCH 28/53] When document status is provided as input use object to determine source lang for translation --- services/language_translator/v3-doc.html | 87 ++++++++++++++++++++++-- services/language_translator/v3-doc.js | 12 +++- 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/services/language_translator/v3-doc.html b/services/language_translator/v3-doc.html index 76ce069d..db2b354f 100644 --- a/services/language_translator/v3-doc.html +++ b/services/language_translator/v3-doc.html @@ -106,19 +106,96 @@ here. -

Usage

-

This node should be provided in input :

+

Translate document.

+

In this mode the node should be provided in input :

  • msg.payload : A stream buffer of the document to convert.
-

On successful conversion this node will output :

+

Source and target language parameters can be configured through the + configuration editor panel or set dynamically using + the language codes in the following properties, msg.srclang + and msg.destlang. Please see the documentation linked below + for the currently supported source and destination + languages translation permutations. +

+ +

+ +

Translate submitted document.

+

In this mode the node should be provided in input :

    -
  • +
  • msg.payload : Document ID in one of the following formats +
      +
    • A string +
    • +
    • Document status JSON object as returned by the get document status + method. The object will contain a document id +
    • +
    • JSON object containing an array of document details + as returned by the get document list, each containing + a document id. In this mode a translation will be attempted for + each document. +
    • +
    +
  • +
+

Source and target language parameters see Translate document mode + for details. If the document id is provided as a JSON object, the source + languge for the new translation is searched for in the JSON object. +

+ +

+ +

List Documents.

+

In this mode no input is required. A JSON object containing an array + of documents submitted for translation is returned in + msg.payload +

+ +

+ +

Document status.

+

In this mode the node should be provided in input :

+
    +
  • msg.payload : Document ID. See Translate submitted + document for the format details. +
+

A JSON object detailing document status is returned in + msg.payload +

+ +

+ +

Delete document.

+

In this mode the node should be provided in input :

+
    +
  • msg.payload : Document ID. See Translate submitted + document for the format details. +
  • +
+

The documents are deleted.

+ +

+ +

Get document.

+

In this mode the node should be provided in input :

+
    +
  • msg.payload : Document ID. See Translate submitted + document for the format details. +
  • +
+

The requested documents are returned as a buffer in + msg.payload +

+ +

+

For more information about the Language Translator service, read the - documentation.

+ documentation. +

diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 7940c870..b30b6304 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -278,6 +278,16 @@ module.exports = function (RED) { } } + function sourceLang(msg) { + if (msg.payload && + 'object' === typeof msg.payload && + msg.payload.source + ) { + return msg.payload.source; + } + return msg.srclang ? msg.srclang : config.srclang; + } + function executePostRequest(uriAddress, params, msg) { return new Promise(function resolver(resolve, reject){ var authSettings = buildAuthSettings(); @@ -334,7 +344,7 @@ module.exports = function (RED) { function executeTranslateSubmittedDocument(msg) { let uriAddress = `${endpoint}/v3/documents?version=${SERVICE_VERSION}`; var params = { - 'source' : msg.srclang ? msg.srclang : config.srclang, + 'source' : sourceLang(msg), 'target' : msg.destlang ? msg.destlang : config.destlang, 'document_id' : docID(msg) }; From 78d31e38c06af137e973181c72562df108bd357e Mon Sep 17 00:00:00 2001 From: chughts Date: Sat, 22 Dec 2018 23:05:28 +0000 Subject: [PATCH 29/53] move assitant nodes from conversation to assistant directory --- package.json | 4 ++-- .../icons/conversation-v1-25x25.png | Bin services/{conversation => assistant}/v1-exp.html | 0 services/{conversation => assistant}/v1-exp.js | 0 .../v1-workspace-manager.html | 0 .../v1-workspace-manager.js | 0 services/{conversation => assistant}/v1.html | 0 services/{conversation => assistant}/v1.js | 0 8 files changed, 2 insertions(+), 2 deletions(-) rename services/{conversation => assistant}/icons/conversation-v1-25x25.png (100%) rename services/{conversation => assistant}/v1-exp.html (100%) rename services/{conversation => assistant}/v1-exp.js (100%) rename services/{conversation => assistant}/v1-workspace-manager.html (100%) rename services/{conversation => assistant}/v1-workspace-manager.js (100%) rename services/{conversation => assistant}/v1.html (100%) rename services/{conversation => assistant}/v1.js (100%) diff --git a/package.json b/package.json index e8db6df2..e01a52e6 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,8 @@ ], "node-red": { "nodes": { - "watson-conversation-v1": "services/conversation/v1.js", - "watson-conversation-workspace-manager-v1": "services/conversation/v1-workspace-manager.js", + "watson-conversation-v1": "services/assistant/v1.js", + "watson-conversation-workspace-manager-v1": "services/assistant/v1-workspace-manager.js", "watson-discovery-v1": "services/discovery/v1.js", "watson-discovery-v1-document-loader": "services/discovery/v1-document-loader.js", "watson-discovery-v1-query-builder": "services/discovery/v1-query-builder.js", diff --git a/services/conversation/icons/conversation-v1-25x25.png b/services/assistant/icons/conversation-v1-25x25.png similarity index 100% rename from services/conversation/icons/conversation-v1-25x25.png rename to services/assistant/icons/conversation-v1-25x25.png diff --git a/services/conversation/v1-exp.html b/services/assistant/v1-exp.html similarity index 100% rename from services/conversation/v1-exp.html rename to services/assistant/v1-exp.html diff --git a/services/conversation/v1-exp.js b/services/assistant/v1-exp.js similarity index 100% rename from services/conversation/v1-exp.js rename to services/assistant/v1-exp.js diff --git a/services/conversation/v1-workspace-manager.html b/services/assistant/v1-workspace-manager.html similarity index 100% rename from services/conversation/v1-workspace-manager.html rename to services/assistant/v1-workspace-manager.html diff --git a/services/conversation/v1-workspace-manager.js b/services/assistant/v1-workspace-manager.js similarity index 100% rename from services/conversation/v1-workspace-manager.js rename to services/assistant/v1-workspace-manager.js diff --git a/services/conversation/v1.html b/services/assistant/v1.html similarity index 100% rename from services/conversation/v1.html rename to services/assistant/v1.html diff --git a/services/conversation/v1.js b/services/assistant/v1.js similarity index 100% rename from services/conversation/v1.js rename to services/assistant/v1.js From 924ba8f8d4ace12367fb0e5f7014bb23aa7a9355 Mon Sep 17 00:00:00 2001 From: chughts Date: Sun, 23 Dec 2018 21:25:45 +0000 Subject: [PATCH 30/53] Initial Skeletal assistant V2 node --- README.md | 1 + package.json | 1 + services/assistant/v2.html | 138 +++++++++++++++++++++++++++++++++++++ services/assistant/v2.js | 65 +++++++++++++++++ 4 files changed, 205 insertions(+) create mode 100644 services/assistant/v2.html create mode 100644 services/assistant/v2.js diff --git a/README.md b/README.md index c97e14f9..0e3dbeaa 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ a stringified JSON objects. - Allow JSON input into Personality Insights node. - Hungarian supported by Language Translator. - New Document Language Translator node. +- New Assistant V2 Node. - Discovery Node changes - Bump Discovery to 2018-12-03 - Implement Query Notices method diff --git a/package.json b/package.json index e01a52e6..0c5259f6 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "nodes": { "watson-conversation-v1": "services/assistant/v1.js", "watson-conversation-workspace-manager-v1": "services/assistant/v1-workspace-manager.js", + "watson-assistant-v2": "services/assistant/v2.js", "watson-discovery-v1": "services/discovery/v1.js", "watson-discovery-v1-document-loader": "services/discovery/v1-document-loader.js", "watson-discovery-v1-query-builder": "services/discovery/v1-query-builder.js", diff --git a/services/assistant/v2.html b/services/assistant/v2.html new file mode 100644 index 00000000..4a459e3c --- /dev/null +++ b/services/assistant/v2.html @@ -0,0 +1,138 @@ + + + + + + + + diff --git a/services/assistant/v2.js b/services/assistant/v2.js new file mode 100644 index 00000000..ea001c4b --- /dev/null +++ b/services/assistant/v2.js @@ -0,0 +1,65 @@ +/** + * Copyright 2018 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +module.exports = function(RED) { + const SERVICE_IDENTIFIER = 'assistant', + OLD_SERVICE_IDENTIFIER = 'conversation'; + + var pkg = require('../../package.json'), + AssistantV2 = require('watson-developer-cloud/assistant/v2'), + serviceutils = require('../../utilities/service-utils'), + service = null, + sApikey = null, + sUsername = null, + sPassword = null; + + service = serviceutils.getServiceCreds(SERVICE_IDENTIFIER); + if (!service) { + service = serviceutils.getServiceCreds(OLD_SERVICE_IDENTIFIER); + } + + if (service) { + sUsername = service.username ? service.username : ''; + sPassword = service.password ? service.password : ''; + sApikey = service.apikey ? service.apikey : ''; + } + + RED.httpAdmin.get('/watson-assistant-v2/vcap', function(req, res) { + res.json(service ? { + bound_service: true + } : null); + }); + + function Node(config) { + var node = this; + RED.nodes.createNode(this, config); + + this.on('input', function(msg) { + + msg.payload = 'No functionality yet'; + node.send(msg); + + }); + } + + RED.nodes.registerType('watson-assistant-v2', Node, { + credentials: { + username: {type: 'text'}, + password: {type: 'password'}, + apikey: {type: 'password'} + } + }); +}; From 6717fb446b1c675a016f99e523fdff126da9e78c Mon Sep 17 00:00:00 2001 From: chughts Date: Sun, 23 Dec 2018 21:38:48 +0000 Subject: [PATCH 31/53] Add Assistant ID to node configuration --- services/assistant/v2.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/services/assistant/v2.html b/services/assistant/v2.html index 4a459e3c..45b6d087 100644 --- a/services/assistant/v2.html +++ b/services/assistant/v2.html @@ -50,6 +50,11 @@ +
+ + +
+ @@ -114,7 +119,8 @@ defaults: { name: { value: '' }, 'default-endpoint' : {value: true}, - 'service-endpoint' : {value: 'https://gateway.watsonplatform.net/assistant/api'} + 'service-endpoint' : {value: 'https://gateway.watsonplatform.net/assistant/api'}, + assitantid: {value: ''}, }, credentials: { username: {type:'text'}, From 523f90389dbe65a59390dde964bf439611c4cffa Mon Sep 17 00:00:00 2001 From: chughts Date: Sun, 23 Dec 2018 21:50:10 +0000 Subject: [PATCH 32/53] Add Multiple Sessions option --- services/assistant/v2.html | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/services/assistant/v2.html b/services/assistant/v2.html index 45b6d087..cbda3644 100644 --- a/services/assistant/v2.html +++ b/services/assistant/v2.html @@ -55,7 +55,23 @@ +
+ + + +
+
+ + + +
+ +
+ Note: When using with multiple sessions, msg.params.session + must be set.
+ See info box for details. +
@@ -164,7 +163,7 @@ name: { value: '' }, 'default-endpoint' : {value: true}, 'service-endpoint' : {value: 'https://gateway.watsonplatform.net/assistant/api'}, - assitantid: {value: ''}, + assistant_id: {value: ''}, debug: {value: false}, restart: {value: false}, returncontext: {value: true}, diff --git a/services/assistant/v2.js b/services/assistant/v2.js index 579f8a3a..4f3b8086 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -77,12 +77,22 @@ module.exports = function(RED) { return Promise.resolve(); } + function idCheck(msg, config) { + if (!config.assistant_id && !(msg.params && msg.params.assistant_id)) { + return Promise.reject('Missing assistant_id. Check node documentation.'); + } + return Promise.resolve(); + } + this.on('input', function(msg) { node.status({}); var creds = setCredentials(msg); credentialCheck(creds.username, creds.password, creds.apikey) + .then(function(){ + return idCheck(msg, config); + }) .then(function(){ msg.payload = 'No functionality yet'; return Promise.resolve(); From 7b3648cbcc4edda831340dc1ea61609ca3cba0fd Mon Sep 17 00:00:00 2001 From: chughts Date: Sun, 23 Dec 2018 23:01:03 +0000 Subject: [PATCH 38/53] Add payload check --- services/assistant/v2.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/services/assistant/v2.js b/services/assistant/v2.js index 4f3b8086..6b645475 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -77,6 +77,13 @@ module.exports = function(RED) { return Promise.resolve(); } + function payloadCheck(msg) { + if (msg.payload && 'string' != typeof msg.payload) { + return Promise.reject('msg.payload must be either empty or a string'); + } + return Promise.resolve(); + } + function idCheck(msg, config) { if (!config.assistant_id && !(msg.params && msg.params.assistant_id)) { return Promise.reject('Missing assistant_id. Check node documentation.'); @@ -84,16 +91,34 @@ module.exports = function(RED) { return Promise.resolve(); } + function buildInputParams(msg, config) { + let params = { + 'message_type': 'text', + 'input' : msg.payload + }; + + + return Promise.resolve(params); + } + this.on('input', function(msg) { node.status({}); var creds = setCredentials(msg); credentialCheck(creds.username, creds.password, creds.apikey) + .then(function(){ + return payloadCheck(msg); + }) .then(function(){ return idCheck(msg, config); }) .then(function(){ + return buildInputParams(msg, config); + }) + .then(function(params){ + console.log('params have been built'); + console.log(params); msg.payload = 'No functionality yet'; return Promise.resolve(); }) From 7962db6e2d9bdd347bf762ec0348483e649865c4 Mon Sep 17 00:00:00 2001 From: chughts Date: Sun, 23 Dec 2018 23:38:38 +0000 Subject: [PATCH 39/53] Input params for session and context --- services/assistant/v2.html | 2 +- services/assistant/v2.js | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/services/assistant/v2.html b/services/assistant/v2.html index f1b59399..c7ffc25e 100644 --- a/services/assistant/v2.html +++ b/services/assistant/v2.html @@ -86,7 +86,7 @@
- Note: When using multiple sessions, and msg.params.session + Note: When using multiple sessions, and msg.params.session_id is not set then a new session id is generated.
See info box for details.
diff --git a/services/assistant/v2.js b/services/assistant/v2.js index 6b645475..01e72900 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -91,12 +91,45 @@ module.exports = function(RED) { return Promise.resolve(); } + function setSessionID(msg, config) { + let session_id = null; + + if (!config.multisession) { + let id = node.context().flow.get('session_id'); + if (id) { + params.session_id = id; + } + } else if (msg.params && msg.params.session_id) { + params.session_id = msg.params.session_id; + } + + return session_id; + } + + function setContext(msg, config, session_id) { + let context = null; + if (session_id) { + let c = null + c = node.context().flow.get('context-' + session_id); + if (c) { + context = c; + } + } + return context; + } + function buildInputParams(msg, config) { let params = { 'message_type': 'text', - 'input' : msg.payload + 'input' : msg.payload, + 'session_id' : setSessionID(msg, config) }; + let context = setContext(msg, config, params.session_id); + if (context) { + params.context = context; + // Look for additional context + } return Promise.resolve(params); } From 217a8261be453b659f53432a015745096633cd83 Mon Sep 17 00:00:00 2001 From: chughts Date: Mon, 24 Dec 2018 14:59:24 +0000 Subject: [PATCH 40/53] Build up input options --- services/assistant/v2.html | 12 ++++---- services/assistant/v2.js | 61 ++++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/services/assistant/v2.html b/services/assistant/v2.html index c7ffc25e..86579142 100644 --- a/services/assistant/v2.html +++ b/services/assistant/v2.html @@ -69,14 +69,14 @@
- - + +
- - + +
@@ -166,8 +166,8 @@ assistant_id: {value: ''}, debug: {value: false}, restart: {value: false}, - returncontext: {value: true}, - alternateintents: {value: false}, + return_context: {value: true}, + alternate_intents: {value: false}, multisession: {value: true} }, credentials: { diff --git a/services/assistant/v2.js b/services/assistant/v2.js index 01e72900..04dac7df 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -106,9 +106,18 @@ module.exports = function(RED) { return session_id; } - function setContext(msg, config, session_id) { + function checkAndSet(source, target, field) { + if (source[field]) { + target[field] = source[field]; + } + } + + function setContext(msg, session_id) { let context = null; - if (session_id) { + if (msg.params) { + checkAndSet(msg.params, params, 'context'); + } + if (!context && session_id) { let c = null c = node.context().flow.get('context-' + session_id); if (c) { @@ -118,18 +127,58 @@ module.exports = function(RED) { return context; } + function setAdditionalContext(msg, params) { + if (msg.additional_context) { + params.context = params.context ? params.context : {}; + + for (prop in msg.additional_context) { + if (msg.additional_context.hasOwnProperty(prop)) { + params.context[prop] = msg.additional_context[prop]; + } + } + } + } + + function setAssistantID(msg, params, config) { + checkAndSet(config, params, 'assistant_id'); + if (msg.params) { + checkAndSet(msg.params, params, 'assistant_id'); + } + } + + function setInputOptions(msg, params, config) { + // Setting the flags this way works as their default + // values are false. + ['alternate_intents', + 'return_context', + 'restart', + 'debug'].forEach((f) => { + checkAndSet(config, params.input.options, f); + if (msg.params) { + checkAndSet(msg.params, params.input.options, f); + } + }); + } + function buildInputParams(msg, config) { let params = { - 'message_type': 'text', - 'input' : msg.payload, + 'input' : { + 'message_type': 'text', + 'text' : msg.payload, + 'options' : {} + }, 'session_id' : setSessionID(msg, config) }; - let context = setContext(msg, config, params.session_id); + let context = setContext(msg, params.session_id); if (context) { params.context = context; - // Look for additional context } + setAdditionalContext(msg, params); + setAssistantID(msg, params, config); + setInputOptions(msg, params, config); + + //verifyOptionalInputs(node, msg, config, params); return Promise.resolve(params); } From 3219c0447d4857e80f27a6554eec905ba8c1084e Mon Sep 17 00:00:00 2001 From: chughts Date: Mon, 24 Dec 2018 22:08:10 +0000 Subject: [PATCH 41/53] Add logic to retrieve session --- services/assistant/v2.html | 15 +++- services/assistant/v2.js | 157 +++++++++++++++++++++++++++++++++---- 2 files changed, 155 insertions(+), 17 deletions(-) diff --git a/services/assistant/v2.html b/services/assistant/v2.html index 86579142..a690d54f 100644 --- a/services/assistant/v2.html +++ b/services/assistant/v2.html @@ -55,6 +55,11 @@
+
+ + +
+
@@ -85,6 +90,12 @@
+
+ + + +
+
Note: When using multiple sessions, and msg.params.session_id is not set then a new session id is generated.
@@ -168,7 +179,9 @@ restart: {value: false}, return_context: {value: true}, alternate_intents: {value: false}, - multisession: {value: true} + multisession: {value: true}, + timeout: {value: '', validate: RED.validators.number(true)}, + 'optout-learning': {value: false} }, credentials: { username: {type:'text'}, diff --git a/services/assistant/v2.js b/services/assistant/v2.js index 04dac7df..e6808c0a 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -16,7 +16,8 @@ module.exports = function(RED) { const SERVICE_IDENTIFIER = 'assistant', - OLD_SERVICE_IDENTIFIER = 'conversation'; + OLD_SERVICE_IDENTIFIER = 'conversation', + SERVICE_VERSION = '2018-11-08'; var pkg = require('../../package.json'), AssistantV2 = require('watson-developer-cloud/assistant/v2'), @@ -84,14 +85,14 @@ module.exports = function(RED) { return Promise.resolve(); } - function idCheck(msg, config) { + function idCheck(msg) { if (!config.assistant_id && !(msg.params && msg.params.assistant_id)) { return Promise.reject('Missing assistant_id. Check node documentation.'); } return Promise.resolve(); } - function setSessionID(msg, config) { + function setSessionID(msg) { let session_id = null; if (!config.multisession) { @@ -128,6 +129,8 @@ module.exports = function(RED) { } function setAdditionalContext(msg, params) { + // needs to go in context.skills['main skill']['user_defined'] + if (msg.additional_context) { params.context = params.context ? params.context : {}; @@ -139,16 +142,16 @@ module.exports = function(RED) { } } - function setAssistantID(msg, params, config) { + function setAssistantID(msg, params) { checkAndSet(config, params, 'assistant_id'); if (msg.params) { checkAndSet(msg.params, params, 'assistant_id'); } } - function setInputOptions(msg, params, config) { + function setInputOptions(msg, params) { // Setting the flags this way works as their default - // values are false. + // values are false. ['alternate_intents', 'return_context', 'restart', @@ -160,14 +163,23 @@ module.exports = function(RED) { }); } - function buildInputParams(msg, config) { + function setParamInputs(msg, params) { + if (msg.params) { + ['intents', + 'entities'].forEach((f) => { + checkAndSet(msg.params, params, f); + }); + } + } + + function buildInputParams(msg) { let params = { 'input' : { 'message_type': 'text', 'text' : msg.payload, 'options' : {} }, - 'session_id' : setSessionID(msg, config) + 'session_id' : setSessionID(msg) }; let context = setContext(msg, params.session_id); @@ -175,33 +187,146 @@ module.exports = function(RED) { params.context = context; } setAdditionalContext(msg, params); - setAssistantID(msg, params, config); - setInputOptions(msg, params, config); + setAssistantID(msg, params); + setInputOptions(msg, params); + setParamInputs(msg, params); //verifyOptionalInputs(node, msg, config, params); return Promise.resolve(params); } + function setServiceSettings(msg, creds) { + const serviceSettings = { + headers: { + 'User-Agent': pkg.name + '-' + pkg.version + } + }; + let endpoint = '', + optoutLearning = false, + version = SERVICE_VERSION; + + if (creds.apikey) { + serviceSettings.iam_apikey = creds.apikey; + } else { + serviceSettings.username = creds.username; + serviceSettings.password = creds.password; + } + + if (service) { + endpoint = service.url; + } + if (!config['default-endpoint'] && config['service-endpoint']) { + endpoint = config['service-endpoint']; + } + + if (config['optout-learning']){ + optoutLearning = true; + } + + if (config['timeout'] && config['timeout'] !== '0' && isFinite(config['timeout'])){ + serviceSettings.timeout = parseInt(config['timeout']); + } + + // Look for message overrides + if (msg.params) { + if (msg.params.endpoint) { + endpoint = msg.params.endpoint; + } + if (msg.params.version) { + version = msg.params.version; + } + if ((msg.params['optout_learning'])){ + optoutLearning = true; + } + if (msg.params.timeout !== '0' && isFinite(msg.params.timeout)){ + serviceSettings.timeout = parseInt(msg.params.timeout); + } + if (msg.params.disable_ssl_verification){ + serviceSettings.disable_ssl_verification = true; + } + } + + serviceSettings.version = version; + if (endpoint) { + serviceSettings.url = endpoint; + } + if (optoutLearning) { + serviceSettings.headers = serviceSettings.headers || {}; + serviceSettings.headers['X-Watson-Learning-Opt-Out'] = '1'; + } + + return Promise.resolve(serviceSettings); + } + + function buildService(settings) { + node.service = new AssistantV2(settings); + return Promise.resolve() + } + + function checkSession(params) { + return new Promise(function resolver(resolve, reject){ + if (params.session_id) { + resolve(); + } else { + node.service.createSession({ + assistant_id: params.assistant_id + }, function(err, response) { + if (err) { + console.log('Error Detected'); + reject(err); + } else { + console.log('Data returned') + console.log(response); + if (response && response.session_id) { + params.session_id = response.session_id; + if (!config.multisession) { + node.context().flow.set('session_id', params.session_id); + } + resolve(); + } else { + reject('Unable to set session'); + } + } + }); + } + }); + } + this.on('input', function(msg) { - node.status({}); + var creds = setCredentials(msg), + params = {}; - var creds = setCredentials(msg); + node.status({}); credentialCheck(creds.username, creds.password, creds.apikey) .then(function(){ return payloadCheck(msg); }) .then(function(){ - return idCheck(msg, config); + return idCheck(msg); }) .then(function(){ - return buildInputParams(msg, config); + return buildInputParams(msg); }) - .then(function(params){ + .then(function(p){ + params = p; console.log('params have been built'); console.log(params); - msg.payload = 'No functionality yet'; + return setServiceSettings(msg, creds); + + }) + .then(function(settings){ + console.log('service settings have been built'); + console.log(settings); + return buildService(settings); + }) + .then(function(){ + console.log('service is ready'); + return checkSession(params); + }) + .then(function(){ + msg.payload = 'Not complete yet'; return Promise.resolve(); }) .then(function(){ From 3f701aa643fafd4427091852507af7b3bd5723f1 Mon Sep 17 00:00:00 2001 From: chughts Date: Mon, 24 Dec 2018 22:52:31 +0000 Subject: [PATCH 42/53] Add Message invokation --- services/assistant/v2.js | 46 ++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/services/assistant/v2.js b/services/assistant/v2.js index e6808c0a..7d5c0001 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -98,10 +98,10 @@ module.exports = function(RED) { if (!config.multisession) { let id = node.context().flow.get('session_id'); if (id) { - params.session_id = id; + session_id = id; } } else if (msg.params && msg.params.session_id) { - params.session_id = msg.params.session_id; + session_id = msg.params.session_id; } return session_id; @@ -129,14 +129,15 @@ module.exports = function(RED) { } function setAdditionalContext(msg, params) { - // needs to go in context.skills['main skill']['user_defined'] - if (msg.additional_context) { - params.context = params.context ? params.context : {}; + params.context = params.context ? + params.context : + {'skills' : {'main skill' : {'user_defined': {}}}}; for (prop in msg.additional_context) { if (msg.additional_context.hasOwnProperty(prop)) { - params.context[prop] = msg.additional_context[prop]; + params.context.skills['main skill']['user_defined'][prop] + = msg.additional_context[prop]; } } } @@ -183,16 +184,16 @@ module.exports = function(RED) { }; let context = setContext(msg, params.session_id); + if (context) { params.context = context; } + setAdditionalContext(msg, params); setAssistantID(msg, params); setInputOptions(msg, params); setParamInputs(msg, params); - //verifyOptionalInputs(node, msg, config, params); - return Promise.resolve(params); } @@ -273,11 +274,8 @@ module.exports = function(RED) { assistant_id: params.assistant_id }, function(err, response) { if (err) { - console.log('Error Detected'); reject(err); } else { - console.log('Data returned') - console.log(response); if (response && response.session_id) { params.session_id = response.session_id; if (!config.multisession) { @@ -293,6 +291,19 @@ module.exports = function(RED) { }); } + function messageTurn(params) { + return new Promise(function resolver(resolve, reject){ + node.service.message(params, function(err, body) { + if (err) { + reject(err); + } else { + resolve(body); + } + }); + }); + } + + this.on('input', function(msg) { var creds = setCredentials(msg), params = {}; @@ -311,22 +322,21 @@ module.exports = function(RED) { }) .then(function(p){ params = p; - console.log('params have been built'); - console.log(params); return setServiceSettings(msg, creds); - }) .then(function(settings){ - console.log('service settings have been built'); - console.log(settings); return buildService(settings); }) .then(function(){ - console.log('service is ready'); return checkSession(params); }) .then(function(){ - msg.payload = 'Not complete yet'; + node.status({ fill: 'blue', shape: 'dot', text: 'Calling Assistant service ...'}); + return messageTurn(params); + }) + .then(function(body){ + body.session_id = params.session_id; + msg.payload = body; return Promise.resolve(); }) .then(function(){ From fde06a31972752b42d582a52c0ddf62d762101fe Mon Sep 17 00:00:00 2001 From: chughts Date: Mon, 24 Dec 2018 23:29:58 +0000 Subject: [PATCH 43/53] Add node info text --- services/assistant/v2.html | 59 +++++++++++++++++++++++++++++--------- services/assistant/v2.js | 13 ++------- 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/services/assistant/v2.html b/services/assistant/v2.html index a690d54f..01f1a59f 100644 --- a/services/assistant/v2.html +++ b/services/assistant/v2.html @@ -104,19 +104,52 @@ diff --git a/services/assistant/v2.js b/services/assistant/v2.js index 7d5c0001..dab8a400 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -113,18 +113,11 @@ module.exports = function(RED) { } } - function setContext(msg, session_id) { + function setContext(msg, params) { let context = null; if (msg.params) { checkAndSet(msg.params, params, 'context'); } - if (!context && session_id) { - let c = null - c = node.context().flow.get('context-' + session_id); - if (c) { - context = c; - } - } return context; } @@ -183,8 +176,7 @@ module.exports = function(RED) { 'session_id' : setSessionID(msg) }; - let context = setContext(msg, params.session_id); - + let context = setContext(msg, params); if (context) { params.context = context; } @@ -303,7 +295,6 @@ module.exports = function(RED) { }); } - this.on('input', function(msg) { var creds = setCredentials(msg), params = {}; From f3e54ba24045965f31c6a4636227a87a19a26a2a Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 00:00:58 +0000 Subject: [PATCH 44/53] Debug dict path --- services/personality_insights/v3.js | 3 +++ utilities/payload-utils.js | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/services/personality_insights/v3.js b/services/personality_insights/v3.js index 8c840014..5a736a93 100644 --- a/services/personality_insights/v3.js +++ b/services/personality_insights/v3.js @@ -181,6 +181,9 @@ module.exports = function (RED) { node.status({}); payloadCheck(msg) + .then(function() { + return Promise.reject(payloadutils.kuromojipath()); + }) .then(function(){ return wordcountCheck(msg, config); }) diff --git a/utilities/payload-utils.js b/utilities/payload-utils.js index 7034edcc..b981f461 100644 --- a/utilities/payload-utils.js +++ b/utilities/payload-utils.js @@ -154,6 +154,12 @@ PayloadUtils.prototype = { return code; }, + kuromojipath: function() { + var dic_path = '/../../kuromoji/dict'; + var dic_dir = path.normalize(__dirname + dic_path); + return dic_dir; + }, + // Function that is returns a function to count // the characters in each language. word_count: function(ct) { From 0231657d2c1f29d5d4d75050ac4da7defd59fbb2 Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 00:49:21 +0000 Subject: [PATCH 45/53] Debug dict path --- utilities/payload-utils.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/utilities/payload-utils.js b/utilities/payload-utils.js index b981f461..27341293 100644 --- a/utilities/payload-utils.js +++ b/utilities/payload-utils.js @@ -157,7 +157,13 @@ PayloadUtils.prototype = { kuromojipath: function() { var dic_path = '/../../kuromoji/dict'; var dic_dir = path.normalize(__dirname + dic_path); - return dic_dir; + var filelist = ''; + + fs.readdirSync(dic_dir).forEach((file) => { + filelist += ',' + file; + }); + + return filelist; }, // Function that is returns a function to count From b4893b082dda4ffc6a2c9b613bbb9656d16fff1b Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 01:05:11 +0000 Subject: [PATCH 46/53] Debug dict path --- services/personality_insights/v3.js | 5 ++--- utilities/payload-utils.js | 12 ------------ 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/services/personality_insights/v3.js b/services/personality_insights/v3.js index 5a736a93..4f14ac1d 100644 --- a/services/personality_insights/v3.js +++ b/services/personality_insights/v3.js @@ -181,9 +181,6 @@ module.exports = function (RED) { node.status({}); payloadCheck(msg) - .then(function() { - return Promise.reject(payloadutils.kuromojipath()); - }) .then(function(){ return wordcountCheck(msg, config); }) @@ -194,9 +191,11 @@ module.exports = function (RED) { return setEndPoint(config); }) .then(function(){ + return Promise.reject('Got to prepareParams'); return prepareParams(msg, config); }) .then(function(params){ + node.status({fill:'blue', shape:'dot', text:'requesting'}); return executeService(msg, params); }) diff --git a/utilities/payload-utils.js b/utilities/payload-utils.js index 27341293..7034edcc 100644 --- a/utilities/payload-utils.js +++ b/utilities/payload-utils.js @@ -154,18 +154,6 @@ PayloadUtils.prototype = { return code; }, - kuromojipath: function() { - var dic_path = '/../../kuromoji/dict'; - var dic_dir = path.normalize(__dirname + dic_path); - var filelist = ''; - - fs.readdirSync(dic_dir).forEach((file) => { - filelist += ',' + file; - }); - - return filelist; - }, - // Function that is returns a function to count // the characters in each language. word_count: function(ct) { From 2fd54cfdb06a7fdfbc3e77b52d3102f09b1b93c2 Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 02:09:17 +0000 Subject: [PATCH 47/53] Debug dict path --- services/personality_insights/v3.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/personality_insights/v3.js b/services/personality_insights/v3.js index 4f14ac1d..dcdc0ea9 100644 --- a/services/personality_insights/v3.js +++ b/services/personality_insights/v3.js @@ -185,13 +185,13 @@ module.exports = function (RED) { return wordcountCheck(msg, config); }) .then(function(){ + return Promise.reject('Got to credentialsCheck'); return credentialsCheck(node); }) .then(function(){ return setEndPoint(config); }) .then(function(){ - return Promise.reject('Got to prepareParams'); return prepareParams(msg, config); }) .then(function(params){ From 77b875c6e726be60f7ef15ddf222381d119fe8ec Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 07:58:38 +0000 Subject: [PATCH 48/53] Debug dict path --- package.json | 2 +- utilities/payload-utils.js | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 0c5259f6..bf327f4e 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "qs": "6.x", "image-type": "^2.0.2", "watson-developer-cloud": "^3.15.0", - "kuromoji": "^0.1.1", + "kuromoji": "^0.1.2", "word-count": "^0.2.2", "is-docx": "^0.0.3", "stream-to-array": "^2.3.0", diff --git a/utilities/payload-utils.js b/utilities/payload-utils.js index 7034edcc..4b9d7bb7 100644 --- a/utilities/payload-utils.js +++ b/utilities/payload-utils.js @@ -157,16 +157,18 @@ PayloadUtils.prototype = { // Function that is returns a function to count // the characters in each language. word_count: function(ct) { - var count = require('word-count'); - var kuromoji = require('kuromoji'), + console.log('performing count for language ', ct); + const count = require('word-count'), + kuromoji = require('kuromoji'); fn = function(txt, cb) { // default + console.log('performing real count'); return cb(txt.split(' ').length); }, dic_path = '/../../kuromoji/dict', dic_dir = path.normalize(__dirname + dic_path), tokenizer = null; - + /* if (ct === 'ja') { fn = function(txt, cb) { kuromoji.builder({dicPath: dic_dir}).build(function(err, tknz) { @@ -177,8 +179,11 @@ PayloadUtils.prototype = { return cb(tokenizer.tokenize(txt).length); }); }; - } else if (ct === 'ko') { + } else + */ + if (ct === 'ko' || ct === 'ja') { fn = function(txt, cb) { + console.log('performing korean count') cb(count(txt)); }; } From dc20a3ef925c29d7e746392a3f225bcf5dfa9503 Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 08:13:12 +0000 Subject: [PATCH 49/53] Remove pre-check word count if text is in japanese --- README.md | 1 + package.json | 1 - services/personality_insights/v3.js | 1 - utilities/payload-utils.js | 21 ++++----------------- 4 files changed, 5 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 0e3dbeaa..61d3d158 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ a stringified JSON objects. - Bump Natural Language Understanding to 2018-11-16 - Add Limit Categories and limit_text_characters options - Allow JSON input into Personality Insights node. +- Japanese word count was causing a Node-RED crash when run in the cloud. - Hungarian supported by Language Translator. - New Document Language Translator node. - New Assistant V2 Node. diff --git a/package.json b/package.json index bf327f4e..3eb2beaa 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "qs": "6.x", "image-type": "^2.0.2", "watson-developer-cloud": "^3.15.0", - "kuromoji": "^0.1.2", "word-count": "^0.2.2", "is-docx": "^0.0.3", "stream-to-array": "^2.3.0", diff --git a/services/personality_insights/v3.js b/services/personality_insights/v3.js index dcdc0ea9..dcedce8e 100644 --- a/services/personality_insights/v3.js +++ b/services/personality_insights/v3.js @@ -185,7 +185,6 @@ module.exports = function (RED) { return wordcountCheck(msg, config); }) .then(function(){ - return Promise.reject('Got to credentialsCheck'); return credentialsCheck(node); }) .then(function(){ diff --git a/utilities/payload-utils.js b/utilities/payload-utils.js index 4b9d7bb7..25395178 100644 --- a/utilities/payload-utils.js +++ b/utilities/payload-utils.js @@ -157,33 +157,20 @@ PayloadUtils.prototype = { // Function that is returns a function to count // the characters in each language. word_count: function(ct) { - console.log('performing count for language ', ct); - const count = require('word-count'), - kuromoji = require('kuromoji'); + var count = require('word-count') ; fn = function(txt, cb) { // default - console.log('performing real count'); return cb(txt.split(' ').length); }, dic_path = '/../../kuromoji/dict', dic_dir = path.normalize(__dirname + dic_path), tokenizer = null; - /* if (ct === 'ja') { fn = function(txt, cb) { - kuromoji.builder({dicPath: dic_dir}).build(function(err, tknz) { - if (err) { - throw err; - } - tokenizer = tknz; - return cb(tokenizer.tokenize(txt).length); - }); - }; - } else - */ - if (ct === 'ko' || ct === 'ja') { + cb(200); + } + } else if (ct === 'ko') { fn = function(txt, cb) { - console.log('performing korean count') cb(count(txt)); }; } From 3ddc1815bb8ab4bce8c4a9312eedab57c6ef653e Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 09:00:51 +0000 Subject: [PATCH 50/53] Codacy Fixes --- services/assistant/v2.js | 98 +++++++++++++------------- services/language_translator/v3-doc.js | 42 +++++------ services/speech_to_text/v1.js | 8 +-- utilities/payload-utils.js | 2 +- 4 files changed, 75 insertions(+), 75 deletions(-) diff --git a/services/assistant/v2.js b/services/assistant/v2.js index dab8a400..8fc899a5 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -50,7 +50,7 @@ module.exports = function(RED) { RED.nodes.createNode(this, config); function setCredentials(msg) { - creds = { + var creds = { username : sUsername || node.credentials.username, password : sPassword || node.credentials.password || config.password, apikey : sApikey || node.credentials.apikey || config.apikey, @@ -127,7 +127,7 @@ module.exports = function(RED) { params.context : {'skills' : {'main skill' : {'user_defined': {}}}}; - for (prop in msg.additional_context) { + for (var prop in msg.additional_context) { if (msg.additional_context.hasOwnProperty(prop)) { params.context.skills['main skill']['user_defined'][prop] = msg.additional_context[prop]; @@ -190,66 +190,66 @@ module.exports = function(RED) { } function setServiceSettings(msg, creds) { - const serviceSettings = { + const serviceSettings = { headers: { 'User-Agent': pkg.name + '-' + pkg.version } - }; - let endpoint = '', - optoutLearning = false, - version = SERVICE_VERSION; + }; + let endpoint = '', + optoutLearning = false, + version = SERVICE_VERSION; + + if (creds.apikey) { + serviceSettings.iam_apikey = creds.apikey; + } else { + serviceSettings.username = creds.username; + serviceSettings.password = creds.password; + } - if (creds.apikey) { - serviceSettings.iam_apikey = creds.apikey; - } else { - serviceSettings.username = creds.username; - serviceSettings.password = creds.password; - } + if (service) { + endpoint = service.url; + } + if (!config['default-endpoint'] && config['service-endpoint']) { + endpoint = config['service-endpoint']; + } - if (service) { - endpoint = service.url; + if (config['optout-learning']){ + optoutLearning = true; + } + + if (config['timeout'] && config['timeout'] !== '0' && isFinite(config['timeout'])){ + serviceSettings.timeout = parseInt(config['timeout']); + } + + // Look for message overrides + if (msg.params) { + if (msg.params.endpoint) { + endpoint = msg.params.endpoint; } - if (!config['default-endpoint'] && config['service-endpoint']) { - endpoint = config['service-endpoint']; + if (msg.params.version) { + version = msg.params.version; } - - if (config['optout-learning']){ + if ((msg.params['optout_learning'])){ optoutLearning = true; } - - if (config['timeout'] && config['timeout'] !== '0' && isFinite(config['timeout'])){ - serviceSettings.timeout = parseInt(config['timeout']); + if (msg.params.timeout !== '0' && isFinite(msg.params.timeout)){ + serviceSettings.timeout = parseInt(msg.params.timeout); } - - // Look for message overrides - if (msg.params) { - if (msg.params.endpoint) { - endpoint = msg.params.endpoint; - } - if (msg.params.version) { - version = msg.params.version; - } - if ((msg.params['optout_learning'])){ - optoutLearning = true; - } - if (msg.params.timeout !== '0' && isFinite(msg.params.timeout)){ - serviceSettings.timeout = parseInt(msg.params.timeout); - } - if (msg.params.disable_ssl_verification){ - serviceSettings.disable_ssl_verification = true; - } + if (msg.params.disable_ssl_verification){ + serviceSettings.disable_ssl_verification = true; } + } - serviceSettings.version = version; - if (endpoint) { - serviceSettings.url = endpoint; - } - if (optoutLearning) { - serviceSettings.headers = serviceSettings.headers || {}; - serviceSettings.headers['X-Watson-Learning-Opt-Out'] = '1'; - } + serviceSettings.version = version; + if (endpoint) { + serviceSettings.url = endpoint; + } + if (optoutLearning) { + serviceSettings.headers = serviceSettings.headers || {}; + serviceSettings.headers['X-Watson-Learning-Opt-Out'] = '1'; + } - return Promise.resolve(serviceSettings); + return Promise.resolve(serviceSettings); } function buildService(settings) { diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index b30b6304..7f77c376 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -15,7 +15,7 @@ **/ module.exports = function (RED) { - const request = require('request'); + const request = require('request'), SERVICE_IDENTIFIER = 'language-translator', SERVICE_VERSION = '2018-05-01'; @@ -121,7 +121,7 @@ module.exports = function (RED) { case 'getDocument': case 'translateSubmittedDocument': if (!docID(msg)) { - message = 'Document ID is required'; + message = 'Document ID is required'; } break; default: @@ -147,7 +147,6 @@ module.exports = function (RED) { } function executeRequest(uriAddress, method) { - console.log('uri is ', uriAddress); return new Promise(function resolver(resolve, reject){ var authSettings = buildAuthSettings(); @@ -160,24 +159,25 @@ module.exports = function (RED) { reject(error); } else { switch (response.statusCode) { - case 200: - let data = null; - try { - data = JSON.parse(body); - } catch(e) { - data = body - } - resolve(data); - break; - case 204: - resolve(body); - break; - case 404: - reject('Document not found ' + response.statusCode); - default: - console.log(body); - reject('Error Invoking API ' + response.statusCode); - break; + case 200: + let data = null; + try { + data = JSON.parse(body); + } catch(e) { + data = body + } + resolve(data); + break; + case 204: + resolve(body); + break; + case 404: + reject('Document not found ' + response.statusCode); + break; + default: + console.log(body); + reject('Error Invoking API ' + response.statusCode); + break; } } }); diff --git a/services/speech_to_text/v1.js b/services/speech_to_text/v1.js index 3b34e3d3..7cb8c220 100644 --- a/services/speech_to_text/v1.js +++ b/services/speech_to_text/v1.js @@ -343,10 +343,10 @@ module.exports = function (RED) { // Check for keywords, which might already be an array if (config['keywords'] && 'string' === typeof config['keywords']) { // Trim any [] from edges of string - var keywords = config['keywords']; - var start = 0; - var end = keywords.length; - var threshold = parseFloat(config['keywords_threshold']); + var keywords = config['keywords'], + start = 0, + end = keywords.length, + threshold = parseFloat(config['keywords_threshold']); if ('[' === keywords[start]) { start++; diff --git a/utilities/payload-utils.js b/utilities/payload-utils.js index 25395178..c4a51f71 100644 --- a/utilities/payload-utils.js +++ b/utilities/payload-utils.js @@ -168,7 +168,7 @@ PayloadUtils.prototype = { if (ct === 'ja') { fn = function(txt, cb) { cb(200); - } + }; } else if (ct === 'ko') { fn = function(txt, cb) { cb(count(txt)); From f2f4e656e1f65e43fdd11bd04d6767bc5f8f8920 Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 16:15:52 +0000 Subject: [PATCH 51/53] Codacy Fixes --- services/assistant/v2.js | 27 +++++++------- services/discovery/v1.js | 1 + services/language_translator/v3-doc.js | 35 +++++++++---------- services/natural_language_understanding/v1.js | 2 +- services/personality_insights/v3.js | 2 +- utilities/payload-utils.js | 8 ++--- 6 files changed, 36 insertions(+), 39 deletions(-) diff --git a/services/assistant/v2.js b/services/assistant/v2.js index 8fc899a5..5f3d518e 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -54,7 +54,7 @@ module.exports = function(RED) { username : sUsername || node.credentials.username, password : sPassword || node.credentials.password || config.password, apikey : sApikey || node.credentials.apikey || config.apikey, - } + }; if (msg.params) { if (msg.params.username) { @@ -191,10 +191,11 @@ module.exports = function(RED) { function setServiceSettings(msg, creds) { const serviceSettings = { - headers: { - 'User-Agent': pkg.name + '-' + pkg.version - } + headers: { + 'User-Agent': pkg.name + '-' + pkg.version + } }; + let endpoint = '', optoutLearning = false, version = SERVICE_VERSION; @@ -254,7 +255,7 @@ module.exports = function(RED) { function buildService(settings) { node.service = new AssistantV2(settings); - return Promise.resolve() + return Promise.resolve(); } function checkSession(params) { @@ -267,16 +268,14 @@ module.exports = function(RED) { }, function(err, response) { if (err) { reject(err); - } else { - if (response && response.session_id) { - params.session_id = response.session_id; - if (!config.multisession) { - node.context().flow.set('session_id', params.session_id); - } - resolve(); - } else { - reject('Unable to set session'); + } else if (response && response.session_id) { + params.session_id = response.session_id; + if (!config.multisession) { + node.context().flow.set('session_id', params.session_id); } + resolve(); + } else { + reject('Unable to set session'); } }); } diff --git a/services/discovery/v1.js b/services/discovery/v1.js index 1fcb5ece..86fdc0d9 100644 --- a/services/discovery/v1.js +++ b/services/discovery/v1.js @@ -263,6 +263,7 @@ module.exports = function (RED) { function executeMethod(node, method, params, msg) { let discovery = discoveryutils.buildService(username, password, apikey, endpoint); + var p = null; switch (method) { case 'createEnvrionment': diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 7f77c376..da633ab0 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -74,8 +74,7 @@ module.exports = function (RED) { lt.listModels({}, function (err, models) { if (err) { res.json(err); - } - else { + } else { res.json(models); } }); @@ -164,7 +163,7 @@ module.exports = function (RED) { try { data = JSON.parse(body); } catch(e) { - data = body + data = body; } resolve(data); break; @@ -260,24 +259,12 @@ module.exports = function (RED) { if (msg && msg.filename) { name = msg.filename; } else if (config && config.filename ) { - name = config.filename + name = config.filename; } name = name.replace(/[^0-9a-z]/gi, ''); return (name + suffix); } - function docID(msg) { - if (msg.payload && 'string' === typeof msg.payload) { - return msg.payload; - } else if (msg.payload && - 'object' === typeof msg.payload && - msg.payload.document_id) { - return msg.payload.document_id; - } else { - return config['document-id']; - } - } - function sourceLang(msg) { if (msg.payload && 'object' === typeof msg.payload && @@ -288,6 +275,18 @@ module.exports = function (RED) { return msg.srclang ? msg.srclang : config.srclang; } + function docID(msg) { + if (msg.payload && 'string' === typeof msg.payload) { + return msg.payload; + } + if (msg.payload && + 'object' === typeof msg.payload && + msg.payload.document_id) { + return msg.payload.document_id; + } + return config['document-id']; + } + function executePostRequest(uriAddress, params, msg) { return new Promise(function resolver(resolve, reject){ var authSettings = buildAuthSettings(); @@ -298,7 +297,7 @@ module.exports = function (RED) { auth: authSettings, formData: params }, (error, response, body) => { - if (!error && response.statusCode == 200) { + if (!error && response.statusCode === 200) { let data = JSON.parse(body); resolve(data); } else if (error) { @@ -407,7 +406,7 @@ module.exports = function (RED) { 'documentStatus' : executeGetDocumentStatus, 'deleteDocument' : executeDeleteDocument, 'getDocument' : executeGetDocument - } + }; f = execute[action] || executeUnknownMethod; node.status({ fill: 'blue', shape: 'dot', text: 'processing' }); diff --git a/services/natural_language_understanding/v1.js b/services/natural_language_understanding/v1.js index 1d426ed4..e30337e0 100644 --- a/services/natural_language_understanding/v1.js +++ b/services/natural_language_understanding/v1.js @@ -83,7 +83,7 @@ module.exports = function (RED) { var limitCharacters = parseInt(config.limittextcharacters); if (! isNaN(limitCharacters) && 0 < limitCharacters) { - options.limit_text_characters = limitCharacters + options.limit_text_characters = limitCharacters; } return Promise.resolve(); diff --git a/services/personality_insights/v3.js b/services/personality_insights/v3.js index dcedce8e..92200015 100644 --- a/services/personality_insights/v3.js +++ b/services/personality_insights/v3.js @@ -51,7 +51,7 @@ module.exports = function (RED) { if (!msg.payload) { return Promise.reject('Missing property: msg.payload'); } - if ('string' !== typeof msg.payload && + if ('string' !== typeof msg.payload && 'object' !== typeof msg.payload) { return Promise.reject('submitted msg.payload is not text or json object'); } diff --git a/utilities/payload-utils.js b/utilities/payload-utils.js index c4a51f71..0038013e 100644 --- a/utilities/payload-utils.js +++ b/utilities/payload-utils.js @@ -157,14 +157,12 @@ PayloadUtils.prototype = { // Function that is returns a function to count // the characters in each language. word_count: function(ct) { - var count = require('word-count') ; + var count = require('word-count'), fn = function(txt, cb) { // default return cb(txt.split(' ').length); - }, - dic_path = '/../../kuromoji/dict', - dic_dir = path.normalize(__dirname + dic_path), - tokenizer = null; + }; + if (ct === 'ja') { fn = function(txt, cb) { cb(200); From ded640425776d1e14041dd84023ceb5154787067 Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 17:31:23 +0000 Subject: [PATCH 52/53] Codacy Fixes --- services/assistant/v2.js | 8 +++---- services/language_translator/v3-doc.js | 31 +++++++++++++------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/services/assistant/v2.js b/services/assistant/v2.js index 5f3d518e..a1db637c 100644 --- a/services/assistant/v2.js +++ b/services/assistant/v2.js @@ -147,9 +147,9 @@ module.exports = function(RED) { // Setting the flags this way works as their default // values are false. ['alternate_intents', - 'return_context', - 'restart', - 'debug'].forEach((f) => { + 'return_context', + 'restart', + 'debug'].forEach((f) => { checkAndSet(config, params.input.options, f); if (msg.params) { checkAndSet(msg.params, params.input.options, f); @@ -160,7 +160,7 @@ module.exports = function(RED) { function setParamInputs(msg, params) { if (msg.params) { ['intents', - 'entities'].forEach((f) => { + 'entities'].forEach((f) => { checkAndSet(msg.params, params, f); }); } diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index da633ab0..1a5a9e62 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -109,6 +109,18 @@ module.exports = function (RED) { return Promise.resolve(); } + function docID(msg) { + if (msg.payload && 'string' === typeof msg.payload) { + return msg.payload; + } + if (msg.payload && + 'object' === typeof msg.payload && + msg.payload.document_id) { + return msg.payload.document_id; + } + return config['document-id']; + } + function paramCheck(msg, mode) { var message = null; switch (mode) { @@ -244,7 +256,6 @@ module.exports = function (RED) { } resolve(); }); - }); } @@ -268,25 +279,12 @@ module.exports = function (RED) { function sourceLang(msg) { if (msg.payload && 'object' === typeof msg.payload && - msg.payload.source - ) { + msg.payload.source) { return msg.payload.source; } return msg.srclang ? msg.srclang : config.srclang; } - function docID(msg) { - if (msg.payload && 'string' === typeof msg.payload) { - return msg.payload; - } - if (msg.payload && - 'object' === typeof msg.payload && - msg.payload.document_id) { - return msg.payload.document_id; - } - return config['document-id']; - } - function executePostRequest(uriAddress, params, msg) { return new Promise(function resolver(resolve, reject){ var authSettings = buildAuthSettings(); @@ -479,7 +477,8 @@ module.exports = function (RED) { node.status({ fill: 'blue', shape: 'dot', text: `Processing document ${pos} of ${len}` }); msgClone.payload = e; doit(msgClone); - }) + }); + } else { doit(msg); } From 0114b149cbe3516eb29a67861f20f48cc218fc6b Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 25 Dec 2018 18:15:48 +0000 Subject: [PATCH 53/53] Codacy Fixes --- services/language_translator/v3-doc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/language_translator/v3-doc.js b/services/language_translator/v3-doc.js index 1a5a9e62..4679a525 100644 --- a/services/language_translator/v3-doc.js +++ b/services/language_translator/v3-doc.js @@ -388,7 +388,7 @@ module.exports = function (RED) { //return Promise.reject('temp disabled'); return executePostRequest(uriAddress, params, msg); - }) + }); return p; }