From ff49d2b21748959dc600b0e26e05dcf7971694aa Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Sat, 3 May 2014 23:32:04 +0100 Subject: [PATCH] Migrate to new node function style --- nodes/99-sample.html.demo | 2 +- nodes/99-sample.js.demo | 64 ++-- nodes/core/analysis/72-sentiment.js | 27 +- nodes/core/analysis/73-parsexml.js | 53 +-- nodes/core/analysis/74-js2xml.js | 39 +- nodes/core/core/20-inject.js | 157 ++++---- nodes/core/core/58-debug.js | 271 +++++++------- nodes/core/core/75-exec.js | 122 +++---- nodes/core/core/80-function.js | 94 ++--- nodes/core/core/80-template.js | 46 +-- nodes/core/core/89-delay.js | 258 ++++++------- nodes/core/core/90-comment.js | 12 +- nodes/core/core/98-unknown.js | 10 +- nodes/core/hardware/35-arduino.js | 320 +++++++++-------- nodes/core/hardware/36-rpi-gpio.js | 263 +++++++------- nodes/core/io/10-mqtt.js | 220 ++++++------ nodes/core/io/21-httpin.js | 418 ++++++++++----------- nodes/core/io/22-websocket.js | 285 +++++++-------- nodes/core/io/23-watch.js | 49 +-- nodes/core/io/25-serial.js | 367 +++++++++---------- nodes/core/io/31-tcpin.js | 533 +++++++++++++-------------- nodes/core/io/32-udp.js | 273 +++++++------- nodes/core/logic/10-switch.js | 108 +++--- nodes/core/logic/15-change.js | 110 +++--- nodes/core/logic/16-range.js | 58 +-- nodes/core/parsers/70-CSV.js | 110 +++--- nodes/core/parsers/70-JSON.js | 47 +-- nodes/core/parsers/70-XML.js | 61 ++-- nodes/core/social/27-twitter.js | 539 ++++++++++++++-------------- nodes/core/social/32-feedparse.js | 102 +++--- nodes/core/social/61-email.js | 461 ++++++++++++------------ nodes/core/social/91-irc.js | 231 ++++++------ nodes/core/storage/28-tail.js | 75 ++-- nodes/core/storage/50-file.js | 133 +++---- nodes/core/storage/65-redisout.js | 149 ++++---- nodes/core/storage/66-mongodb.js | 295 +++++++-------- red/nodes/registry.js | 2 +- 37 files changed, 3194 insertions(+), 3170 deletions(-) diff --git a/nodes/99-sample.html.demo b/nodes/99-sample.html.demo index c946ad119..2a9617c70 100644 --- a/nodes/99-sample.html.demo +++ b/nodes/99-sample.html.demo @@ -17,7 +17,7 @@ - + diff --git a/nodes/99-sample.js.demo b/nodes/99-sample.js.demo index bb458c816..efda25a70 100644 --- a/nodes/99-sample.js.demo +++ b/nodes/99-sample.js.demo @@ -14,39 +14,41 @@ * limitations under the License. **/ -// If you use this as a template, replace IBM Corp. with your own name. +// If you use this as a template, update the copyright with your own name. // Sample Node-RED node file -// Require main module -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -// The main node definition - most things happen in here -function SampleNode(n) { - // Create a RED node - RED.nodes.createNode(this,n); - - // Store local copies of the node configuration (as defined in the .html) - this.topic = n.topic; - - // Do whatever you need to do in here - declare callbacks etc - // Note: this sample doesn't do anything much - it will only send - // this message once at startup... - // Look at other real nodes for some better ideas of what to do.... - var msg = {}; - msg.topic = this.topic; - msg.payload = "Hello world !" - - // send out the message to the rest of the workspace. - this.send(msg); - - this.on("close", function() { - // Called when the node is shutdown - eg on redeploy. - // Allows ports to be closed, connections dropped etc. - // eg: this.client.disconnect(); - }); +module.export = function(RED) { + + // The main node definition - most things happen in here + function SampleNode(n) { + // Create a RED node + RED.nodes.createNode(this,n); + + // Store local copies of the node configuration (as defined in the .html) + this.topic = n.topic; + + // Do whatever you need to do in here - declare callbacks etc + // Note: this sample doesn't do anything much - it will only send + // this message once at startup... + // Look at other real nodes for some better ideas of what to do.... + var msg = {}; + msg.topic = this.topic; + msg.payload = "Hello world !" + + // send out the message to the rest of the workspace. + this.send(msg); + + this.on("close", function() { + // Called when the node is shutdown - eg on redeploy. + // Allows ports to be closed, connections dropped etc. + // eg: this.client.disconnect(); + }); + } + + // Register the node by name. This must be called before overriding any of the + // Node functions. + RED.nodes.registerType("sample",SampleNode); + } - -// Register the node by name. This must be called before overriding any of the -// Node functions. -RED.nodes.registerType("sample",SampleNode); diff --git a/nodes/core/analysis/72-sentiment.js b/nodes/core/analysis/72-sentiment.js index 179f852f9..16a4d7ea2 100644 --- a/nodes/core/analysis/72-sentiment.js +++ b/nodes/core/analysis/72-sentiment.js @@ -14,18 +14,19 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var sentiment = require('sentiment'); - -function SentimentNode(n) { - RED.nodes.createNode(this,n); - var node = this; - - this.on("input", function(msg) { - sentiment(msg.payload, msg.overrides || null, function (err, result) { - msg.sentiment = result; - node.send(msg); +module.exports = function(RED) { + var sentiment = require('sentiment'); + + function SentimentNode(n) { + RED.nodes.createNode(this,n); + var node = this; + + this.on("input", function(msg) { + sentiment(msg.payload, msg.overrides || null, function (err, result) { + msg.sentiment = result; + node.send(msg); + }); }); - }); + } + RED.nodes.registerType("sentiment",SentimentNode); } -RED.nodes.registerType("sentiment",SentimentNode); diff --git a/nodes/core/analysis/73-parsexml.js b/nodes/core/analysis/73-parsexml.js index cd3e30f3d..05ae6cd44 100644 --- a/nodes/core/analysis/73-parsexml.js +++ b/nodes/core/analysis/73-parsexml.js @@ -14,31 +14,32 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var util = require("util"); -var parseString = require('xml2js').parseString; -var useColors = true; -//util.inspect.styles.boolean = "red"; - -function Xml2jsNode(n) { - RED.nodes.createNode(this,n); - this.useEyes = n.useEyes||false; - var node = this; - this.on("input", function(msg) { - try { - parseString(msg.payload, {strict:true,async:true}, function (err, result) { - //parseString(msg.payload, {strict:false,async:true}, function (err, result) { - if (err) { node.error(err); } - else { - msg.payload = result; - node.send(msg); - if (node.useEyes == true) { - node.log("\n"+util.inspect(msg, {colors:useColors, depth:10})); +module.exports = function(RED) { + var util = require("util"); + var parseString = require('xml2js').parseString; + var useColors = true; + //util.inspect.styles.boolean = "red"; + + function Xml2jsNode(n) { + RED.nodes.createNode(this,n); + this.useEyes = n.useEyes||false; + var node = this; + this.on("input", function(msg) { + try { + parseString(msg.payload, {strict:true,async:true}, function (err, result) { + //parseString(msg.payload, {strict:false,async:true}, function (err, result) { + if (err) { node.error(err); } + else { + msg.payload = result; + node.send(msg); + if (node.useEyes == true) { + node.log("\n"+util.inspect(msg, {colors:useColors, depth:10})); + } } - } - }); - } - catch(e) { util.log("[73-parsexml.js] "+e); } - }); + }); + } + catch(e) { util.log("[73-parsexml.js] "+e); } + }); + } + RED.nodes.registerType("xml2js",Xml2jsNode); } -RED.nodes.registerType("xml2js",Xml2jsNode); diff --git a/nodes/core/analysis/74-js2xml.js b/nodes/core/analysis/74-js2xml.js index 70ef8cfee..106053789 100644 --- a/nodes/core/analysis/74-js2xml.js +++ b/nodes/core/analysis/74-js2xml.js @@ -14,23 +14,24 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var js2xmlparser = require("js2xmlparser"); - -function Js2XmlNode(n) { - RED.nodes.createNode(this,n); - this.root = n.root; - var node = this; - - this.on("input", function(msg) { - try { - var root = node.root || typeof msg.payload; - if (typeof msg.payload !== "object") { msg.payload = '"'+msg.payload+'"'; } - console.log(root, typeof msg.payload,msg.payload); - msg.payload = js2xmlparser(root, msg.payload); - node.send(msg); - } - catch(e) { console.log(e); } - }); +module.exports = function(RED) { + var js2xmlparser = require("js2xmlparser"); + + function Js2XmlNode(n) { + RED.nodes.createNode(this,n); + this.root = n.root; + var node = this; + + this.on("input", function(msg) { + try { + var root = node.root || typeof msg.payload; + if (typeof msg.payload !== "object") { msg.payload = '"'+msg.payload+'"'; } + console.log(root, typeof msg.payload,msg.payload); + msg.payload = js2xmlparser(root, msg.payload); + node.send(msg); + } + catch(e) { console.log(e); } + }); + } + RED.nodes.registerType("json2xml",Js2XmlNode); } -RED.nodes.registerType("json2xml",Js2XmlNode); diff --git a/nodes/core/core/20-inject.js b/nodes/core/core/20-inject.js index 5e806bf44..dff0fb65e 100644 --- a/nodes/core/core/20-inject.js +++ b/nodes/core/core/20-inject.js @@ -1,5 +1,5 @@ /** - * Copyright 2013 IBM Corp. + * Copyright 2013, 2014 IBM Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,87 +14,84 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -try { +module.exports = function(RED) { var cron = require("cron"); -} catch(err) { - require("util").log("[inject] Warning: cannot find module 'cron'"); -} - -function InjectNode(n) { - RED.nodes.createNode(this,n); - this.topic = n.topic; - this.payload = n.payload; - this.payloadType = n.payloadType; - this.repeat = n.repeat; - this.crontab = n.crontab; - this.once = n.once; - var node = this; - this.interval_id = null; - this.cronjob = null; - - if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) { - this.repeat = this.repeat * 1000; - this.log("repeat = "+this.repeat); - this.interval_id = setInterval( function() { - node.emit("input",{}); - }, this.repeat ); - } else if (this.crontab) { - if (cron) { - this.log("crontab = "+this.crontab); - this.cronjob = new cron.CronJob(this.crontab, - function() { - node.emit("input",{}); - }, - null,true); - } else { - this.error("'cron' module not found"); + + function InjectNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.payload = n.payload; + this.payloadType = n.payloadType; + this.repeat = n.repeat; + this.crontab = n.crontab; + this.once = n.once; + var node = this; + this.interval_id = null; + this.cronjob = null; + + if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) { + this.repeat = this.repeat * 1000; + this.log("repeat = "+this.repeat); + this.interval_id = setInterval( function() { + node.emit("input",{}); + }, this.repeat ); + } else if (this.crontab) { + if (cron) { + this.log("crontab = "+this.crontab); + this.cronjob = new cron.CronJob(this.crontab, + function() { + node.emit("input",{}); + }, + null,true); + } else { + this.error("'cron' module not found"); + } + } + + if (this.once) { + setTimeout( function(){ node.emit("input",{}); }, 100); + } + + this.on("input",function(msg) { + var msg = {topic:this.topic}; + if ( (this.payloadType == null && this.payload == "") || this.payloadType == "date") { + msg.payload = Date.now(); + } else if (this.payloadType == null || this.payloadType == "string") { + msg.payload = this.payload; + } else { + msg.payload = ""; + } + this.send(msg); + msg = null; + }); + } + + RED.nodes.registerType("inject",InjectNode); + + InjectNode.prototype.close = function() { + if (this.interval_id != null) { + clearInterval(this.interval_id); + this.log("inject: repeat stopped"); + } else if (this.cronjob != null) { + this.cronjob.stop(); + this.log("inject: cronjob stopped"); + delete this.cronjob; } } - - if (this.once) { - setTimeout( function(){ node.emit("input",{}); }, 100); - } - - this.on("input",function(msg) { - var msg = {topic:this.topic}; - if ( (this.payloadType == null && this.payload == "") || this.payloadType == "date") { - msg.payload = Date.now(); - } else if (this.payloadType == null || this.payloadType == "string") { - msg.payload = this.payload; - } else { - msg.payload = ""; - } - this.send(msg); - msg = null; + + RED.httpAdmin.post("/inject/:id", function(req,res) { + var node = RED.nodes.getNode(req.params.id); + if (node != null) { + try { + node.receive(); + res.send(200); + } catch(err) { + res.send(500); + node.error("Inject failed:"+err); + console.log(err.stack); + } + } else { + res.send(404); + } }); } - -RED.nodes.registerType("inject",InjectNode); - -InjectNode.prototype.close = function() { - if (this.interval_id != null) { - clearInterval(this.interval_id); - this.log("inject: repeat stopped"); - } else if (this.cronjob != null) { - this.cronjob.stop(); - this.log("inject: cronjob stopped"); - delete this.cronjob; - } -} - -RED.httpAdmin.post("/inject/:id", function(req,res) { - var node = RED.nodes.getNode(req.params.id); - if (node != null) { - try { - node.receive(); - res.send(200); - } catch(err) { - res.send(500); - node.error("Inject failed:"+err); - console.log(err.stack); - } - } else { - res.send(404); - } -}); diff --git a/nodes/core/core/58-debug.js b/nodes/core/core/58-debug.js index 77fc62b0a..6c5a4aa38 100644 --- a/nodes/core/core/58-debug.js +++ b/nodes/core/core/58-debug.js @@ -14,157 +14,158 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var util = require("util"); -var ws = require("ws"); -var events = require("events"); -var debuglength = RED.settings.debugMaxLength||1000; -var useColors = false; -// util.inspect.styles.boolean = "red"; - -function DebugNode(n) { - RED.nodes.createNode(this,n); - this.name = n.name; - this.complete = n.complete; - this.console = n.console; - this.active = (n.active == null)||n.active; - var node = this; - - this.on("input",function(msg) { - if (this.complete == "true") { // debug complete msg object - if (this.console == "true") { - node.log("\n"+util.inspect(msg, {colors:useColors, depth:10})); - } - if (msg.payload instanceof Buffer) { msg.payload = "(Buffer) "+msg.payload.toString('hex'); } - if (this.active) { - DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg,_path:msg._path}); - } - } else { // debug just the msg.payload - if (this.console == "true") { - if (typeof msg.payload === "string") { - if (msg.payload.indexOf("\n") != -1) { msg.payload = "\n"+msg.payload; } - node.log(msg.payload); +module.exports = function(RED) { + var util = require("util"); + var ws = require("ws"); + var events = require("events"); + var debuglength = RED.settings.debugMaxLength||1000; + var useColors = false; + // util.inspect.styles.boolean = "red"; + + function DebugNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.complete = n.complete; + this.console = n.console; + this.active = (n.active == null)||n.active; + var node = this; + + this.on("input",function(msg) { + if (this.complete == "true") { // debug complete msg object + if (this.console == "true") { + node.log("\n"+util.inspect(msg, {colors:useColors, depth:10})); + } + if (msg.payload instanceof Buffer) { msg.payload = "(Buffer) "+msg.payload.toString('hex'); } + if (this.active) { + DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg,_path:msg._path}); + } + } else { // debug just the msg.payload + if (this.console == "true") { + if (typeof msg.payload === "string") { + if (msg.payload.indexOf("\n") != -1) { msg.payload = "\n"+msg.payload; } + node.log(msg.payload); + } + else if (typeof msg.payload === "object") { node.log("\n"+util.inspect(msg.payload, {colors:useColors, depth:10})); } + else { node.log(util.inspect(msg.payload, {colors:useColors})); } + } + if (typeof msg.payload == "undefined") { msg.payload = "(undefined)"; } + if (msg.payload instanceof Buffer) { msg.payload = "(Buffer) "+msg.payload.toString('hex'); } + if (this.active) { + DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path}); } - else if (typeof msg.payload === "object") { node.log("\n"+util.inspect(msg.payload, {colors:useColors, depth:10})); } - else { node.log(util.inspect(msg.payload, {colors:useColors})); } } - if (typeof msg.payload == "undefined") { msg.payload = "(undefined)"; } - if (msg.payload instanceof Buffer) { msg.payload = "(Buffer) "+msg.payload.toString('hex'); } - if (this.active) { - DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path}); + }); + } + + var lastSentTime = (new Date()).getTime(); + + setInterval(function() { + var now = (new Date()).getTime(); + if (now-lastSentTime > 15000) { + lastSentTime = now; + for (var i in DebugNode.activeConnections) { + var ws = DebugNode.activeConnections[i]; + try { + var p = JSON.stringify({heartbeat:lastSentTime}); + ws.send(p); + } catch(err) { + util.log("[debug] ws heartbeat error : "+err); + } } } - }); -} - -var lastSentTime = (new Date()).getTime(); - -setInterval(function() { - var now = (new Date()).getTime(); - if (now-lastSentTime > 15000) { - lastSentTime = now; + }, 15000); + + + + RED.nodes.registerType("debug",DebugNode); + + DebugNode.send = function(msg) { + if (msg.msg instanceof Error) { + msg.msg = msg.msg.toString(); + } else if (typeof msg.msg === 'object') { + var seen = []; + var ty = "(Object) "; + if (util.isArray(msg.msg)) { ty = "(Array) "; } + msg.msg = ty + JSON.stringify(msg.msg, function(key, value) { + if (typeof value === 'object' && value !== null) { + if (seen.indexOf(value) !== -1) { return "[circular]"; } + seen.push(value); + } + return value; + }," "); + seen = null; + } else if (typeof msg.msg === "boolean") { + msg.msg = "(boolean) "+msg.msg.toString(); + } else if (msg.msg === 0) { + msg.msg = "0"; + } else if (msg.msg == null) { + msg.msg = "[undefined]"; + } + + if (msg.msg.length > debuglength) { + msg.msg = msg.msg.substr(0,debuglength) +" ...."; + } + for (var i in DebugNode.activeConnections) { var ws = DebugNode.activeConnections[i]; try { - var p = JSON.stringify({heartbeat:lastSentTime}); + var p = JSON.stringify(msg); ws.send(p); } catch(err) { - util.log("[debug] ws heartbeat error : "+err); + util.log("[debug] ws error : "+err); } } - } -}, 15000); - - - -RED.nodes.registerType("debug",DebugNode); - -DebugNode.send = function(msg) { - if (msg.msg instanceof Error) { - msg.msg = msg.msg.toString(); - } else if (typeof msg.msg === 'object') { - var seen = []; - var ty = "(Object) "; - if (util.isArray(msg.msg)) { ty = "(Array) "; } - msg.msg = ty + JSON.stringify(msg.msg, function(key, value) { - if (typeof value === 'object' && value !== null) { - if (seen.indexOf(value) !== -1) { return "[circular]"; } - seen.push(value); - } - return value; - }," "); - seen = null; - } else if (typeof msg.msg === "boolean") { - msg.msg = "(boolean) "+msg.msg.toString(); - } else if (msg.msg === 0) { - msg.msg = "0"; - } else if (msg.msg == null) { - msg.msg = "[undefined]"; - } - - if (msg.msg.length > debuglength) { - msg.msg = msg.msg.substr(0,debuglength) +" ...."; + lastSentTime = (new Date()).getTime(); } - for (var i in DebugNode.activeConnections) { - var ws = DebugNode.activeConnections[i]; - try { - var p = JSON.stringify(msg); - ws.send(p); - } catch(err) { - util.log("[debug] ws error : "+err); - } - } - lastSentTime = (new Date()).getTime(); -} - -DebugNode.activeConnections = []; - -var path = RED.settings.httpAdminRoot || "/"; -path = path + (path.slice(-1) == "/" ? "":"/") + "debug/ws"; - -DebugNode.wsServer = new ws.Server({server:RED.server,path:path}); -DebugNode.wsServer.on('connection',function(ws) { - DebugNode.activeConnections.push(ws); - ws.on('close',function() { - for (var i in DebugNode.activeConnections) { - if (DebugNode.activeConnections[i] === ws) { - DebugNode.activeConnections.splice(i,1); - break; + DebugNode.activeConnections = []; + + var path = RED.settings.httpAdminRoot || "/"; + path = path + (path.slice(-1) == "/" ? "":"/") + "debug/ws"; + + DebugNode.wsServer = new ws.Server({server:RED.server,path:path}); + DebugNode.wsServer.on('connection',function(ws) { + DebugNode.activeConnections.push(ws); + ws.on('close',function() { + for (var i in DebugNode.activeConnections) { + if (DebugNode.activeConnections[i] === ws) { + DebugNode.activeConnections.splice(i,1); + break; + } } + }); + ws.on('error', function(err) { + util.log("[debug] ws error : "+err); + }); + }); + + DebugNode.wsServer.on('error', function(err) { + util.log("[debug] ws server error : "+err); + }); + + DebugNode.logHandler = new events.EventEmitter(); + DebugNode.logHandler.on("log",function(msg) { + if (msg.level == "warn" || msg.level == "error") { + DebugNode.send(msg); } }); - ws.on('error', function(err) { - util.log("[debug] ws error : "+err); - }); -}); - -DebugNode.wsServer.on('error', function(err) { - util.log("[debug] ws server error : "+err); -}); - -DebugNode.logHandler = new events.EventEmitter(); -DebugNode.logHandler.on("log",function(msg) { - if (msg.level == "warn" || msg.level == "error") { - DebugNode.send(msg); - } -}); -RED.log.addHandler(DebugNode.logHandler); - -RED.httpAdmin.post("/debug/:id/:state", function(req,res) { - var node = RED.nodes.getNode(req.params.id); - var state = req.params.state; - if (node != null) { - if (state === "enable") { - node.active = true; - res.send(200); - } else if (state === "disable") { - node.active = false; - res.send(201); + RED.log.addHandler(DebugNode.logHandler); + + RED.httpAdmin.post("/debug/:id/:state", function(req,res) { + var node = RED.nodes.getNode(req.params.id); + var state = req.params.state; + if (node != null) { + if (state === "enable") { + node.active = true; + res.send(200); + } else if (state === "disable") { + node.active = false; + res.send(201); + } else { + res.send(404); + } } else { res.send(404); } - } else { - res.send(404); - } -}); + }); +} diff --git a/nodes/core/core/75-exec.js b/nodes/core/core/75-exec.js index eb6834e49..4c3b67b62 100644 --- a/nodes/core/core/75-exec.js +++ b/nodes/core/core/75-exec.js @@ -14,68 +14,68 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); - -var spawn = require('child_process').spawn; -var exec = require('child_process').exec; - -function ExecNode(n) { - RED.nodes.createNode(this,n); - this.cmd = n.command.trim(); - this.append = n.append.trim() || ""; - this.useSpawn = n.useSpawn; - - var node = this; - this.on("input", function(msg) { - if (msg != null) { - - if (this.useSpawn == true) { - // make the extra args into an array - // then prepend with the msg.payload - if (typeof(msg.payload !== "string")) { msg.payload = msg.payload.toString(); } - var arg = []; - if (node.append.length > 0) { arg = node.append.split(","); } - if (msg.payload.trim() != "") { arg.unshift(msg.payload); } - node.log(node.cmd+" ["+arg+"]"); - if (node.cmd.indexOf(" ") == -1) { - var ex = spawn(node.cmd,arg); - ex.stdout.on('data', function (data) { - //console.log('[exec] stdout: ' + data); - msg.payload = data.toString(); - node.send([msg,null,null]); - }); - ex.stderr.on('data', function (data) { - //console.log('[exec] stderr: ' + data); - msg.payload = data.toString(); - node.send([null,msg,null]); - }); - ex.on('close', function (code) { - //console.log('[exec] result: ' + code); - msg.payload = code; - node.send([null,null,msg]); +module.exports = function(RED) { + var spawn = require('child_process').spawn; + var exec = require('child_process').exec; + + function ExecNode(n) { + RED.nodes.createNode(this,n); + this.cmd = n.command.trim(); + this.append = n.append.trim() || ""; + this.useSpawn = n.useSpawn; + + var node = this; + this.on("input", function(msg) { + if (msg != null) { + + if (this.useSpawn == true) { + // make the extra args into an array + // then prepend with the msg.payload + if (typeof(msg.payload !== "string")) { msg.payload = msg.payload.toString(); } + var arg = []; + if (node.append.length > 0) { arg = node.append.split(","); } + if (msg.payload.trim() != "") { arg.unshift(msg.payload); } + node.log(node.cmd+" ["+arg+"]"); + if (node.cmd.indexOf(" ") == -1) { + var ex = spawn(node.cmd,arg); + ex.stdout.on('data', function (data) { + //console.log('[exec] stdout: ' + data); + msg.payload = data.toString(); + node.send([msg,null,null]); + }); + ex.stderr.on('data', function (data) { + //console.log('[exec] stderr: ' + data); + msg.payload = data.toString(); + node.send([null,msg,null]); + }); + ex.on('close', function (code) { + //console.log('[exec] result: ' + code); + msg.payload = code; + node.send([null,null,msg]); + }); + } + else { node.error("Spawn command must be just the command - no spaces or extra parameters"); } + } + + else { + var cl = node.cmd+" "+msg.payload+" "+node.append; + node.log(cl); + var child = exec(cl, function (error, stdout, stderr) { + msg.payload = stdout; + var msg2 = {payload:stderr}; + //console.log('[exec] stdout: ' + stdout); + //console.log('[exec] stderr: ' + stderr); + if (error !== null) { + var msg3 = {payload:error}; + //console.log('[exec] error: ' + error); + } + node.send([msg,msg2,msg3]); }); } - else { node.error("Spawn command must be just the command - no spaces or extra parameters"); } } - - else { - var cl = node.cmd+" "+msg.payload+" "+node.append; - node.log(cl); - var child = exec(cl, function (error, stdout, stderr) { - msg.payload = stdout; - var msg2 = {payload:stderr}; - //console.log('[exec] stdout: ' + stdout); - //console.log('[exec] stderr: ' + stderr); - if (error !== null) { - var msg3 = {payload:error}; - //console.log('[exec] error: ' + error); - } - node.send([msg,msg2,msg3]); - }); - } - } - - }); + + }); + } + + RED.nodes.registerType("exec",ExecNode); } - -RED.nodes.registerType("exec",ExecNode); diff --git a/nodes/core/core/80-function.js b/nodes/core/core/80-function.js index 683eecd69..08fbce1f4 100644 --- a/nodes/core/core/80-function.js +++ b/nodes/core/core/80-function.js @@ -14,58 +14,58 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); - -var util = require("util"); -var vm = require("vm"); -var fs = require('fs'); -var fspath = require('path'); - -function FunctionNode(n) { - RED.nodes.createNode(this,n); - this.name = n.name; - this.func = n.func; - var functionText = "var results = (function(msg){"+this.func+"\n})(msg);"; - this.topic = n.topic; - this.context = {global:RED.settings.functionGlobalContext || {}}; - try { - this.script = vm.createScript(functionText); - this.on("input", function(msg) { - if (msg != null) { - var sandbox = {msg:msg,console:console,util:util,Buffer:Buffer,context:this.context}; - try { - this.script.runInNewContext(sandbox); - var results = sandbox.results; - - if (results == null) { - results = []; - } else if (results.length == null) { - results = [results]; - } - if (msg._topic) { - for (var m in results) { - if (results[m]) { - if (util.isArray(results[m])) { - for (var n in results[m]) { - results[m][n]._topic = msg._topic; +module.exports = function(RED) { + var util = require("util"); + var vm = require("vm"); + var fs = require('fs'); + var fspath = require('path'); + + function FunctionNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.func = n.func; + var functionText = "var results = (function(msg){"+this.func+"\n})(msg);"; + this.topic = n.topic; + this.context = {global:RED.settings.functionGlobalContext || {}}; + try { + this.script = vm.createScript(functionText); + this.on("input", function(msg) { + if (msg != null) { + var sandbox = {msg:msg,console:console,util:util,Buffer:Buffer,context:this.context}; + try { + this.script.runInNewContext(sandbox); + var results = sandbox.results; + + if (results == null) { + results = []; + } else if (results.length == null) { + results = [results]; + } + if (msg._topic) { + for (var m in results) { + if (results[m]) { + if (util.isArray(results[m])) { + for (var n in results[m]) { + results[m][n]._topic = msg._topic; + } + } else { + results[m]._topic = msg._topic; } - } else { - results[m]._topic = msg._topic; } } } + this.send(results); + + } catch(err) { + this.error(err); } - this.send(results); - - } catch(err) { - this.error(err); } - } - }); - } catch(err) { - this.error(err); + }); + } catch(err) { + this.error(err); + } } + + RED.nodes.registerType("function",FunctionNode); + RED.library.register("functions"); } - -RED.nodes.registerType("function",FunctionNode); -RED.library.register("functions"); diff --git a/nodes/core/core/80-template.js b/nodes/core/core/80-template.js index 7d1dcfbac..e5939537c 100644 --- a/nodes/core/core/80-template.js +++ b/nodes/core/core/80-template.js @@ -14,28 +14,28 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); - -var mustache = require("mustache"); -var util = require("util"); -var fs = require('fs'); - -function TemplateNode(n) { - RED.nodes.createNode(this,n); - this.name = n.name; - this.template = n.template; - this.on("input", function(msg) { - if (msg != null) { - try { - msg.payload = mustache.render(this.template,msg) - this.send(msg); - } catch(err) { - this.error(err.message); +module.exports = function(RED) { + var mustache = require("mustache"); + var util = require("util"); + var fs = require('fs'); + + function TemplateNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.template = n.template; + this.on("input", function(msg) { + if (msg != null) { + try { + msg.payload = mustache.render(this.template,msg) + this.send(msg); + } catch(err) { + this.error(err.message); + } } - } - }); + }); + } + + RED.nodes.registerType("template",TemplateNode); + + RED.library.register("templates"); } - -RED.nodes.registerType("template",TemplateNode); - -RED.library.register("templates"); diff --git a/nodes/core/core/89-delay.js b/nodes/core/core/89-delay.js index d8ef4fe2f..c081d452a 100644 --- a/nodes/core/core/89-delay.js +++ b/nodes/core/core/89-delay.js @@ -15,140 +15,140 @@ **/ //Simple node to introduce a pause into a flow -var RED = require(process.env.NODE_RED_HOME+"/red/red"); - -function random(n) { - var wait = n.randomFirst + (n.diff * Math.random()); - if (n.buffer.length > 0) { - n.send(n.buffer.pop()); - n.randomID = setTimeout(function() {random(n);},wait); - } else { - n.randomID = -1; +module.exports = function(RED) { + function random(n) { + var wait = n.randomFirst + (n.diff * Math.random()); + if (n.buffer.length > 0) { + n.send(n.buffer.pop()); + n.randomID = setTimeout(function() {random(n);},wait); + } else { + n.randomID = -1; + } } -} - -function DelayNode(n) { - RED.nodes.createNode(this,n); - - this.pauseType = n.pauseType; - this.timeoutUnits = n.timeoutUnits; - this.randomUnits = n.randomUnits; - this.rateUnits = n.rateUnits; - - if (n.timeoutUnits === "milliseconds") { - this.timeout = n.timeout; - } else if (n.timeoutUnits === "seconds") { - this.timeout = n.timeout * 1000; - } else if (n.timeoutUnits === "minutes") { - this.timeout = n.timeout * (60 * 1000); - } else if (n.timeoutUnits === "hours") { - this.timeout = n.timeout * (60 * 60 * 1000); - } else if (n.timeoutUnits === "days") { - this.timeout = n.timeout * (24 * 60 * 60 * 1000); - } - - if (n.rateUnits === "second") { - this.rate = 1000/n.rate; - } else if (n.rateUnits === "minute") { - this.rate = (60 * 1000)/n.rate; - } else if (n.rateUnits === "hour") { - this.rate = (60 * 60 * 1000)/n.rate; - } else if (n.rateUnits === "day") { - this.rate = (24 * 60 * 60 * 1000)/n.rate; - } - - if (n.randomUnits === "milliseconds") { - this.randomFirst = n.randomFirst; - this.randomLast = n.randomLast; - } else if (n.randomUnits === "seconds") { - this.randomFirst = n.randomFirst * 1000; - this.randomLast = n.randomLast * 1000; - } else if (n.randomUnits === "minutes") { - this.randomFirst = n.randomFirst * (60 * 1000); - this.randomLast = n.randomLast * (60 * 1000); - } else if (n.randomUnits === "hours") { - this.randomFirst = n.randomFirst * (60 * 60 * 1000); - this.randomLast = n.randomLast * (60 * 60 * 1000); - } else if (n.randomUnits === "days") { - this.randomFirst = n.randomFirst * (24 * 60 * 60 * 1000); - this.randomLast = n.randomLast * (24 * 60 * 60 * 1000); - } - - this.diff = this.randomLast - this.randomFirst; - this.name = n.name; - this.idList = []; - this.buffer = []; - this.intervalID = -1; - this.randomID = -1; - this.lastSent = Date.now(); - var node = this; - - if (this.pauseType === "delay") { - this.on("input", function(msg) { - var id; - id = setTimeout(function(){ - node.idList.splice(node.idList.indexOf(id),1); - node.send(msg); - }, node.timeout); - this.idList.push(id); - }); - - this.on("close", function() { - for (var i=0; i 1000) { - node.warn(this.name + " buffer exceeded 1000 messages"); + + function DelayNode(n) { + RED.nodes.createNode(this,n); + + this.pauseType = n.pauseType; + this.timeoutUnits = n.timeoutUnits; + this.randomUnits = n.randomUnits; + this.rateUnits = n.rateUnits; + + if (n.timeoutUnits === "milliseconds") { + this.timeout = n.timeout; + } else if (n.timeoutUnits === "seconds") { + this.timeout = n.timeout * 1000; + } else if (n.timeoutUnits === "minutes") { + this.timeout = n.timeout * (60 * 1000); + } else if (n.timeoutUnits === "hours") { + this.timeout = n.timeout * (60 * 60 * 1000); + } else if (n.timeoutUnits === "days") { + this.timeout = n.timeout * (24 * 60 * 60 * 1000); + } + + if (n.rateUnits === "second") { + this.rate = 1000/n.rate; + } else if (n.rateUnits === "minute") { + this.rate = (60 * 1000)/n.rate; + } else if (n.rateUnits === "hour") { + this.rate = (60 * 60 * 1000)/n.rate; + } else if (n.rateUnits === "day") { + this.rate = (24 * 60 * 60 * 1000)/n.rate; + } + + if (n.randomUnits === "milliseconds") { + this.randomFirst = n.randomFirst; + this.randomLast = n.randomLast; + } else if (n.randomUnits === "seconds") { + this.randomFirst = n.randomFirst * 1000; + this.randomLast = n.randomLast * 1000; + } else if (n.randomUnits === "minutes") { + this.randomFirst = n.randomFirst * (60 * 1000); + this.randomLast = n.randomLast * (60 * 1000); + } else if (n.randomUnits === "hours") { + this.randomFirst = n.randomFirst * (60 * 60 * 1000); + this.randomLast = n.randomLast * (60 * 60 * 1000); + } else if (n.randomUnits === "days") { + this.randomFirst = n.randomFirst * (24 * 60 * 60 * 1000); + this.randomLast = n.randomLast * (24 * 60 * 60 * 1000); + } + + this.diff = this.randomLast - this.randomFirst; + this.name = n.name; + this.idList = []; + this.buffer = []; + this.intervalID = -1; + this.randomID = -1; + this.lastSent = Date.now(); + var node = this; + + if (this.pauseType === "delay") { + this.on("input", function(msg) { + var id; + id = setTimeout(function(){ + node.idList.splice(node.idList.indexOf(id),1); + node.send(msg); + }, node.timeout); + this.idList.push(id); + }); + + this.on("close", function() { + for (var i=0; i 1000) { + node.warn(this.name + " buffer exceeded 1000 messages"); + } + } else { + node.send(msg); + node.intervalID = setInterval(function() { + if (node.buffer.length === 0) { + clearInterval(node.intervalID); + node.intervalID = -1; + } + + if (node.buffer.length > 0) { + node.send(node.buffer.shift()); + } + },node.rate); } } else { - node.send(msg); - node.intervalID = setInterval(function() { - if (node.buffer.length === 0) { - clearInterval(node.intervalID); - node.intervalID = -1; - } + var now = Date.now(); + if (now-node.lastSent > node.rate) { + node.lastSent = now; + node.send(msg); + } + } + }); - if (node.buffer.length > 0) { - node.send(node.buffer.shift()); - } - },node.rate); + this.on("close", function() { + clearInterval(this.intervalID); + this.buffer = []; + }); + + } else if (this.pauseType === "random") { + this.on("input",function(msg){ + node.buffer.push(msg); + if (node.randomID === -1) { + var wait = node.randomFirst + (node.diff * Math.random()); + node.randomID = setTimeout(function() {random(node);},wait); } - } else { - var now = Date.now(); - if (now-node.lastSent > node.rate) { - node.lastSent = now; - node.send(msg); + }); + + this.on("close", function (){ + if (this.randomID !== -1) { + clearTimeout(this.randomID); } - } - }); - - this.on("close", function() { - clearInterval(this.intervalID); - this.buffer = []; - }); - - } else if (this.pauseType === "random") { - this.on("input",function(msg){ - node.buffer.push(msg); - if (node.randomID === -1) { - var wait = node.randomFirst + (node.diff * Math.random()); - node.randomID = setTimeout(function() {random(node);},wait); - } - }); - - this.on("close", function (){ - if (this.randomID !== -1) { - clearTimeout(this.randomID); - } - }); + }); + } } + RED.nodes.registerType("delay",DelayNode); } -RED.nodes.registerType("delay",DelayNode); diff --git a/nodes/core/core/90-comment.js b/nodes/core/core/90-comment.js index 4b6fbacc7..2cb5ed75d 100644 --- a/nodes/core/core/90-comment.js +++ b/nodes/core/core/90-comment.js @@ -14,10 +14,10 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); - -function CommentNode(n) { - RED.nodes.createNode(this,n); +module.exports = function(RED) { + function CommentNode(n) { + RED.nodes.createNode(this,n); + } + + RED.nodes.registerType("comment",CommentNode); } - -RED.nodes.registerType("comment",CommentNode); diff --git a/nodes/core/core/98-unknown.js b/nodes/core/core/98-unknown.js index 12872baba..1a7362263 100644 --- a/nodes/core/core/98-unknown.js +++ b/nodes/core/core/98-unknown.js @@ -14,9 +14,9 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); - -function UnknownNode(n) { - RED.nodes.createNode(this,n); +module.exports = function(RED) { + function UnknownNode(n) { + RED.nodes.createNode(this,n); + } + RED.nodes.registerType("unknown",UnknownNode); } -RED.nodes.registerType("unknown",UnknownNode); diff --git a/nodes/core/hardware/35-arduino.js b/nodes/core/hardware/35-arduino.js index 82447299d..dc2750f5b 100644 --- a/nodes/core/hardware/35-arduino.js +++ b/nodes/core/hardware/35-arduino.js @@ -14,174 +14,176 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var util = require("util"); -var firmata = require("firmata"); -var arduinoReady = false; -var thisboard = null; - -// The Board Definition - this opens (and closes) the connection -function ArduinoNode(n) { - RED.nodes.createNode(this,n); - this.device = n.device; - this.repeat = n.repeat||25; - util.log("[firmata] Opening "+this.device); - var node = this; - - node.toun = setInterval(function() { - if (!arduinoReady) { - if (thisboard == null) { - node.board = new firmata.Board(node.device, function(err) { - if (err) { - util.log("[firmata] error: "+err); - return; - } - arduinoReady = true; - thisboard = node.board; - clearInterval(node.toun); - util.log('[firmata] Arduino connected'); - }); - } - else { - node.board = thisboard; - node.board.removeAllListeners(); - arduinoReady = true; - clearInterval(node.toun); - node.toun = false; - util.log("[firmata] Arduino already connected"); - } - } else { util.log("[firmata] Waiting for Firmata"); } - }, 10000); // wait for firmata to connect to arduino - - this.on('close', function() { - //this.board.sp.close(function() { console.log("[firmata] Serial port closed"); arduinoReady = false; }); - arduinoReady = false; - if (node.toun) { - clearInterval(node.toun); - util.log("[firmata] arduino wait loop stopped"); - } - util.log("[firmata] Stopped"); - }); -} -RED.nodes.registerType("arduino-board",ArduinoNode); - - -// The Input Node -function DuinoNodeIn(n) { - RED.nodes.createNode(this,n); - this.buttonState = -1; - this.pin = n.pin; - this.state = n.state; - this.arduino = n.arduino; - this.serverConfig = RED.nodes.getNode(this.arduino); - if (typeof this.serverConfig === "object") { - this.board = this.serverConfig.board; - this.repeat = this.serverConfig.repeat; +module.exports = function(RED) { + + var util = require("util"); + var firmata = require("firmata"); + var arduinoReady = false; + var thisboard = null; + + // The Board Definition - this opens (and closes) the connection + function ArduinoNode(n) { + RED.nodes.createNode(this,n); + this.device = n.device; + this.repeat = n.repeat||25; + util.log("[firmata] Opening "+this.device); var node = this; - - node.toui = setInterval(function() { - if (thisboard != null) { - node.board = thisboard; - clearInterval(node.toui); - node.toui = false; - //console.log("i",node.state,node.pin,node.board.MODES[node.state]); - node.board.pinMode(node.pin, node.board.MODES[node.state]); - node.board.setSamplingInterval(node.repeat); - var oldrdg = ""; - if (node.state == "ANALOG") { - node.board.analogRead(node.pin, function(data) { - var msg = {payload:data, topic:"A"+node.pin}; - if (data != oldrdg) { - node.send(msg); - oldrdg = data; + + node.toun = setInterval(function() { + if (!arduinoReady) { + if (thisboard == null) { + node.board = new firmata.Board(node.device, function(err) { + if (err) { + util.log("[firmata] error: "+err); + return; } + arduinoReady = true; + thisboard = node.board; + clearInterval(node.toun); + util.log('[firmata] Arduino connected'); }); } else { - node.board.digitalRead(node.pin, function(data) { - var msg = {payload:data, topic:node.pin}; - node.send(msg); - }); + node.board = thisboard; + node.board.removeAllListeners(); + arduinoReady = true; + clearInterval(node.toun); + node.toun = false; + util.log("[firmata] Arduino already connected"); } - } - else { node.log("Waiting for Arduino"); } - }, 5000); // loop to wait for firmata to connect to arduino - + } else { util.log("[firmata] Waiting for Firmata"); } + }, 10000); // wait for firmata to connect to arduino + this.on('close', function() { - if (node.toui) { - clearInterval(node.toui); - util.log("[firmata] input wait loop stopped"); + //this.board.sp.close(function() { console.log("[firmata] Serial port closed"); arduinoReady = false; }); + arduinoReady = false; + if (node.toun) { + clearInterval(node.toun); + util.log("[firmata] arduino wait loop stopped"); } + util.log("[firmata] Stopped"); }); } - else { - util.log("[firmata] Serial Port not Configured"); + RED.nodes.registerType("arduino-board",ArduinoNode); + + + // The Input Node + function DuinoNodeIn(n) { + RED.nodes.createNode(this,n); + this.buttonState = -1; + this.pin = n.pin; + this.state = n.state; + this.arduino = n.arduino; + this.serverConfig = RED.nodes.getNode(this.arduino); + if (typeof this.serverConfig === "object") { + this.board = this.serverConfig.board; + this.repeat = this.serverConfig.repeat; + var node = this; + + node.toui = setInterval(function() { + if (thisboard != null) { + node.board = thisboard; + clearInterval(node.toui); + node.toui = false; + //console.log("i",node.state,node.pin,node.board.MODES[node.state]); + node.board.pinMode(node.pin, node.board.MODES[node.state]); + node.board.setSamplingInterval(node.repeat); + var oldrdg = ""; + if (node.state == "ANALOG") { + node.board.analogRead(node.pin, function(data) { + var msg = {payload:data, topic:"A"+node.pin}; + if (data != oldrdg) { + node.send(msg); + oldrdg = data; + } + }); + } + else { + node.board.digitalRead(node.pin, function(data) { + var msg = {payload:data, topic:node.pin}; + node.send(msg); + }); + } + } + else { node.log("Waiting for Arduino"); } + }, 5000); // loop to wait for firmata to connect to arduino + + this.on('close', function() { + if (node.toui) { + clearInterval(node.toui); + util.log("[firmata] input wait loop stopped"); + } + }); + } + else { + util.log("[firmata] Serial Port not Configured"); + } } + RED.nodes.registerType("arduino in",DuinoNodeIn); + + + // The Output Node + function DuinoNodeOut(n) { + RED.nodes.createNode(this,n); + this.buttonState = -1; + this.pin = n.pin; + this.state = n.state; + this.arduino = n.arduino; + this.serverConfig = RED.nodes.getNode(this.arduino); + if (typeof this.serverConfig === "object") { + this.board = this.serverConfig.board; + var node = this; + + this.on("input", function(msg) { + //console.log(msg); + if (node.board != null) { + if (node.state == "OUTPUT") { + if ((msg.payload == true)||(msg.payload == 1)||(msg.payload.toString().toLowerCase() == "on")) { + node.board.digitalWrite(node.pin, node.board.HIGH); + } + if ((msg.payload == false)||(msg.payload == 0)||(msg.payload.toString().toLowerCase() == "off")) { + node.board.digitalWrite(node.pin, node.board.LOW); + } + } + if (node.state == "PWM") { + msg.payload = msg.payload * 1; + if ((msg.payload >= 0) && (msg.payload <= 255)) { + //console.log(msg.payload, node.pin); + node.board.servoWrite(node.pin, msg.payload); + } + } + if (node.state == "SERVO") { + msg.payload = msg.payload * 1; + if ((msg.payload >= 0) && (msg.payload <= 180)) { + //console.log(msg.payload, node.pin); + node.board.servoWrite(node.pin, msg.payload); + } + } + } + //else { console.log("Arduino not ready"); } + }); + + node.touo = setInterval(function() { + if (thisboard != null) { + clearInterval(node.touo); + node.touo = false; + node.board = thisboard; + //console.log("o",node.state,node.pin,node.board.MODES[node.state]); + node.board.pinMode(node.pin, node.board.MODES[node.state]); + } + else { util.log("[firmata] waiting for arduino to connect"); } + }, 5000); // loop to wait for firmata to connect to arduino + + this.on('close', function() { + if (node.touo) { + clearInterval(node.touo); + util.log("[firmata] output wait loop stopped"); + } + }); + } + else { + util.log("[firmata] Serial Port not Configured"); + } + } + RED.nodes.registerType("arduino out",DuinoNodeOut); } -RED.nodes.registerType("arduino in",DuinoNodeIn); - - -// The Output Node -function DuinoNodeOut(n) { - RED.nodes.createNode(this,n); - this.buttonState = -1; - this.pin = n.pin; - this.state = n.state; - this.arduino = n.arduino; - this.serverConfig = RED.nodes.getNode(this.arduino); - if (typeof this.serverConfig === "object") { - this.board = this.serverConfig.board; - var node = this; - - this.on("input", function(msg) { - //console.log(msg); - if (node.board != null) { - if (node.state == "OUTPUT") { - if ((msg.payload == true)||(msg.payload == 1)||(msg.payload.toString().toLowerCase() == "on")) { - node.board.digitalWrite(node.pin, node.board.HIGH); - } - if ((msg.payload == false)||(msg.payload == 0)||(msg.payload.toString().toLowerCase() == "off")) { - node.board.digitalWrite(node.pin, node.board.LOW); - } - } - if (node.state == "PWM") { - msg.payload = msg.payload * 1; - if ((msg.payload >= 0) && (msg.payload <= 255)) { - //console.log(msg.payload, node.pin); - node.board.servoWrite(node.pin, msg.payload); - } - } - if (node.state == "SERVO") { - msg.payload = msg.payload * 1; - if ((msg.payload >= 0) && (msg.payload <= 180)) { - //console.log(msg.payload, node.pin); - node.board.servoWrite(node.pin, msg.payload); - } - } - } - //else { console.log("Arduino not ready"); } - }); - - node.touo = setInterval(function() { - if (thisboard != null) { - clearInterval(node.touo); - node.touo = false; - node.board = thisboard; - //console.log("o",node.state,node.pin,node.board.MODES[node.state]); - node.board.pinMode(node.pin, node.board.MODES[node.state]); - } - else { util.log("[firmata] waiting for arduino to connect"); } - }, 5000); // loop to wait for firmata to connect to arduino - - this.on('close', function() { - if (node.touo) { - clearInterval(node.touo); - util.log("[firmata] output wait loop stopped"); - } - }); - } - else { - util.log("[firmata] Serial Port not Configured"); - } -} -RED.nodes.registerType("arduino out",DuinoNodeOut); diff --git a/nodes/core/hardware/36-rpi-gpio.js b/nodes/core/hardware/36-rpi-gpio.js index 05195fc02..8a7805a72 100644 --- a/nodes/core/hardware/36-rpi-gpio.js +++ b/nodes/core/hardware/36-rpi-gpio.js @@ -14,145 +14,146 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var util = require("util"); -var exec = require('child_process').exec; -var fs = require('fs'); - -if (!fs.existsSync("/dev/ttyAMA0")) { // unlikely if not on a Pi - throw "Info : Ignoring Raspberry Pi specific node."; -} - -if (!fs.existsSync("/usr/local/bin/gpio")) { // gpio command not installed - throw "Info : Can't find Raspberry Pi wiringPi gpio command."; -} - -// Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant) -var pintable = { -// Physical : WiringPi - "11":"0", - "12":"1", - "13":"2", - "15":"3", - "16":"4", - "18":"5", - "22":"6", - "7":"7", - "3":"8", - "5":"9", - "24":"10", - "26":"11", - "19":"12", - "21":"13", - "23":"14", - "8":"15", - "10":"16" -} -var tablepin = { -// WiringPi : Physical - "0":"11", - "1":"12", - "2":"13", - "3":"15", - "4":"16", - "5":"18", - "6":"22", - "7":"7", - "8":"3", - "9":"5", - "10":"24", - "11":"26", - "12":"19", - "13":"21", - "14":"23", - "15":"8", - "16":"10" -} - -function GPIOInNode(n) { - RED.nodes.createNode(this,n); - this.buttonState = -1; - this.pin = pintable[n.pin]; - this.intype = n.intype; - var node = this; - - if (this.pin) { - exec("gpio mode "+node.pin+" "+node.intype, function(err,stdout,stderr) { - if (err) node.error(err); - else { - node._interval = setInterval( function() { - exec("gpio read "+node.pin, function(err,stdout,stderr) { - if (err) node.error(err); - else { - if (node.buttonState !== Number(stdout)) { - var previousState = node.buttonState; - node.buttonState = Number(stdout); - if (previousState !== -1) { - var msg = {topic:"pi/"+tablepin[node.pin], payload:node.buttonState}; - node.send(msg); - } - } - } - }); - }, 250); - } - }); +module.exports = function(RED) { + var util = require("util"); + var exec = require('child_process').exec; + var fs = require('fs'); + + if (!fs.existsSync("/dev/ttyAMA0")) { // unlikely if not on a Pi + throw "Info : Ignoring Raspberry Pi specific node."; } - else { - this.error("Invalid GPIO pin: "+this.pin); + + if (!fs.existsSync("/usr/local/bin/gpio")) { // gpio command not installed + throw "Info : Can't find Raspberry Pi wiringPi gpio command."; } - - this.on("close", function() { - clearInterval(this._interval); - }); -} - -function GPIOOutNode(n) { - RED.nodes.createNode(this,n); - this.pin = pintable[n.pin]; - var node = this; - - if (this.pin) { - process.nextTick(function() { - exec("gpio mode "+node.pin+" out", function(err,stdout,stderr) { + + // Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant) + var pintable = { + // Physical : WiringPi + "11":"0", + "12":"1", + "13":"2", + "15":"3", + "16":"4", + "18":"5", + "22":"6", + "7":"7", + "3":"8", + "5":"9", + "24":"10", + "26":"11", + "19":"12", + "21":"13", + "23":"14", + "8":"15", + "10":"16" + } + var tablepin = { + // WiringPi : Physical + "0":"11", + "1":"12", + "2":"13", + "3":"15", + "4":"16", + "5":"18", + "6":"22", + "7":"7", + "8":"3", + "9":"5", + "10":"24", + "11":"26", + "12":"19", + "13":"21", + "14":"23", + "15":"8", + "16":"10" + } + + function GPIOInNode(n) { + RED.nodes.createNode(this,n); + this.buttonState = -1; + this.pin = pintable[n.pin]; + this.intype = n.intype; + var node = this; + + if (this.pin) { + exec("gpio mode "+node.pin+" "+node.intype, function(err,stdout,stderr) { if (err) node.error(err); else { - node.on("input", function(msg) { - if (msg.payload === "true") msg.payload = true; - if (msg.payload === "false") msg.payload = false; - var out = Number(msg.payload); - if ((out == 0)|(out == 1)) { - exec("gpio write "+node.pin+" "+out, function(err,stdout,stderr) { - if (err) node.error(err); - }); - } - else node.warn("Invalid input - not 0 or 1"); - }); + node._interval = setInterval( function() { + exec("gpio read "+node.pin, function(err,stdout,stderr) { + if (err) node.error(err); + else { + if (node.buttonState !== Number(stdout)) { + var previousState = node.buttonState; + node.buttonState = Number(stdout); + if (previousState !== -1) { + var msg = {topic:"pi/"+tablepin[node.pin], payload:node.buttonState}; + node.send(msg); + } + } + } + }); + }, 250); } }); + } + else { + this.error("Invalid GPIO pin: "+this.pin); + } + + this.on("close", function() { + clearInterval(this._interval); }); } - else { - this.error("Invalid GPIO pin: "+this.pin); + + function GPIOOutNode(n) { + RED.nodes.createNode(this,n); + this.pin = pintable[n.pin]; + var node = this; + + if (this.pin) { + process.nextTick(function() { + exec("gpio mode "+node.pin+" out", function(err,stdout,stderr) { + if (err) node.error(err); + else { + node.on("input", function(msg) { + if (msg.payload === "true") msg.payload = true; + if (msg.payload === "false") msg.payload = false; + var out = Number(msg.payload); + if ((out == 0)|(out == 1)) { + exec("gpio write "+node.pin+" "+out, function(err,stdout,stderr) { + if (err) node.error(err); + }); + } + else node.warn("Invalid input - not 0 or 1"); + }); + } + }); + }); + } + else { + this.error("Invalid GPIO pin: "+this.pin); + } + + this.on("close", function() { + exec("gpio mode "+this.pin+" in"); + }); } - - this.on("close", function() { - exec("gpio mode "+this.pin+" in"); + + exec("gpio mode 0 in",function(err,stdout,stderr) { + if (err) { + util.log('[36-rpi-gpio.js] Error: "gpio" command failed for some reason.'); + } + exec("gpio mode 1 in"); + exec("gpio mode 2 in"); + exec("gpio mode 3 in"); + exec("gpio mode 4 in"); + exec("gpio mode 5 in"); + exec("gpio mode 6 in"); + exec("gpio mode 7 in"); }); + + RED.nodes.registerType("rpi-gpio in",GPIOInNode); + RED.nodes.registerType("rpi-gpio out",GPIOOutNode); } - -exec("gpio mode 0 in",function(err,stdout,stderr) { - if (err) { - util.log('[36-rpi-gpio.js] Error: "gpio" command failed for some reason.'); - } - exec("gpio mode 1 in"); - exec("gpio mode 2 in"); - exec("gpio mode 3 in"); - exec("gpio mode 4 in"); - exec("gpio mode 5 in"); - exec("gpio mode 6 in"); - exec("gpio mode 7 in"); -}); - -RED.nodes.registerType("rpi-gpio in",GPIOInNode); -RED.nodes.registerType("rpi-gpio out",GPIOOutNode); diff --git a/nodes/core/io/10-mqtt.js b/nodes/core/io/10-mqtt.js index 410ca2a0b..fb37d448f 100644 --- a/nodes/core/io/10-mqtt.js +++ b/nodes/core/io/10-mqtt.js @@ -14,122 +14,124 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var connectionPool = require("./lib/mqttConnectionPool"); -var util = require("util"); - -function MQTTBrokerNode(n) { - RED.nodes.createNode(this,n); - this.broker = n.broker; - this.port = n.port; - this.clientid = n.clientid; - var credentials = RED.nodes.getCredentials(n.id); - if (credentials) { - this.username = credentials.user; - this.password = credentials.password; - } -} -RED.nodes.registerType("mqtt-broker",MQTTBrokerNode); - -var querystring = require('querystring'); - -RED.httpAdmin.get('/mqtt-broker/:id',function(req,res) { - var credentials = RED.nodes.getCredentials(req.params.id); - if (credentials) { - res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!="")})); - } else { - res.send(JSON.stringify({})); +module.exports = function(RED) { + + var connectionPool = require("./lib/mqttConnectionPool"); + var util = require("util"); + + function MQTTBrokerNode(n) { + RED.nodes.createNode(this,n); + this.broker = n.broker; + this.port = n.port; + this.clientid = n.clientid; + var credentials = RED.nodes.getCredentials(n.id); + if (credentials) { + this.username = credentials.user; + this.password = credentials.password; + } } -}); - -RED.httpAdmin.delete('/mqtt-broker/:id',function(req,res) { - RED.nodes.deleteCredentials(req.params.id); - res.send(200); -}); - -RED.httpAdmin.post('/mqtt-broker/:id',function(req,res) { - var body = ""; - req.on('data', function(chunk) { - body+=chunk; + RED.nodes.registerType("mqtt-broker",MQTTBrokerNode); + + var querystring = require('querystring'); + + RED.httpAdmin.get('/mqtt-broker/:id',function(req,res) { + var credentials = RED.nodes.getCredentials(req.params.id); + if (credentials) { + res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!="")})); + } else { + res.send(JSON.stringify({})); + } }); - req.on('end', function(){ - var newCreds = querystring.parse(body); - var credentials = RED.nodes.getCredentials(req.params.id)||{}; - if (newCreds.user == null || newCreds.user == "") { - delete credentials.user; - } else { - credentials.user = newCreds.user; - } - if (newCreds.password == "") { - delete credentials.password; - } else { - credentials.password = newCreds.password||credentials.password; - } - RED.nodes.addCredentials(req.params.id,credentials); + + RED.httpAdmin.delete('/mqtt-broker/:id',function(req,res) { + RED.nodes.deleteCredentials(req.params.id); res.send(200); }); -}); - - -function MQTTInNode(n) { - RED.nodes.createNode(this,n); - this.topic = n.topic; - this.broker = n.broker; - this.brokerConfig = RED.nodes.getNode(this.broker); - if (this.brokerConfig) { - this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port,this.brokerConfig.clientid,this.brokerConfig.username,this.brokerConfig.password); - var node = this; - this.client.subscribe(this.topic,2,function(topic,payload,qos,retain) { - var msg = {topic:topic,payload:payload,qos:qos,retain:retain}; - if ((node.brokerConfig.broker == "localhost")||(node.brokerConfig.broker == "127.0.0.1")) { - msg._topic = topic; - } - node.send(msg); + + RED.httpAdmin.post('/mqtt-broker/:id',function(req,res) { + var body = ""; + req.on('data', function(chunk) { + body+=chunk; }); - this.client.connect(); - } else { - this.error("missing broker configuration"); - } -} - -RED.nodes.registerType("mqtt in",MQTTInNode); - -MQTTInNode.prototype.close = function() { - if (this.client) { - this.client.disconnect(); - } -} - - -function MQTTOutNode(n) { - RED.nodes.createNode(this,n); - - this.topic = n.topic; - this.broker = n.broker; - - this.brokerConfig = RED.nodes.getNode(this.broker); - - if (this.brokerConfig) { - this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port,this.brokerConfig.clientid,this.brokerConfig.username,this.brokerConfig.password); - this.on("input",function(msg) { - if (msg != null) { - if (this.topic) { - msg.topic = this.topic; - } - this.client.publish(msg); + req.on('end', function(){ + var newCreds = querystring.parse(body); + var credentials = RED.nodes.getCredentials(req.params.id)||{}; + if (newCreds.user == null || newCreds.user == "") { + delete credentials.user; + } else { + credentials.user = newCreds.user; } + if (newCreds.password == "") { + delete credentials.password; + } else { + credentials.password = newCreds.password||credentials.password; + } + RED.nodes.addCredentials(req.params.id,credentials); + res.send(200); }); - this.client.connect(); - } else { - this.error("missing broker configuration"); - } -} - -RED.nodes.registerType("mqtt out",MQTTOutNode); - -MQTTOutNode.prototype.close = function() { - if (this.client) { - this.client.disconnect(); + }); + + + function MQTTInNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.broker = n.broker; + this.brokerConfig = RED.nodes.getNode(this.broker); + if (this.brokerConfig) { + this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port,this.brokerConfig.clientid,this.brokerConfig.username,this.brokerConfig.password); + var node = this; + this.client.subscribe(this.topic,2,function(topic,payload,qos,retain) { + var msg = {topic:topic,payload:payload,qos:qos,retain:retain}; + if ((node.brokerConfig.broker == "localhost")||(node.brokerConfig.broker == "127.0.0.1")) { + msg._topic = topic; + } + node.send(msg); + }); + this.client.connect(); + } else { + this.error("missing broker configuration"); + } + } + + RED.nodes.registerType("mqtt in",MQTTInNode); + + MQTTInNode.prototype.close = function() { + if (this.client) { + this.client.disconnect(); + } + } + + + function MQTTOutNode(n) { + RED.nodes.createNode(this,n); + + this.topic = n.topic; + this.broker = n.broker; + + this.brokerConfig = RED.nodes.getNode(this.broker); + + if (this.brokerConfig) { + this.client = connectionPool.get(this.brokerConfig.broker,this.brokerConfig.port,this.brokerConfig.clientid,this.brokerConfig.username,this.brokerConfig.password); + this.on("input",function(msg) { + if (msg != null) { + if (this.topic) { + msg.topic = this.topic; + } + this.client.publish(msg); + } + }); + this.client.connect(); + } else { + this.error("missing broker configuration"); + } + } + + RED.nodes.registerType("mqtt out",MQTTOutNode); + + MQTTOutNode.prototype.close = function() { + if (this.client) { + this.client.disconnect(); + } } } diff --git a/nodes/core/io/21-httpin.js b/nodes/core/io/21-httpin.js index d56292adc..39cfcf5e5 100644 --- a/nodes/core/io/21-httpin.js +++ b/nodes/core/io/21-httpin.js @@ -14,232 +14,234 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var util = require("util"); -var http = require("follow-redirects").http; -var https = require("follow-redirects").https; -var urllib = require("url"); -var express = require("express"); -var getBody = require('raw-body'); -var mustache = require("mustache"); -var querystring = require("querystring"); - -var cors = require('cors'); -var jsonParser = express.json(); -var urlencParser = express.urlencoded(); - -function rawBodyParser(req, res, next) { - if (req._body) return next(); - req.body = ""; - req._body = true; - getBody(req, { - limit: '1mb', - length: req.headers['content-length'], - encoding: 'utf8' - }, function (err, buf) { - if (err) return next(err); - req.body = buf; - next(); - }); -} - - -function HTTPIn(n) { - RED.nodes.createNode(this,n); - if (RED.settings.httpNodeRoot !== false) { - - this.url = n.url; - this.method = n.method; - - var node = this; - - this.errorHandler = function(err,req,res,next) { - node.warn(err); - res.send(500); - }; - - this.callback = function(req,res) { - if (node.method == "post") { - node.send({req:req,res:res,payload:req.body}); - } else if (node.method == "get") { - node.send({req:req,res:res,payload:req.query}); - } else { - node.send({req:req,res:res}); - } - } - - var corsHandler = function(req,res,next) { next(); } - - if (RED.settings.httpNodeCors) { - corsHandler = cors(RED.settings.httpNodeCors); - RED.httpNode.options(this.url,corsHandler); - } - - if (this.method == "get") { - RED.httpNode.get(this.url,corsHandler,this.callback,this.errorHandler); - } else if (this.method == "post") { - RED.httpNode.post(this.url,corsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler); - } else if (this.method == "put") { - RED.httpNode.put(this.url,corsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler); - } else if (this.method == "delete") { - RED.httpNode.delete(this.url,corsHandler,this.callback,errorHandler); - } - - this.on("close",function() { - var routes = RED.httpNode.routes[this.method]; - for (var i = 0; i 0)) { - var msg = {topic:node.topic,payload:buffer}; - msg._session = {type:"tcp",id:id}; - node.send(msg); - buffer = null; - } - }); - client.on('close', function() { - delete connectionPool[id]; - node.log("connection lost to "+node.host+":"+node.port); - if (!node.closing) { - reconnectTimeout = setTimeout(setupTcpClient, reconnectTime); - } - }); - client.on('error', function(err) { - node.log(err); - }); - } - setupTcpClient(); - - this.on('close', function() { - this.closing = true; - client.end(); - clearTimeout(reconnectTimeout); - }); - } else { - var server = net.createServer(function (socket) { - if (socketTimeout !== null) { socket.setTimeout(socketTimeout); } - var id = (1+Math.random()*4294967295).toString(16); - connectionPool[id] = socket; - - var buffer = (node.datatype == 'buffer')? new Buffer(0):""; - socket.on('data', function (data) { - if (node.datatype != 'buffer') { - data = data.toString(node.datatype); - } - - if (node.stream) { - if ((typeof data) === "string" && node.newline != "") { - buffer = buffer+data; - var parts = buffer.split(node.newline); - for (var i = 0;i 0)) { - var msg = {topic:node.topic,payload:buffer}; - msg._session = {type:"tcp",id:id}; - node.send(msg); - buffer = null; - } - }); - socket.on('timeout', function() { - node.log('timeout closed socket port '+node.port); - socket.end(); - }); - socket.on('close', function() { - delete connectionPool[id]; - }); - socket.on('error',function(err) { - node.log(err); - }); - }); - server.on('error', function(err) { - if (err) { - node.error('unable to listen on port '+node.port+' : '+err); - } - }); - server.listen(node.port, function(err) { - if (err) { - node.error('unable to listen on port '+node.port+' : '+err); - } else { - node.log('listening on port '+node.port); +module.exports = function(RED) { + var reconnectTime = RED.settings.socketReconnectTime||10000; + var socketTimeout = RED.settings.socketTimeout||null; + var net = require('net'); - node.on('close', function() { - node.closing = true; - server.close(); - node.log('stopped listening on port '+node.port); + var connectionPool = {}; + + function TcpIn(n) { + RED.nodes.createNode(this,n); + this.host = n.host; + this.port = n.port * 1; + this.topic = n.topic; + this.stream = (!n.datamode||n.datamode=='stream'); /* stream,single*/ + this.datatype = n.datatype||'buffer'; /* buffer,utf8,base64 */ + this.newline = (n.newline||"").replace("\\n","\n").replace("\\r","\r"); + this.base64 = n.base64; + this.server = (typeof n.server == 'boolean')?n.server:(n.server == "server"); + this.closing = false; + var node = this; + + if (!node.server) { + var buffer = null; + var client; + var reconnectTimeout; + function setupTcpClient() { + node.log("connecting to "+node.host+":"+node.port); + var id = (1+Math.random()*4294967295).toString(16); + client = net.connect(node.port, node.host, function() { + buffer = (node.datatype == 'buffer')? new Buffer(0):""; + node.log("connected to "+node.host+":"+node.port); + }); + connectionPool[id] = client; + + client.on('data', function (data) { + if (node.datatype != 'buffer') { + data = data.toString(node.datatype); + } + if (node.stream) { + if ((node.datatype) === "utf8" && node.newline != "") { + buffer = buffer+data; + var parts = buffer.split(node.newline); + for (var i = 0;i 0)) { + var msg = {topic:node.topic,payload:buffer}; + msg._session = {type:"tcp",id:id}; + node.send(msg); + buffer = null; + } + }); + client.on('close', function() { + delete connectionPool[id]; + node.log("connection lost to "+node.host+":"+node.port); + if (!node.closing) { + reconnectTimeout = setTimeout(setupTcpClient, reconnectTime); + } + }); + client.on('error', function(err) { + node.log(err); }); } - }); - } - -} -RED.nodes.registerType("tcp in",TcpIn); - -function TcpOut(n) { - RED.nodes.createNode(this,n); - this.host = n.host; - this.port = n.port * 1; - this.base64 = n.base64; - this.beserver = n.beserver; - this.name = n.name; - this.closing = false; - var node = this; - - if (!node.beserver||node.beserver=="client") { - var reconnectTimeout; - var client = null; - var connected = false; - - function setupTcpClient() { - node.log("connecting to "+node.host+":"+node.port); - client = net.connect(node.port, node.host, function() { - connected = true; - node.log("connected to "+node.host+":"+node.port); + setupTcpClient(); + + this.on('close', function() { + this.closing = true; + client.end(); + clearTimeout(reconnectTimeout); }); - client.on('error', function (err) { - node.log('error : '+err); + } else { + var server = net.createServer(function (socket) { + if (socketTimeout !== null) { socket.setTimeout(socketTimeout); } + var id = (1+Math.random()*4294967295).toString(16); + connectionPool[id] = socket; + + var buffer = (node.datatype == 'buffer')? new Buffer(0):""; + socket.on('data', function (data) { + if (node.datatype != 'buffer') { + data = data.toString(node.datatype); + } + + if (node.stream) { + if ((typeof data) === "string" && node.newline != "") { + buffer = buffer+data; + var parts = buffer.split(node.newline); + for (var i = 0;i 0)) { + var msg = {topic:node.topic,payload:buffer}; + msg._session = {type:"tcp",id:id}; + node.send(msg); + buffer = null; + } + }); + socket.on('timeout', function() { + node.log('timeout closed socket port '+node.port); + socket.end(); + }); + socket.on('close', function() { + delete connectionPool[id]; + }); + socket.on('error',function(err) { + node.log(err); + }); }); - client.on('end', function (err) { + server.on('error', function(err) { + if (err) { + node.error('unable to listen on port '+node.port+' : '+err); + } }); - client.on('close', function() { - node.log("connection lost to "+node.host+":"+node.port); - connected = false; - client.destroy(); - if (!node.closing) { - reconnectTimeout = setTimeout(setupTcpClient,reconnectTime); + server.listen(node.port, function(err) { + if (err) { + node.error('unable to listen on port '+node.port+' : '+err); + } else { + node.log('listening on port '+node.port); + + node.on('close', function() { + node.closing = true; + server.close(); + node.log('stopped listening on port '+node.port); + }); } }); } - setupTcpClient(); - - node.on("input", function(msg) { - if (connected && msg.payload != null) { - if (Buffer.isBuffer(msg.payload)) { - client.write(msg.payload); - } else if (typeof msg.payload === "string" && node.base64) { - client.write(new Buffer(msg.payload,'base64')); - } else { - client.write(new Buffer(""+msg.payload)); - } + + } + RED.nodes.registerType("tcp in",TcpIn); + + function TcpOut(n) { + RED.nodes.createNode(this,n); + this.host = n.host; + this.port = n.port * 1; + this.base64 = n.base64; + this.beserver = n.beserver; + this.name = n.name; + this.closing = false; + var node = this; + + if (!node.beserver||node.beserver=="client") { + var reconnectTimeout; + var client = null; + var connected = false; + + function setupTcpClient() { + node.log("connecting to "+node.host+":"+node.port); + client = net.connect(node.port, node.host, function() { + connected = true; + node.log("connected to "+node.host+":"+node.port); + }); + client.on('error', function (err) { + node.log('error : '+err); + }); + client.on('end', function (err) { + }); + client.on('close', function() { + node.log("connection lost to "+node.host+":"+node.port); + connected = false; + client.destroy(); + if (!node.closing) { + reconnectTimeout = setTimeout(setupTcpClient,reconnectTime); + } + }); } - }); - - node.on("close", function() { - this.closing = true; - client.end(); - clearTimeout(reconnectTimeout); - }); - - } else if (node.beserver == "reply") { - node.on("input",function(msg) { - if (msg._session && msg._session.type == "tcp") { - var client = connectionPool[msg._session.id]; - if (client) { + setupTcpClient(); + + node.on("input", function(msg) { + if (connected && msg.payload != null) { if (Buffer.isBuffer(msg.payload)) { client.write(msg.payload); } else if (typeof msg.payload === "string" && node.base64) { @@ -245,62 +224,84 @@ function TcpOut(n) { client.write(new Buffer(""+msg.payload)); } } - } - }); - } else { - var connectedSockets = []; - var server = net.createServer(function (socket) { - if (socketTimeout !== null) { socket.setTimeout(socketTimeout); } - var remoteDetails = socket.remoteAddress+":"+socket.remotePort; - node.log("connection from "+remoteDetails); - connectedSockets.push(socket); - socket.on('timeout', function() { - node.log('timeout closed socket port '+node.port); - socket.end(); }); - socket.on('close',function() { - node.log("connection closed from "+remoteDetails); - connectedSockets.splice(connectedSockets.indexOf(socket),1); + + node.on("close", function() { + this.closing = true; + client.end(); + clearTimeout(reconnectTimeout); }); - socket.on('error',function() { - node.log("socket error from "+remoteDetails); - connectedSockets.splice(connectedSockets.indexOf(socket),1); - }); - }); - node.on("input", function(msg) { - if (msg.payload != null) { - var buffer; - if (Buffer.isBuffer(msg.payload)) { - buffer = msg.payload; - } else if (typeof msg.payload === "string" && node.base64) { - buffer = new Buffer(msg.payload,'base64'); - } else { - buffer = new Buffer(""+msg.payload); + + } else if (node.beserver == "reply") { + node.on("input",function(msg) { + if (msg._session && msg._session.type == "tcp") { + var client = connectionPool[msg._session.id]; + if (client) { + if (Buffer.isBuffer(msg.payload)) { + client.write(msg.payload); + } else if (typeof msg.payload === "string" && node.base64) { + client.write(new Buffer(msg.payload,'base64')); + } else { + client.write(new Buffer(""+msg.payload)); + } + } } - for (var i = 0; i '+node.addr+":"+node.port); + server.setMulticastTTL(128); + server.addMembership(node.group,node.iface); + node.log("udp multicast group "+node.group); } catch (e) { - if (e.errno == "EINVAL") { + if (e.errno == "EINVAL") { node.error("Bad Multicast Address"); } else if (e.errno == "ENODEV") { node.error("Must be ip address of the required interface"); @@ -117,52 +68,102 @@ function UDPout(n) { node.error("Error :"+e.errno); } } - } else { - node.log('udp broadcast ready : '+node.outport+' -> '+node.addr+":"+node.port); } }); - } else if (node.outport != "") { - sock.bind(node.outport); - node.log('udp ready : '+node.outport+' -> '+node.addr+":"+node.port); - } else { - node.log('udp ready : '+node.addr+":"+node.port); - } - - node.on("input", function(msg) { - if (msg.payload != null) { - var add = node.addr || msg.ip || ""; - var por = node.port || msg.port || 0; - if (add == "") { - node.warn("udp: ip address not set"); - } else if (por == 0) { - node.warn("udp: port not set"); - } else if (isNaN(por) || (por < 1) || (por > 65535)) { - node.warn("udp: port number not valid"); - } else { - var message; - if (node.base64) { - message = new Buffer(b64string, 'base64'); - } else if (msg.payload instanceof Buffer) { - message = msg.payload; - } else { - message = new Buffer(""+msg.payload); - } - sock.send(message, 0, message.length, por, add, function(err, bytes) { - if (err) { - node.error("udp : "+err); - } - }); + + node.on("close", function() { + try { + server.close(); + node.log('udp listener stopped'); + } catch (err) { + node.error(err); } + }); + + server.bind(node.port,node.iface); + } + RED.nodes.registerType("udp in",UDPin); + + + // The Output Node + function UDPout(n) { + RED.nodes.createNode(this,n); + //this.group = n.group; + this.port = n.port; + this.outport = n.outport||""; + this.base64 = n.base64; + this.addr = n.addr; + this.iface = n.iface || null; + this.multicast = n.multicast; + var node = this; + + var sock = dgram.createSocket('udp4'); // only use ipv4 for now + + if (node.multicast != "false") { + if (node.outport == "") { node.outport = node.port; } + sock.bind(node.outport, function() { // have to bind before you can enable broadcast... + sock.setBroadcast(true); // turn on broadcast + if (node.multicast == "multi") { + try { + sock.setMulticastTTL(128); + sock.addMembership(node.addr,node.iface); // Add to the multicast group + node.log('udp multicast ready : '+node.outport+' -> '+node.addr+":"+node.port); + } catch (e) { + if (e.errno == "EINVAL") { + node.error("Bad Multicast Address"); + } else if (e.errno == "ENODEV") { + node.error("Must be ip address of the required interface"); + } else { + node.error("Error :"+e.errno); + } + } + } else { + node.log('udp broadcast ready : '+node.outport+' -> '+node.addr+":"+node.port); + } + }); + } else if (node.outport != "") { + sock.bind(node.outport); + node.log('udp ready : '+node.outport+' -> '+node.addr+":"+node.port); + } else { + node.log('udp ready : '+node.addr+":"+node.port); } - }); - - node.on("close", function() { - try { - sock.close(); - node.log('udp output stopped'); - } catch (err) { - node.error(err); - } - }); + + node.on("input", function(msg) { + if (msg.payload != null) { + var add = node.addr || msg.ip || ""; + var por = node.port || msg.port || 0; + if (add == "") { + node.warn("udp: ip address not set"); + } else if (por == 0) { + node.warn("udp: port not set"); + } else if (isNaN(por) || (por < 1) || (por > 65535)) { + node.warn("udp: port number not valid"); + } else { + var message; + if (node.base64) { + message = new Buffer(b64string, 'base64'); + } else if (msg.payload instanceof Buffer) { + message = msg.payload; + } else { + message = new Buffer(""+msg.payload); + } + sock.send(message, 0, message.length, por, add, function(err, bytes) { + if (err) { + node.error("udp : "+err); + } + }); + } + } + }); + + node.on("close", function() { + try { + sock.close(); + node.log('udp output stopped'); + } catch (err) { + node.error(err); + } + }); + } + RED.nodes.registerType("udp out",UDPout); } -RED.nodes.registerType("udp out",UDPout); diff --git a/nodes/core/logic/10-switch.js b/nodes/core/logic/10-switch.js index e054d2464..e607281de 100644 --- a/nodes/core/logic/10-switch.js +++ b/nodes/core/logic/10-switch.js @@ -14,60 +14,60 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME + "/red/red"); - -var operators = { - 'eq': function(a, b) { return a == b; }, - 'neq': function(a, b) { return a != b; }, - 'lt': function(a, b) { return a < b; }, - 'lte': function(a, b) { return a <= b; }, - 'gt': function(a, b) { return a > b; }, - 'gte': function(a, b) { return a >= b; }, - 'btwn': function(a, b, c) { return a >= b && a <= c; }, - 'cont': function(a, b) { return (a + "").indexOf(b) != -1; }, - 'regex': function(a, b) { return (a + "").match(new RegExp(b)); }, - 'true': function(a) { return a === true; }, - 'false': function(a) { return a === false; }, - 'null': function(a) { return typeof a == "undefined"; }, - 'nnull': function(a) { return typeof a != "undefined"; }, - 'else': function(a) { return a === true; } -}; - -function SwitchNode(n) { - RED.nodes.createNode(this, n); - this.rules = n.rules; - this.property = n.property; - this.checkall = n.checkall || "true"; - var propertyParts = n.property.split("."), - node = this; - - for (var i=0; i b; }, + 'gte': function(a, b) { return a >= b; }, + 'btwn': function(a, b, c) { return a >= b && a <= c; }, + 'cont': function(a, b) { return (a + "").indexOf(b) != -1; }, + 'regex': function(a, b) { return (a + "").match(new RegExp(b)); }, + 'true': function(a) { return a === true; }, + 'false': function(a) { return a === false; }, + 'null': function(a) { return typeof a == "undefined"; }, + 'nnull': function(a) { return typeof a != "undefined"; }, + 'else': function(a) { return a === true; } + }; + + function SwitchNode(n) { + RED.nodes.createNode(this, n); + this.rules = n.rules; + this.property = n.property; + this.checkall = n.checkall || "true"; + var propertyParts = n.property.split("."), + node = this; + + for (var i=0; i node.maxin) { n = node.maxin; } +module.exports = function(RED) { + function RangeNode(n) { + RED.nodes.createNode(this, n); + this.action = n.action; + this.round = n.round || false; + this.minin = Number(n.minin); + this.maxin = Number(n.maxin); + this.minout = Number(n.minout); + this.maxout = Number(n.maxout); + var node = this; + + this.on('input', function (msg) { + var n = Number(msg.payload); + if (!isNaN(n)) { + if (node.action == "clamp") { + if (n < node.minin) { n = node.minin; } + if (n > node.maxin) { n = node.maxin; } + } + if (node.action == "roll") { + if (n >= node.maxin) { n = (n - node.minin) % (node.maxin - node.minin) + node.minin; } + if (n < node.minin) { n = (n - node.minin) % (node.maxin - node.minin) + node.maxin; } + } + msg.payload = ((n - node.minin) / (node.maxin - node.minin) * (node.maxout - node.minout)) + node.minout; + if (node.round) { msg.payload = Math.round(msg.payload); } + node.send(msg); } - if (node.action == "roll") { - if (n >= node.maxin) { n = (n - node.minin) % (node.maxin - node.minin) + node.minin; } - if (n < node.minin) { n = (n - node.minin) % (node.maxin - node.minin) + node.maxin; } - } - msg.payload = ((n - node.minin) / (node.maxin - node.minin) * (node.maxout - node.minout)) + node.minout; - if (node.round) { msg.payload = Math.round(msg.payload); } - node.send(msg); - } - else { node.log("Not a number: "+msg.payload); } - }); + else { node.log("Not a number: "+msg.payload); } + }); + } + RED.nodes.registerType("range", RangeNode); } -RED.nodes.registerType("range", RangeNode); diff --git a/nodes/core/parsers/70-CSV.js b/nodes/core/parsers/70-CSV.js index afe83900f..83b47b223 100644 --- a/nodes/core/parsers/70-CSV.js +++ b/nodes/core/parsers/70-CSV.js @@ -14,65 +14,65 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); - -function CSVNode(n) { - RED.nodes.createNode(this,n); - this.template = n.temp.split(","); - this.sep = n.sep || ','; - this.sep = this.sep.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t"); - this.quo = '"'; - var node = this; - this.on("input", function(msg) { - if (msg.hasOwnProperty("payload")) { - if (typeof msg.payload == "object") { // convert to csv - try { - var o = ""; - for (var i in node.template) { - if (msg.payload.hasOwnProperty(node.template[i])) { - if (msg.payload[node.template[i]].indexOf(node.sep) != -1) { - o += node.quo + msg.payload[node.template[i]] + node.quo + node.sep; +module.exports = function(RED) { + function CSVNode(n) { + RED.nodes.createNode(this,n); + this.template = n.temp.split(","); + this.sep = n.sep || ','; + this.sep = this.sep.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t"); + this.quo = '"'; + var node = this; + this.on("input", function(msg) { + if (msg.hasOwnProperty("payload")) { + if (typeof msg.payload == "object") { // convert to csv + try { + var o = ""; + for (var i in node.template) { + if (msg.payload.hasOwnProperty(node.template[i])) { + if (msg.payload[node.template[i]].indexOf(node.sep) != -1) { + o += node.quo + msg.payload[node.template[i]] + node.quo + node.sep; + } + else if (msg.payload[node.template[i]].indexOf(node.quo) != -1) { + msg.payload[node.template[i]] = msg.payload[node.template[i]].replace(/"/g, '""'); + o += node.quo + msg.payload[node.template[i]] + node.quo + node.sep; + } + else { o += msg.payload[node.template[i]] + node.sep; } } - else if (msg.payload[node.template[i]].indexOf(node.quo) != -1) { - msg.payload[node.template[i]] = msg.payload[node.template[i]].replace(/"/g, '""'); - o += node.quo + msg.payload[node.template[i]] + node.quo + node.sep; + } + msg.payload = o.slice(0,-1); + node.send(msg); + } + catch(e) { node.log(e); } + } + else if (typeof msg.payload == "string") { // convert to object + try { + var f = true; + var j = 0; + var k = [""]; + var o = {}; + for (var i = 0; i < msg.payload.length; i++) { + if (msg.payload[i] === node.quo) { + f = !f; + if (msg.payload[i-1] === node.quo) { k[j] += '\"'; } + } + else if ((msg.payload[i] === node.sep) && f) { + if ( node.template[j] && (node.template[j] != "") ) { o[node.template[j]] = k[j]; } + j += 1; + k[j] = ""; + } + else { + k[j] += msg.payload[i]; } - else { o += msg.payload[node.template[i]] + node.sep; } } + if ( node.template[j] && (node.template[j] != "") ) { o[node.template[j]] = k[j]; } + msg.payload = o; + node.send(msg); } - msg.payload = o.slice(0,-1); - node.send(msg); + catch(e) { node.log(e); } } - catch(e) { node.log(e); } + else { node.log("This node only handles csv strings or js objects."); } } - else if (typeof msg.payload == "string") { // convert to object - try { - var f = true; - var j = 0; - var k = [""]; - var o = {}; - for (var i = 0; i < msg.payload.length; i++) { - if (msg.payload[i] === node.quo) { - f = !f; - if (msg.payload[i-1] === node.quo) { k[j] += '\"'; } - } - else if ((msg.payload[i] === node.sep) && f) { - if ( node.template[j] && (node.template[j] != "") ) { o[node.template[j]] = k[j]; } - j += 1; - k[j] = ""; - } - else { - k[j] += msg.payload[i]; - } - } - if ( node.template[j] && (node.template[j] != "") ) { o[node.template[j]] = k[j]; } - msg.payload = o; - node.send(msg); - } - catch(e) { node.log(e); } - } - else { node.log("This node only handles csv strings or js objects."); } - } - }); + }); + } + RED.nodes.registerType("csv",CSVNode); } -RED.nodes.registerType("csv",CSVNode); diff --git a/nodes/core/parsers/70-JSON.js b/nodes/core/parsers/70-JSON.js index b807cc2f1..67b4e6e21 100644 --- a/nodes/core/parsers/70-JSON.js +++ b/nodes/core/parsers/70-JSON.js @@ -14,31 +14,32 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var util = require("util"); - -function JSONNode(n) { - RED.nodes.createNode(this,n); - var node = this; - this.on("input", function(msg) { - if (msg.hasOwnProperty("payload")) { - if (typeof msg.payload === "string") { - try { - msg.payload = JSON.parse(msg.payload); - node.send(msg); - } - catch(e) { node.log(e+ "\n"+msg.payload); } - } - else if (typeof msg.payload === "object") { - if (!Buffer.isBuffer(msg.payload) ) { - if (!util.isArray(msg.payload)) { - msg.payload = JSON.stringify(msg.payload); +module.exports = function(RED) { + var util = require("util"); + + function JSONNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.on("input", function(msg) { + if (msg.hasOwnProperty("payload")) { + if (typeof msg.payload === "string") { + try { + msg.payload = JSON.parse(msg.payload); node.send(msg); } + catch(e) { node.log(e+ "\n"+msg.payload); } } + else if (typeof msg.payload === "object") { + if (!Buffer.isBuffer(msg.payload) ) { + if (!util.isArray(msg.payload)) { + msg.payload = JSON.stringify(msg.payload); + node.send(msg); + } + } + } + else { node.log("dropped: "+msg.payload); } } - else { node.log("dropped: "+msg.payload); } - } - }); + }); + } + RED.nodes.registerType("json",JSONNode); } -RED.nodes.registerType("json",JSONNode); diff --git a/nodes/core/parsers/70-XML.js b/nodes/core/parsers/70-XML.js index 52a2e1158..e93398260 100644 --- a/nodes/core/parsers/70-XML.js +++ b/nodes/core/parsers/70-XML.js @@ -14,37 +14,38 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var xml2js = require('xml2js'); -var parseString = xml2js.parseString; -var builder = new xml2js.Builder({renderOpts:{pretty:false}}); - -function XMLNode(n) { - RED.nodes.createNode(this,n); - var node = this; - this.on("input", function(msg) { - if (msg.hasOwnProperty("payload")) { - if (typeof msg.payload == "object") { - try { - msg.payload = builder.buildObject(msg.payload); - node.send(msg); +module.exports = function(RED) { + var xml2js = require('xml2js'); + var parseString = xml2js.parseString; + var builder = new xml2js.Builder({renderOpts:{pretty:false}}); + + function XMLNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.on("input", function(msg) { + if (msg.hasOwnProperty("payload")) { + if (typeof msg.payload == "object") { + try { + msg.payload = builder.buildObject(msg.payload); + node.send(msg); + } + catch(e) { node.log(e); } } - catch(e) { node.log(e); } - } - else if (typeof msg.payload == "string") { - try { - parseString(msg.payload, {strict:true,async:true}, function (err, result) { - if (err) { node.error(err); } - else { - msg.payload = result; - node.send(msg); - } - }); + else if (typeof msg.payload == "string") { + try { + parseString(msg.payload, {strict:true,async:true}, function (err, result) { + if (err) { node.error(err); } + else { + msg.payload = result; + node.send(msg); + } + }); + } + catch(e) { node.log(e); } } - catch(e) { node.log(e); } + else { node.log("This node only handles xml strings or js objects."); } } - else { node.log("This node only handles xml strings or js objects."); } - } - }); + }); + } + RED.nodes.registerType("xml",XMLNode); } -RED.nodes.registerType("xml",XMLNode); diff --git a/nodes/core/social/27-twitter.js b/nodes/core/social/27-twitter.js index fc377205c..fe3a60a4a 100644 --- a/nodes/core/social/27-twitter.js +++ b/nodes/core/social/27-twitter.js @@ -14,82 +14,122 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var ntwitter = require('twitter-ng'); -var OAuth= require('oauth').OAuth; - -function TwitterNode(n) { - RED.nodes.createNode(this,n); - this.screen_name = n.screen_name; -} -RED.nodes.registerType("twitter-credentials",TwitterNode); - -function TwitterInNode(n) { - RED.nodes.createNode(this,n); - this.active = true; - this.user = n.user; - //this.tags = n.tags.replace(/ /g,''); - this.tags = n.tags; - this.twitter = n.twitter; - this.topic = n.topic||"tweets"; - this.twitterConfig = RED.nodes.getNode(this.twitter); - var credentials = RED.nodes.getCredentials(this.twitter); - - if (credentials && credentials.screen_name == this.twitterConfig.screen_name) { - var twit = new ntwitter({ - consumer_key: "OKjYEd1ef2bfFolV25G5nQ", - consumer_secret: "meRsltCktVMUI8gmggpXett7WBLd1k0qidYazoML6g", - access_token_key: credentials.access_token, - access_token_secret: credentials.access_token_secret - }); - - - //setInterval(function() { - // twit.get("/application/rate_limit_status.json",null,function(err,cb) { - // console.log("direct_messages:",cb["resources"]["direct_messages"]); - // }); - // - //},10000); - - var node = this; - if (this.user === "user") { - node.poll_ids = []; - node.since_ids = {}; - var users = node.tags.split(","); - for (var i=0;i=0;t-=1) { + var tweet = cb[t]; + var where = tweet.user.location||""; + var la = tweet.lang || tweet.user.lang; + //console.log(tweet.user.location,"=>",tweet.user.screen_name,"=>",pay); + var msg = { topic:node.topic+"/"+tweet.user.screen_name, payload:tweet.text, location:where, lang:la, tweet:tweet }; + node.send(msg); + if (t == 0) { + node.since_ids[u] = tweet.id_str; + } + } + } + if (err) { + node.error(err); + } + }); + },60000)); + } + }()); + } + } else if (this.user === "dm") { + node.poll_ids = []; + twit.getDirectMessages({ + screen_name:node.twitterConfig.screen_name, trim_user:0, count:1 - },function() { - var u = user+""; - return function(err,cb) { - if (err) { - node.error(err); - return; - } - if (cb[0]) { - node.since_ids[u] = cb[0].id_str; - } else { - node.since_ids[u] = '0'; - } - node.poll_ids.push(setInterval(function() { - twit.getUserTimeline({ - screen_name:u, + },function(err,cb) { + if (err) { + node.error(err); + return; + } + if (cb[0]) { + node.since_id = cb[0].id_str; + } else { + node.since_id = '0'; + } + node.poll_ids.push(setInterval(function() { + twit.getDirectMessages({ + screen_name:node.twitterConfig.screen_name, trim_user:0, - since_id:node.since_ids[u] + since_id:node.since_id },function(err,cb) { if (cb) { for (var t=cb.length-1;t>=0;t-=1) { var tweet = cb[t]; - var where = tweet.user.location||""; - var la = tweet.lang || tweet.user.lang; - //console.log(tweet.user.location,"=>",tweet.user.screen_name,"=>",pay); - var msg = { topic:node.topic+"/"+tweet.user.screen_name, payload:tweet.text, location:where, lang:la, tweet:tweet }; + var msg = { topic:node.topic+"/"+tweet.sender.screen_name, payload:tweet.text, tweet:tweet }; node.send(msg); if (t == 0) { - node.since_ids[u] = tweet.id_str; + node.since_id = tweet.id_str; } } } @@ -97,226 +137,187 @@ function TwitterInNode(n) { node.error(err); } }); - },60000)); + },120000)); + }); + + } else if (this.tags !== "") { + try { + var thing = 'statuses/filter'; + if (this.user === "true") { thing = 'user'; } + var st = { track: [node.tags] }; + var bits = node.tags.split(","); + if ((bits.length > 0) && (bits.length % 4 == 0)) { + if ((Number(bits[0]) < Number(bits[2])) && (Number(bits[1]) < Number(bits[3]))) { + st = { locations: node.tags }; + } + else { + node.warn("twitter: possible bad geo area format. Should be lower-left lon,lat, upper-right lon,lat"); + } } - }()); - } - } else if (this.user === "dm") { - node.poll_ids = []; - twit.getDirectMessages({ - screen_name:node.twitterConfig.screen_name, - trim_user:0, - count:1 - },function(err,cb) { - if (err) { - node.error(err); - return; - } - if (cb[0]) { - node.since_id = cb[0].id_str; - } else { - node.since_id = '0'; - } - node.poll_ids.push(setInterval(function() { - twit.getDirectMessages({ - screen_name:node.twitterConfig.screen_name, - trim_user:0, - since_id:node.since_id - },function(err,cb) { - if (cb) { - for (var t=cb.length-1;t>=0;t-=1) { - var tweet = cb[t]; - var msg = { topic:node.topic+"/"+tweet.sender.screen_name, payload:tweet.text, tweet:tweet }; - node.send(msg); - if (t == 0) { - node.since_id = tweet.id_str; + + function setupStream() { + if (node.active) { + twit.stream(thing, st, function(stream) { + //console.log(st); + //twit.stream('user', { track: [node.tags] }, function(stream) { + //twit.stream('site', { track: [node.tags] }, function(stream) { + //twit.stream('statuses/filter', { track: [node.tags] }, function(stream) { + node.stream = stream; + stream.on('data', function(tweet) { + //console.log(tweet.user); + if (tweet.user !== undefined) { + var where = tweet.user.location||""; + var la = tweet.lang || tweet.user.lang; + //console.log(tweet.user.location,"=>",tweet.user.screen_name,"=>",pay); + var msg = { topic:node.topic+"/"+tweet.user.screen_name, payload:tweet.text, location:where, lang:la, tweet:tweet }; + node.send(msg); } - } - } - if (err) { - node.error(err); - } - }); - },120000)); - }); - - } else if (this.tags !== "") { - try { - var thing = 'statuses/filter'; - if (this.user === "true") { thing = 'user'; } - var st = { track: [node.tags] }; - var bits = node.tags.split(","); - if ((bits.length > 0) && (bits.length % 4 == 0)) { - if ((Number(bits[0]) < Number(bits[2])) && (Number(bits[1]) < Number(bits[3]))) { - st = { locations: node.tags }; - } - else { - node.warn("twitter: possible bad geo area format. Should be lower-left lon,lat, upper-right lon,lat"); - } - } - - function setupStream() { - if (node.active) { - twit.stream(thing, st, function(stream) { - //console.log(st); - //twit.stream('user', { track: [node.tags] }, function(stream) { - //twit.stream('site', { track: [node.tags] }, function(stream) { - //twit.stream('statuses/filter', { track: [node.tags] }, function(stream) { - node.stream = stream; - stream.on('data', function(tweet) { - //console.log(tweet.user); - if (tweet.user !== undefined) { - var where = tweet.user.location||""; - var la = tweet.lang || tweet.user.lang; - //console.log(tweet.user.location,"=>",tweet.user.screen_name,"=>",pay); - var msg = { topic:node.topic+"/"+tweet.user.screen_name, payload:tweet.text, location:where, lang:la, tweet:tweet }; - node.send(msg); - } - }); - stream.on('limit', function(tweet) { - node.log("tweet rate limit hit"); - }); - stream.on('error', function(tweet,rc) { - node.warn(tweet); - setTimeout(setupStream,10000); - }); - stream.on('destroy', function (response) { - if (this.active) { - node.warn("twitter ended unexpectedly"); + }); + stream.on('limit', function(tweet) { + node.log("tweet rate limit hit"); + }); + stream.on('error', function(tweet,rc) { + node.warn(tweet); setTimeout(setupStream,10000); - } + }); + stream.on('destroy', function (response) { + if (this.active) { + node.warn("twitter ended unexpectedly"); + setTimeout(setupStream,10000); + } + }); }); - }); + } } + setupStream(); } - setupStream(); - } - catch (err) { - node.error(err); + catch (err) { + node.error(err); + } + } else { + this.error("Invalid tag property"); } } else { - this.error("Invalid tag property"); + this.error("missing twitter credentials"); } - } else { - this.error("missing twitter credentials"); - } - - this.on('close', function() { - if (this.stream) { - this.active = false; - this.stream.destroy(); - } - if (this.poll_ids) { - for (var i=0;i 140) { - msg.payload = msg.payload.slice(0,139); - node.warn("Tweet greater than 140 : truncated"); - } - twit.updateStatus(msg.payload, function (err, data) { - if (err) node.error(err); - }); - } - }); + if (this.poll_ids) { + for (var i=0;i 140) { + msg.payload = msg.payload.slice(0,139); + node.warn("Tweet greater than 140 : truncated"); + } + twit.updateStatus(msg.payload, function (err, data) { + if (err) node.error(err); + }); + } + }); + } + }); + } } -}); - -RED.httpAdmin.delete('/twitter/:id', function(req,res) { - RED.nodes.deleteCredentials(req.params.id); - res.send(200); -}); - -RED.httpAdmin.get('/twitter/:id/auth', function(req, res){ + RED.nodes.registerType("twitter out",TwitterOutNode); + + var oa = new OAuth( + "https://api.twitter.com/oauth/request_token", + "https://api.twitter.com/oauth/access_token", + "OKjYEd1ef2bfFolV25G5nQ", + "meRsltCktVMUI8gmggpXett7WBLd1k0qidYazoML6g", + "1.0", + null, + "HMAC-SHA1" + ); + var credentials = {}; - oa.getOAuthRequestToken({ - oauth_callback: req.query.callback - },function(error, oauth_token, oauth_token_secret, results){ - if (error) { - var resp = '

