mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Update CSV node to support Property In/Out
This commit is contained in:
parent
2621a3a628
commit
4874e64387
@ -1,5 +1,13 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="csv">
|
<script type="text/html" data-template-name="csv">
|
||||||
|
<div class="form-row">
|
||||||
|
<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-row">
|
||||||
|
<label for="node-input-property"><i class="fa fa-sign-in"></i> <span data-i18n="common.label.propertyIn"></span></label>
|
||||||
|
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||||
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-temp"><i class="fa fa-list"></i> <span data-i18n="csv.label.columns"></span></label>
|
<label for="node-input-temp"><i class="fa fa-list"></i> <span data-i18n="csv.label.columns"></span></label>
|
||||||
<input type="text" id="node-input-temp" data-i18n="[placeholder]csv.placeholder.columns">
|
<input type="text" id="node-input-temp" data-i18n="[placeholder]csv.placeholder.columns">
|
||||||
@ -32,8 +40,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-propertyOut"><i class="fa fa-sign-out"></i> <span data-i18n="common.label.propertyOut"></span></label>
|
||||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
<input type="text" id="node-input-propertyOut" style="width:70%;"/>
|
||||||
</div>
|
</div>
|
||||||
<hr align="middle"/>
|
<hr align="middle"/>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -102,7 +110,13 @@
|
|||||||
skip: {value:"0"},
|
skip: {value:"0"},
|
||||||
strings: {value:true},
|
strings: {value:true},
|
||||||
include_empty_strings: {value:""},
|
include_empty_strings: {value:""},
|
||||||
include_null_values: {value:""}
|
include_null_values: {value:""},
|
||||||
|
property: {value:"payload",required:true,
|
||||||
|
validate: RED.validators.typedInput({ type: 'msg', allowUndefined: true }),
|
||||||
|
label:RED._("node-red:common.label.propertyIn")},
|
||||||
|
propertyOut: {value:"payload",required:true,
|
||||||
|
validate: RED.validators.typedInput({ type: 'msg', allowUndefined: true}),
|
||||||
|
label:RED._("node-red:common.label.propertyOut")}
|
||||||
},
|
},
|
||||||
inputs:1,
|
inputs:1,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
|
@ -26,6 +26,9 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
node.status({}) // clear status
|
node.status({}) // clear status
|
||||||
|
|
||||||
|
node.property = n.property||"payload";
|
||||||
|
node.propertyOut = n.propertyOut||node.property;
|
||||||
|
|
||||||
if (legacyMode) {
|
if (legacyMode) {
|
||||||
this.template = (n.temp || "");
|
this.template = (n.temp || "");
|
||||||
this.sep = (n.sep || ',').replace(/\\t/g,"\t").replace(/\\n/g,"\n").replace(/\\r/g,"\r");
|
this.sep = (n.sep || ',').replace(/\\t/g,"\t").replace(/\\n/g,"\n").replace(/\\r/g,"\r");
|
||||||
@ -66,43 +69,44 @@ module.exports = function(RED) {
|
|||||||
if (msg.hasOwnProperty("reset")) {
|
if (msg.hasOwnProperty("reset")) {
|
||||||
node.hdrSent = false;
|
node.hdrSent = false;
|
||||||
}
|
}
|
||||||
if (msg.hasOwnProperty("payload")) {
|
if (msg.hasOwnProperty(node.property)) {
|
||||||
if (typeof msg.payload == "object") { // convert object to CSV string
|
let inputData = RED.util.getMessageProperty(msg, node.property)
|
||||||
|
if (typeof inputData == "object") { // convert object to CSV string
|
||||||
try {
|
try {
|
||||||
if (!(notemplate && (msg.hasOwnProperty("parts") && msg.parts.hasOwnProperty("index") && msg.parts.index > 0))) {
|
if (!(notemplate && (msg.hasOwnProperty("parts") && msg.parts.hasOwnProperty("index") && msg.parts.index > 0))) {
|
||||||
template = clean(node.template);
|
template = clean(node.template);
|
||||||
}
|
}
|
||||||
const ou = [];
|
const ou = [];
|
||||||
if (!Array.isArray(msg.payload)) { msg.payload = [ msg.payload ]; }
|
if (!Array.isArray(inputData)) { inputData = [ inputData ]; }
|
||||||
if (node.hdrout !== "none" && node.hdrSent === false) {
|
if (node.hdrout !== "none" && node.hdrSent === false) {
|
||||||
if ((template.length === 1) && (template[0] === '')) {
|
if ((template.length === 1) && (template[0] === '')) {
|
||||||
if (msg.hasOwnProperty("columns")) {
|
if (msg.hasOwnProperty("columns")) {
|
||||||
template = clean(msg.columns || "",",");
|
template = clean(msg.columns || "",",");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
template = Object.keys(msg.payload[0]);
|
template = Object.keys(inputData[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ou.push(template.map(v => v.indexOf(node.sep)!==-1 ? '"'+v+'"' : v).join(node.sep));
|
ou.push(template.map(v => v.indexOf(node.sep)!==-1 ? '"'+v+'"' : v).join(node.sep));
|
||||||
if (node.hdrout === "once") { node.hdrSent = true; }
|
if (node.hdrout === "once") { node.hdrSent = true; }
|
||||||
}
|
}
|
||||||
for (var s = 0; s < msg.payload.length; s++) {
|
for (var s = 0; s < inputData.length; s++) {
|
||||||
if ((Array.isArray(msg.payload[s])) || (typeof msg.payload[s] !== "object")) {
|
if ((Array.isArray(inputData[s])) || (typeof inputData[s] !== "object")) {
|
||||||
if (typeof msg.payload[s] !== "object") { msg.payload = [ msg.payload ]; }
|
if (typeof inputData[s] !== "object") { inputData = [ inputData ]; }
|
||||||
for (var t = 0; t < msg.payload[s].length; t++) {
|
for (var t = 0; t < inputData[s].length; t++) {
|
||||||
if (msg.payload[s][t] === undefined) { msg.payload[s][t] = ""; }
|
if (inputData[s][t] === undefined) { inputData[s][t] = ""; }
|
||||||
if (msg.payload[s][t].toString().indexOf(node.quo) !== -1) { // add double quotes if any quotes
|
if (inputData[s][t].toString().indexOf(node.quo) !== -1) { // add double quotes if any quotes
|
||||||
msg.payload[s][t] = msg.payload[s][t].toString().replace(/"/g, '""');
|
inputData[s][t] = inputData[s][t].toString().replace(/"/g, '""');
|
||||||
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
|
inputData[s][t] = node.quo + inputData[s][t].toString() + node.quo;
|
||||||
}
|
}
|
||||||
else if (msg.payload[s][t].toString().indexOf(node.sep) !== -1) { // add quotes if any "commas"
|
else if (inputData[s][t].toString().indexOf(node.sep) !== -1) { // add quotes if any "commas"
|
||||||
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
|
inputData[s][t] = node.quo + inputData[s][t].toString() + node.quo;
|
||||||
}
|
}
|
||||||
else if (msg.payload[s][t].toString().indexOf("\n") !== -1) { // add quotes if any "\n"
|
else if (inputData[s][t].toString().indexOf("\n") !== -1) { // add quotes if any "\n"
|
||||||
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
|
inputData[s][t] = node.quo + inputData[s][t].toString() + node.quo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ou.push(msg.payload[s].join(node.sep));
|
ou.push(inputData[s].join(node.sep));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((template.length === 1) && (template[0] === '') && (msg.hasOwnProperty("columns"))) {
|
if ((template.length === 1) && (template[0] === '') && (msg.hasOwnProperty("columns"))) {
|
||||||
@ -115,16 +119,16 @@ module.exports = function(RED) {
|
|||||||
tmpwarn = false;
|
tmpwarn = false;
|
||||||
}
|
}
|
||||||
const row = [];
|
const row = [];
|
||||||
for (var p in msg.payload[0]) {
|
for (var p in inputData[0]) {
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
if (msg.payload[s].hasOwnProperty(p)) {
|
if (inputData[s].hasOwnProperty(p)) {
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
if (typeof msg.payload[s][p] !== "object") {
|
if (typeof inputData[s][p] !== "object") {
|
||||||
// Fix to honour include null values flag
|
// Fix to honour include null values flag
|
||||||
//if (typeof msg.payload[s][p] !== "object" || (node.include_null_values === true && msg.payload[s][p] === null)) {
|
//if (typeof inputData[s][p] !== "object" || (node.include_null_values === true && inputData[s][p] === null)) {
|
||||||
var q = "";
|
var q = "";
|
||||||
if (msg.payload[s][p] !== undefined) {
|
if (inputData[s][p] !== undefined) {
|
||||||
q += msg.payload[s][p];
|
q += inputData[s][p];
|
||||||
}
|
}
|
||||||
if (q.indexOf(node.quo) !== -1) { // add double quotes if any quotes
|
if (q.indexOf(node.quo) !== -1) { // add double quotes if any quotes
|
||||||
q = q.replace(/"/g, '""');
|
q = q.replace(/"/g, '""');
|
||||||
@ -149,7 +153,7 @@ module.exports = function(RED) {
|
|||||||
var tt = template[t];
|
var tt = template[t];
|
||||||
if (template[t].indexOf('"') >=0 ) { tt = "'"+tt+"'"; }
|
if (template[t].indexOf('"') >=0 ) { tt = "'"+tt+"'"; }
|
||||||
else { tt = '"'+tt+'"'; }
|
else { tt = '"'+tt+'"'; }
|
||||||
var p = RED.util.getMessageProperty(msg,'payload["'+s+'"]['+tt+']');
|
var p = RED.util.getMessageProperty(msg, node.property + '["'+s+'"]['+tt+']');
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
if (p === undefined) { p = ""; }
|
if (p === undefined) { p = ""; }
|
||||||
// fix to honour include null values flag
|
// fix to honour include null values flag
|
||||||
@ -170,16 +174,17 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// join lines, don't forget to add the last new line
|
// join lines, don't forget to add the last new line
|
||||||
msg.payload = ou.join(node.ret) + node.ret;
|
inputData = ou.join(node.ret) + node.ret;
|
||||||
|
RED.util.setMessageProperty(msg, node.propertyOut, inputData)
|
||||||
msg.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).join(',');
|
msg.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).join(',');
|
||||||
if (msg.payload !== '') {
|
if (inputData !== '') {
|
||||||
send(msg);
|
send(msg);
|
||||||
}
|
}
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
catch(e) { done(e); }
|
catch(e) { done(e); }
|
||||||
}
|
}
|
||||||
else if (typeof msg.payload == "string") { // convert CSV string to object
|
else if (typeof inputData == "string") { // convert CSV string to object
|
||||||
try {
|
try {
|
||||||
var f = true; // flag to indicate if inside or outside a pair of quotes true = outside.
|
var f = true; // flag to indicate if inside or outside a pair of quotes true = outside.
|
||||||
var j = 0; // pointer into array of template items
|
var j = 0; // pointer into array of template items
|
||||||
@ -188,7 +193,7 @@ module.exports = function(RED) {
|
|||||||
var a = []; // output array is needed for multiline option
|
var a = []; // output array is needed for multiline option
|
||||||
var first = true; // is this the first line
|
var first = true; // is this the first line
|
||||||
var last = false;
|
var last = false;
|
||||||
var line = msg.payload;
|
var line = inputData;
|
||||||
var linecount = 0;
|
var linecount = 0;
|
||||||
var tmp = "";
|
var tmp = "";
|
||||||
var has_parts = msg.hasOwnProperty("parts");
|
var has_parts = msg.hasOwnProperty("parts");
|
||||||
@ -282,13 +287,13 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node.multi !== "one") {
|
if (node.multi !== "one") {
|
||||||
msg.payload = a;
|
inputData = a;
|
||||||
if (has_parts && nocr <= 1) {
|
if (has_parts && nocr <= 1) {
|
||||||
if (JSON.stringify(o) !== "{}") {
|
if (JSON.stringify(o) !== "{}") {
|
||||||
node.store.push(o);
|
node.store.push(o);
|
||||||
}
|
}
|
||||||
if (msg.parts.index + 1 === msg.parts.count) {
|
if (msg.parts.index + 1 === msg.parts.count) {
|
||||||
msg.payload = node.store;
|
inputData = node.store;
|
||||||
msg.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(',');
|
msg.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(',');
|
||||||
delete msg.parts;
|
delete msg.parts;
|
||||||
send(msg);
|
send(msg);
|
||||||
@ -305,7 +310,7 @@ module.exports = function(RED) {
|
|||||||
for (var i = 0; i < len; i++) {
|
for (var i = 0; i < len; i++) {
|
||||||
var newMessage = RED.util.cloneMessage(msg);
|
var newMessage = RED.util.cloneMessage(msg);
|
||||||
newMessage.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(',');
|
newMessage.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).filter(v => v).join(',');
|
||||||
newMessage.payload = a[i];
|
RED.util.setMessageProperty(newMessage, node.propertyOut, a[i])
|
||||||
if (!has_parts) {
|
if (!has_parts) {
|
||||||
newMessage.parts = {
|
newMessage.parts = {
|
||||||
id: msg._msgid,
|
id: msg._msgid,
|
||||||
@ -411,8 +416,8 @@ module.exports = function(RED) {
|
|||||||
if (msg.hasOwnProperty("reset")) {
|
if (msg.hasOwnProperty("reset")) {
|
||||||
node.hdrSent = false
|
node.hdrSent = false
|
||||||
}
|
}
|
||||||
if (msg.hasOwnProperty("payload")) {
|
if (msg.hasOwnProperty(node.property)) {
|
||||||
let inputData = msg.payload
|
let inputData = RED.util.getMessageProperty(msg, node.property)
|
||||||
if (typeof inputData == "object") { // convert object to CSV string
|
if (typeof inputData == "object") { // convert object to CSV string
|
||||||
try {
|
try {
|
||||||
// first determine the payload kind. Array or objects? Array of primitives? Array of arrays? Just an object?
|
// first determine the payload kind. Array or objects? Array of primitives? Array of arrays? Just an object?
|
||||||
@ -517,9 +522,10 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// join lines, don't forget to add the last new line
|
// join lines, don't forget to add the last new line
|
||||||
msg.payload = stringBuilder.join(node.ret) + node.ret
|
const result = stringBuilder.join(node.ret) + node.ret
|
||||||
|
RED.util.setMessageProperty(msg, node.propertyOut, result)
|
||||||
msg.columns = templateArrayToColumnString(template)
|
msg.columns = templateArrayToColumnString(template)
|
||||||
if (msg.payload !== '') { send(msg) }
|
if (result !== '') { send(msg) }
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
@ -614,7 +620,7 @@ module.exports = function(RED) {
|
|||||||
node.store.push(...data)
|
node.store.push(...data)
|
||||||
}
|
}
|
||||||
if (msg.parts.index + 1 === msg.parts.count) {
|
if (msg.parts.index + 1 === msg.parts.count) {
|
||||||
msg.payload = node.store
|
RED.util.setMessageProperty(msg, node.propertyOut, node.store)
|
||||||
msg.columns = csvParseResult.header
|
msg.columns = csvParseResult.header
|
||||||
// msg._mode = 'RFC4180 mode'
|
// msg._mode = 'RFC4180 mode'
|
||||||
delete msg.parts
|
delete msg.parts
|
||||||
@ -625,7 +631,7 @@ module.exports = function(RED) {
|
|||||||
else {
|
else {
|
||||||
msg.columns = csvParseResult.header
|
msg.columns = csvParseResult.header
|
||||||
// msg._mode = 'RFC4180 mode'
|
// msg._mode = 'RFC4180 mode'
|
||||||
msg.payload = data
|
RED.util.setMessageProperty(msg, node.propertyOut, data)
|
||||||
send(msg); // finally send the array
|
send(msg); // finally send the array
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,7 +640,7 @@ module.exports = function(RED) {
|
|||||||
for (let row = 0; row < len; row++) {
|
for (let row = 0; row < len; row++) {
|
||||||
const newMessage = RED.util.cloneMessage(msg)
|
const newMessage = RED.util.cloneMessage(msg)
|
||||||
newMessage.columns = csvParseResult.header
|
newMessage.columns = csvParseResult.header
|
||||||
newMessage.payload = data[row]
|
RED.util.setMessageProperty(newMessage, node.propertyOut, data[row])
|
||||||
if (!has_parts) {
|
if (!has_parts) {
|
||||||
newMessage.parts = {
|
newMessage.parts = {
|
||||||
id: msg._msgid,
|
id: msg._msgid,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user