mirror of
				https://github.com/node-red/node-red-nodes.git
				synced 2025-03-01 10:37:43 +00:00 
			
		
		
		
	add multilang sentiment node as separate node
This commit is contained in:
		
							
								
								
									
										13
									
								
								analysis/mlsentiment/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								analysis/mlsentiment/LICENSE
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | Copyright 2019 JS Foundation and other contributors, https://js.foundation/ | ||||||
|  |  | ||||||
|  | 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. | ||||||
							
								
								
									
										33
									
								
								analysis/mlsentiment/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								analysis/mlsentiment/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | node-red-node-multilang-sentiment | ||||||
|  | ================================= | ||||||
|  |  | ||||||
|  | A <a href="http://nodered.org" target="new">Node-RED</a> node that scores incoming words | ||||||
|  | using the AFINN-165 wordlist and attaches a sentiment.score property to the msg. | ||||||
|  |  | ||||||
|  | This is similar to the default sentiment node but supports many more languages at the cost of using more disk space. (approx 11MB) | ||||||
|  |  | ||||||
|  | Install | ||||||
|  | ------- | ||||||
|  |  | ||||||
|  | Either use the Menu - Manage palette - Install option in the editor or run the following command in your Node-RED user directory - typically `~/.node-red` | ||||||
|  |  | ||||||
|  |     npm install node-red-node-multilang-sentiment | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Usage | ||||||
|  | ----- | ||||||
|  |  | ||||||
|  | Uses the AFINN-165 wordlist to attempt to assign scores to words in text. | ||||||
|  |  | ||||||
|  | Attaches `msg.sentiment` to the msg and within that `msg.sentiment.score` holds the score. | ||||||
|  |  | ||||||
|  | Supports multiple languages. These can be preselected in the node configuration. You can also set it so that `msg.lang` can be used to set the language dynamically if required. The cldr language codes supported are: | ||||||
|  |  | ||||||
|  |     af, am, ar, az, be, bg, bn, bs, ca, ceb, co, cs, cy, da, de, el, en, eo, es, et, eu, fa, fi, | ||||||
|  |     fr, fy, ga, gd, gl, gu, ha, haw, hi, hmn, hr, ht, hu, hy, id, ig, is, it, iw, ja, jw, ka, kk, km, kn, ko, ku, ky, la, lb, lo, lt, | ||||||
|  |     lv, mg, mi, mk, ml, mn, mr, ms, mt, my, ne, nl, no, ny, pa, pl, ps, pt, ro, ru, sd, si, sk, sl, sm, sn, so, sq, sr, st, su, sv, | ||||||
|  |     sw, ta, te, tg, th, tl, tr, uk, ur, uz, vi, xh, yi, yo, zh, zh-tw, zu | ||||||
|  |  | ||||||
|  | A score greater than zero is positive and less than zero is negative. The score typically ranges from -5 to +5, but can go higher and lower. | ||||||
|  |  | ||||||
|  | See the <a href="https://github.com/marcellobarile/multilang-sentiment/blob/develop/README.md" target="_blank">Multilang Sentiment docs here</a>.</p> | ||||||
							
								
								
									
										8
									
								
								analysis/mlsentiment/locales/en-US/mlsentiment.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								analysis/mlsentiment/locales/en-US/mlsentiment.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |     "mlsentiment": { | ||||||
|  |         "sentiment": "sentiment", | ||||||
|  |         "label": { | ||||||
|  |             "language": "Language" | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								analysis/mlsentiment/locales/ja/mlsentiment.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								analysis/mlsentiment/locales/ja/mlsentiment.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  |  | ||||||
|  | <script type="text/x-red" data-help-name="mlsentiment"> | ||||||
|  |     <p>指定したプロパティ(デフォルトは<code>payload</code>)を分析し、<code>sentiment</code>オブジェクトを追加します。</p> | ||||||
|  |     <h3>出力</h3> | ||||||
|  |     <dl class="message-properties"> | ||||||
|  |         <dt>sentiment <span class="property-type">オブジェクト</span></dt> | ||||||
|  |         <dd>AFINN-111による感情分析の結果</dd> | ||||||
|  |         <dt>sentiment.score <span class="property-type">数値</span></dt> | ||||||
|  |         <dd>感情分析スコア</dd> | ||||||
|  |     </dl> | ||||||
|  |     <h3>入力</h3> | ||||||
|  |     <dl class="message-properties"> | ||||||
|  |         <dt>overrides <span class="property-type">オブジェクト</span></dt> | ||||||
|  |         <dd>単語スコアの上書きをするためのオブジェクト - <code>{ word:score,... }</code></dd> | ||||||
|  |     </dl> | ||||||
|  |     <h3>詳細</h3> | ||||||
|  |     <p>ゼロ以上のスコアはポジティブ、ゼロ以下はネガティブを意味します。</p> | ||||||
|  |     <p>スコアの範囲は通常-5から+5ですが、より大きかったり小さかったりすることもあります。</p> | ||||||
|  |     <p>詳細は<a href="https://github.com/marcellobarile/multilang-sentiment/blob/develop/README.md" target="_blank">the Multilang-Sentiment docs here</a>を参照してください。</p> | ||||||
|  | </script> | ||||||
							
								
								
									
										8
									
								
								analysis/mlsentiment/locales/ja/mlsentiment.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								analysis/mlsentiment/locales/ja/mlsentiment.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |     "mlsentiment": { | ||||||
|  |         "sentiment": "sentiment", | ||||||
|  |         "label": { | ||||||
|  |             "language": "言語" | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										176
									
								
								analysis/mlsentiment/mlsentiment.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								analysis/mlsentiment/mlsentiment.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | |||||||
|  |  | ||||||
|  | <script type="text/x-red" data-template-name="mlsentiment"> | ||||||
|  |     <div class="form-row"> | ||||||
|  |         <label for="node-input-lang"><i class="fa fa-language"></i> <span data-i18n="mlsentiment.label.language"></span></label> | ||||||
|  |         <select type="text" id="node-input-lang" style="width:70%;"> | ||||||
|  |             <option value="">set by msg.lang</option> | ||||||
|  |             <option value="af">Afrikaans</option> | ||||||
|  |             <option value="sq">Albanian</option> | ||||||
|  |             <option value="am">Amharic</option> | ||||||
|  |             <option value="ar">Arabic</option> | ||||||
|  |             <option value="hy">Armenian</option> | ||||||
|  |             <option value="az">Azerbaijani</option> | ||||||
|  |             <option value="bn">Bangla</option> | ||||||
|  |             <option value="eu">Basque</option> | ||||||
|  |             <option value="be">Belarusian</option> | ||||||
|  |             <option value="bs">Bosnian</option> | ||||||
|  |             <option value="bg">Bulgarian</option> | ||||||
|  |             <option value="my">Burmese</option> | ||||||
|  |             <option value="ca">Catalan</option> | ||||||
|  |             <option value="ceb">Cebuano</option> | ||||||
|  |             <option value="zh">Chinese</option> | ||||||
|  |             <option value="zh-tw">Chinese (Taiwanese)</option> | ||||||
|  |             <option value="co">Corsican</option> | ||||||
|  |             <option value="hr">Croatian</option> | ||||||
|  |             <option value="cs">Czech</option> | ||||||
|  |             <option value="da">Danish</option> | ||||||
|  |             <option value="nl">Dutch</option> | ||||||
|  |             <option value="en">English</option> | ||||||
|  |             <option value="eo">Esperanto</option> | ||||||
|  |             <option value="et">Estonian</option> | ||||||
|  |             <option value="fi">Finnish</option> | ||||||
|  |             <option value="fr">French</option> | ||||||
|  |             <option value="fy">Frisian</option> | ||||||
|  |             <option value="gl">Galician</option> | ||||||
|  |             <option value="ka">Georgian</option> | ||||||
|  |             <option value="de">German</option> | ||||||
|  |             <option value="el">Greek</option> | ||||||
|  |             <option value="gu">Gujarati</option> | ||||||
|  |             <option value="ht">Haitian Creole</option> | ||||||
|  |             <option value="ha">Hausa</option> | ||||||
|  |             <option value="haw">Hawaiian</option> | ||||||
|  |             <option value="hi">Hindi</option> | ||||||
|  |             <option value="hmn">Hmong</option> | ||||||
|  |             <option value="hu">Hungarian</option> | ||||||
|  |             <option value="is">Icelandic</option> | ||||||
|  |             <option value="ig">Igbo</option> | ||||||
|  |             <option value="id">Indonesian</option> | ||||||
|  |             <option value="ga">Irish</option> | ||||||
|  |             <option value="it">Italian</option> | ||||||
|  |             <option value="ja">Japanese</option> | ||||||
|  |             <option value="kn">Kannada</option> | ||||||
|  |             <option value="kk">Kazakh</option> | ||||||
|  |             <option value="km">Khmer</option> | ||||||
|  |             <option value="ko">Korean</option> | ||||||
|  |             <option value="ku">Kurdish</option> | ||||||
|  |             <option value="ky">Kyrgyz</option> | ||||||
|  |             <option value="lo">Lao</option> | ||||||
|  |             <option value="la">Latin</option> | ||||||
|  |             <option value="lv">Latvian</option> | ||||||
|  |             <option value="lt">Lithuanian</option> | ||||||
|  |             <option value="lb">Luxembourgish</option> | ||||||
|  |             <option value="mk">Macedonian</option> | ||||||
|  |             <option value="mg">Malagasy</option> | ||||||
|  |             <option value="ms">Malay</option> | ||||||
|  |             <option value="ml">Malayalam</option> | ||||||
|  |             <option value="mt">Maltese</option> | ||||||
|  |             <option value="mi">Maori</option> | ||||||
|  |             <option value="mr">Marathi</option> | ||||||
|  |             <option value="mn">Mongolian</option> | ||||||
|  |             <option value="ne">Nepali</option> | ||||||
|  |             <option value="no">Norwegian</option> | ||||||
|  |             <option value="ny">Nyanja</option> | ||||||
|  |             <option value="ps">Pashto</option> | ||||||
|  |             <option value="fa">Persian</option> | ||||||
|  |             <option value="pl">Polish</option> | ||||||
|  |             <option value="pt">Portuguese</option> | ||||||
|  |             <option value="pa">Punjabi</option> | ||||||
|  |             <option value="ro">Romanian</option> | ||||||
|  |             <option value="ru">Russian</option> | ||||||
|  |             <option value="sm">Samoan</option> | ||||||
|  |             <option value="gd">Scottish Gaelic</option> | ||||||
|  |             <option value="sr">Serbian</option> | ||||||
|  |             <option value="sn">Shona</option> | ||||||
|  |             <option value="sd">Sindhi</option> | ||||||
|  |             <option value="si">Sinhala</option> | ||||||
|  |             <option value="sk">Slovak</option> | ||||||
|  |             <option value="sl">Slovenian</option> | ||||||
|  |             <option value="so">Somali</option> | ||||||
|  |             <option value="st">Southern Sotho</option> | ||||||
|  |             <option value="es">Spanish</option> | ||||||
|  |             <option value="su">Sundanese</option> | ||||||
|  |             <option value="sw">Swahili</option> | ||||||
|  |             <option value="sv">Swedish</option> | ||||||
|  |             <option value="tl">Tagalog</option> | ||||||
|  |             <option value="tg">Tajik</option> | ||||||
|  |             <option value="ta">Tamil</option> | ||||||
|  |             <option value="te">Telugu</option> | ||||||
|  |             <option value="th">Thai</option> | ||||||
|  |             <option value="tr">Turkish</option> | ||||||
|  |             <option value="uk">Ukrainian</option> | ||||||
|  |             <option value="ur">Urdu</option> | ||||||
|  |             <option value="uz">Uzbek</option> | ||||||
|  |             <option value="vi">Vietnamese</option> | ||||||
|  |             <option value="cy">Welsh</option> | ||||||
|  |             <option value="xh">Xhosa</option> | ||||||
|  |             <option value="yi">Yiddish</option> | ||||||
|  |             <option value="yo">Yoruba</option> | ||||||
|  |             <option value="zu">Zulu</option> | ||||||
|  |         </select> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-row"> | ||||||
|  |         <label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label> | ||||||
|  |         <input type="text" id="node-input-property" style="width:70%;"/> | ||||||
|  |     </div> | ||||||
|  |     <div class="form-row"> | ||||||
|  |         <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label> | ||||||
|  |         <input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name"> | ||||||
|  |     </div> | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <script type="text/x-red" data-help-name="mlsentiment"> | ||||||
|  |     <p>Analyses the chosen property, default <code>payload</code>, and adds a <code>sentiment</code> object.</p> | ||||||
|  |     <h3>Outputs</h3> | ||||||
|  |     <dl class="message-properties"> | ||||||
|  |         <dt>sentiment <span class="property-type">object</span></dt> | ||||||
|  |         <dd>contains the resulting AFINN-111 sentiment.</dd> | ||||||
|  |         <dt>sentiment.score <span class="property-type">number</span></dt> | ||||||
|  |         <dd>the sentiment score.</dd> | ||||||
|  |     </dl> | ||||||
|  |     <h3>Inputs</h3> | ||||||
|  |     <dl class="message-properties"> | ||||||
|  |         <dt>words <span class="property-type">object</span></dt> | ||||||
|  |         <dd>an object of words and scores to override or add words can be supplied - <code>{ word:score,... }</code>.</dd> | ||||||
|  |     </dl> | ||||||
|  |     <dl class="message-properties"> | ||||||
|  |         <dt>lang <span class="property-type">string</span></dt> | ||||||
|  |         <dd>Two letter cldr code to specify the language to use - from the list below</dd> | ||||||
|  |     </dl> | ||||||
|  |     <h3>Details</h3> | ||||||
|  |     <p>A score greater than zero is positive and less than zero is negative.</p> | ||||||
|  |     <p>The score typically ranges from -5 to +5, but can go higher and lower.</p> | ||||||
|  |     <p>See <a href="https://github.com/marcellobarile/multilang-sentiment/blob/develop/README.md" target="_blank">the Sentiment docs here</a>.</p> | ||||||
|  |     <p>The node can also be configured to let the language be specified by setting <code>msg.lang</code> to one of the codes below</p> | ||||||
|  |     <p>The language codes supported are - af, am, ar, az, be, bg, bn, bs, ca, ceb, co, cs, cy, da, de, el, en, eo, es, et, eu, fa, fi, | ||||||
|  |     fr, fy, ga, gd, gl, gu, ha, haw, hi, hmn, hr, ht, hu, hy, id, ig, is, it, iw, ja, jw, ka, kk, km, kn, ko, ku, ky, la, lb, lo, lt, | ||||||
|  |     lv, mg, mi, mk, ml, mn, mr, ms, mt, my, ne, nl, no, ny, pa, pl, ps, pt, ro, ru, sd, si, sk, sl, sm, sn, so, sq, sr, st, su, sv, | ||||||
|  |     sw, ta, te, tg, th, tl, tr, uk, ur, uz, vi, xh, yi, yo, zh, zh-tw, zu</p> | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <script type="text/javascript"> | ||||||
|  |     RED.nodes.registerType('mlsentiment',{ | ||||||
|  |         category: 'analysis-function', | ||||||
|  |         color:"#E6E0F8", | ||||||
|  |         defaults: { | ||||||
|  |             name: {value:""}, | ||||||
|  |             property: {value:"payload",required:true}, | ||||||
|  |             lang: {value:"en"} | ||||||
|  |         }, | ||||||
|  |         inputs:1, | ||||||
|  |         outputs:1, | ||||||
|  |         icon: "arrow-in.png", | ||||||
|  |         paletteLabel: "multilang sentiment", | ||||||
|  |         label: function() { | ||||||
|  |             return this.name||"multilang sentiment"; | ||||||
|  |         }, | ||||||
|  |         labelStyle: function() { | ||||||
|  |             return this.name?"node_label_italic":""; | ||||||
|  |         }, | ||||||
|  |         oneditprepare: function() { | ||||||
|  |             if (this.property === undefined) { | ||||||
|  |                 $("#node-input-property").val("payload"); | ||||||
|  |             } | ||||||
|  |             $("#node-input-property").typedInput({default:'msg',types:['msg']}); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | </script> | ||||||
							
								
								
									
										28
									
								
								analysis/mlsentiment/mlsentiment.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								analysis/mlsentiment/mlsentiment.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  |  | ||||||
|  | module.exports = function(RED) { | ||||||
|  |     "use strict"; | ||||||
|  |     var multilangsentiment = require('multilang-sentiment'); | ||||||
|  |  | ||||||
|  |     function MultiLangSentimentNode(n) { | ||||||
|  |         RED.nodes.createNode(this,n); | ||||||
|  |         this.lang = n.lang; | ||||||
|  |         this.property = n.property||"payload"; | ||||||
|  |         var node = this; | ||||||
|  |  | ||||||
|  |         this.on("input", function(msg) { | ||||||
|  |             var value = RED.util.getMessageProperty(msg,node.property); | ||||||
|  |             if (value !== undefined) { | ||||||
|  |                 if (msg.hasOwnProperty("overrides")) { | ||||||
|  |                     msg.extras = msg.overrides; | ||||||
|  |                     delete msg.overrides; | ||||||
|  |                 } | ||||||
|  |                 multilangsentiment(value, node.lang || msg.lang || 'en', {words: msg.extras || null}, function (err, result) { | ||||||
|  |                     msg.sentiment = result; | ||||||
|  |                     node.send(msg); | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |             else { node.send(msg); } // If no matching property - just pass it on. | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |     RED.nodes.registerType("mlsentiment",MultiLangSentimentNode); | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								analysis/mlsentiment/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								analysis/mlsentiment/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | { | ||||||
|  |     "name"          : "node-red-node-multilang-sentiment", | ||||||
|  |     "version"       : "0.1.0", | ||||||
|  |     "description"   : "A Node-RED node that uses the AFINN-165 wordlists for sentiment analysis of words translated into multiple languages including emojis.", | ||||||
|  |     "dependencies"  : { | ||||||
|  |         "multilang-sentiment" : "^1.2.0" | ||||||
|  |     }, | ||||||
|  |     "repository" : { | ||||||
|  |         "type":"git", | ||||||
|  |         "url":"https://github.com/node-red/node-red-nodes/tree/master/analysis/sentiment" | ||||||
|  |     }, | ||||||
|  |     "license": "Apache-2.0", | ||||||
|  |     "keywords": [ "node-red", "sentiment", "anaylsis", "AFINN" ], | ||||||
|  |     "node-red" : { | ||||||
|  |         "nodes" : { | ||||||
|  |             "mlsentiment": "mlsentiment.js" | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "author": { | ||||||
|  |         "name": "Dave Conway-Jones", | ||||||
|  |         "email": "ceejay@vnet.ibm.com", | ||||||
|  |         "url": "http://nodered.org" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -79,28 +79,6 @@ describe('sentiment Node', function() { | |||||||
|         }); |         }); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     it('should add a positive score for good words (in French)', function(done) { |  | ||||||
|         var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]],lang:"fr"}, |  | ||||||
|                     {id:"jn2", type:"helper"}]; |  | ||||||
|         helper.load(sentimentNode, flow, function() { |  | ||||||
|             var jn1 = helper.getNode("jn1"); |  | ||||||
|             var jn2 = helper.getNode("jn2"); |  | ||||||
|             jn2.on("input", function(msg) { |  | ||||||
|                 try { |  | ||||||
|                     msg.should.have.property('sentiment'); |  | ||||||
|                     msg.sentiment.should.have.property('score'); |  | ||||||
|                     msg.sentiment.score.should.be.a.Number(); |  | ||||||
|                     msg.sentiment.score.should.be.above(5); |  | ||||||
|                     done(); |  | ||||||
|                 } catch(err) { |  | ||||||
|                     done(err); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|             var testString = 'bon, belle, don du ciel, brillant'; |  | ||||||
|             jn1.receive({payload:testString}); |  | ||||||
|         }); |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     it('should add a positive score for good words - alternative property', function(done) { |     it('should add a positive score for good words - alternative property', function(done) { | ||||||
|         var flow = [{id:"jn1",type:"sentiment",property:"foo",wires:[["jn2"]]}, |         var flow = [{id:"jn1",type:"sentiment",property:"foo",wires:[["jn2"]]}, | ||||||
|                     {id:"jn2", type:"helper"}]; |                     {id:"jn2", type:"helper"}]; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user