mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
Add i18n content for moved core nodes
This commit is contained in:
parent
36bc2e6b06
commit
7d011dac99
@ -19,21 +19,21 @@
|
||||
<input type="text" id="node-input-arduino">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-pin"><i class="fa fa-circle"></i> Pin</label>
|
||||
<label for="node-input-pin"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.pin"></span></label>
|
||||
<input type="text" id="node-input-pin" placeholder="2">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-state"><i class="fa fa-wrench"></i> Type</label>
|
||||
<label for="node-input-state"><i class="fa fa-wrench"></i> <span data-i18n="arduino.label.type"></span></label>
|
||||
<select type="text" id="node-input-state" style="width: 150px;">
|
||||
<option value="INPUT">Digital pin</option>
|
||||
<option value="ANALOG">Analogue pin</option>
|
||||
<option value="INPUT" data-i18n="arduino.state.in.digital"></option>
|
||||
<option value="ANALOG" data-i18n="arduino.state.in.analogue"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips"><b>Note:</b> You cannot use the same pin for both output and input.</div>
|
||||
<div class="form-tips"><span data-i18n="[html]arduino.tip.io"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="arduino in">
|
||||
@ -70,26 +70,26 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="arduino out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-arduino"><i class="fa fa-tasks"></i> Arduino</label>
|
||||
<label for="node-input-arduino"><i class="fa fa-tasks"></i> <span data-i18n="arduino.label.arduino"></span></label>
|
||||
<input type="text" id="node-input-arduino">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-pin"><i class="fa fa-circle"></i> Pin</label>
|
||||
<label for="node-input-pin"><i class="fa fa-circle"></i> <span data-i18n="arduino.label.pin"></span></label>
|
||||
<input type="text" id="node-input-pin" placeholder="13">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-state"><i class="fa fa-wrench"></i> Type</label>
|
||||
<label for="node-input-state"><i class="fa fa-wrench"></i> <span data-i18n="arduino.label.type"></span></label>
|
||||
<select type="text" id="node-input-state" style="width: 200px;">
|
||||
<option value="OUTPUT">Digital (0/1)</option>
|
||||
<option value="PWM">Analogue (0-255)</option>
|
||||
<option value="SERVO">Servo (0-180)</option>
|
||||
<option value="OUTPUT" data-i18n="arduino.state.out.digital"></option>
|
||||
<option value="PWM" data-i18n="arduino.state.out.analogue"></option>
|
||||
<option value="SERVO" data-i18n="arduino.state.out.servo"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips"><b>Note:</b> You cannot use the same pin for both output and input.</div>
|
||||
<div class="form-tips"><span data-i18n="[html]arduino.tip.io"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="arduino out">
|
||||
@ -124,11 +124,11 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="arduino-board">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-device"><i class="fa fa-random"></i> Port</label>
|
||||
<input type="text" id="node-config-input-device" style="width:60%;" placeholder="e.g. /dev/ttyUSB0 COM1"/>
|
||||
<label for="node-config-input-device"><i class="fa fa-random"></i> <span data-i18n="arduino.label.port"></span></label>
|
||||
<input type="text" id="node-config-input-device" style="width:60%;" data-i18n="[placeholder]arduino.placeholder.port"/>
|
||||
<a id="node-config-lookup-serial" class="btn"><i id="node-config-lookup-serial-icon" class="fa fa-search"></i></a>
|
||||
</div>
|
||||
<div class="form-tips"><b>Tip:</b> Use search to list serial ports, or leave blank to connect to first device found.</div>
|
||||
<div class="form-tips"><span data-i18n="[html]arduino.tip.conf"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
@ -23,28 +23,30 @@ module.exports = function(RED) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.device = n.device || null;
|
||||
this.repeat = n.repeat||25;
|
||||
//node.log("opening connection "+this.device);
|
||||
var node = this;
|
||||
node.board = new ArduinoFirmata();
|
||||
// TODO: nls
|
||||
ArduinoFirmata.list(function (err, ports) {
|
||||
if (!node.device) {
|
||||
node.log("connecting to first board found.");
|
||||
node.log(RED._("arduino.status.connectfirst"));
|
||||
node.board.connect();
|
||||
}
|
||||
else {
|
||||
if (ports.indexOf(node.device) === -1) {
|
||||
node.warn(node.device + " not found. Trying to find board.");
|
||||
node.warn(RED._("arduino.errors.devnotfound",{dev:node.device}));
|
||||
node.board.connect();
|
||||
}
|
||||
else {
|
||||
node.log("connecting to "+node.device);
|
||||
node.log(RED._("arduino.status.connect",{device:node.device}));
|
||||
node.board.connect(node.device);
|
||||
}
|
||||
}
|
||||
|
||||
node.board.on('boardReady', function() {
|
||||
node.log("connected to "+node.board.serialport_name);
|
||||
if (RED.settings.verbose) { node.log("version "+node.board.boardVersion); }
|
||||
node.log(RED._("arduino.status.connected",{device:node.board.serialport_name}));
|
||||
if (RED.settings.verbose) {
|
||||
node.log(RED._("arduino.status.version",{version:node.board.boardVersion}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -53,7 +55,7 @@ module.exports = function(RED) {
|
||||
try {
|
||||
node.board.close(function() {
|
||||
done();
|
||||
if (RED.settings.verbose) { node.log("port closed"); }
|
||||
if (RED.settings.verbose) { node.log(RED._("arduino.status.portclosed")); }
|
||||
});
|
||||
} catch(e) { done(); }
|
||||
} else { done(); }
|
||||
@ -73,9 +75,9 @@ module.exports = function(RED) {
|
||||
if (typeof this.serverConfig === "object") {
|
||||
this.board = this.serverConfig.board;
|
||||
var node = this;
|
||||
node.status({fill:"red",shape:"ring",text:"connecting"});
|
||||
node.status({fill:"red",shape:"ring",text:RED._("common.status.connecting")});
|
||||
node.board.on('connect', function() {
|
||||
node.status({fill:"green",shape:"dot",text:"connected"});
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.connected")});
|
||||
//console.log("i",node.state,node.pin);
|
||||
if (node.state == "ANALOG") {
|
||||
node.board.on('analogChange', function(e) {
|
||||
@ -103,7 +105,7 @@ module.exports = function(RED) {
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.warn("port not configured");
|
||||
this.warn(RED._("arduino.errors.portnotconf"));
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("arduino in",DuinoNodeIn);
|
||||
@ -120,10 +122,10 @@ module.exports = function(RED) {
|
||||
if (typeof this.serverConfig === "object") {
|
||||
this.board = this.serverConfig.board;
|
||||
var node = this;
|
||||
node.status({fill:"red",shape:"ring",text:"connecting"});
|
||||
node.status({fill:"red",shape:"ring",text:RED._("common.status.connecting")});
|
||||
|
||||
node.board.on('connect', function() {
|
||||
node.status({fill:"green",shape:"dot",text:"connected"});
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.connected")});
|
||||
//console.log("o",node.state,node.pin);
|
||||
node.board.pinMode(node.pin, node.state);
|
||||
node.on("input", function(msg) {
|
||||
@ -154,7 +156,7 @@ module.exports = function(RED) {
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.warn("port not configured");
|
||||
this.warn(RED._("arduino.errors.portnotconf"));
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("arduino out",DuinoNodeOut);
|
||||
|
38
hardware/Arduino/locales/en-US/35-arduino.json
Normal file
38
hardware/Arduino/locales/en-US/35-arduino.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"arduino": {
|
||||
"label": {
|
||||
"pin": "Pin",
|
||||
"type": "Type",
|
||||
"port": "Port"
|
||||
},
|
||||
"placeholder": {
|
||||
"port": "e.g. /dev/ttyUSB0 COM1"
|
||||
},
|
||||
"status": {
|
||||
"connectfirst": "connecting to first board found",
|
||||
"connect": "connecting to __device__",
|
||||
"connected": "connected to __device__",
|
||||
"version": "version: __version__",
|
||||
"portclosed": "port closed"
|
||||
},
|
||||
"state": {
|
||||
"in": {
|
||||
"digital": "Digital pin",
|
||||
"analogue": "Analogue pin"
|
||||
},
|
||||
"out": {
|
||||
"digital": "Digital (0/1)",
|
||||
"analogue": "Analogue (0-255)",
|
||||
"servo": "Servo (0-180)"
|
||||
}
|
||||
},
|
||||
"tip": {
|
||||
"io": "<b>Note:</b> You cannot use the same pin for both output and input.",
|
||||
"conf": "<b>Tip:</b> Use search to try to auto-detect serial port."
|
||||
},
|
||||
"errors": {
|
||||
"portnotconf": "port not configured",
|
||||
"devnotfound": "device __dev__ not found. Trying to find board."
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Copyright 2013,2015 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.
|
||||
@ -16,20 +16,20 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="serial in">
|
||||
<div class="form-row node-input-serial">
|
||||
<label for="node-input-serial"><i class="fa fa-random"></i> Serial Port</label>
|
||||
<label for="node-input-serial"><i class="fa fa-random"></i> <span data-i18n="serial.label.serialport"></span></label>
|
||||
<input type="text" id="node-input-serial">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="serial in">
|
||||
<p>Reads data from a local serial port.</p>
|
||||
<p>Can either <ul><li>wait for a "split" character (default \n). Also accepts hex notation (0x0a).</li>
|
||||
<li>wait for a timeout in milliseconds for the first character received</li>
|
||||
<li>wait to fill a fixed sized buffer</li></ul></p>
|
||||
<li>Wait for a timeout in milliseconds for the first character received</li>
|
||||
<li>Wait to fill a fixed sized buffer</li></ul></p>
|
||||
<p>It then outputs <b>msg.payload</b> as either a UTF8 ascii string or a binary Buffer object.</p>
|
||||
<p>If no split character is specified, or a timeout or buffer size of 0, then a stream of single characters is sent - again either as ascii chars or size 1 binary buffers.</p>
|
||||
</script>
|
||||
@ -47,7 +47,7 @@
|
||||
icon: "serial.png",
|
||||
label: function() {
|
||||
var serialNode = RED.nodes.node(this.serial);
|
||||
return this.name||(serialNode?serialNode.label().split(":")[0]:"serial");
|
||||
return this.name||(serialNode?serialNode.label().split(":")[0]:this._("serial.label.serial"));
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
@ -57,12 +57,12 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="serial out">
|
||||
<div class="form-row node-input-serial">
|
||||
<label for="node-input-serial"><i class="fa fa-random"></i> Serial Port</label>
|
||||
<label for="node-input-serial"><i class="fa fa-random"></i> <span data-i18n="serial.label.serialport"></span></label>
|
||||
<input type="text" id="node-input-serial">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
@ -86,7 +86,7 @@
|
||||
align: "right",
|
||||
label: function() {
|
||||
var serialNode = RED.nodes.node(this.serial);
|
||||
return this.name||(serialNode?serialNode.label().split(":")[0]:"serial");
|
||||
return this.name||(serialNode?serialNode.label().split(":")[0]:this._("serial.label.serial"));
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
@ -97,17 +97,17 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="serial-port">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-serialport"><i class="fa fa-random"></i> Serial Port</label>
|
||||
<input type="text" id="node-config-input-serialport" style="width:60%;" placeholder="/dev/ttyUSB0"/>
|
||||
<label for="node-config-input-serialport"><i class="fa fa-random"></i> <span data-i18n="serial.label.serialport"></span></label>
|
||||
<input type="text" id="node-config-input-serialport" style="width:60%;" data-i18n="[placeholder]serial.placeholder.serialport">
|
||||
<a id="node-config-lookup-serial" class="btn"><i id="node-config-lookup-serial-icon" class="fa fa-search"></i></a>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<table><tr>
|
||||
<td width="102px"><i class="fa fa-wrench"></i> Settings</td>
|
||||
<td width="100px">Baud Rate</td>
|
||||
<td width="80px">Data Bits</td>
|
||||
<td width="80px">Parity</td>
|
||||
<td width="80px">Stop Bits</td>
|
||||
<td width="102px"><i class="fa fa-wrench"></i> <span data-i18n="serial.label.settings"></span></td>
|
||||
<td width="100px" data-i18n="serial.label.baudrate"></td>
|
||||
<td width="80px" data-i18n="serial.label.databits"></td>
|
||||
<td width="80px" data-i18n="serial.label.parity"></td>
|
||||
<td width="80px" data-i18n="serial.label.stopbits"></td>
|
||||
</tr><tr><td> </td>
|
||||
<td>
|
||||
<select type="text" id="node-config-input-serialbaud" style="width: 100px;">
|
||||
@ -138,11 +138,11 @@
|
||||
</select>
|
||||
</td><td>
|
||||
<select type="text" id="node-config-input-parity" style="width: 80px;">
|
||||
<option value="none">None</option>
|
||||
<option value="even">Even</option>
|
||||
<option value="mark">Mark</option>
|
||||
<option value="odd">Odd</option>
|
||||
<option value="space">Space</option>
|
||||
<option value="none" data-i18n="serial.parity.none"></option>
|
||||
<option value="even" data-i18n="serial.parity.even"></option>
|
||||
<option value="mark" data-i18n="serial.parity.mark"></option>
|
||||
<option value="odd" data-i18n="serial.parity.odd"></option>
|
||||
<option value="space" data-i18n="serial.parity.space"></option>
|
||||
</select>
|
||||
</td><td>
|
||||
<select type="text" id="node-config-input-stopbits" style="width: 80px;">
|
||||
@ -153,36 +153,36 @@
|
||||
</tr></table><br/>
|
||||
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-sign-in"></i> Input</label>
|
||||
<label><i class="fa fa-sign-in"></i> <span data-i18n="serial.label.input"></span></label>
|
||||
</div>
|
||||
<div class="form-row" style="padding-left: 10px;">
|
||||
Split input
|
||||
<span data-i18n="serial.label.split"></span>
|
||||
<select type="text" id="node-config-input-out" style="margin-left: 5px; width:200px;">
|
||||
<option value="char">on the character</option>
|
||||
<option value="time">after a timeout of</option>
|
||||
<option value="count">into fixed lengths of</option>
|
||||
<option value="char" data-i18n="serial.split.character"></option>
|
||||
<option value="time" data-i18n="serial.split.timeout"></option>
|
||||
<option value="count" data-i18n="serial.split.lengths"></option>
|
||||
</select>
|
||||
<input type="text" id="node-config-input-newline" style="width:50px;">
|
||||
<span id="node-units"></span>
|
||||
</div>
|
||||
<div class="form-row" style="padding-left: 10px;">
|
||||
and deliver
|
||||
<span data-i18n="serial.label.deliver"></span>
|
||||
<select type="text" id="node-config-input-bin" style="margin-left: 5px; width: 150px;">
|
||||
<option value="false">ascii strings</option>
|
||||
<option value="bin">binary buffers</option>
|
||||
<option value="false" data-i18n="serial.output.ascii"></option>
|
||||
<option value="bin" data-i18n="serial.output.binary"></option>
|
||||
</select>
|
||||
</div>
|
||||
<br/>
|
||||
<div id="node-config-addchar">
|
||||
<div class="form-row">
|
||||
<label><i class="fa fa-sign-out"></i> Output</label>
|
||||
<label><i class="fa fa-sign-out"></i> <span data-i18n="serial.label.output"></span></label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input style="width: 30px;margin-left: 10px; vertical-align: top;" type="checkbox" id="node-config-input-addchar"><label style="width: auto;" for="node-config-input-addchar">add split character to output messages</label>
|
||||
<input style="width: 30px;margin-left: 10px; vertical-align: top;" type="checkbox" id="node-config-input-addchar"><label style="width: auto;" for="node-config-input-addchar"><span data-i18n="serial.addsplit"></span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-tips" id="tip-split">Tip: the "Split on" character is used to split the input into separate messages. It can also be added to every message sent out to the serial port.</div>
|
||||
<div class="form-tips" id="tip-bin" hidden>Tip: In timeout mode timeout starts from arrival of first character.</div>
|
||||
<div class="form-tips" id="tip-split"><span data-i18n="serial.tip.split"></span></div>
|
||||
<div class="form-tips" id="tip-bin" hidden><span data-i18n="serial.tip.timeout"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -203,7 +203,7 @@
|
||||
label: function() {
|
||||
this.serialbaud = this.serialbaud || 57600;
|
||||
this.databits = this.databits || 8;
|
||||
this.parity = this.parity || 'none';
|
||||
this.parity = this.parity || this._("serial.label.none");
|
||||
this.stopbits = this.stopbits || 1;
|
||||
return this.serialport+":"+this.serialbaud+"-"+this.databits+this.parity.charAt(0).toUpperCase()+this.stopbits;
|
||||
},
|
||||
|
@ -52,7 +52,7 @@ module.exports = function(RED) {
|
||||
this.serialConfig.newline);
|
||||
node.addCh = "";
|
||||
if (node.serialConfig.addchar == "true" || node.serialConfig.addchar === true) {
|
||||
node.addCh = this.serialConfig.newline.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0"); // jshint ignore:line
|
||||
node.addCh = this.serialConfig.newline.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0");
|
||||
}
|
||||
node.on("input",function(msg) {
|
||||
if (msg.hasOwnProperty("payload")) {
|
||||
@ -76,13 +76,13 @@ module.exports = function(RED) {
|
||||
}
|
||||
});
|
||||
node.port.on('ready', function() {
|
||||
node.status({fill:"green",shape:"dot",text:"connected"});
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.connected")});
|
||||
});
|
||||
node.port.on('closed', function() {
|
||||
node.status({fill:"red",shape:"ring",text:"not connected"});
|
||||
node.status({fill:"red",shape:"ring",text:RED._("common.status.not-connected")});
|
||||
});
|
||||
} else {
|
||||
this.error("missing serial config");
|
||||
this.error(RED._("serial.errors.missing-conf"));
|
||||
}
|
||||
|
||||
this.on("close", function(done) {
|
||||
@ -108,7 +108,7 @@ module.exports = function(RED) {
|
||||
if (node.serialConfig.out != "count") { buf = new Buffer(bufMaxSize); }
|
||||
else { buf = new Buffer(Number(node.serialConfig.newline)); }
|
||||
var i = 0;
|
||||
node.status({fill:"grey",shape:"dot",text:"unknown"});
|
||||
node.status({fill:"grey",shape:"dot",text:RED._("common.status.not-connected")});
|
||||
node.port = serialPool.get(this.serialConfig.serialport,
|
||||
this.serialConfig.serialbaud,
|
||||
this.serialConfig.databits,
|
||||
@ -121,7 +121,7 @@ module.exports = function(RED) {
|
||||
if (node.serialConfig.newline.substr(0,2) == "0x") {
|
||||
splitc = new Buffer([parseInt(node.serialConfig.newline)]);
|
||||
} else {
|
||||
splitc = new Buffer(node.serialConfig.newline.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0")); // jshint ignore:line
|
||||
splitc = new Buffer(node.serialConfig.newline.replace("\\n","\n").replace("\\r","\r").replace("\\t","\t").replace("\\e","\e").replace("\\f","\f").replace("\\0","\0"));
|
||||
}
|
||||
|
||||
this.port.on('data', function(msg) {
|
||||
@ -132,7 +132,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
else {
|
||||
// do the timer thing
|
||||
if (node.serialConfig.out === "time") {
|
||||
if (node.serialConfig.out === "time") {
|
||||
if (node.tout) {
|
||||
i += 1;
|
||||
buf[i] = msg;
|
||||
@ -168,25 +168,24 @@ module.exports = function(RED) {
|
||||
buf[i] = msg;
|
||||
i += 1;
|
||||
if ((msg === splitc[0]) || (i === bufMaxSize)) {
|
||||
var n = new Buffer(i);
|
||||
buf.copy(n,0,0,i);
|
||||
if (node.serialConfig.bin !== "bin") { n = n.toString(); }
|
||||
node.send({"payload":n});
|
||||
n = null;
|
||||
var m = new Buffer(i);
|
||||
buf.copy(m,0,0,i);
|
||||
if (node.serialConfig.bin !== "bin") { m = m.toString(); }
|
||||
node.send({"payload":m});
|
||||
m = null;
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
else { node.log("should never get here"); }
|
||||
}
|
||||
});
|
||||
this.port.on('ready', function() {
|
||||
node.status({fill:"green",shape:"dot",text:"connected"});
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.connected")});
|
||||
});
|
||||
this.port.on('closed', function() {
|
||||
node.status({fill:"red",shape:"ring",text:"not connected"});
|
||||
node.status({fill:"red",shape:"ring",text:RED._("common.status.not-connected")});
|
||||
});
|
||||
} else {
|
||||
this.error("missing serial config");
|
||||
this.error(RED._("serial.errors.missing-conf"));
|
||||
}
|
||||
|
||||
this.on("close", function(done) {
|
||||
@ -200,13 +199,13 @@ module.exports = function(RED) {
|
||||
RED.nodes.registerType("serial in",SerialInNode);
|
||||
|
||||
|
||||
var serialPool = (function() {
|
||||
var serialPool = function() {
|
||||
var connections = {};
|
||||
return {
|
||||
get:function(port,baud,databits,parity,stopbits,newline,callback) {
|
||||
var id = port;
|
||||
if (!connections[id]) {
|
||||
connections[id] = (function() {
|
||||
connections[id] = function() {
|
||||
var obj = {
|
||||
_emitter: new events.EventEmitter(),
|
||||
serial: null,
|
||||
@ -218,15 +217,26 @@ module.exports = function(RED) {
|
||||
}
|
||||
//newline = newline.replace("\\n","\n").replace("\\r","\r");
|
||||
var setupSerial = function() {
|
||||
obj.serial = new serialp.SerialPort(port,{
|
||||
baudrate: baud,
|
||||
databits: databits,
|
||||
parity: parity,
|
||||
stopbits: stopbits,
|
||||
parser: serialp.parsers.raw
|
||||
},true, function(err, results) { if (err) { obj.serial.emit('error',err); } });
|
||||
//if (newline == "") {
|
||||
obj.serial = new serialp.SerialPort(port,{
|
||||
baudrate: baud,
|
||||
databits: databits,
|
||||
parity: parity,
|
||||
stopbits: stopbits,
|
||||
parser: serialp.parsers.raw
|
||||
},true, function(err, results) { if (err) { obj.serial.emit('error',err); } });
|
||||
//}
|
||||
//else {
|
||||
// obj.serial = new serialp.SerialPort(port,{
|
||||
// baudrate: baud,
|
||||
// databits: databits,
|
||||
// parity: parity,
|
||||
// stopbits: stopbits,
|
||||
// parser: serialp.parsers.readline(newline)
|
||||
// },true, function(err, results) { if (err) obj.serial.emit('error',err); });
|
||||
//}
|
||||
obj.serial.on('error', function(err) {
|
||||
RED.log.error("serial port "+port+" error "+err);
|
||||
RED.log.error(RED._("serial.errors.error",{port:port,error:err.toString()}));
|
||||
obj._emitter.emit('closed');
|
||||
obj.tout = setTimeout(function() {
|
||||
setupSerial();
|
||||
@ -234,7 +244,7 @@ module.exports = function(RED) {
|
||||
});
|
||||
obj.serial.on('close', function() {
|
||||
if (!obj._closing) {
|
||||
RED.log.error("serial port "+port+" closed unexpectedly");
|
||||
RED.log.error(RED._("serial.errors.unexpected-close",{port:port}));
|
||||
obj._emitter.emit('closed');
|
||||
obj.tout = setTimeout(function() {
|
||||
setupSerial();
|
||||
@ -242,23 +252,30 @@ module.exports = function(RED) {
|
||||
}
|
||||
});
|
||||
obj.serial.on('open',function() {
|
||||
RED.log.info("serial port "+port+" opened at "+baud+" baud "+databits+""+parity.charAt(0).toUpperCase()+stopbits);
|
||||
RED.log.info(RED._("serial.onopen",{port:port,baud:baud,config: databits+""+parity.charAt(0).toUpperCase()+stopbits}));
|
||||
if (obj.tout) { clearTimeout(obj.tout); }
|
||||
//obj.serial.flush();
|
||||
obj._emitter.emit('ready');
|
||||
});
|
||||
obj.serial.on('data',function(d) {
|
||||
for (var z=0; z<d.length; z++) {
|
||||
obj._emitter.emit('data',d[z]);
|
||||
}
|
||||
//console.log(Buffer.isBuffer(d),d.length,d);
|
||||
//if (typeof d !== "string") {
|
||||
// //d = d.toString();
|
||||
for (var z=0; z<d.length; z++) {
|
||||
obj._emitter.emit('data',d[z]);
|
||||
}
|
||||
//}
|
||||
//else {
|
||||
// obj._emitter.emit('data',d);
|
||||
//}
|
||||
});
|
||||
obj.serial.on("disconnect",function() {
|
||||
RED.log.error("serial port "+port+" gone away");
|
||||
RED.log.error(RED._("serial.errors.disconnected",{port:port}));
|
||||
});
|
||||
}
|
||||
setupSerial();
|
||||
return obj;
|
||||
}());
|
||||
}();
|
||||
}
|
||||
return connections[id];
|
||||
},
|
||||
@ -270,7 +287,7 @@ module.exports = function(RED) {
|
||||
connections[port]._closing = true;
|
||||
try {
|
||||
connections[port].close(function() {
|
||||
RED.log.info("serial port closed");
|
||||
RED.log.info(RED._("serial.errors.closed",{port:port}));
|
||||
done();
|
||||
});
|
||||
}
|
||||
@ -281,7 +298,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}());
|
||||
}();
|
||||
|
||||
RED.httpAdmin.get("/serialports", RED.auth.needsPermission('serial.read'), function(req,res) {
|
||||
serialp.list(function (err, ports) {
|
||||
|
51
io/serialport/locales/en-US/25-serial.json
Normal file
51
io/serialport/locales/en-US/25-serial.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"serial": {
|
||||
"label": {
|
||||
"serialport": "Serial Port",
|
||||
"settings": "Settings",
|
||||
"baudrate": "Baud Rate",
|
||||
"databits": "Data Bits",
|
||||
"parity": "Parity",
|
||||
"stopbits": "Stop Bits",
|
||||
"input": "Input",
|
||||
"split": "Split input",
|
||||
"deliver": "and deliver",
|
||||
"output": "Output",
|
||||
"serial": "serial",
|
||||
"none": "none"
|
||||
},
|
||||
"placeholder": {
|
||||
"serialport": "for example: /dev/ttyUSB0/"
|
||||
},
|
||||
"parity": {
|
||||
"none": "None",
|
||||
"even": "Even",
|
||||
"mark": "Mark",
|
||||
"odd": "Odd",
|
||||
"space": "Space"
|
||||
},
|
||||
"split": {
|
||||
"character": "on the character",
|
||||
"timeout": "after a timeout of",
|
||||
"length": "into fixed lengths of"
|
||||
},
|
||||
"output": {
|
||||
"ascii": "ascii strings",
|
||||
"binary": "binary buffers"
|
||||
},
|
||||
"addsplit": "add split character to output messages",
|
||||
"tip": {
|
||||
"split": "Tip: the \"Split on\" character is used to split the input into separate messages. It can also be added to every message sent out to the serial port.",
|
||||
"timeout": "Tip: In timeout mode timeout starts from arrival of first character."
|
||||
},
|
||||
"onopen": "serial port __port__ opened at __baud__ baud __config__",
|
||||
"errors": {
|
||||
"missing-conf": "missing serial config",
|
||||
"serial-port": "serial port",
|
||||
"error": "serial port __port__ error: __error__",
|
||||
"unexpected-close": "serial port __port__ closed unexpectedly",
|
||||
"disconnected": "serial port __port__ disconnected",
|
||||
"closed": "serial port __port__ closed"
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="e-mail">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-envelope"></i> To</label>
|
||||
<label for="node-input-name"><i class="fa fa-envelope"></i> <span data-i18n="email.label.to"></span></label>
|
||||
<input type="text" id="node-input-name" placeholder="email@address.com">
|
||||
</div>
|
||||
<!-- <div class="form-row">
|
||||
@ -45,27 +45,27 @@
|
||||
</select>
|
||||
</div> -->
|
||||
<div class="form-row">
|
||||
<label for="node-input-server"><i class="fa fa-globe"></i> Server</label>
|
||||
<label for="node-input-server"><i class="fa fa-globe"></i> <span data-i18n="email.label.server"></span></label>
|
||||
<input type="text" id="node-input-server" placeholder="smtp.gmail.com">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-port"><i class="fa fa-random"></i> Port</label>
|
||||
<label for="node-input-port"><i class="fa fa-random"></i> <span data-i18n="email.label.port"></span></label>
|
||||
<input type="text" id="node-input-port" placeholder="465">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-userid"><i class="fa fa-user"></i> Userid</label>
|
||||
<label for="node-input-userid"><i class="fa fa-user"></i> <span data-i18n="email.label.userid"></span></label>
|
||||
<input type="text" id="node-input-userid">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-password"><i class="fa fa-lock"></i> Password</label>
|
||||
<label for="node-input-password"><i class="fa fa-lock"></i> <span data-i18n="email.label.password"></span></label>
|
||||
<input type="password" id="node-input-password">
|
||||
</div>
|
||||
<br/>
|
||||
<div class="form-row">
|
||||
<label for="node-input-dname"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-dname" placeholder="Name">
|
||||
<label for="node-input-dname"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-dname" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips" id="node-tip"><b>Note:</b> Copied credentials from global emailkeys.js file.</div>
|
||||
<div class="form-tips" id="node-tip"><span data-i18n="[html]email.tip.cred"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="e-mail">
|
||||
@ -110,7 +110,7 @@
|
||||
$('#node-tip').show();
|
||||
} else {
|
||||
$('#node-tip').hide();
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -119,36 +119,36 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="e-mail in">
|
||||
<div class="form-row node-input-repeat">
|
||||
<label for="node-input-repeat"><i class="fa fa-repeat"></i> Check Repeat (S)</label>
|
||||
<input type="text" id="node-input-repeat" placeholder="300">
|
||||
<label for="node-input-repeat"><i class="fa fa-repeat"></i> <span data-i18n="email.label.repeat"></span></label>
|
||||
<input type="text" id="node-input-repeat" style="width: 80px"> <span data-i18n="email.label.seconds">seconds</span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-server"><i class="fa fa-globe"></i> Server</label>
|
||||
<label for="node-input-server"><i class="fa fa-globe"></i> <span data-i18n="email.label.server"></span></label>
|
||||
<input type="text" id="node-input-server" placeholder="imap.gmail.com">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-port"><i class="fa fa-random"></i> Port</label>
|
||||
<label for="node-input-port"><i class="fa fa-random"></i> <span data-i18n="email.label.port"></span></label>
|
||||
<input type="text" id="node-input-port" placeholder="993">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-userid"><i class="fa fa-user"></i> Userid</label>
|
||||
<label for="node-input-userid"><i class="fa fa-user"></i> <span data-i18n="email.label.userid"></span></label>
|
||||
<input type="text" id="node-input-userid">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-password"><i class="fa fa-lock"></i> Password</label>
|
||||
<label for="node-input-password"><i class="fa fa-lock"></i> <span data-i18n="email.label.password"></span></label>
|
||||
<input type="password" id="node-input-password">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-box"><i class="fa fa-inbox"></i> Folder</label>
|
||||
<label for="node-input-box"><i class="fa fa-inbox"></i> <span data-i18n="email.label.folder"></span></label>
|
||||
<input type="text" id="node-input-box">
|
||||
</div>
|
||||
<br/>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips" id="node-tip"><b>Note:</b> Copied credentials from global emailkeys.js file.</div>
|
||||
<div id="node-input-tip" class="form-tips">Tip: <b>ONLY</b> retrieves the single most recent email.</div>
|
||||
<div class="form-tips" id="node-tip"><span data-i18n="[html]email.tip.cred"></span></div>
|
||||
<div id="node-input-tip" class="form-tips"><span data-i18n="[html]email.tip.recent"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="e-mail in">
|
||||
@ -192,7 +192,7 @@
|
||||
$('#node-tip').show();
|
||||
} else {
|
||||
$('#node-tip').hide();
|
||||
}
|
||||
};
|
||||
if (typeof this.box === 'undefined') {
|
||||
$("#node-input-box").val("INBOX");
|
||||
this.box = "INBOX";
|
||||
|
@ -40,7 +40,7 @@ module.exports = function(RED) {
|
||||
this.userid = globalkeys.user;
|
||||
flag = true;
|
||||
} else {
|
||||
this.error("No e-mail userid set");
|
||||
this.error(RED._("email.errors.nouserid"));
|
||||
}
|
||||
}
|
||||
if (this.credentials && this.credentials.hasOwnProperty("password")) {
|
||||
@ -50,7 +50,7 @@ module.exports = function(RED) {
|
||||
this.password = globalkeys.pass;
|
||||
flag = true;
|
||||
} else {
|
||||
this.error("No e-mail password set");
|
||||
this.error(RED._("email.errors.nopassword"));
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
@ -71,9 +71,9 @@ module.exports = function(RED) {
|
||||
this.on("input", function(msg) {
|
||||
if (msg.hasOwnProperty("payload")) {
|
||||
if (smtpTransport) {
|
||||
node.status({fill:"blue",shape:"dot",text:"sending"});
|
||||
node.status({fill:"blue",shape:"dot",text:RED._("email.status.sending")});
|
||||
if (msg.to && node.name && (msg.to !== node.name)) {
|
||||
node.warn("Warning: msg properties can no longer override set node properties. See bit.ly/nr-override-msg-props");
|
||||
node.warn(RED._("common.errors.nooverride"));
|
||||
}
|
||||
var sendopts = { from: node.userid }; // sender address
|
||||
sendopts.to = node.name || msg.to; // comma separated list of addressees
|
||||
@ -92,27 +92,27 @@ module.exports = function(RED) {
|
||||
sendopts.attachments[0].contentType = msg.headers["content-type"];
|
||||
}
|
||||
// Create some body text..
|
||||
sendopts.text = "Your file from Node-RED is attached : "+(msg.filename.replace(/^.*[\\\/]/, '') || "file.bin")+ (msg.hasOwnProperty("description") ? "\n\n"+msg.description : "");
|
||||
sendopts.text = RED._("email.default-message",{filename:(msg.filename.replace(/^.*[\\\/]/, '') || "file.bin"),description:(msg.hasOwnProperty("description") ? "\n\n"+msg.description : "")});
|
||||
}
|
||||
else {
|
||||
var payload = RED.util.ensureString(msg.payload);
|
||||
sendopts.text = payload; // plaintext body
|
||||
sendopts.text = payload; // plaintext body
|
||||
if (/<[a-z][\s\S]*>/i.test(payload)) { sendopts.html = payload; } // html body
|
||||
if (msg.attachments) { sendopts.attachments = msg.attachments; } // add attachments
|
||||
}
|
||||
smtpTransport.sendMail(sendopts, function(error, info) {
|
||||
if (error) {
|
||||
node.error(error,msg);
|
||||
node.status({fill:"red",shape:"ring",text:"send failed"});
|
||||
node.status({fill:"red",shape:"ring",text:RED._("email.status.sendfail")});
|
||||
} else {
|
||||
node.log("Message sent: " + info.response);
|
||||
node.log(RED._("email.status.messagesent",{response:info.response}));
|
||||
node.status({});
|
||||
}
|
||||
});
|
||||
}
|
||||
else { node.warn("No Email credentials found. See info panel."); }
|
||||
else { node.warn(RED._("email.errors.nocredentials")); }
|
||||
}
|
||||
else { node.warn("No payload to send"); }
|
||||
else { node.warn(RED._("email.errors.nopayload")); }
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("e-mail",EmailNode,{
|
||||
@ -139,7 +139,7 @@ module.exports = function(RED) {
|
||||
this.userid = globalkeys.user;
|
||||
flag = true;
|
||||
} else {
|
||||
this.error("No e-mail userid set");
|
||||
this.error(RED._("email.errors.nouserid"));
|
||||
}
|
||||
}
|
||||
if (this.credentials && this.credentials.hasOwnProperty("password")) {
|
||||
@ -149,7 +149,7 @@ module.exports = function(RED) {
|
||||
this.password = globalkeys.pass;
|
||||
flag = true;
|
||||
} else {
|
||||
this.error("No e-mail password set");
|
||||
this.error(RED._("email.errors.nopassword"));
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
@ -172,7 +172,6 @@ module.exports = function(RED) {
|
||||
});
|
||||
|
||||
if (!isNaN(this.repeat) && this.repeat > 0) {
|
||||
node.log("repeat = "+this.repeat);
|
||||
this.interval_id = setInterval( function() {
|
||||
node.emit("input",{});
|
||||
}, this.repeat );
|
||||
@ -180,19 +179,19 @@ module.exports = function(RED) {
|
||||
|
||||
this.on("input", function(msg) {
|
||||
imap.once('ready', function() {
|
||||
node.status({fill:"blue",shape:"dot",text:"fetching"});
|
||||
node.status({fill:"blue",shape:"dot",text:RED._("email.status.fetching")});
|
||||
var pay = {};
|
||||
imap.openBox(node.box, false, function(err, box) {
|
||||
if (err) {
|
||||
node.status({fill:"red",shape:"ring",text:"fetch folder error"});
|
||||
node.error("Failed to fetch folder "+node.box,err);
|
||||
node.status({fill:"red",shape:"ring",text:RED._("email.status.foldererror")});
|
||||
node.error(RED._("email.errors.fetchfail",{folder:node.box}),err);
|
||||
}
|
||||
else {
|
||||
if (box.messages.total > 0) {
|
||||
//var f = imap.seq.fetch(box.messages.total + ':*', { markSeen:true, bodies: ['HEADER.FIELDS (FROM SUBJECT DATE TO CC BCC)','TEXT'] });
|
||||
var f = imap.seq.fetch(box.messages.total + ':*', { markSeen:true, bodies: ['HEADER','TEXT'] });
|
||||
f.on('message', function(msg, seqno) {
|
||||
node.log('message: #'+ seqno);
|
||||
node.log(RED._("email.status.message",{number:seqno}));
|
||||
var prefix = '(#' + seqno + ') ';
|
||||
msg.on('body', function(stream, info) {
|
||||
var buffer = '';
|
||||
@ -210,62 +209,54 @@ module.exports = function(RED) {
|
||||
var parts = buffer.split("Content-Type");
|
||||
for (var p = 0; p < parts.length; p++) {
|
||||
if (parts[p].indexOf("text/plain") >= 0) {
|
||||
console.log("TEXT");
|
||||
pay.payload = parts[p].split("\n").slice(1,-2).join("\n").trim();
|
||||
}
|
||||
else if (parts[p].indexOf("text/html") >= 0) {
|
||||
console.log("HTML");
|
||||
pay.html = parts[p].split("\n").slice(1,-2).join("\n").trim();
|
||||
} else {
|
||||
console.log("OTHER");
|
||||
pay.payload = parts[0];
|
||||
}
|
||||
console.log("***",pay.payload,"***");
|
||||
}
|
||||
//pay.body = buffer;
|
||||
}
|
||||
});
|
||||
});
|
||||
msg.on('end', function() {
|
||||
//node.log('Finished: '+prefix);
|
||||
//node.log('finished: '+prefix);
|
||||
});
|
||||
});
|
||||
f.on('error', function(err) {
|
||||
node.warn('fetch message error: ' + err);
|
||||
node.status({fill:"red",shape:"ring",text:"fetch message error"});
|
||||
node.warn(RED._("email.errors.messageerror",{error:err}));
|
||||
node.status({fill:"red",shape:"ring",text:RED._("email.status.messageerror")});
|
||||
});
|
||||
f.on('end', function() {
|
||||
delete(pay._msgid);
|
||||
if (JSON.stringify(pay) !== oldmail) {
|
||||
oldmail = JSON.stringify(pay);
|
||||
node.send(pay);
|
||||
node.log('received new email: '+pay.topic);
|
||||
node.log(RED._("email.status.newemail",{topic:pay.topic}));
|
||||
}
|
||||
else { node.log('duplicate not sent: '+pay.topic); }
|
||||
//node.status({fill:"green",shape:"dot",text:"ok"});
|
||||
else { node.log(RED._("email.status.duplicate",{topic:pay.topic})); }
|
||||
//node.status({fill:"green",shape:"dot",text:RED._("common.status.ok")});
|
||||
node.status({});
|
||||
});
|
||||
}
|
||||
else {
|
||||
node.log("you have achieved inbox zero");
|
||||
//node.status({fill:"green",shape:"dot",text:"ok"});
|
||||
node.log(RED._("email.status.inboxzero"));
|
||||
//node.status({fill:"green",shape:"dot",text:RED._("common.status.ok")});
|
||||
node.status({});
|
||||
}
|
||||
}
|
||||
imap.end();
|
||||
});
|
||||
});
|
||||
node.status({fill:"grey",shape:"dot",text:"connecting"});
|
||||
node.status({fill:"grey",shape:"dot",text:RED._("common.status.connecting")});
|
||||
imap.connect();
|
||||
});
|
||||
|
||||
imap.on('error', function(err) {
|
||||
node.log(err);
|
||||
node.status({fill:"red",shape:"ring",text:"connect error"});
|
||||
});
|
||||
|
||||
this.on("error", function(err) {
|
||||
node.log("error: ",err);
|
||||
node.status({fill:"red",shape:"ring",text:RED._("email.status.connecterror")});
|
||||
});
|
||||
|
||||
this.on("close", function() {
|
||||
|
43
social/email/locales/en-US/61-email.json
Normal file
43
social/email/locales/en-US/61-email.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"email": {
|
||||
"label": {
|
||||
"to": "To",
|
||||
"server": "Server",
|
||||
"port": "Port",
|
||||
"userid": "Userid",
|
||||
"password": "Password",
|
||||
"repeat": "Refresh",
|
||||
"seconds": "seconds",
|
||||
"folder": "Folder"
|
||||
},
|
||||
|
||||
"default-message": "Your file from Node-RED is attached: __filename__ __description__",
|
||||
|
||||
|
||||
"tip": {
|
||||
"cred": "<b>Note:</b> Copied credentials from global emailkeys.js file.",
|
||||
"recent": "Tip: Only retrieves the single most recent email."
|
||||
},
|
||||
"status": {
|
||||
"messagesent": "Message sent: __response__",
|
||||
"fetching": "fetching",
|
||||
"foldererror": "fetch folder error",
|
||||
"messageerror": "fetch message error",
|
||||
"message": "message #__number__",
|
||||
"newemail": "received new email: __topic__",
|
||||
"duplicate": "duplicate not sent: __topic__",
|
||||
"inboxzero": "you have achieved Inbox Zero",
|
||||
"sending": "sending",
|
||||
"sendfail": "send failed",
|
||||
"connecterror": "connect error"
|
||||
},
|
||||
"errors": {
|
||||
"nouserid": "No e-mail userid set",
|
||||
"nopassword": "No e-mail password set",
|
||||
"nocredentials": "No Email credentials found. See info panel.",
|
||||
"nopayload": "No payload to send",
|
||||
"fetchfail": "Failed to fetch folder: __folder__",
|
||||
"messageerror": "Fetch message error: __error__"
|
||||
}
|
||||
}
|
||||
}
|
@ -16,18 +16,17 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="feedparse">
|
||||
<div class="form-row">
|
||||
<label for="node-input-url"><i class="fa fa-globe"></i> Feed url</label>
|
||||
<label for="node-input-url"><i class="fa fa-globe"></i> <span data-i18n="feedparse.label.feedurl"></span></label>
|
||||
<input type="text" id="node-input-url">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-interval"><i class="fa fa-repeat"></i> Repeat <span style="font-size: 0.9em;">(M)</span></label>
|
||||
<input type="text" id="node-input-interval" placeholder="minutes">
|
||||
<label for="node-input-interval"><i class="fa fa-repeat"></i> <span data-i18n="feedparse.label.refresh"></span></label>
|
||||
<input type="text" id="node-input-interval" style="width: 50px"> <span data-i18n="feedparse.label.minutes"></span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<!-- <div class="form-tips"></div> -->
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="feedparse">
|
||||
|
@ -38,7 +38,7 @@ module.exports = function(RED) {
|
||||
req.on('error', function(err) { node.error(err); });
|
||||
|
||||
req.on('response', function(res) {
|
||||
if (res.statusCode != 200) { node.warn('error - Bad status code'); }
|
||||
if (res.statusCode != 200) { node.warn(RED._("feedparse.errors.badstatuscode")); }
|
||||
else { res.pipe(feedparser); }
|
||||
});
|
||||
|
||||
@ -46,7 +46,7 @@ module.exports = function(RED) {
|
||||
|
||||
feedparser.on('readable', function () {
|
||||
var stream = this, article;
|
||||
while (article = stream.read()) { // jshint ignore:line
|
||||
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 = {
|
||||
@ -65,7 +65,7 @@ module.exports = function(RED) {
|
||||
this.interval_id = setInterval(function() { getFeed(); }, node.interval);
|
||||
getFeed();
|
||||
} else {
|
||||
this.error("Invalid url");
|
||||
this.error(RED._("feedparse.errors.invalidurl"));
|
||||
}
|
||||
|
||||
this.on("close", function() {
|
||||
|
13
social/feedparser/locales/en-US/32-feedparse.json
Normal file
13
social/feedparser/locales/en-US/32-feedparse.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"feedparse": {
|
||||
"label": {
|
||||
"feedurl": "Feed url",
|
||||
"refresh": "Refresh",
|
||||
"minutes": "minutes"
|
||||
},
|
||||
"errors": {
|
||||
"badstatuscode": "error - Bad status code",
|
||||
"invalidurl": "Invalid url"
|
||||
}
|
||||
}
|
||||
}
|
@ -16,19 +16,18 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="irc in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-ircserver"><i class="fa fa-globe"></i> IRC Server</label>
|
||||
<label for="node-input-ircserver"><i class="fa fa-globe"></i> <span data-i18n="irc.label.ircserver"></span></label>
|
||||
<input type="text" id="node-input-ircserver">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-channel"><i class="fa fa-random"></i> Channel</label>
|
||||
<label for="node-input-channel"><i class="fa fa-random"></i> <span data-i18n="irc.label.channel"></span></label>
|
||||
<input type="text" id="node-input-channel" placeholder="#nodered">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips">The channel to join must start with a # (as per normal irc rules...)<br/>
|
||||
You may join multiple channels by comma separating a list - #chan1,#chan2,etc.</div>
|
||||
<div class="form-tips"><span data-i18n="[html]irc.tip.in"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="irc in">
|
||||
@ -118,27 +117,26 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="irc out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-ircserver"><i class="fa fa-globe"></i> IRC Server</label>
|
||||
<label for="node-input-ircserver"><i class="fa fa-globe"></i> <span data-i18n="irc.label.ircserver"></span></label>
|
||||
<input type="text" id="node-input-ircserver">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-channel"><i class="fa fa-random"></i> Channel</label>
|
||||
<label for="node-input-channel"><i class="fa fa-random"></i> <span data-i18n="irc.label.channel"></span></label>
|
||||
<input type="text" id="node-input-channel" placeholder="#nodered">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-sendObject"><i class="fa fa-arrows"></i> Action</label>
|
||||
<label for="node-input-sendObject"><i class="fa fa-arrows"></i> <span data-i18n="irc.label.action"></span></label>
|
||||
<select type="text" id="node-input-sendObject" style="display: inline-block; vertical-align: middle; width:70%;">
|
||||
<option value="pay">Send payload to channel(s)</option>
|
||||
<option value="true">Use msg.topic to set nickname or channel(s)</option>
|
||||
<option value="false">Send complete msg object to channel(s)</option>
|
||||
<option value="pay" data-i18n="irc.payload"></option>
|
||||
<option value="true" data-i18n="irc.topic"></option>
|
||||
<option value="false" data-i18n="irc.msg"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips">The channel to join must start with a # (as per normal irc rules...)<br/>
|
||||
Sending the complete object will stringify the whole msg object before sending.</div>
|
||||
<div class="form-tips"><span data-i18n="[html]irc.tip.out"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="irc out">
|
||||
@ -183,24 +181,24 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="irc-server">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-server"><i class="fa fa-globe"></i> IRC Server</label>
|
||||
<label for="node-config-input-server"><i class="fa fa-globe"></i> <span data-i18n="irc.label.ircserver"></span></label>
|
||||
<input type="text" id="node-config-input-server" placeholder="irc.freenode.net" style="width: 45%;" >
|
||||
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
|
||||
<input type="text" id="node-config-input-port" placeholder="Port" style="width:45px">
|
||||
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> <span data-i18n="irc.label.port"></span></label>
|
||||
<input type="text" id="node-config-input-port" style="width:45px">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-config-input-ssl" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-config-input-ssl" style="width: 70%;">Use Secure SSL connection ?</label>
|
||||
<label for="node-config-input-ssl" style="width: 70%;"><span data-i18n="irc.label.ssl"></span></label>
|
||||
</div>
|
||||
<div class="form-row" id="certrow">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-config-input-cert" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-config-input-cert" style="width: 70%;">Allow self-signed certificates ?</label>
|
||||
<label for="node-config-input-cert" style="width: 70%;"><span data-i18n="irc.label.self"></span></label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-nickname"><i class="fa fa-user"></i> Nickname</label>
|
||||
<input type="text" id="node-config-input-nickname" placeholder="joe123">
|
||||
<label for="node-config-input-nickname"><i class="fa fa-user"></i> <span data-i18n="irc.label.nickname"></span></label>
|
||||
<input type="text" id="node-config-input-nickname">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
@ -47,45 +47,45 @@ module.exports = function(RED) {
|
||||
this.channel = n.channel || this.serverConfig.channel;
|
||||
var node = this;
|
||||
if (node.serverConfig.ircclient === null) {
|
||||
node.log("CONNECT: "+node.serverConfig.server);
|
||||
node.status({fill:"grey",shape:"dot",text:"connecting"});
|
||||
node.log(RED._("irc.errors.connect")+": "+node.serverConfig.server);
|
||||
node.status({fill:"grey",shape:"dot",text:RED._("common.status.connecting")});
|
||||
var options = {autoConnect:true,autoRejoin:false,floodProtection:true,secure:node.serverConfig.ssl,selfSigned:node.serverConfig.cert,port:node.serverConfig.port,retryDelay:20000};
|
||||
node.serverConfig.ircclient = new irc.Client(node.serverConfig.server, node.serverConfig.nickname, options);
|
||||
node.serverConfig.ircclient.setMaxListeners(0);
|
||||
node.serverConfig.ircclient.addListener('error', function(message) {
|
||||
if (RED.settings.verbose) { node.log("ERR: "+JSON.stringify(message)); }
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.err")+": "+JSON.stringify(message)); }
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('netError', function(message) {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
if (RED.settings.verbose) { node.log("NET: "+JSON.stringify(message)); }
|
||||
node.status({fill:"red",shape:"ring",text:"net error"});
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.net")+": "+JSON.stringify(message)); }
|
||||
node.status({fill:"red",shape:"ring",text:RED._("common.status.neterror")});
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('connect', function() {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
if (RED.settings.verbose) { node.log("CONNECTED "); }
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.connected")); }
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('registered', function(message) {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
node.log(node.serverConfig.ircclient.nick+" ONLINE: "+message.server);
|
||||
node.status({fill:"yellow",shape:"dot",text:"connected"});
|
||||
node.log(node.serverConfig.ircclient.nick+" "+RED._("irc.errors.online")+": "+message.server);
|
||||
node.status({fill:"yellow",shape:"dot",text:RED._("common.status.connected")});
|
||||
node.serverConfig.ircclient.join( node.channel, function(data) {
|
||||
node.log(data+" JOINED: "+node.channel);
|
||||
node.status({fill:"green",shape:"dot",text:"joined"});
|
||||
node.log(data+" "+RED._("irc.errors.joined")+": "+node.channel);
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.joined")});
|
||||
});
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('ping', function(server) {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
if (RED.settings.verbose) { node.log("PING from "+JSON.stringify(server)); }
|
||||
node.status({fill:"green",shape:"dot",text:"ok"});
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.ping")+" "+JSON.stringify(server)); }
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.ok")});
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('quit', function(nick, reason, channels, message) {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
if (RED.settings.verbose) { node.log("QUIT: "+nick+" "+reason+" "+channels+" "+JSON.stringify(message)); }
|
||||
node.status({fill:"grey",shape:"ring",text:"quit"});
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.quit")+": "+nick+" "+reason+" "+channels+" "+JSON.stringify(message)); }
|
||||
node.status({fill:"grey",shape:"ring",text:RED._("common.status.quit")});
|
||||
//node.serverConfig.ircclient.disconnect( function() {
|
||||
// node.serverConfig.ircclient.connect();
|
||||
//});
|
||||
//if (RED.settings.verbose) { node.log("restart"); } // then retry
|
||||
//if (RED.settings.verbose) { node.log(RED._("irc.errors.restart")); } // then retry
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('raw', function (message) { // any message received means we are alive
|
||||
//console.log("RAW:"+JSON.stringify(message));
|
||||
@ -102,8 +102,8 @@ module.exports = function(RED) {
|
||||
if ((Date.now()-node.serverConfig.lastseen) > 300000) { // If more than 5 mins
|
||||
//node.serverConfig.ircclient.disconnect();
|
||||
//node.serverConfig.ircclient.connect();
|
||||
node.status({fill:"grey",shape:"ring",text:"no connection"});
|
||||
if (RED.settings.verbose) { node.log("CONNECTION LOST ?"); }
|
||||
node.status({fill:"grey",shape:"ring",text:RED._("common.status.noconnection")});
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.connectionlost")); }
|
||||
}
|
||||
//node.serverConfig.ircclient.send.apply(node.serverConfig.ircclient,["TIME"]); // request time to check link
|
||||
}, 60000); // check every 1 min
|
||||
@ -113,11 +113,11 @@ module.exports = function(RED) {
|
||||
node.ircclient = node.serverConfig.ircclient;
|
||||
|
||||
node.ircclient.addListener('registered', function(message) {
|
||||
//node.log(node.ircclient.nick+" ONLINE");
|
||||
node.status({fill:"yellow",shape:"dot",text:"connected"});
|
||||
//node.log(node.ircclient.nick+" "+RED._("irc.errors.online"));
|
||||
node.status({fill:"yellow",shape:"dot",text:RED._("common.status.connected")});
|
||||
node.ircclient.join( node.channel, function(data) {
|
||||
// node.log(data+" JOINED "+node.channel);
|
||||
node.status({fill:"green",shape:"dot",text:"joined"});
|
||||
// node.log(data+" "+RED._("irc.errors.joined")+" "+node.channel);
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.joined")});
|
||||
});
|
||||
});
|
||||
node.ircclient.addListener('message', function (from, to, message) {
|
||||
@ -136,27 +136,27 @@ module.exports = function(RED) {
|
||||
node.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);
|
||||
//node.log(who+' '+RED._("irc.errors.hasjoined")+' '+channel);
|
||||
});
|
||||
node.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);
|
||||
//node.log(from+' '+RED._("irc.errors.sentinvite")+' '+channel+': '+message);
|
||||
});
|
||||
node.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);
|
||||
//node.log(who+' '+RED._("irc.errors.hasleft")+' '+channel+': '+reason);
|
||||
});
|
||||
node.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);
|
||||
//node.log(nick+' '+RED._("irc.errors.hasquit")+' '+channels+': '+reason);
|
||||
});
|
||||
node.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);
|
||||
//node.log(who+' '+RED._("irc.errors.kickedfrom")+' '+channel+' by '+by+': '+reason);
|
||||
});
|
||||
node.ircclient.addListener('names', function (channel, nicks) {
|
||||
var msg = { "payload": { "type": "names", "channel": channel, "names": nicks} };
|
||||
@ -182,45 +182,45 @@ module.exports = function(RED) {
|
||||
this.channel = n.channel || this.serverConfig.channel;
|
||||
var node = this;
|
||||
if (node.serverConfig.ircclient === null) {
|
||||
node.log("CONNECT: "+node.serverConfig.server);
|
||||
node.status({fill:"grey",shape:"dot",text:"connecting"});
|
||||
node.log(RED._("irc.errors.connect")+": "+node.serverConfig.server);
|
||||
node.status({fill:"grey",shape:"dot",text:RED._("common.status.connecting")});
|
||||
var options = {autoConnect:true,autoRejoin:false,floodProtection:true,secure:node.serverConfig.ssl,selfSigned:node.serverConfig.cert,port:node.serverConfig.port,retryDelay:20000};
|
||||
node.serverConfig.ircclient = new irc.Client(node.serverConfig.server, node.serverConfig.nickname, options);
|
||||
node.serverConfig.ircclient.setMaxListeners(0);
|
||||
node.serverConfig.ircclient.addListener('error', function(message) {
|
||||
if (RED.settings.verbose) { node.log("ERR: "+JSON.stringify(message)); }
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.err")+": "+JSON.stringify(message)); }
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('netError', function(message) {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
if (RED.settings.verbose) { node.log("NET: "+JSON.stringify(message)); }
|
||||
node.status({fill:"red",shape:"ring",text:"net error"});
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.net")+": "+JSON.stringify(message)); }
|
||||
node.status({fill:"red",shape:"ring",text:RED._("common.status.neterror")});
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('connect', function() {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
if (RED.settings.verbose) { node.log("CONNECTED "); }
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.connected")); }
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('registered', function(message) {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
node.log(node.serverConfig.ircclient.nick+" ONLINE: "+message.server);
|
||||
node.status({fill:"yellow",shape:"dot",text:"connected"});
|
||||
node.log(node.serverConfig.ircclient.nick+" "+RED._("irc.errors.online")+": "+message.server);
|
||||
node.status({fill:"yellow",shape:"dot",text:RED._("common.status.connected")});
|
||||
node.serverConfig.ircclient.join( node.channel, function(data) {
|
||||
node.log(data+" JOINED: "+node.channel);
|
||||
node.status({fill:"green",shape:"dot",text:"joined"});
|
||||
node.log(data+" "+RED._("irc.errors.joined")+": "+node.channel);
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.joined")});
|
||||
});
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('ping', function(server) {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
if (RED.settings.verbose) { node.log("PING from "+JSON.stringify(server)); }
|
||||
node.status({fill:"green",shape:"dot",text:"ok"});
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.ping")+" "+JSON.stringify(server)); }
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.ok")});
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('quit', function(nick, reason, channels, message) {
|
||||
node.serverConfig.lastseen = Date.now();
|
||||
if (RED.settings.verbose) { node.log("QUIT: "+nick+" "+reason+" "+channels+" "+JSON.stringify(message)); }
|
||||
node.status({fill:"grey",shape:"ring",text:"quit"});
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.quit")+": "+nick+" "+reason+" "+channels+" "+JSON.stringify(message)); }
|
||||
node.status({fill:"grey",shape:"ring",text:RED._("common.status.quit")});
|
||||
//node.serverConfig.ircclient.disconnect( function() {
|
||||
// node.serverConfig.ircclient.connect();
|
||||
//});
|
||||
//if (RED.settings.verbose) { node.log("restart"); } // then retry
|
||||
//if (RED.settings.verbose) { node.log(RED._("irc.errors.restart")); } // then retry
|
||||
});
|
||||
node.serverConfig.ircclient.addListener('raw', function (message) { // any message received means we are alive
|
||||
//console.log("RAW:"+JSON.stringify(message));
|
||||
@ -237,8 +237,8 @@ module.exports = function(RED) {
|
||||
if ((Date.now()-node.serverConfig.lastseen) > 300000) { // If more than 5 mins
|
||||
//node.serverConfig.ircclient.disconnect();
|
||||
//node.serverConfig.ircclient.connect();
|
||||
node.status({fill:"grey",shape:"ring",text:"no connection"});
|
||||
if (RED.settings.verbose) { node.log("CONNECTION LOST ?"); }
|
||||
node.status({fill:"grey",shape:"ring",text:RED._("common.status.noconnection")});
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.connectionlost")); }
|
||||
}
|
||||
//node.serverConfig.ircclient.send.apply(node.serverConfig.ircclient,["TIME"]); // request time to check link
|
||||
}, 60000); // check every 1 min
|
||||
@ -249,7 +249,7 @@ module.exports = function(RED) {
|
||||
|
||||
node.on("input", function(msg) {
|
||||
if (Object.prototype.toString.call( msg.raw ) === '[object Array]') {
|
||||
if (RED.settings.verbose) { node.log("RAW command:"+msg.raw); }
|
||||
if (RED.settings.verbose) { node.log(RED._("irc.errors.rawcommand")+":"+msg.raw); }
|
||||
node.ircclient.send.apply(node.ircclient,msg.raw);
|
||||
}
|
||||
else {
|
||||
@ -259,7 +259,7 @@ module.exports = function(RED) {
|
||||
if ((msg.hasOwnProperty('topic'))&&(typeof msg.topic === "string")) {
|
||||
ch = msg.topic.split(","); // split on , so we can send to multiple
|
||||
}
|
||||
else { node.warn("msg.topic not set"); }
|
||||
else { node.warn(RED._("irc.errors.topicnotset")); }
|
||||
}
|
||||
for (var c = 0; c < ch.length; c++) {
|
||||
if (node.sendFlag == "false") { // send whole message object to each channel
|
||||
|
39
social/irc/locales/en-US/91-irc.json
Normal file
39
social/irc/locales/en-US/91-irc.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"irc": {
|
||||
"label": {
|
||||
"ircserver": "IRC Server",
|
||||
"channel": "Channel",
|
||||
"action": "Action",
|
||||
"port": "Port",
|
||||
"ssl": "Use Secure SSL connection?",
|
||||
"self": "Allow self-signed certificates?",
|
||||
"nickname": "Nickname"
|
||||
},
|
||||
"payload": "Send payload to channel(s)",
|
||||
"topic": "Use msg.topic to set nickname or channel(s)",
|
||||
"msg": "Send complete msg object to channel(s)",
|
||||
"tip": {
|
||||
"in": "The channel to join must start with a #<br/>You may join multiple channels by comma separating a list - #chan1,#chan2,etc.",
|
||||
"out": "The channel to join must start with a #<br/>Sending the complete object will stringify the whole msg object before sending."
|
||||
},
|
||||
"errors": {
|
||||
"connect": "CONNECT",
|
||||
"err": "ERR",
|
||||
"net": "NET",
|
||||
"connected": "CONNECTED",
|
||||
"online": "ONLINE",
|
||||
"joined": "JOINED",
|
||||
"ping": "PING from",
|
||||
"quit": "QUIT",
|
||||
"restart": "restart",
|
||||
"connectionlost": "CONNECTION LOST?",
|
||||
"hasjoined": "has joined",
|
||||
"sentinvite": "sent invite to",
|
||||
"hasleft": "has left",
|
||||
"hasquit": "has quit",
|
||||
"kickedfrom": "was kicked from",
|
||||
"rawcommand": "RAW command",
|
||||
"topicnotset": "msg.topic not set"
|
||||
}
|
||||
}
|
||||
}
|
@ -24,33 +24,6 @@
|
||||
var twitterConfigNodeId = null;
|
||||
var twitterConfigNodeIntervalId = null;
|
||||
|
||||
function showTwitterAuthStart() {
|
||||
var pathname = document.location.pathname;
|
||||
if (pathname.slice(-1) != "/") {
|
||||
pathname += "/";
|
||||
}
|
||||
var callback = encodeURIComponent(location.protocol+"//"+location.hostname+":"+location.port+pathname+"twitter-credentials/"+twitterConfigNodeId+"/auth/callback");
|
||||
$("#node-config-dialog-ok").button("disable");
|
||||
$("#node-config-twitter-row").html('<div style="text-align: center; margin-top: 20px; "><a class="btn" id="node-config-twitter-start" href="twitter-credentials/'+twitterConfigNodeId+'/auth?callback='+callback+'" target="_blank">Click here to authenticate with Twitter.</a></div>');
|
||||
$("#node-config-twitter-start").click(function() {
|
||||
twitterConfigNodeIntervalId = window.setTimeout(pollTwitterCredentials,2000);
|
||||
});
|
||||
}
|
||||
function updateTwitterScreenName(sn) {
|
||||
$("#node-config-input-screen_name").val(sn);
|
||||
$("#node-config-twitter-row").html('<label><i class="fa fa-user"></i> Twitter ID</label><span class="input-xlarge uneditable-input">'+sn+'</span>');
|
||||
}
|
||||
function pollTwitterCredentials(e) {
|
||||
$.getJSON('credentials/twitter-credentials/'+twitterConfigNodeId,function(data) {
|
||||
if (data.screen_name) {
|
||||
updateTwitterScreenName(data.screen_name);
|
||||
twitterConfigNodeIntervalId = null;
|
||||
$("#node-config-dialog-ok").button("enable");
|
||||
} else {
|
||||
twitterConfigNodeIntervalId = window.setTimeout(pollTwitterCredentials,2000);
|
||||
}
|
||||
})
|
||||
}
|
||||
RED.nodes.registerType('twitter-credentials',{
|
||||
category: 'config',
|
||||
defaults: {
|
||||
@ -66,8 +39,36 @@
|
||||
},
|
||||
exportable: false,
|
||||
oneditprepare: function() {
|
||||
twitterConfigNodeId = this.id;
|
||||
if (!this.screen_name || this.screen_name === "") {
|
||||
var clickhere = this._("twitter.label.clickhere");
|
||||
var twitterID = this._("twitter.label.twitter-id");
|
||||
function showTwitterAuthStart() {
|
||||
var pathname = document.location.pathname;
|
||||
if (pathname.slice(-1) != "/") {
|
||||
pathname += "/";
|
||||
}
|
||||
var callback = encodeURIComponent(location.protocol+"//"+location.hostname+":"+location.port+pathname+"twitter-credentials/"+twitterConfigNodeId+"/auth/callback");
|
||||
$("#node-config-dialog-ok").button("disable");
|
||||
$("#node-config-twitter-row").html('<div style="text-align: center; margin-top: 20px; "><a class="btn" id="node-config-twitter-start" href="twitter-credentials/'+twitterConfigNodeId+'/auth?callback='+callback+'" target="_blank">'+clickhere+'</a></div>');
|
||||
$("#node-config-twitter-start").click(function() {
|
||||
twitterConfigNodeIntervalId = window.setTimeout(pollTwitterCredentials,2000);
|
||||
});
|
||||
}
|
||||
function updateTwitterScreenName(sn) {
|
||||
$("#node-config-input-screen_name").val(sn);
|
||||
$("#node-config-twitter-row").html('<label><i class="fa fa-user"></i> '+twitterID+'</label><span class="input-xlarge uneditable-input">'+sn+'</span>');
|
||||
}
|
||||
function pollTwitterCredentials(e) {
|
||||
$.getJSON('credentials/twitter-credentials/'+twitterConfigNodeId,function(data) {
|
||||
if (data.screen_name) {
|
||||
updateTwitterScreenName(data.screen_name);
|
||||
twitterConfigNodeIntervalId = null;
|
||||
$("#node-config-dialog-ok").button("enable");
|
||||
} else {
|
||||
twitterConfigNodeIntervalId = window.setTimeout(pollTwitterCredentials,2000);
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!this.screen_name || this.screen_name == "") {
|
||||
showTwitterAuthStart();
|
||||
} else {
|
||||
if (this.credentials.screen_name) {
|
||||
@ -93,29 +94,27 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="twitter in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-twitter"><i class="fa fa-user"></i> Log in as</label>
|
||||
<label for="node-input-twitter"><i class="fa fa-user"></i> <span data-i18n="twitter.label.twitter-id"></span></label>
|
||||
<input type="text" id="node-input-twitter">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-user"><i class="fa fa-search"></i> Search</label>
|
||||
<label for="node-input-user"><i class="fa fa-search"></i> <span data-i18n="twitter.label.search"></span></label>
|
||||
<select type="text" id="node-input-user" style="display: inline-block; vertical-align: middle; width:60%;">
|
||||
<option value="false">all public tweets</option>
|
||||
<option value="true">the tweets of who you follow</option>
|
||||
<option value="user">the tweets of specific users</option>
|
||||
<option value="dm">your direct messages</option>
|
||||
<option value="false" data-i18n="twitter.search.public"></option>
|
||||
<option value="true" data-i18n="twitter.search.follow"></option>
|
||||
<option value="user" data-i18n="twitter.search.user"></option>
|
||||
<option value="dm" data-i18n="twitter.search.direct"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row" id="node-input-tags-row">
|
||||
<label for="node-input-tags"><i class="fa fa-tags"></i> <span id="node-input-tags-label">for</span></label>
|
||||
<input type="text" id="node-input-tags" placeholder="comma-separated words, @ids, #tags">
|
||||
<label for="node-input-tags"><i class="fa fa-tags"></i> <span id="node-input-tags-label" data-i18n="twitter.label.for"></span></label>
|
||||
<input type="text" id="node-input-tags" data-i18n="[placeholder]twitter.placeholder.for">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips">Tip: Use commas without spaces between multiple search terms. Comma = OR, Space = AND.
|
||||
<br/>The Twitter API WILL NOT deliver 100% of all tweets.
|
||||
<br/>Tweets of who you follow will include their retweets and favourites.</div>
|
||||
<div class="form-tips"><span data-i18n="[html]twitter.tip"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="twitter in">
|
||||
@ -154,9 +153,9 @@
|
||||
}
|
||||
if (this.user == "dm") {
|
||||
var user = RED.nodes.node(this.twitter);
|
||||
return (user?user.label()+" ":"")+"DMs";
|
||||
return (user?user.label()+" ":"")+this._("twitter.label.dmslabel");
|
||||
} else if (this.user == "user") {
|
||||
return this.tags+" tweets";
|
||||
return this.tags+" "+this._("twitter.label.tweetslabel");
|
||||
}
|
||||
return this.tags;
|
||||
},
|
||||
@ -164,18 +163,22 @@
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
var userlabel = this._("twitter.label.user");
|
||||
var userph = this._("twitter.placeholder.user");
|
||||
var forlabel = this._("twitter.label.for");
|
||||
var forph = this._("twitter.placeholder.for");
|
||||
$("#node-input-user").change(function() {
|
||||
var type = $("#node-input-user option:selected").val();
|
||||
if (type == "user") {
|
||||
$("#node-input-tags-row").show();
|
||||
$("#node-input-tags-label").html("User");
|
||||
$("#node-input-tags").attr("placeholder","comma-separated @twitter handles");
|
||||
$("#node-input-tags-label").html(userlabel);
|
||||
$("#node-input-tags").attr("placeholder",userph);
|
||||
} else if (type == "dm") {
|
||||
$("#node-input-tags-row").hide();
|
||||
} else {
|
||||
$("#node-input-tags-row").show();
|
||||
$("#node-input-tags-label").html("for");
|
||||
$("#node-input-tags").attr("placeholder","comma-separated words, @ids, #hashtags");
|
||||
$("#node-input-tags-label").html(forlabel);
|
||||
$("#node-input-tags").attr("placeholder",forph);
|
||||
}
|
||||
|
||||
});
|
||||
@ -187,12 +190,12 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="twitter out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-twitter"><i class="fa fa-user"></i> Twitter</label>
|
||||
<label for="node-input-twitter"><i class="fa fa-user"></i> <span data-i18n="twitter.label.twitter-id"></span></label>
|
||||
<input type="text" id="node-input-twitter">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
var Ntwitter = require('twitter-ng');
|
||||
var ntwitter = require('twitter-ng');
|
||||
var OAuth= require('oauth').OAuth;
|
||||
var request = require('request');
|
||||
|
||||
@ -37,17 +37,17 @@ module.exports = function(RED) {
|
||||
* Populate msg.location based on data found in msg.tweet.
|
||||
*/
|
||||
function addLocationToTweet(msg) {
|
||||
if (msg.tweet) {
|
||||
if (msg.tweet.geo) { // if geo is set, always set location from geo
|
||||
if (msg.tweet.geo.coordinates && msg.tweet.geo.coordinates.length === 2) {
|
||||
if(msg.tweet) {
|
||||
if(msg.tweet.geo) { // if geo is set, always set location from geo
|
||||
if(msg.tweet.geo.coordinates && msg.tweet.geo.coordinates.length === 2) {
|
||||
if (!msg.location) { msg.location = {}; }
|
||||
// coordinates[0] is lat, coordinates[1] is lon
|
||||
msg.location.lat = msg.tweet.geo.coordinates[0];
|
||||
msg.location.lon = msg.tweet.geo.coordinates[1];
|
||||
msg.location.icon = "twitter";
|
||||
}
|
||||
} else if (msg.tweet.coordinates) { // otherwise attempt go get it from coordinates
|
||||
if (msg.tweet.coordinates.coordinates && msg.tweet.coordinates.coordinates.length === 2) {
|
||||
} else if(msg.tweet.coordinates) { // otherwise attempt go get it from coordinates
|
||||
if(msg.tweet.coordinates.coordinates && msg.tweet.coordinates.coordinates.length === 2) {
|
||||
if (!msg.location) { msg.location = {}; }
|
||||
// WARNING! coordinates[1] is lat, coordinates[0] is lon!!!
|
||||
msg.location.lat = msg.tweet.coordinates.coordinates[1];
|
||||
@ -70,7 +70,7 @@ module.exports = function(RED) {
|
||||
var credentials = RED.nodes.getCredentials(this.twitter);
|
||||
|
||||
if (credentials && credentials.screen_name == this.twitterConfig.screen_name) {
|
||||
var twit = new Ntwitter({
|
||||
var twit = new ntwitter({
|
||||
consumer_key: "OKjYEd1ef2bfFolV25G5nQ",
|
||||
consumer_secret: "meRsltCktVMUI8gmggpXett7WBLd1k0qidYazoML6g",
|
||||
access_token_key: credentials.access_token,
|
||||
@ -92,10 +92,10 @@ module.exports = function(RED) {
|
||||
for (var i=0;i<users.length;i++) {
|
||||
var user = users[i].replace(" ","");
|
||||
twit.getUserTimeline({
|
||||
screen_name:user,
|
||||
trim_user:0,
|
||||
count:1
|
||||
},(function() {
|
||||
screen_name:user,
|
||||
trim_user:0,
|
||||
count:1
|
||||
},function() {
|
||||
var u = user+"";
|
||||
return function(err,cb) {
|
||||
if (err) {
|
||||
@ -109,9 +109,9 @@ module.exports = function(RED) {
|
||||
}
|
||||
node.poll_ids.push(setInterval(function() {
|
||||
twit.getUserTimeline({
|
||||
screen_name:u,
|
||||
trim_user:0,
|
||||
since_id:node.since_ids[u]
|
||||
screen_name:u,
|
||||
trim_user:0,
|
||||
since_id:node.since_ids[u]
|
||||
},function(err,cb) {
|
||||
if (cb) {
|
||||
for (var t=cb.length-1;t>=0;t-=1) {
|
||||
@ -124,7 +124,7 @@ module.exports = function(RED) {
|
||||
addLocationToTweet(msg);
|
||||
}
|
||||
node.send(msg);
|
||||
if (t === 0) {
|
||||
if (t == 0) {
|
||||
node.since_ids[u] = tweet.id_str;
|
||||
}
|
||||
}
|
||||
@ -135,14 +135,14 @@ module.exports = function(RED) {
|
||||
});
|
||||
},60000));
|
||||
}
|
||||
}()));
|
||||
}());
|
||||
}
|
||||
} else if (this.user === "dm") {
|
||||
node.poll_ids = [];
|
||||
twit.getDirectMessages({
|
||||
screen_name:node.twitterConfig.screen_name,
|
||||
trim_user:0,
|
||||
count:1
|
||||
screen_name:node.twitterConfig.screen_name,
|
||||
trim_user:0,
|
||||
count:1
|
||||
},function(err,cb) {
|
||||
if (err) {
|
||||
node.error(err);
|
||||
@ -154,11 +154,11 @@ module.exports = function(RED) {
|
||||
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) {
|
||||
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];
|
||||
@ -170,7 +170,7 @@ module.exports = function(RED) {
|
||||
addLocationToTweet(msg);
|
||||
}
|
||||
node.send(msg);
|
||||
if (t === 0) {
|
||||
if (t == 0) {
|
||||
node.since_id = tweet.id_str;
|
||||
}
|
||||
}
|
||||
@ -191,9 +191,7 @@ module.exports = function(RED) {
|
||||
if (bits.length == 4) {
|
||||
if ((Number(bits[0]) < Number(bits[2])) && (Number(bits[1]) < Number(bits[3]))) {
|
||||
st = { locations: node.tags };
|
||||
}
|
||||
else {
|
||||
node.log("possible bad geo area format. Should be lower-left lon, lat, upper-right lon, lat");
|
||||
node.log(RED._("twitter.status.using-geo",{location:node.tags.toString()}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,19 +216,19 @@ module.exports = function(RED) {
|
||||
}
|
||||
});
|
||||
stream.on('limit', function(tweet) {
|
||||
node.warn("tweet rate limit hit");
|
||||
node.warn(RED._("twitter.errors.ratelimit"));
|
||||
});
|
||||
stream.on('error', function(tweet,rc) {
|
||||
if (rc == 420) {
|
||||
node.warn("Twitter rate limit hit");
|
||||
node.warn(RED._("twitter.errors.ratelimit"));
|
||||
} else {
|
||||
node.warn("Stream error:"+tweet.toString()+" ("+rc+")");
|
||||
node.warn(RED._("twitter.errors.streamerror",{error:tweet.toString(),rc:rc}));
|
||||
}
|
||||
setTimeout(setupStream,10000);
|
||||
});
|
||||
stream.on('destroy', function (response) {
|
||||
if (this.active) {
|
||||
node.warn("twitter ended unexpectedly");
|
||||
node.warn(RED._("twitter.errors.unexpectedend"));
|
||||
setTimeout(setupStream,10000);
|
||||
}
|
||||
});
|
||||
@ -243,10 +241,10 @@ module.exports = function(RED) {
|
||||
node.error(err);
|
||||
}
|
||||
} else {
|
||||
this.error("Invalid tag property");
|
||||
this.error(RED._("twitter.errors.invalidtag"));
|
||||
}
|
||||
} else {
|
||||
this.error("missing twitter credentials");
|
||||
this.error(RED._("twitter.errors.missingcredentials"));
|
||||
}
|
||||
|
||||
this.on('close', function() {
|
||||
@ -273,7 +271,7 @@ module.exports = function(RED) {
|
||||
var node = this;
|
||||
|
||||
if (credentials && credentials.screen_name == this.twitterConfig.screen_name) {
|
||||
var twit = new Ntwitter({
|
||||
var twit = new ntwitter({
|
||||
consumer_key: "OKjYEd1ef2bfFolV25G5nQ",
|
||||
consumer_secret: "meRsltCktVMUI8gmggpXett7WBLd1k0qidYazoML6g",
|
||||
access_token_key: credentials.access_token,
|
||||
@ -281,11 +279,11 @@ module.exports = function(RED) {
|
||||
});
|
||||
node.on("input", function(msg) {
|
||||
if (msg.hasOwnProperty("payload")) {
|
||||
node.status({fill:"blue",shape:"dot",text:"tweeting"});
|
||||
node.status({fill:"blue",shape:"dot",text:RED._("twitter.status.tweeting")});
|
||||
|
||||
if (msg.payload.length > 140) {
|
||||
msg.payload = msg.payload.slice(0,139);
|
||||
node.warn("Tweet greater than 140 : truncated");
|
||||
node.warn(RED._("twitter.errors.truncated"));
|
||||
}
|
||||
|
||||
if (msg.media && Buffer.isBuffer(msg.media)) {
|
||||
@ -298,13 +296,13 @@ module.exports = function(RED) {
|
||||
var r = request.post(signedUrl,function(err,httpResponse,body) {
|
||||
if (err) {
|
||||
node.error(err,msg);
|
||||
node.status({fill:"red",shape:"ring",text:"failed"});
|
||||
node.status({fill:"red",shape:"ring",text:RED._("twitter.status.failed")});
|
||||
} else {
|
||||
var response = JSON.parse(body);
|
||||
if (response.errors) {
|
||||
var errorList = response.errors.map(function(er) { return er.code+": "+er.message }).join(", ");
|
||||
node.error("Send tweet failed: "+errorList,msg);
|
||||
node.status({fill:"red",shape:"ring",text:"failed"});
|
||||
node.error(RED._("twitter.errors.sendfail",{error:errorList}),msg);
|
||||
node.status({fill:"red",shape:"ring",text:RED._("twitter.status.failed")});
|
||||
} else {
|
||||
node.status({});
|
||||
}
|
||||
@ -317,14 +315,14 @@ module.exports = function(RED) {
|
||||
} else {
|
||||
twit.updateStatus(msg.payload, function (err, data) {
|
||||
if (err) {
|
||||
node.status({fill:"red",shape:"ring",text:"failed"});
|
||||
node.status({fill:"red",shape:"ring",text:RED._("twitter.status.failed")});
|
||||
node.error(err,msg);
|
||||
}
|
||||
node.status({});
|
||||
});
|
||||
}
|
||||
}
|
||||
else { node.warn("No payload to tweet"); }
|
||||
else { node.warn(RED._("twitter.errors.nopayload")); }
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -340,16 +338,14 @@ module.exports = function(RED) {
|
||||
"HMAC-SHA1"
|
||||
);
|
||||
|
||||
RED.httpAdmin.get('/twitter-credentials/:id/auth', function(req, res) {
|
||||
RED.httpAdmin.get('/twitter-credentials/:id/auth', function(req, res){
|
||||
var credentials = {};
|
||||
oa.getOAuthRequestToken({
|
||||
oauth_callback: req.query.callback
|
||||
},function(error, oauth_token, oauth_token_secret, results) {
|
||||
oauth_callback: req.query.callback
|
||||
},function(error, oauth_token, oauth_token_secret, results){
|
||||
if (error) {
|
||||
var resp = '<h2>Oh no!</h2>'+
|
||||
'<p>Something went wrong with the authentication process. The following error was returned:<p>'+
|
||||
'<p><b>'+error.statusCode+'</b>: '+error.data+'</p>'+
|
||||
'<p>One known cause of this type of failure is if the clock is wrong on system running Node-RED.';
|
||||
var error = {statusCode: 401, data: "dummy error"};
|
||||
var resp = RED._("twitter.errors.oautherror",{statusCode: error.statusCode, errorData: error.data});
|
||||
res.send(resp)
|
||||
} else {
|
||||
credentials.oauth_token = oauth_token;
|
||||
@ -360,7 +356,7 @@ module.exports = function(RED) {
|
||||
});
|
||||
});
|
||||
|
||||
RED.httpAdmin.get('/twitter-credentials/:id/auth/callback', function(req, res, next) {
|
||||
RED.httpAdmin.get('/twitter-credentials/:id/auth/callback', function(req, res, next){
|
||||
var credentials = RED.nodes.getCredentials(req.params.id);
|
||||
credentials.oauth_verifier = req.query.oauth_verifier;
|
||||
|
||||
@ -368,17 +364,17 @@ module.exports = function(RED) {
|
||||
credentials.oauth_token,
|
||||
credentials.token_secret,
|
||||
credentials.oauth_verifier,
|
||||
function(error, oauth_access_token, oauth_access_token_secret, results) {
|
||||
if (error) {
|
||||
function(error, oauth_access_token, oauth_access_token_secret, results){
|
||||
if (error){
|
||||
RED.log.error(error);
|
||||
res.send("something in twitter oauth broke.");
|
||||
res.send(RED._("twitter.errors.oauthbroke"));
|
||||
} 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("<html><head></head><body>Authorised - you can close this window and return to Node-RED</body></html>");
|
||||
res.send(RED._("twitter.errors.authorized"));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
43
social/twitter/locales/en-US/27-twitter.json
Normal file
43
social/twitter/locales/en-US/27-twitter.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"twitter": {
|
||||
"label": {
|
||||
"twitter-id":"Twitter ID",
|
||||
"search": "Search",
|
||||
"for": "for",
|
||||
"user": "User",
|
||||
"dmslabel": "DMs",
|
||||
"tweetslabel": "tweets",
|
||||
"clickhere": "Click here to authenticate with Twitter."
|
||||
},
|
||||
"placeholder": {
|
||||
"for": "comma-separated words, @ids, #tags",
|
||||
"user": "comma-separated @twitter handles"
|
||||
},
|
||||
"search": {
|
||||
"public": "all public tweets",
|
||||
"follow": "the tweets of who you follow",
|
||||
"user": "the tweets of specific users",
|
||||
"direct": "your direct messages"
|
||||
},
|
||||
"tip": "Tip: Use commas without spaces between multiple search terms. Comma = OR, Space = AND.<br/>The Twitter API WILL NOT deliver 100% of all tweets.<br/>Tweets of who you follow will include their retweets and favourites.",
|
||||
"status": {
|
||||
"using-geo": "Using geo location: __location__",
|
||||
"tweeting": "tweeting",
|
||||
"failed":"failed"
|
||||
},
|
||||
"errors": {
|
||||
"ratelimit":"tweet rate limit hit",
|
||||
"streamerror":"stream error: __error__ (__rc__)",
|
||||
"unexpectedend":"stream ended unexpectedly",
|
||||
"invalidtag":"invalid tag property",
|
||||
"missingcredentials":"missing twitter credentials",
|
||||
"truncated":"truncated tweet greater than 140 characters",
|
||||
"sendfail":"send tweet failed: __error__",
|
||||
"nopayload":"no payload to tweet",
|
||||
|
||||
"oauthbroke":"something in twitter oauth broke.",
|
||||
"oautherror": "<html><head></head><body><p>Something went wrong with the authentication process. The following error was returned:</p><p><b>__statusCode__</b>: __errorData__</p><p>One known cause of this type of failure is if the clock is wrong on system running Node-RED</p></body></html>",
|
||||
"authorized": "<html><head></head><body><p>Authorised - you can close this window and return to Node-RED</p></body></html>"
|
||||
}
|
||||
}
|
||||
}
|
@ -16,26 +16,26 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="mongodb">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-hostname"><i class="fa fa-bookmark"></i> Host</label>
|
||||
<label for="node-config-input-hostname"><i class="fa fa-bookmark"></i> <span data-i18n="mongodb.label.host"></span></label>
|
||||
<input class="input-append-left" type="text" id="node-config-input-hostname" placeholder="localhost" style="width: 40%;" >
|
||||
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
|
||||
<input type="text" id="node-config-input-port" placeholder="27017" style="width:45px">
|
||||
<label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> <span data-i18n="mongodb.label.port"></span></label>
|
||||
<input type="text" id="node-config-input-port" style="width:45px">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-db"><i class="fa fa-database"></i> Database</label>
|
||||
<input type="text" id="node-config-input-db" placeholder="test">
|
||||
<label for="node-config-input-db"><i class="fa fa-database"></i> <span data-i18n="mongodb.label.database"></span></label>
|
||||
<input type="text" id="node-config-input-db">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-user"><i class="fa fa-user"></i> Username</label>
|
||||
<label for="node-config-input-user"><i class="fa fa-user"></i> <span data-i18n="mongodb.label.username"></span></label>
|
||||
<input type="text" id="node-config-input-user">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-password"><i class="fa fa-lock"></i> Password</label>
|
||||
<label for="node-config-input-password"><i class="fa fa-lock"></i> <span data-i18n="mongodb.label.password"></span></label>
|
||||
<input type="password" id="node-config-input-password">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-config-input-name" placeholder="Name">
|
||||
<label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-config-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
@ -62,43 +62,42 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="mongodb out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-mongodb"><i class="fa fa-bookmark"></i> Server</label>
|
||||
<label for="node-input-mongodb"><i class="fa fa-bookmark"></i> <span data-i18n="mongodb.label.server"></span></label>
|
||||
<input type="text" id="node-input-mongodb">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-collection"><i class="fa fa-briefcase"></i> Collection</label>
|
||||
<input type="text" id="node-input-collection" placeholder="collection">
|
||||
<label for="node-input-collection"><i class="fa fa-briefcase"></i> <span data-i18n="mongodb.label.collection"></span></label>
|
||||
<input type="text" id="node-input-collection">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-operation"><i class="fa fa-wrench"></i> Operation</label>
|
||||
<label for="node-input-operation"><i class="fa fa-wrench"></i> <span data-i18n="mongodb.label.operation"></span></label>
|
||||
<select type="text" id="node-input-operation" style="display: inline-block; vertical-align: top;">
|
||||
<option value="store">save</option>
|
||||
<option value="insert">insert</option>
|
||||
<option value="update">update</option>
|
||||
<option value="delete">remove</option>
|
||||
<option value="store" data-i18n="mongodb.operation.save"></option>
|
||||
<option value="insert" data-i18n="mongodb.operation.insert"></option>
|
||||
<option value="update" data-i18n="mongodb.operation.update"></option>
|
||||
<option value="delete" data-i18n="mongodb.operation.remove"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row node-input-payonly">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-payonly" placeholder="Only" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-payonly" style="width: 70%;">Only store msg.payload object</label>
|
||||
<input type="checkbox" id="node-input-payonly" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-payonly" style="width: 70%;"><span data-i18n="mongodb.label.onlystore"></span></label>
|
||||
</div>
|
||||
<div class="form-row node-input-upsert">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-upsert" placeholder="Only" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-upsert" style="width: 70%;">Create a new document if no match found</label>
|
||||
<input type="checkbox" id="node-input-upsert" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-upsert" style="width: 70%;"><span data-i18n="mongodb.label.createnew"></span></label>
|
||||
</div>
|
||||
<div class="form-row node-input-multi">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-multi" placeholder="Only" style="display: inline-block; width: auto; vertical-align: top;;">
|
||||
<label for="node-input-multi" style="width: 70%;">Update all matching documents</label>
|
||||
<input type="checkbox" id="node-input-multi" style="display: inline-block; width: auto; vertical-align: top;;">
|
||||
<label for="node-input-multi" style="width: 70%;"><span data-i18n="mongodb.label.updateall"></span></label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips" id="node-warning" style="display: none"><b> Tip:</b> If no collection is set, ensure <b>msg.collection</b> will contain the collection name
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips" id="node-warning" style="display: none"><span data-i18n="[html]mongodb.tip"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="mongodb out">
|
||||
@ -172,27 +171,26 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="mongodb in">
|
||||
<div class="form-row">
|
||||
<label for="node-input-mongodb"><i class="fa fa-bookmark"></i> Server</label>
|
||||
<label for="node-input-mongodb"><i class="fa fa-bookmark"></i> <span data-i18n="mongodb.label.server"></span></label>
|
||||
<input type="text" id="node-input-mongodb">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-collection"><i class="fa fa-briefcase"></i> Collection</label>
|
||||
<input type="text" id="node-input-collection" placeholder="collection">
|
||||
<label for="node-input-collection"><i class="fa fa-briefcase"></i> <span data-i18n="mongodb.label.collection"></span></label>
|
||||
<input type="text" id="node-input-collection">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-operation"><i class="fa fa-wrench"></i> Operation</label>
|
||||
<label for="node-input-operation"><i class="fa fa-wrench"></i> <span data-i18n="mongodb.label.operation"></span></label>
|
||||
<select type="text" id="node-input-operation" style="display: inline-block; vertical-align: top;">
|
||||
<option value="find">find</option>
|
||||
<option value="count">count</option>
|
||||
<option value="aggregate">aggregate</option>
|
||||
<option value="find" data-i18n="mongodb.operation.find"></option>
|
||||
<option value="count" data-i18n="mongodb.operation.count"></option>
|
||||
<option value="aggregate" data-i18n="mongodb.operation.aggregate"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips" id="node-warning" style="display: none"><b> Tip:</b> If no collection is set, ensure <b>msg.collection</b> will contain the collection name
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips" id="node-warning" style="display: none"><span data-i18n="[html]mongodb.tip"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="mongodb in">
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2013,2015 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.
|
||||
@ -76,7 +76,7 @@ module.exports = function(RED) {
|
||||
if (msg.collection) {
|
||||
coll = db.collection(msg.collection);
|
||||
} else {
|
||||
node.error("No collection defined",msg);
|
||||
node.error(RED._("mongodb.errors.nocollection"),msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -87,9 +87,6 @@ module.exports = function(RED) {
|
||||
if (typeof msg.payload !== "object") {
|
||||
msg.payload = {"payload": msg.payload};
|
||||
}
|
||||
if (msg.hasOwnProperty("_id") && !msg.payload.hasOwnProperty("_id")) {
|
||||
msg.payload._id = msg._id;
|
||||
}
|
||||
coll.save(msg.payload,function(err, item) {
|
||||
if (err) {
|
||||
node.error(err,msg);
|
||||
@ -107,9 +104,6 @@ module.exports = function(RED) {
|
||||
if (typeof msg.payload !== "object") {
|
||||
msg.payload = {"payload": msg.payload};
|
||||
}
|
||||
if (msg.hasOwnProperty("_id") && !msg.payload.hasOwnProperty("_id")) {
|
||||
msg.payload._id = msg._id;
|
||||
}
|
||||
coll.insert(msg.payload, function(err, item) {
|
||||
if (err) {
|
||||
node.error(err,msg);
|
||||
@ -149,7 +143,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.error("missing mongodb configuration");
|
||||
this.error(RED._("mongodb.errors.missingconfig"));
|
||||
}
|
||||
|
||||
this.on("close", function() {
|
||||
@ -169,6 +163,7 @@ module.exports = function(RED) {
|
||||
|
||||
if (this.mongoConfig) {
|
||||
var node = this;
|
||||
var selector;
|
||||
MongoClient.connect(this.mongoConfig.url, function(err,db) {
|
||||
if (err) {
|
||||
node.error(err);
|
||||
@ -183,11 +178,10 @@ module.exports = function(RED) {
|
||||
if (msg.collection) {
|
||||
coll = db.collection(msg.collection);
|
||||
} else {
|
||||
node.error("No collection defined");
|
||||
node.error(RED._("mongodb.errors.nocollection"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
var selector;
|
||||
if (node.operation === "find") {
|
||||
msg.projection = msg.projection || {};
|
||||
selector = ensureValidSelectorObject(msg.payload);
|
||||
@ -237,7 +231,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.error("missing mongodb configuration");
|
||||
this.error(RED._("mongodb.errors.missingconfig"));
|
||||
}
|
||||
|
||||
this.on("close", function() {
|
||||
|
31
storage/mongodb/locales/en-US/66-mongodb.json
Normal file
31
storage/mongodb/locales/en-US/66-mongodb.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"mongodb": {
|
||||
"label": {
|
||||
"host": "Host",
|
||||
"port": "Port",
|
||||
"database": "Database",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"server": "Server",
|
||||
"collection": "Collection",
|
||||
"operation": "Operation",
|
||||
"onlystore": "Only store msg.payload object",
|
||||
"createnew": "Create a new document if no match found",
|
||||
"updateall": "Update all matching documents"
|
||||
},
|
||||
"operation": {
|
||||
"save": "save",
|
||||
"insert": "insert",
|
||||
"update": "update",
|
||||
"remove": "remove",
|
||||
"find": "find",
|
||||
"count": "count",
|
||||
"aggregate": "aggregate"
|
||||
},
|
||||
"tip": "<b> Tip:</b> If no collection is set, ensure <b>msg.collection</b> will contain the collection name",
|
||||
"errors": {
|
||||
"nocollection": "No collection defined",
|
||||
"missingconfig": "missing mongodb configuration"
|
||||
}
|
||||
}
|
||||
}
|
@ -16,32 +16,29 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="redis out">
|
||||
<div class="form-row node-input-hostname">
|
||||
<label for="node-input-hostname"><i class="fa fa-bookmark"></i> Host</label>
|
||||
<label for="node-input-hostname"><i class="fa fa-bookmark"></i> <span data-i18n="redisout.label.host"></span></label>
|
||||
<input class="input-append-left" type="text" id="node-input-hostname" placeholder="127.0.0.1" style="width: 40%;" ><button id="node-input-hostname-lookup" class="btn input-append-right"><span class="caret"></span></button>
|
||||
<label for="node-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
|
||||
<label for="node-input-port" style="margin-left: 10px; width: 35px; "> <span data-i18n="redisout.label.port"></span></label>
|
||||
<input type="text" id="node-input-port" placeholder="6379" style="width:45px">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-key"><i class="fa fa-key"></i> Key</label>
|
||||
<input type="text" id="node-input-key" placeholder="Redis Key">
|
||||
<label for="node-input-key"><i class="fa fa-key"></i> <span data-i18n="redisout.label.key"></span></label>
|
||||
<input type="text" id="node-input-key">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-type"><i class="fa fa-th"></i> Type</label>
|
||||
<label for="node-input-type"><i class="fa fa-th"></i> <span data-i18n="redisout.label.type"></span></label>
|
||||
<select type="text" id="node-input-structtype" style="width: 150px;">
|
||||
<option value="string">String</option>
|
||||
<option value="hash">Hash</option>
|
||||
<option value="set">Set</option>
|
||||
<option value="list">List</option>
|
||||
<option value="string" data-i18n="redisout.type.string"></option>
|
||||
<option value="hash" data-i18n="redisout.type.hash"></option>
|
||||
<option value="set" data-i18n="redisout.type.set"></option>
|
||||
<option value="list" data-i18n="redisout.type.list"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
<div class="form-tips">
|
||||
If key is blank, the topic will be used as the key.<br>
|
||||
If type is hash, payload should be an object or field=value string.
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
</div>
|
||||
<div class="form-tips"><span data-i18n="[html]redisout.tip"></span></div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="redis out">
|
||||
|
@ -20,7 +20,7 @@ module.exports = function(RED) {
|
||||
|
||||
var hashFieldRE = /^([^=]+)=(.*)$/;
|
||||
|
||||
var redisConnectionPool = (function() {
|
||||
var redisConnectionPool = function() {
|
||||
var connections = {};
|
||||
var obj = {
|
||||
get: function(host,port) {
|
||||
@ -30,9 +30,6 @@ module.exports = function(RED) {
|
||||
connections[id].on("error",function(err) {
|
||||
RED.log.error(err);
|
||||
});
|
||||
connections[id].on("connect",function() {
|
||||
if (RED.settings.verbose) { RED.log.info("connected to "+host+":"+port); }
|
||||
});
|
||||
connections[id]._id = id;
|
||||
connections[id]._nodeCount = 0;
|
||||
}
|
||||
@ -51,7 +48,7 @@ module.exports = function(RED) {
|
||||
}
|
||||
};
|
||||
return obj;
|
||||
}());
|
||||
}();
|
||||
|
||||
|
||||
function RedisOutNode(n) {
|
||||
@ -64,17 +61,17 @@ module.exports = function(RED) {
|
||||
this.client = redisConnectionPool.get(this.hostname,this.port);
|
||||
|
||||
if (this.client.connected) {
|
||||
this.status({fill:"green",shape:"dot",text:"connected"});
|
||||
this.status({fill:"green",shape:"dot",text:RED._("common.status.connected")});
|
||||
} else {
|
||||
this.status({fill:"red",shape:"ring",text:"disconnected"},true);
|
||||
this.status({fill:"red",shape:"ring",text:RED._("common.status.disconnected")},true);
|
||||
}
|
||||
|
||||
var node = this;
|
||||
this.client.on("end", function() {
|
||||
node.status({fill:"red",shape:"ring",text:"disconnected"});
|
||||
node.status({fill:"red",shape:"ring",text:RED._("common.status.disconnected")});
|
||||
});
|
||||
this.client.on("connect", function() {
|
||||
node.status({fill:"green",shape:"dot",text:"connected"});
|
||||
node.status({fill:"green",shape:"dot",text:RED._("common.status.connected")});
|
||||
});
|
||||
|
||||
this.on("input", function(msg) {
|
||||
@ -90,7 +87,7 @@ module.exports = function(RED) {
|
||||
if (r) {
|
||||
this.client.hset(k,r[1],r[2]);
|
||||
} else {
|
||||
this.warn("Invalid payload for redis hash");
|
||||
this.warn(RED._("redisout.errors.invalidpayload"));
|
||||
}
|
||||
}
|
||||
} else if (this.structtype == "set") {
|
||||
@ -99,7 +96,7 @@ module.exports = function(RED) {
|
||||
this.client.rpush(k,msg.payload);
|
||||
}
|
||||
} else {
|
||||
this.warn("No key or topic set");
|
||||
this.warn(RED._("redisout.errors.nokey"));
|
||||
}
|
||||
});
|
||||
this.on("close", function() {
|
||||
|
21
storage/redis/locales/en-US/65-redisout.json
Normal file
21
storage/redis/locales/en-US/65-redisout.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"redisout": {
|
||||
"label": {
|
||||
"host": "Host",
|
||||
"port": "Port",
|
||||
"key": "Key",
|
||||
"type": "Type"
|
||||
},
|
||||
"type": {
|
||||
"string": "String",
|
||||
"hash": "Hash",
|
||||
"set": "Set",
|
||||
"list": "List"
|
||||
},
|
||||
"tip": "If key is blank, the topic will be used as the key.<br>If type is hash, payload should be an object or field=value string.",
|
||||
"errors": {
|
||||
"invalidpayload": "Invalid payload for redis hash",
|
||||
"nokey": "No key or topic set"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user