Oh no!

'+ - '

Something went wrong with the authentication process. The following error was returned:

'+ - '

'+error.statusCode+': '+error.data+'

'+ - '

One known cause of this type of failure is if the clock is wrong on system running Node-RED.'; - res.send(resp) + + RED.httpAdmin.get('/twitter/:id', function(req,res) { + var credentials = RED.nodes.getCredentials(req.params.id); + if (credentials) { + res.send(JSON.stringify({sn:credentials.screen_name})); } else { - credentials.oauth_token = oauth_token; - credentials.oauth_token_secret = oauth_token_secret; - res.redirect('https://twitter.com/oauth/authorize?oauth_token='+oauth_token) - RED.nodes.addCredentials(req.params.id,credentials); + res.send(JSON.stringify({})); } }); -}); - -RED.httpAdmin.get('/twitter/:id/auth/callback', function(req, res, next){ - var credentials = RED.nodes.getCredentials(req.params.id); - credentials.oauth_verifier = req.query.oauth_verifier; - - oa.getOAuthAccessToken( - credentials.oauth_token, - credentials.token_secret, - credentials.oauth_verifier, - function(error, oauth_access_token, oauth_access_token_secret, results){ - if (error){ - console.log(error); - res.send("yeah something broke."); + + RED.httpAdmin.delete('/twitter/:id', function(req,res) { + RED.nodes.deleteCredentials(req.params.id); + res.send(200); + }); + + RED.httpAdmin.get('/twitter/:id/auth', function(req, res){ + var credentials = {}; + oa.getOAuthRequestToken({ + oauth_callback: req.query.callback + },function(error, oauth_token, oauth_token_secret, results){ + if (error) { + var resp = '

Oh no!

'+ + '

Something went wrong with the authentication process. The following error was returned:

'+ + '

'+error.statusCode+': '+error.data+'

'+ + '

One known cause of this type of failure is if the clock is wrong on system running Node-RED.'; + res.send(resp) } else { - credentials = {}; - credentials.access_token = oauth_access_token; - credentials.access_token_secret = oauth_access_token_secret; - credentials.screen_name = "@"+results.screen_name; + credentials.oauth_token = oauth_token; + credentials.oauth_token_secret = oauth_token_secret; + res.redirect('https://twitter.com/oauth/authorize?oauth_token='+oauth_token) RED.nodes.addCredentials(req.params.id,credentials); - res.send("Authorised - you can close this window and return to Node-RED"); } - } - ); -}); + }); + }); + + RED.httpAdmin.get('/twitter/:id/auth/callback', function(req, res, next){ + var credentials = RED.nodes.getCredentials(req.params.id); + credentials.oauth_verifier = req.query.oauth_verifier; + + oa.getOAuthAccessToken( + credentials.oauth_token, + credentials.token_secret, + credentials.oauth_verifier, + function(error, oauth_access_token, oauth_access_token_secret, results){ + if (error){ + console.log(error); + res.send("yeah something broke."); + } else { + credentials = {}; + credentials.access_token = oauth_access_token; + credentials.access_token_secret = oauth_access_token_secret; + credentials.screen_name = "@"+results.screen_name; + RED.nodes.addCredentials(req.params.id,credentials); + res.send("Authorised - you can close this window and return to Node-RED"); + } + } + ); + }); +} diff --git a/nodes/core/social/32-feedparse.js b/nodes/core/social/32-feedparse.js index 77ae4a8d2..ad5e4995b 100644 --- a/nodes/core/social/32-feedparse.js +++ b/nodes/core/social/32-feedparse.js @@ -14,58 +14,58 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var FeedParser = require("feedparser"); -var request = require("request"); - -function FeedParseNode(n) { - RED.nodes.createNode(this,n); - this.url = n.url; - this.interval = (parseInt(n.interval)||15)*60000; - var node = this; - this.interval_id = null; - this.seen = {}; - if (this.url !== "") { - var getFeed = function() { - request(node.url,function(err) { - if (err) node.error(err); - }) - .pipe(new FeedParser({feedurl:node.url})) - .on('error', function(error) { - node.error(error); +module.exports = function(RED) { + var FeedParser = require("feedparser"); + var request = require("request"); + + function FeedParseNode(n) { + RED.nodes.createNode(this,n); + this.url = n.url; + this.interval = (parseInt(n.interval)||15)*60000; + var node = this; + this.interval_id = null; + this.seen = {}; + if (this.url !== "") { + var getFeed = function() { + request(node.url,function(err) { + if (err) node.error(err); }) - .on('meta', function (meta) {}) - .on('readable', function () { - var stream = this, article; - while (article = stream.read()) { - if (!(article.guid in node.seen) || ( node.seen[article.guid] != 0 && node.seen[article.guid] != article.date.getTime())) { - node.seen[article.guid] = article.date?article.date.getTime():0; - var msg = { - topic:article.origlink||article.link, - payload: article.description, - article: article - }; - node.send(msg); + .pipe(new FeedParser({feedurl:node.url})) + .on('error', function(error) { + node.error(error); + }) + .on('meta', function (meta) {}) + .on('readable', function () { + var stream = this, article; + while (article = stream.read()) { + if (!(article.guid in node.seen) || ( node.seen[article.guid] != 0 && node.seen[article.guid] != article.date.getTime())) { + node.seen[article.guid] = article.date?article.date.getTime():0; + var msg = { + topic:article.origlink||article.link, + payload: article.description, + article: article + }; + node.send(msg); + } } - } - }) - .on('end', function () { - }); - }; - this.interval_id = setInterval(getFeed,node.interval); - getFeed(); - - } else { - this.error("Invalid url"); - } -} - -RED.nodes.registerType("feedparse",FeedParseNode); - -FeedParseNode.prototype.close = function() { - if (this.interval_id != null) { - clearInterval(this.interval_id); + }) + .on('end', function () { + }); + }; + this.interval_id = setInterval(getFeed,node.interval); + getFeed(); + + } else { + this.error("Invalid url"); + } } -} - + + RED.nodes.registerType("feedparse",FeedParseNode); + + FeedParseNode.prototype.close = function() { + if (this.interval_id != null) { + clearInterval(this.interval_id); + } + } +} diff --git a/nodes/core/social/61-email.js b/nodes/core/social/61-email.js index 4f017e18c..70eeb5106 100644 --- a/nodes/core/social/61-email.js +++ b/nodes/core/social/61-email.js @@ -14,247 +14,248 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var util = require('util'); -var nodemailer = require("nodemailer"); -var Imap = null; -try { - Imap = require('imap'); -} catch (e) { - util.log("[61-email.js] - imap npm not installed - no inbound email available"); -} - -//console.log(nodemailer.Transport.transports.SMTP.wellKnownHosts); - -// module.exports = { service: "Gmail", user: "blahblah@gmail.com", pass: "password", server: "imap.gmail.com", port: "993" } -try { var globalkeys = RED.settings.email || require(process.env.NODE_RED_HOME+"/../emailkeys.js"); } -catch(err) { } - -function EmailNode(n) { - RED.nodes.createNode(this,n); - this.topic = n.topic; - this.name = n.name; - this.outserver = n.server; - this.outport = n.port; - var flag = false; - var credentials = RED.nodes.getCredentials(n.id); - if ((credentials) && (credentials.hasOwnProperty("userid"))) { this.userid = credentials.userid; } - else { - if (globalkeys) { this.userid = globalkeys.user; flag = true; } - else { this.error("No e-mail userid set"); } +module.exports = function(RED) { + var util = require('util'); + var nodemailer = require("nodemailer"); + var Imap = null; + try { + Imap = require('imap'); + } catch (e) { + util.log("[61-email.js] - imap npm not installed - no inbound email available"); } - if ((credentials) && (credentials.hasOwnProperty("password"))) { this.password = credentials.password; } - else { - if (globalkeys) { this.password = globalkeys.pass; flag = true; } - else { this.error("No e-mail password set"); } - } - if (flag) { RED.nodes.addCredentials(n.id,{userid:this.userid, password:this.password, global:true}); } - var node = this; - - var smtpTransport = nodemailer.createTransport("SMTP",{ - //service: emailkey.service, - // { - //transport: 'SMTP', - host: node.outserver, - port: node.outport, - requiresAuth: true, - secureConnection: true, - //domains: [ 'gmail.com', 'googlemail.com' ], - //}, - auth: { - user: node.userid, - pass: node.password + + //console.log(nodemailer.Transport.transports.SMTP.wellKnownHosts); + + // module.exports = { service: "Gmail", user: "blahblah@gmail.com", pass: "password", server: "imap.gmail.com", port: "993" } + try { var globalkeys = RED.settings.email || require(process.env.NODE_RED_HOME+"/../emailkeys.js"); } + catch(err) { } + + function EmailNode(n) { + RED.nodes.createNode(this,n); + this.topic = n.topic; + this.name = n.name; + this.outserver = n.server; + this.outport = n.port; + var flag = false; + var credentials = RED.nodes.getCredentials(n.id); + if ((credentials) && (credentials.hasOwnProperty("userid"))) { this.userid = credentials.userid; } + else { + if (globalkeys) { this.userid = globalkeys.user; flag = true; } + else { this.error("No e-mail userid set"); } } - }); - - this.on("input", function(msg) { - //node.log("email :",this.id,this.topic," received",msg.payload); - if (msg != null) { - if (smtpTransport) { - smtpTransport.sendMail({ - from: node.userid, // sender address - to: node.name, // comma separated list of receivers - subject: msg.topic, // subject line - text: msg.payload // plaintext body - }, function(error, response) { - if (error) { - node.error(error); - } else { - node.log("Message sent: " + response.message); + if ((credentials) && (credentials.hasOwnProperty("password"))) { this.password = credentials.password; } + else { + if (globalkeys) { this.password = globalkeys.pass; flag = true; } + else { this.error("No e-mail password set"); } + } + if (flag) { RED.nodes.addCredentials(n.id,{userid:this.userid, password:this.password, global:true}); } + var node = this; + + var smtpTransport = nodemailer.createTransport("SMTP",{ + //service: emailkey.service, + // { + //transport: 'SMTP', + host: node.outserver, + port: node.outport, + requiresAuth: true, + secureConnection: true, + //domains: [ 'gmail.com', 'googlemail.com' ], + //}, + auth: { + user: node.userid, + pass: node.password + } + }); + + this.on("input", function(msg) { + //node.log("email :",this.id,this.topic," received",msg.payload); + if (msg != null) { + if (smtpTransport) { + smtpTransport.sendMail({ + from: node.userid, // sender address + to: node.name, // comma separated list of receivers + subject: msg.topic, // subject line + text: msg.payload // plaintext body + }, function(error, response) { + if (error) { + node.error(error); + } else { + node.log("Message sent: " + response.message); + } + }); + } + else { node.warn("No Email credentials found. See info panel."); } + } + }); + } + RED.nodes.registerType("e-mail",EmailNode); + + function EmailInNode(n) { + RED.nodes.createNode(this,n); + this.name = n.name; + this.repeat = n.repeat * 1000 || 300000; + this.inserver = n.server || emailkey.server || "imap.gmail.com"; + this.inport = n.port || emailkey.port || "993"; + var flag = false; + var credentials = RED.nodes.getCredentials(n.id); + if ((credentials) && (credentials.hasOwnProperty("userid"))) { this.userid = credentials.userid; } + else { + if (globalkeys) { this.userid = globalkeys.user; flag = true; } + else { this.error("No e-mail userid set"); } + } + if ((credentials) && (credentials.hasOwnProperty("password"))) { this.password = credentials.password; } + else { + if (globalkeys) { this.password = globalkeys.pass; flag = true; } + else { this.error("No e-mail password set"); } + } + if (flag) { RED.nodes.addCredentials(n.id,{userid:this.userid, password:this.password, global:true}); } + var node = this; + this.interval_id = null; + var oldmail = {}; + + var imap = new Imap({ + user: node.userid, + password: node.password, + host: node.inserver, + port: node.inport, + tls: true, + tlsOptions: { rejectUnauthorized: false }, + connTimeout: node.repeat, + authTimeout: node.repeat + }); + + if (!isNaN(this.repeat) && this.repeat > 0) { + node.log("repeat = "+this.repeat); + this.interval_id = setInterval( function() { + node.emit("input",{}); + }, this.repeat ); + } + + this.on("input", function(msg) { + imap.once('ready', function() { + var pay = {}; + imap.openBox('INBOX', true, function(err, box) { + if (box.messages.total > 0) { + var f = imap.seq.fetch(box.messages.total + ':*', { bodies: ['HEADER.FIELDS (FROM SUBJECT DATE)','TEXT'] }); + f.on('message', function(msg, seqno) { + node.log('message: #'+ seqno); + var prefix = '(#' + seqno + ') '; + msg.on('body', function(stream, info) { + var buffer = ''; + stream.on('data', function(chunk) { + buffer += chunk.toString('utf8'); + }); + stream.on('end', function() { + if (info.which !== 'TEXT') { + pay.from = Imap.parseHeader(buffer).from[0]; + pay.topic = Imap.parseHeader(buffer).subject[0]; + pay.date = Imap.parseHeader(buffer).date[0]; + } else { + var parts = buffer.split("Content-Type"); + for (var p in parts) { + if (parts[p].indexOf("text/plain") >= 0) { + pay.payload = parts[p].split("\n").slice(1,-2).join("\n").trim(); + } + if (parts[p].indexOf("text/html") >= 0) { + pay.html = parts[p].split("\n").slice(1,-2).join("\n").trim(); + } + } + //pay.body = buffer; + } + }); + }); + msg.on('end', function() { + //node.log('Finished: '+prefix); + }); + }); + f.on('error', function(err) { + node.warn('fetch error: ' + err); + }); + f.on('end', function() { + if (JSON.stringify(pay) !== oldmail) { + node.send(pay); + oldmail = JSON.stringify(pay); + node.log('received new email: '+pay.topic); + } + else { node.log('duplicate not sent: '+pay.topic); } + imap.end(); + }); + } + else { + node.log("you have achieved inbox zero"); + imap.end(); } }); - } - else { node.warn("No Email credentials found. See info panel."); } - } - }); -} -RED.nodes.registerType("e-mail",EmailNode); - -function EmailInNode(n) { - RED.nodes.createNode(this,n); - this.name = n.name; - this.repeat = n.repeat * 1000 || 300000; - this.inserver = n.server || emailkey.server || "imap.gmail.com"; - this.inport = n.port || emailkey.port || "993"; - var flag = false; - var credentials = RED.nodes.getCredentials(n.id); - if ((credentials) && (credentials.hasOwnProperty("userid"))) { this.userid = credentials.userid; } - else { - if (globalkeys) { this.userid = globalkeys.user; flag = true; } - else { this.error("No e-mail userid set"); } - } - if ((credentials) && (credentials.hasOwnProperty("password"))) { this.password = credentials.password; } - else { - if (globalkeys) { this.password = globalkeys.pass; flag = true; } - else { this.error("No e-mail password set"); } - } - if (flag) { RED.nodes.addCredentials(n.id,{userid:this.userid, password:this.password, global:true}); } - var node = this; - this.interval_id = null; - var oldmail = {}; - - var imap = new Imap({ - user: node.userid, - password: node.password, - host: node.inserver, - port: node.inport, - tls: true, - tlsOptions: { rejectUnauthorized: false }, - connTimeout: node.repeat, - authTimeout: node.repeat - }); - - if (!isNaN(this.repeat) && this.repeat > 0) { - node.log("repeat = "+this.repeat); - this.interval_id = setInterval( function() { - node.emit("input",{}); - }, this.repeat ); - } - - this.on("input", function(msg) { - imap.once('ready', function() { - var pay = {}; - imap.openBox('INBOX', true, function(err, box) { - if (box.messages.total > 0) { - var f = imap.seq.fetch(box.messages.total + ':*', { bodies: ['HEADER.FIELDS (FROM SUBJECT DATE)','TEXT'] }); - f.on('message', function(msg, seqno) { - node.log('message: #'+ seqno); - var prefix = '(#' + seqno + ') '; - msg.on('body', function(stream, info) { - var buffer = ''; - stream.on('data', function(chunk) { - buffer += chunk.toString('utf8'); - }); - stream.on('end', function() { - if (info.which !== 'TEXT') { - pay.from = Imap.parseHeader(buffer).from[0]; - pay.topic = Imap.parseHeader(buffer).subject[0]; - pay.date = Imap.parseHeader(buffer).date[0]; - } else { - var parts = buffer.split("Content-Type"); - for (var p in parts) { - if (parts[p].indexOf("text/plain") >= 0) { - pay.payload = parts[p].split("\n").slice(1,-2).join("\n").trim(); - } - if (parts[p].indexOf("text/html") >= 0) { - pay.html = parts[p].split("\n").slice(1,-2).join("\n").trim(); - } - } - //pay.body = buffer; - } - }); - }); - msg.on('end', function() { - //node.log('Finished: '+prefix); - }); - }); - f.on('error', function(err) { - node.warn('fetch error: ' + err); - }); - f.on('end', function() { - if (JSON.stringify(pay) !== oldmail) { - node.send(pay); - oldmail = JSON.stringify(pay); - node.log('received new email: '+pay.topic); - } - else { node.log('duplicate not sent: '+pay.topic); } - imap.end(); - }); - } - else { - node.log("you have achieved inbox zero"); - imap.end(); - } }); + imap.on('error', function(err) { + node.log(err); + }); + imap.connect(); }); - imap.on('error', function(err) { - node.log(err); + + this.on("error", function(err) { + node.log("error: ",err); }); - imap.connect(); - }); - - this.on("error", function(err) { - node.log("error: ",err); - }); - - this.on("close", function() { - if (this.interval_id != null) { - clearInterval(this.interval_id); - } - if (imap) { imap.destroy(); } - }); - - node.emit("input",{}); -} -if (Imap != null) { -RED.nodes.registerType("e-mail in",EmailInNode); -} - -var querystring = require('querystring'); - -RED.httpAdmin.get('/email/global',function(req,res) { - res.send(JSON.stringify({hasToken:!(globalkeys && globalkeys.userid && globalkeys.password)})); -}); - -RED.httpAdmin.get('/email/:id',function(req,res) { - var credentials = RED.nodes.getCredentials(req.params.id); - if (credentials) { - res.send(JSON.stringify({userid:credentials.userid,hasPassword:(credentials.password&&credentials.password!="")})); + + this.on("close", function() { + if (this.interval_id != null) { + clearInterval(this.interval_id); + } + if (imap) { imap.destroy(); } + }); + + node.emit("input",{}); } - else if (globalkeys && globalkeys.user && globalkeys.pass) { - RED.nodes.addCredentials(req.params.id,{userid:globalkeys.user, password:globalkeys.pass, global:true}); - credentials = RED.nodes.getCredentials(req.params.id); - res.send(JSON.stringify({userid:credentials.userid,global:credentials.global,hasPassword:(credentials.password&&credentials.password!="")})); + if (Imap != null) { + RED.nodes.registerType("e-mail in",EmailInNode); } - else { - res.send(JSON.stringify({})); - } -}); - -RED.httpAdmin.delete('/email/:id',function(req,res) { - RED.nodes.deleteCredentials(req.params.id); - res.send(200); -}); - -RED.httpAdmin.post('/email/:id',function(req,res) { - var body = ""; - req.on('data', function(chunk) { - body+=chunk; + + var querystring = require('querystring'); + + RED.httpAdmin.get('/email/global',function(req,res) { + res.send(JSON.stringify({hasToken:!(globalkeys && globalkeys.userid && globalkeys.password)})); }); - req.on('end', function(){ - var newCreds = querystring.parse(body); - var credentials = RED.nodes.getCredentials(req.params.id)||{}; - if (newCreds.userid == null || newCreds.userid == "") { - delete credentials.userid; - } else { - credentials.userid = newCreds.userid; + + RED.httpAdmin.get('/email/:id',function(req,res) { + var credentials = RED.nodes.getCredentials(req.params.id); + if (credentials) { + res.send(JSON.stringify({userid:credentials.userid,hasPassword:(credentials.password&&credentials.password!="")})); } - if (newCreds.password == "") { - delete credentials.password; - } else { - credentials.password = newCreds.password||credentials.password; + else if (globalkeys && globalkeys.user && globalkeys.pass) { + RED.nodes.addCredentials(req.params.id,{userid:globalkeys.user, password:globalkeys.pass, global:true}); + credentials = RED.nodes.getCredentials(req.params.id); + res.send(JSON.stringify({userid:credentials.userid,global:credentials.global,hasPassword:(credentials.password&&credentials.password!="")})); } - RED.nodes.addCredentials(req.params.id,credentials); + else { + res.send(JSON.stringify({})); + } + }); + + RED.httpAdmin.delete('/email/:id',function(req,res) { + RED.nodes.deleteCredentials(req.params.id); res.send(200); }); -}); + + RED.httpAdmin.post('/email/:id',function(req,res) { + var body = ""; + req.on('data', function(chunk) { + body+=chunk; + }); + req.on('end', function(){ + var newCreds = querystring.parse(body); + var credentials = RED.nodes.getCredentials(req.params.id)||{}; + if (newCreds.userid == null || newCreds.userid == "") { + delete credentials.userid; + } else { + credentials.userid = newCreds.userid; + } + if (newCreds.password == "") { + delete credentials.password; + } else { + credentials.password = newCreds.password||credentials.password; + } + RED.nodes.addCredentials(req.params.id,credentials); + res.send(200); + }); + }); +} diff --git a/nodes/core/social/91-irc.js b/nodes/core/social/91-irc.js index eccacb7d1..708e67dcf 100644 --- a/nodes/core/social/91-irc.js +++ b/nodes/core/social/91-irc.js @@ -14,127 +14,128 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var irc = require("irc"); -var util = require("util"); - -// The Server Definition - this opens (and closes) the connection -function IRCServerNode(n) { - RED.nodes.createNode(this,n); - this.server = n.server; - this.channel = n.channel; - this.nickname = n.nickname; - this.ircclient = null; - this.on("close", function() { - if (this.ircclient != null) { - this.ircclient.disconnect(); - } - }); -} -RED.nodes.registerType("irc-server",IRCServerNode); - - -// The Input Node -function IrcInNode(n) { - RED.nodes.createNode(this,n); - this.ircserver = n.ircserver; - this.serverConfig = RED.nodes.getNode(this.ircserver); - this.channel = n.channel || this.serverConfig.channel; - if (this.serverConfig.ircclient == null) { - this.serverConfig.ircclient = new irc.Client(this.serverConfig.server, this.serverConfig.nickname, { - channels: [this.channel] - }); - this.serverConfig.ircclient.addListener('error', function(message) { - util.log('[irc] '+ JSON.stringify(message)); - }); - } - this.ircclient = this.serverConfig.ircclient; - var node = this; - - this.ircclient.addListener('message', function (from, to, message) { - //util.log(from + ' => ' + to + ': ' + message); - var msg = { "topic":from, "from":from, "to":to, "payload":message }; - node.send([msg,null]); - }); - this.ircclient.addListener('pm', function(from, message) { - var msg = { "topic":from, "from":from, "to":"PRIV", "payload":message }; - node.send([msg,null]); - }); - - this.ircclient.addListener('join', function(channel, who) { - var msg = { "payload": { "type":"join", "who":who, "channel":channel } }; - node.send([null,msg]); - node.log(who+' has joined '+channel); - }); - this.ircclient.addListener('invite', function(channel, from, message) { - var msg = { "payload": { "type":"invite", "who":from, "channel":channel, "message":message } }; - node.send([null,msg]); - node.log(from+' sent invite to '+channel+': '+message); - }); - this.ircclient.addListener('part', function(channel, who, reason) { - var msg = { "payload": { "type":"part", "who":who, "channel":channel, "reason":reason } }; - node.send([null,msg]); - node.log(who+'has left '+channel+': '+reason); - }); - this.ircclient.addListener('quit', function(nick, reason, channels, message) { - var msg = { "payload": { "type":"quit", "who":nick, "channel":channels, "reason":reason } }; - node.send([null,msg]); - node.log(nick+'has quit '+channels+': '+reason); - }); - this.ircclient.addListener('kick', function(channel, who, by, reason) { - var msg = { "payload": { "type":"kick", "who":who, "channel":channel, "by":by, "reason":reason } }; - node.send([null,msg]); - node.log(who+' was kicked from '+channel+' by '+by+': '+reason); - }); - -} -RED.nodes.registerType("irc in",IrcInNode); - - -// The Output Node -function IrcOutNode(n) { - RED.nodes.createNode(this,n); - this.sendAll = n.sendObject; - this.ircserver = n.ircserver; - this.serverConfig = RED.nodes.getNode(this.ircserver); - this.channel = n.channel || this.serverConfig.channel; - if (this.serverConfig.ircclient == null) { - this.serverConfig.ircclient = new irc.Client(this.serverConfig.server, this.serverConfig.nickname, { - channels: [this.channel] - }); - this.serverConfig.ircclient.addListener('error', function(message) { - util.log('[irc] '+ JSON.stringify(message)); - }); - } - this.ircclient = this.serverConfig.ircclient; - var node = this; - - this.on("input", function(msg) { - if (Object.prototype.toString.call( msg.raw ) === '[object Array]') { - var m = msg.raw; - for (var i = 0; i < 10; i++) { - if (typeof m[i] !== "string") { m[i] = ""; } - m[i] = m[i].replace(/"/g, ""); +module.exports = function(RED) { + var irc = require("irc"); + var util = require("util"); + + // The Server Definition - this opens (and closes) the connection + function IRCServerNode(n) { + RED.nodes.createNode(this,n); + this.server = n.server; + this.channel = n.channel; + this.nickname = n.nickname; + this.ircclient = null; + this.on("close", function() { + if (this.ircclient != null) { + this.ircclient.disconnect(); } - util.log("[irc] RAW command:"+m); - node.ircclient.send(m[0],m[1],m[2],m[3],m[4],m[5],m[6],m[7],m[8],m[9]); + }); + } + RED.nodes.registerType("irc-server",IRCServerNode); + + + // The Input Node + function IrcInNode(n) { + RED.nodes.createNode(this,n); + this.ircserver = n.ircserver; + this.serverConfig = RED.nodes.getNode(this.ircserver); + this.channel = n.channel || this.serverConfig.channel; + if (this.serverConfig.ircclient == null) { + this.serverConfig.ircclient = new irc.Client(this.serverConfig.server, this.serverConfig.nickname, { + channels: [this.channel] + }); + this.serverConfig.ircclient.addListener('error', function(message) { + util.log('[irc] '+ JSON.stringify(message)); + }); } - else { - if (msg._topic) { delete msg._topic; } - if (node.sendAll == "false") { - node.ircclient.say(node.channel, JSON.stringify(msg)); + this.ircclient = this.serverConfig.ircclient; + var node = this; + + this.ircclient.addListener('message', function (from, to, message) { + //util.log(from + ' => ' + to + ': ' + message); + var msg = { "topic":from, "from":from, "to":to, "payload":message }; + node.send([msg,null]); + }); + this.ircclient.addListener('pm', function(from, message) { + var msg = { "topic":from, "from":from, "to":"PRIV", "payload":message }; + node.send([msg,null]); + }); + + this.ircclient.addListener('join', function(channel, who) { + var msg = { "payload": { "type":"join", "who":who, "channel":channel } }; + node.send([null,msg]); + node.log(who+' has joined '+channel); + }); + this.ircclient.addListener('invite', function(channel, from, message) { + var msg = { "payload": { "type":"invite", "who":from, "channel":channel, "message":message } }; + node.send([null,msg]); + node.log(from+' sent invite to '+channel+': '+message); + }); + this.ircclient.addListener('part', function(channel, who, reason) { + var msg = { "payload": { "type":"part", "who":who, "channel":channel, "reason":reason } }; + node.send([null,msg]); + node.log(who+'has left '+channel+': '+reason); + }); + this.ircclient.addListener('quit', function(nick, reason, channels, message) { + var msg = { "payload": { "type":"quit", "who":nick, "channel":channels, "reason":reason } }; + node.send([null,msg]); + node.log(nick+'has quit '+channels+': '+reason); + }); + this.ircclient.addListener('kick', function(channel, who, by, reason) { + var msg = { "payload": { "type":"kick", "who":who, "channel":channel, "by":by, "reason":reason } }; + node.send([null,msg]); + node.log(who+' was kicked from '+channel+' by '+by+': '+reason); + }); + + } + RED.nodes.registerType("irc in",IrcInNode); + + + // The Output Node + function IrcOutNode(n) { + RED.nodes.createNode(this,n); + this.sendAll = n.sendObject; + this.ircserver = n.ircserver; + this.serverConfig = RED.nodes.getNode(this.ircserver); + this.channel = n.channel || this.serverConfig.channel; + if (this.serverConfig.ircclient == null) { + this.serverConfig.ircclient = new irc.Client(this.serverConfig.server, this.serverConfig.nickname, { + channels: [this.channel] + }); + this.serverConfig.ircclient.addListener('error', function(message) { + util.log('[irc] '+ JSON.stringify(message)); + }); + } + this.ircclient = this.serverConfig.ircclient; + var node = this; + + this.on("input", function(msg) { + if (Object.prototype.toString.call( msg.raw ) === '[object Array]') { + var m = msg.raw; + for (var i = 0; i < 10; i++) { + if (typeof m[i] !== "string") { m[i] = ""; } + m[i] = m[i].replace(/"/g, ""); + } + util.log("[irc] RAW command:"+m); + node.ircclient.send(m[0],m[1],m[2],m[3],m[4],m[5],m[6],m[7],m[8],m[9]); } else { - if (typeof msg.payload === "object") { msg.payload = JSON.stringify(msg.payload); } - if (node.sendAll == "pay") { - node.ircclient.say(node.channel, msg.payload); + if (msg._topic) { delete msg._topic; } + if (node.sendAll == "false") { + node.ircclient.say(node.channel, JSON.stringify(msg)); } else { - var to = msg.topic || node.channel; - node.ircclient.say(to, msg.payload); + if (typeof msg.payload === "object") { msg.payload = JSON.stringify(msg.payload); } + if (node.sendAll == "pay") { + node.ircclient.say(node.channel, msg.payload); + } + else { + var to = msg.topic || node.channel; + node.ircclient.say(to, msg.payload); + } } } - } - }); + }); + } + RED.nodes.registerType("irc out",IrcOutNode); } -RED.nodes.registerType("irc out",IrcOutNode); diff --git a/nodes/core/storage/28-tail.js b/nodes/core/storage/28-tail.js index fe76a920a..bd30df6cf 100644 --- a/nodes/core/storage/28-tail.js +++ b/nodes/core/storage/28-tail.js @@ -14,43 +14,44 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var fs = require("fs"); -var spawn = require('child_process').spawn; - -function TailNode(n) { - RED.nodes.createNode(this,n); - - this.filename = n.filename; - this.split = n.split; - var node = this; - - var err = ""; - var tail = spawn("tail", ["-f", this.filename]); - tail.stdout.on("data", function (data) { - var msg = {topic:node.filename}; - if (node.split) { - var strings = data.toString().split("\n"); - for (s in strings) { - if (strings[s] != "") { - msg.payload = strings[s]; - node.send(msg); +module.exports = function(RED) { + var fs = require("fs"); + var spawn = require('child_process').spawn; + + function TailNode(n) { + RED.nodes.createNode(this,n); + + this.filename = n.filename; + this.split = n.split; + var node = this; + + var err = ""; + var tail = spawn("tail", ["-f", this.filename]); + tail.stdout.on("data", function (data) { + var msg = {topic:node.filename}; + if (node.split) { + var strings = data.toString().split("\n"); + for (s in strings) { + if (strings[s] != "") { + msg.payload = strings[s]; + node.send(msg); + } } } - } - else { - msg.payload = data.toString(); - node.send(msg); - } - }); - - tail.stderr.on("data", function(data) { - node.warn(data.toString()); - }); - - this.on("close", function() { - if (tail) tail.kill(); - }); + else { + msg.payload = data.toString(); + node.send(msg); + } + }); + + tail.stderr.on("data", function(data) { + node.warn(data.toString()); + }); + + this.on("close", function() { + if (tail) tail.kill(); + }); + } + + RED.nodes.registerType("tail",TailNode); } - -RED.nodes.registerType("tail",TailNode); diff --git a/nodes/core/storage/50-file.js b/nodes/core/storage/50-file.js index c1b42f638..026d4fd27 100644 --- a/nodes/core/storage/50-file.js +++ b/nodes/core/storage/50-file.js @@ -14,77 +14,78 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var fs = require("fs"); - -function FileNode(n) { - RED.nodes.createNode(this,n); - - this.filename = n.filename; - this.appendNewline = n.appendNewline; - this.overwriteFile = n.overwriteFile; - var node = this; - this.on("input",function(msg) { - var filename = msg.filename || this.filename; - - if (filename == "") { - node.warn('No filename specified'); - } else if (typeof msg.payload != "undefined") { - var data = msg.payload; - if (typeof data == "object") { data = JSON.stringify(data); } - if (typeof data == "boolean") { data = data.toString(); } - if (this.appendNewline) { - data += "\n"; - } - if (msg.hasOwnProperty('delete')) { - fs.unlink(filename, function (err) { - if (err) node.warn('Failed to delete file : '+err); - //console.log('Deleted file",filename); - }); - } - else { - if (this.overwriteFile) { - fs.writeFile(filename, data, function (err) { - if (err) node.warn('Failed to write to file : '+err); - //console.log('Message written to file',filename); +module.exports = function(RED) { + var fs = require("fs"); + + function FileNode(n) { + RED.nodes.createNode(this,n); + + this.filename = n.filename; + this.appendNewline = n.appendNewline; + this.overwriteFile = n.overwriteFile; + var node = this; + this.on("input",function(msg) { + var filename = msg.filename || this.filename; + + if (filename == "") { + node.warn('No filename specified'); + } else if (typeof msg.payload != "undefined") { + var data = msg.payload; + if (typeof data == "object") { data = JSON.stringify(data); } + if (typeof data == "boolean") { data = data.toString(); } + if (this.appendNewline) { + data += "\n"; + } + if (msg.hasOwnProperty('delete')) { + fs.unlink(filename, function (err) { + if (err) node.warn('Failed to delete file : '+err); + //console.log('Deleted file",filename); }); } else { - fs.appendFile(filename, data, function (err) { - if (err) node.warn('Failed to append to file : '+err); - //console.log('Message appended to file',filename); - }); + if (this.overwriteFile) { + fs.writeFile(filename, data, function (err) { + if (err) node.warn('Failed to write to file : '+err); + //console.log('Message written to file',filename); + }); + } + else { + fs.appendFile(filename, data, function (err) { + if (err) node.warn('Failed to append to file : '+err); + //console.log('Message appended to file',filename); + }); + } } } - } - }); -} -RED.nodes.registerType("file",FileNode); - -function FileInNode(n) { - RED.nodes.createNode(this,n); - - this.filename = n.filename; - this.format = n.format; - var node = this; - var options = {}; - if (this.format) { - options['encoding'] = this.format; + }); } - this.on("input",function(msg) { - var filename = msg.filename || this.filename; - - if (filename == "") { - node.warn('No filename specified'); - } else { - fs.readFile(filename,options,function(err,data) { - if (err) { - node.warn(err); - } else { - node.send({payload:data}); - } - }); + RED.nodes.registerType("file",FileNode); + + function FileInNode(n) { + RED.nodes.createNode(this,n); + + this.filename = n.filename; + this.format = n.format; + var node = this; + var options = {}; + if (this.format) { + options['encoding'] = this.format; } - }); + this.on("input",function(msg) { + var filename = msg.filename || this.filename; + + if (filename == "") { + node.warn('No filename specified'); + } else { + fs.readFile(filename,options,function(err,data) { + if (err) { + node.warn(err); + } else { + node.send({payload:data}); + } + }); + } + }); + } + RED.nodes.registerType("file in",FileInNode); } -RED.nodes.registerType("file in",FileInNode); diff --git a/nodes/core/storage/65-redisout.js b/nodes/core/storage/65-redisout.js index 17aaf9bfc..b01e8e4a0 100644 --- a/nodes/core/storage/65-redisout.js +++ b/nodes/core/storage/65-redisout.js @@ -14,83 +14,84 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var util = require("util"); -var redis = require("redis"); - -var hashFieldRE = /^([^=]+)=(.*)$/; - -var redisConnectionPool = function() { - var connections = {}; - var obj = { - get: function(host,port) { - var id = host+":"+port; - if (!connections[id]) { - connections[id] = redis.createClient(port,host); - connections[id].on("error",function(err) { - util.log("[redis] "+err); - }); - connections[id].on("connect",function() { - util.log("[redis] connected to "+host+":"+port); - }); - connections[id]._id = id; - connections[id]._nodeCount = 0; - } - connections[id]._nodeCount += 1; - return connections[id]; - }, - close: function(connection) { - connection._nodeCount -= 1; - if (connection._nodeCount == 0) { - if (connection) { - clearTimeout(connection.retry_timer); - connection.end(); +module.exports = function(RED) { + var util = require("util"); + var redis = require("redis"); + + var hashFieldRE = /^([^=]+)=(.*)$/; + + var redisConnectionPool = function() { + var connections = {}; + var obj = { + get: function(host,port) { + var id = host+":"+port; + if (!connections[id]) { + connections[id] = redis.createClient(port,host); + connections[id].on("error",function(err) { + util.log("[redis] "+err); + }); + connections[id].on("connect",function() { + util.log("[redis] connected to "+host+":"+port); + }); + connections[id]._id = id; + connections[id]._nodeCount = 0; } - delete connections[connection._id]; - } - } - }; - return obj; -}(); - - -function RedisOutNode(n) { - RED.nodes.createNode(this,n); - this.port = n.port||"6379"; - this.hostname = n.hostname||"127.0.0.1"; - this.key = n.key; - this.structtype = n.structtype; - - this.client = redisConnectionPool.get(this.hostname,this.port); - - this.on("input", function(msg) { - if (msg != null) { - var k = this.key || msg.topic; - if (k) { - if (this.structtype == "string") { - this.client.set(k,msg.payload); - } else if (this.structtype == "hash") { - var r = hashFieldRE.exec(msg.payload); - if (r) { - this.client.hset(k,r[1],r[2]); - } else { - this.warn("Invalid payload for redis hash"); - } - } else if (this.structtype == "set") { - this.client.sadd(k,msg.payload); - } else if (this.structtype == "list") { - this.client.rpush(k,msg.payload); + connections[id]._nodeCount += 1; + return connections[id]; + }, + close: function(connection) { + connection._nodeCount -= 1; + if (connection._nodeCount == 0) { + if (connection) { + clearTimeout(connection.retry_timer); + connection.end(); } - } else { - this.warn("No key or topic set"); + delete connections[connection._id]; } } - }); -} - -RED.nodes.registerType("redis out",RedisOutNode); - -RedisOutNode.prototype.close = function() { - redisConnectionPool.close(this.client); + }; + return obj; + }(); + + + function RedisOutNode(n) { + RED.nodes.createNode(this,n); + this.port = n.port||"6379"; + this.hostname = n.hostname||"127.0.0.1"; + this.key = n.key; + this.structtype = n.structtype; + + this.client = redisConnectionPool.get(this.hostname,this.port); + + this.on("input", function(msg) { + if (msg != null) { + var k = this.key || msg.topic; + if (k) { + if (this.structtype == "string") { + this.client.set(k,msg.payload); + } else if (this.structtype == "hash") { + var r = hashFieldRE.exec(msg.payload); + if (r) { + this.client.hset(k,r[1],r[2]); + } else { + this.warn("Invalid payload for redis hash"); + } + } else if (this.structtype == "set") { + this.client.sadd(k,msg.payload); + } else if (this.structtype == "list") { + this.client.rpush(k,msg.payload); + } + } else { + this.warn("No key or topic set"); + } + } + }); + } + + RED.nodes.registerType("redis out",RedisOutNode); + + RedisOutNode.prototype.close = function() { + redisConnectionPool.close(this.client); + } } diff --git a/nodes/core/storage/66-mongodb.js b/nodes/core/storage/66-mongodb.js index 897c03b6d..50a3bbcc6 100644 --- a/nodes/core/storage/66-mongodb.js +++ b/nodes/core/storage/66-mongodb.js @@ -14,165 +14,166 @@ * limitations under the License. **/ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -var mongo = require('mongodb'); -var MongoClient = mongo.MongoClient; - -function MongoNode(n) { - RED.nodes.createNode(this,n); - this.hostname = n.hostname; - this.port = n.port; - this.db = n.db; - this.name = n.name; - var credentials = RED.nodes.getCredentials(n.id); - if (credentials) { - this.username = credentials.user; - this.password = credentials.password; +module.exports = function(RED) { + var mongo = require('mongodb'); + var MongoClient = mongo.MongoClient; + + function MongoNode(n) { + RED.nodes.createNode(this,n); + this.hostname = n.hostname; + this.port = n.port; + this.db = n.db; + this.name = n.name; + var credentials = RED.nodes.getCredentials(n.id); + if (credentials) { + this.username = credentials.user; + this.password = credentials.password; + } + + var url = "mongodb://"; + if (this.username && this.password) { + url += this.username+":"+this.password+"@"; + } + url += this.hostname+":"+this.port+"/"+this.db; + + this.url = url; } - var url = "mongodb://"; - if (this.username && this.password) { - url += this.username+":"+this.password+"@"; - } - url += this.hostname+":"+this.port+"/"+this.db; + RED.nodes.registerType("mongodb",MongoNode); - this.url = url; -} - -RED.nodes.registerType("mongodb",MongoNode); - -var querystring = require('querystring'); - -RED.httpAdmin.get('/mongodb/:id',function(req,res) { - var credentials = RED.nodes.getCredentials(req.params.id); - if (credentials) { - res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!="")})); - } else { - res.send(JSON.stringify({})); - } -}); - -RED.httpAdmin.delete('/mongodb/:id',function(req,res) { - RED.nodes.deleteCredentials(req.params.id); - res.send(200); -}); - -RED.httpAdmin.post('/mongodb/:id',function(req,res) { - var body = ""; - req.on('data', function(chunk) { - body+=chunk; + var querystring = require('querystring'); + + RED.httpAdmin.get('/mongodb/:id',function(req,res) { + var credentials = RED.nodes.getCredentials(req.params.id); + if (credentials) { + res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!="")})); + } else { + res.send(JSON.stringify({})); + } }); - req.on('end', function(){ - var newCreds = querystring.parse(body); - var credentials = RED.nodes.getCredentials(req.params.id)||{}; - if (newCreds.user == null || newCreds.user == "") { - delete credentials.user; - } else { - credentials.user = newCreds.user; - } - if (newCreds.password == "") { - delete credentials.password; - } else { - credentials.password = newCreds.password||credentials.password; - } - RED.nodes.addCredentials(req.params.id,credentials); + + RED.httpAdmin.delete('/mongodb/:id',function(req,res) { + RED.nodes.deleteCredentials(req.params.id); res.send(200); }); -}); - - -function MongoOutNode(n) { - RED.nodes.createNode(this,n); - this.collection = n.collection; - this.mongodb = n.mongodb; - this.payonly = n.payonly || false; - this.operation = n.operation; - this.mongoConfig = RED.nodes.getNode(this.mongodb); - - if (this.mongoConfig) { - var node = this; - MongoClient.connect(this.mongoConfig.url, function(err,db) { - if (err) { - node.error(err); - } else { - node.clientDb = db; - var coll = db.collection(node.collection); - node.on("input",function(msg) { - if (node.operation == "store") { - delete msg._topic; - if (node.payonly) { - if (typeof msg.payload !== "object") { msg.payload = {"payload":msg.payload}; } - coll.save(msg.payload,function(err,item){ if (err){node.error(err);} }); - } else { - coll.save(msg,function(err,item){if (err){node.error(err);}}); - } - } - else if (node.operation == "insert") { - delete msg._topic; - if (node.payonly) { - if (typeof msg.payload !== "object") { msg.payload = {"payload":msg.payload}; } - coll.insert(msg.payload,function(err,item){ if (err){node.error(err);} }); - } else { - coll.insert(msg,function(err,item){if (err){node.error(err);}}); - } - } - if (node.operation == "delete") { - coll.remove(msg.payload, {w:1}, function(err, items){ if (err) node.error(err); }); - } - }); - } + + RED.httpAdmin.post('/mongodb/:id',function(req,res) { + var body = ""; + req.on('data', function(chunk) { + body+=chunk; }); - } else { - this.error("missing mongodb configuration"); - } - - this.on("close", function() { - if (this.clientDb) { - this.clientDb.close(); - } - }); -} -RED.nodes.registerType("mongodb out",MongoOutNode); - - -function MongoInNode(n) { - RED.nodes.createNode(this,n); - this.collection = n.collection; - this.mongodb = n.mongodb; - this.mongoConfig = RED.nodes.getNode(this.mongodb); - - if (this.mongoConfig) { - var node = this; - MongoClient.connect(this.mongoConfig.url, function(err,db) { - if (err) { - node.error(err); + req.on('end', function(){ + var newCreds = querystring.parse(body); + var credentials = RED.nodes.getCredentials(req.params.id)||{}; + if (newCreds.user == null || newCreds.user == "") { + delete credentials.user; } else { - node.clientDb = db; - var coll = db.collection(node.collection); - node.on("input",function(msg) { - msg.projection = msg.projection || {}; - coll.find(msg.payload,msg.projection).sort(msg.sort).limit(msg.limit).toArray(function(err, items) { - if (err) { - node.error(err); - } else { - msg.payload = items; - delete msg.projection; - delete msg.sort; - delete msg.limit; - node.send(msg); + credentials.user = newCreds.user; + } + if (newCreds.password == "") { + delete credentials.password; + } else { + credentials.password = newCreds.password||credentials.password; + } + RED.nodes.addCredentials(req.params.id,credentials); + res.send(200); + }); + }); + + + function MongoOutNode(n) { + RED.nodes.createNode(this,n); + this.collection = n.collection; + this.mongodb = n.mongodb; + this.payonly = n.payonly || false; + this.operation = n.operation; + this.mongoConfig = RED.nodes.getNode(this.mongodb); + + if (this.mongoConfig) { + var node = this; + MongoClient.connect(this.mongoConfig.url, function(err,db) { + if (err) { + node.error(err); + } else { + node.clientDb = db; + var coll = db.collection(node.collection); + node.on("input",function(msg) { + if (node.operation == "store") { + delete msg._topic; + if (node.payonly) { + if (typeof msg.payload !== "object") { msg.payload = {"payload":msg.payload}; } + coll.save(msg.payload,function(err,item){ if (err){node.error(err);} }); + } else { + coll.save(msg,function(err,item){if (err){node.error(err);}}); + } + } + else if (node.operation == "insert") { + delete msg._topic; + if (node.payonly) { + if (typeof msg.payload !== "object") { msg.payload = {"payload":msg.payload}; } + coll.insert(msg.payload,function(err,item){ if (err){node.error(err);} }); + } else { + coll.insert(msg,function(err,item){if (err){node.error(err);}}); + } + } + if (node.operation == "delete") { + coll.remove(msg.payload, {w:1}, function(err, items){ if (err) node.error(err); }); } }); - }); + } + }); + } else { + this.error("missing mongodb configuration"); + } + + this.on("close", function() { + if (this.clientDb) { + this.clientDb.close(); } }); - } else { - this.error("missing mongodb configuration"); } - - this.on("close", function() { - if (this.clientDb) { - this.clientDb.close(); + RED.nodes.registerType("mongodb out",MongoOutNode); + + + function MongoInNode(n) { + RED.nodes.createNode(this,n); + this.collection = n.collection; + this.mongodb = n.mongodb; + this.mongoConfig = RED.nodes.getNode(this.mongodb); + + if (this.mongoConfig) { + var node = this; + MongoClient.connect(this.mongoConfig.url, function(err,db) { + if (err) { + node.error(err); + } else { + node.clientDb = db; + var coll = db.collection(node.collection); + node.on("input",function(msg) { + msg.projection = msg.projection || {}; + coll.find(msg.payload,msg.projection).sort(msg.sort).limit(msg.limit).toArray(function(err, items) { + if (err) { + node.error(err); + } else { + msg.payload = items; + delete msg.projection; + delete msg.sort; + delete msg.limit; + node.send(msg); + } + }); + }); + } + }); + } else { + this.error("missing mongodb configuration"); } - }); + + this.on("close", function() { + if (this.clientDb) { + this.clientDb.close(); + } + }); + } + RED.nodes.registerType("mongodb in",MongoInNode); } -RED.nodes.registerType("mongodb in",MongoInNode); diff --git a/red/nodes/registry.js b/red/nodes/registry.js index c467c1833..beafa9620 100644 --- a/red/nodes/registry.js +++ b/red/nodes/registry.js @@ -54,7 +54,7 @@ function loadNode(nodeDir, nodeFn) { var r = require(nodeFilename); if (typeof r === "function") { try { - var promise = r(RED); + var promise = r(require('../red')); if (promise != null && typeof promise.then === "function") { promise.then(function() { resolve(loadTemplate(templateFilename));