Aggiunti nodi per parsare comandi tipo pidgin
parent
99840b7ac2
commit
d712a65326
|
|
@ -0,0 +1,287 @@
|
||||||
|
<script type="text/html" data-template-name="parser-consume">
|
||||||
|
<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-ellipsis-h"></i> <span data-i18n="switch.label.property"></span></label>
|
||||||
|
<input type="text" id="node-input-property" style="width: 70%"/>
|
||||||
|
<input type="hidden" id="node-input-outputs"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-row node-input-rule-container-row">
|
||||||
|
<ol id="node-input-rule-container"></ol>
|
||||||
|
</div>
|
||||||
|
<!--<div class="form-row">
|
||||||
|
<label> </label>
|
||||||
|
<input type="checkbox" id="node-input-elsenode" placeholder="" style="display:inline-block; width:auto; vertical-align:top;">
|
||||||
|
<label for="node-input-elsenode" style="width:70%;">Add <code>else</code> output</label>
|
||||||
|
</div>-->
|
||||||
|
<div class="form-row">
|
||||||
|
<select id="node-input-checkall" style="width:100%; margin-right:5px;">
|
||||||
|
<option value="true" data-i18n="switch.checkall">All matches</option>
|
||||||
|
<option value="false" data-i18n="switch.stopfirst">First match</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
(function () {
|
||||||
|
var operators = [
|
||||||
|
{ v: "eq", t: "==", kind: 'V' },
|
||||||
|
{ v: "regex", t: "/regex/", kind: 'V' }
|
||||||
|
];
|
||||||
|
|
||||||
|
function clipValueLength(v) {
|
||||||
|
if (v.length > 15) {
|
||||||
|
return v.substring(0, 15) + "...";
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
function prop2name(key) {
|
||||||
|
var result = RED.utils.parseContextKey(key);
|
||||||
|
return result.key;
|
||||||
|
}
|
||||||
|
function getValueLabel(t, v) {
|
||||||
|
if (t === 'str') {
|
||||||
|
return '"' + clipValueLength(v) + '"';
|
||||||
|
} else if (t === 'msg') {
|
||||||
|
return t + "." + clipValueLength(v);
|
||||||
|
} else if (t === 'flow' || t === 'global') {
|
||||||
|
return t + "." + clipValueLength(prop2name(v));
|
||||||
|
}
|
||||||
|
return clipValueLength(v);
|
||||||
|
}
|
||||||
|
RED.nodes.registerType('parser-consume', {
|
||||||
|
color: "#E2D96E",
|
||||||
|
category: 'function',
|
||||||
|
defaults: {
|
||||||
|
name: { value: "" },
|
||||||
|
property: { value: "payload", required: true, validate: RED.validators.typedInput("propertyType") },
|
||||||
|
propertyType: { value: "msg" },
|
||||||
|
rules: { value: [{ t: "eq", v: "", vt: "str" }] },
|
||||||
|
checkall: { value: "true", required: true },
|
||||||
|
outputs: { value: 1 },
|
||||||
|
elsenode: { value: false }
|
||||||
|
},
|
||||||
|
inputs: 1,
|
||||||
|
outputs: 1,
|
||||||
|
outputLabels: function (index) {
|
||||||
|
var rule = this.rules[index];
|
||||||
|
var label = "";
|
||||||
|
if (rule) {
|
||||||
|
label = rule.v;
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: "switch.svg",
|
||||||
|
label: function () {
|
||||||
|
return this.name || "Consume token";
|
||||||
|
},
|
||||||
|
labelStyle: function () {
|
||||||
|
return this.name ? "node_label_italic" : "";
|
||||||
|
},
|
||||||
|
oneditprepare: function () {
|
||||||
|
var node = this;
|
||||||
|
var previousValueType = { value: "prev", label: this._("switch.previous"), hasValue: false };
|
||||||
|
|
||||||
|
$("#node-input-property").typedInput({ default: this.propertyType || 'msg', types: ['msg', 'flow', 'global', 'jsonata', 'env'] });
|
||||||
|
var outputCount = $("#node-input-outputs").val("{}");
|
||||||
|
|
||||||
|
var andLabel = this._("switch.and");
|
||||||
|
var caseLabel = this._("switch.ignorecase");
|
||||||
|
|
||||||
|
function resizeRule(rule) {
|
||||||
|
var newWidth = rule.width();
|
||||||
|
var selectField = rule.find("select");
|
||||||
|
var type = selectField.val() || "";
|
||||||
|
var valueField = rule.find(".node-input-rule-value");
|
||||||
|
var typeField = rule.find(".node-input-rule-type-value");
|
||||||
|
var numField = rule.find(".node-input-rule-num-value");
|
||||||
|
var expField = rule.find(".node-input-rule-exp-value");
|
||||||
|
var keyField = rule.find(".node-input-rule-key-value");
|
||||||
|
var btwnField1 = rule.find(".node-input-rule-btwn-value");
|
||||||
|
var btwnField2 = rule.find(".node-input-rule-btwn-value2");
|
||||||
|
var selectWidth;
|
||||||
|
if (type.length < 4) {
|
||||||
|
selectWidth = 60;
|
||||||
|
} else if (type === "regex") {
|
||||||
|
selectWidth = 147;
|
||||||
|
} else {
|
||||||
|
selectWidth = 120;
|
||||||
|
}
|
||||||
|
selectField.width(selectWidth);
|
||||||
|
valueField.typedInput("width", (newWidth - selectWidth - 70));
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#node-input-rule-container").css('min-height', '150px').css('min-width', '450px').editableList({
|
||||||
|
addItem: function (container, i, opt) {
|
||||||
|
if (!opt.hasOwnProperty('r')) {
|
||||||
|
opt.r = {};
|
||||||
|
}
|
||||||
|
var rule = opt.r;
|
||||||
|
if (!rule.hasOwnProperty('t')) {
|
||||||
|
rule.t = 'eq';
|
||||||
|
}
|
||||||
|
if (!opt.hasOwnProperty('i')) {
|
||||||
|
opt._i = Math.floor((0x99999 - 0x10000) * Math.random()).toString();
|
||||||
|
}
|
||||||
|
container.css({
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
|
});
|
||||||
|
var row = $('<div/>').appendTo(container);
|
||||||
|
var selectField = $('<select/>', { style: "width:120px; margin-left: 5px; text-align: center;" }).appendTo(row);
|
||||||
|
var group0 = $('<optgroup/>', { label: "value rules" }).appendTo(selectField);
|
||||||
|
for (var d in operators) {
|
||||||
|
if (operators[d].kind === 'V') {
|
||||||
|
group0.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t) ? node._(operators[d].t) : operators[d].t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createValueField() {
|
||||||
|
return $('<input/>', { class: "node-input-rule-value", type: "text", style: "margin-left: 5px;" }).appendTo(row).typedInput({ default: 'str', types: ['str'] });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function createTypeValueField() {
|
||||||
|
return $('<input/>', { class: "node-input-rule-type-value", type: "text", style: "margin-left: 5px;" }).appendTo(row).typedInput({
|
||||||
|
default: 'string', types: [
|
||||||
|
{ value: "string", label: RED._("common.type.string"), hasValue: false, icon: "red/images/typedInput/az.png" },
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var valueField = null;
|
||||||
|
var numValueField = null;
|
||||||
|
var expValueField = null;
|
||||||
|
var btwnAndLabel = null;
|
||||||
|
var btwnValueField = null;
|
||||||
|
var btwnValue2Field = null;
|
||||||
|
var typeValueField = null;
|
||||||
|
|
||||||
|
var finalspan = $('<span/>', { style: "float: right;margin-top: 6px;" }).appendTo(row);
|
||||||
|
finalspan.append(' → <span class="node-input-rule-index">' + (i + 1) + '</span> ');
|
||||||
|
selectField.on("change", function () {
|
||||||
|
var type = selectField.val();
|
||||||
|
valueField.typedInput('hide');
|
||||||
|
if (!valueField) {
|
||||||
|
valueField = createValueField();
|
||||||
|
}
|
||||||
|
valueField.typedInput('show');
|
||||||
|
resizeRule(container);
|
||||||
|
});
|
||||||
|
selectField.val(rule.t);
|
||||||
|
if (!valueField) {
|
||||||
|
valueField = createValueField();
|
||||||
|
}
|
||||||
|
valueField.typedInput('value', rule.v);
|
||||||
|
valueField.typedInput('type', 'str');
|
||||||
|
selectField.change();
|
||||||
|
|
||||||
|
var currentOutputs = JSON.parse(outputCount.val() || "{}");
|
||||||
|
currentOutputs[opt.hasOwnProperty('i') ? opt.i : opt._i] = i + 1;
|
||||||
|
outputCount.val(JSON.stringify(currentOutputs));
|
||||||
|
},
|
||||||
|
removeItem: function (opt) {
|
||||||
|
var currentOutputs = JSON.parse(outputCount.val() || "{}");
|
||||||
|
if (opt.hasOwnProperty('i')) {
|
||||||
|
currentOutputs[opt.i] = -1;
|
||||||
|
} else {
|
||||||
|
delete currentOutputs[opt._i];
|
||||||
|
}
|
||||||
|
var rules = $("#node-input-rule-container").editableList('items');
|
||||||
|
rules.each(function (i) {
|
||||||
|
$(this).find(".node-input-rule-index").html(i + 1);
|
||||||
|
var data = $(this).data('data');
|
||||||
|
currentOutputs[data.hasOwnProperty('i') ? data.i : data._i] = i + 1;
|
||||||
|
});
|
||||||
|
outputCount.val(JSON.stringify(currentOutputs));
|
||||||
|
},
|
||||||
|
resizeItem: resizeRule,
|
||||||
|
sortItems: function (rules) {
|
||||||
|
var currentOutputs = JSON.parse(outputCount.val() || "{}");
|
||||||
|
var rules = $("#node-input-rule-container").editableList('items');
|
||||||
|
rules.each(function (i) {
|
||||||
|
$(this).find(".node-input-rule-index").html(i + 1);
|
||||||
|
var data = $(this).data('data');
|
||||||
|
currentOutputs[data.hasOwnProperty('i') ? data.i : data._i] = i;
|
||||||
|
});
|
||||||
|
outputCount.val(JSON.stringify(currentOutputs));
|
||||||
|
},
|
||||||
|
sortable: true,
|
||||||
|
removable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
for (var i = 0; i < this.rules.length; i++) {
|
||||||
|
var rule = this.rules[i];
|
||||||
|
$("#node-input-rule-container").editableList('addItem', { r: rule, i: i });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
oneditsave: function () {
|
||||||
|
var rules = $("#node-input-rule-container").editableList('items');
|
||||||
|
var node = this;
|
||||||
|
node.rules = [];
|
||||||
|
rules.each(function (i) {
|
||||||
|
var ruleData = $(this).data('data');
|
||||||
|
var rule = $(this);
|
||||||
|
var type = rule.find("select").val();
|
||||||
|
var r = { t: type };
|
||||||
|
r.v = rule.find(".node-input-rule-value").typedInput('value');
|
||||||
|
r.vt = rule.find(".node-input-rule-value").typedInput('type');
|
||||||
|
node.rules.push(r);
|
||||||
|
});
|
||||||
|
this.propertyType = $("#node-input-property").typedInput('type');
|
||||||
|
},
|
||||||
|
oneditresize: function (size) {
|
||||||
|
var rows = $("#dialog-form>div:not(.node-input-rule-container-row)");
|
||||||
|
var height = size.height;
|
||||||
|
for (var i = 0; i < rows.length; i++) {
|
||||||
|
height -= $(rows[i]).outerHeight(true);
|
||||||
|
}
|
||||||
|
var editorRow = $("#dialog-form>div.node-input-rule-container-row");
|
||||||
|
height -= (parseInt(editorRow.css("marginTop")) + parseInt(editorRow.css("marginBottom")));
|
||||||
|
height += 16;
|
||||||
|
$("#node-input-rule-container").editableList('height', height);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/html" data-template-name="parser-entry-point">
|
||||||
|
<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-ellipsis-h"></i> Property:</label>
|
||||||
|
<input type="text" id="node-input-property" style="width: 70%"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="node-input-help_text"><i class="fa fa-ellipsis-h"></i> Help text:</label>
|
||||||
|
<input type="text" id="node-input-property" style="width: 70%"/>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
RED.nodes.registerType('parser-entry-point',{
|
||||||
|
category: 'function',
|
||||||
|
color: "#E6E0F8",
|
||||||
|
defaults: {
|
||||||
|
property: { value: "payload", required: true, validate: RED.validators.typedInput("propertyType") },
|
||||||
|
name: { value: "" },
|
||||||
|
help_text: {value: ""}
|
||||||
|
},
|
||||||
|
inputs: 1,
|
||||||
|
outputs: 1,
|
||||||
|
label: function() {
|
||||||
|
return this.name || "parser entry point";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
module.exports = function (RED) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function ParserEntryPoint(n) {
|
||||||
|
RED.nodes.createNode(this, n);
|
||||||
|
this.property = n.property;
|
||||||
|
this.help_message = n.help_message;
|
||||||
|
this.on("input", msg => {
|
||||||
|
RED.util.evaluateNodeProperty(this.property, "msg", this, msg,
|
||||||
|
(err, value) => {
|
||||||
|
if (err) {
|
||||||
|
this.error(`Can't evaluate msg.${this.property}`);
|
||||||
|
} else {
|
||||||
|
let tokens = value.trim().toLowerCase().split(" ");
|
||||||
|
msg.token_parser = {
|
||||||
|
new_tokens: tokens,
|
||||||
|
consumed_tokens: [],
|
||||||
|
help_message: this.help_message
|
||||||
|
};
|
||||||
|
this.send(msg);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RED.nodes.registerType("parser-entry-point", ParserEntryPoint);
|
||||||
|
|
||||||
|
function ConsumaToken(n) {
|
||||||
|
RED.nodes.createNode(this, n);
|
||||||
|
this.rules = n.rules;
|
||||||
|
this.behavior= n.behavior;
|
||||||
|
this.checkall= n.checkall;
|
||||||
|
function check_rule(r, token) {
|
||||||
|
switch(r.t){
|
||||||
|
case "eq":
|
||||||
|
return token == r.v.toLowerCase();
|
||||||
|
case "regex":
|
||||||
|
let reg = new RegExp(r.v);
|
||||||
|
return token.match(reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.on("input", msg => {
|
||||||
|
let token = msg.token_parser.new_tokens.shift() || "";
|
||||||
|
msg.token_parser.consumed_tokens.push(token);
|
||||||
|
let out = [];
|
||||||
|
let n_matches = 0;
|
||||||
|
for (let r of this.rules) {
|
||||||
|
if(check_rule(r, token)){
|
||||||
|
out.push(msg);
|
||||||
|
n_matches += 1;
|
||||||
|
if (!this.checkall) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.push(undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//out.push(n_matches == 0 ? msg : undefined);
|
||||||
|
this.send(out);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
RED.nodes.registerType("parser-consume", ConsumaToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,8 @@
|
||||||
"node-red" : {
|
"node-red" : {
|
||||||
"nodes" : {
|
"nodes" : {
|
||||||
"xmpp": "92-xmpp.js",
|
"xmpp": "92-xmpp.js",
|
||||||
"my-debounce": "my-debounce.js"
|
"my-debounce": "my-debounce.js",
|
||||||
|
"command-parse": "command-parse.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue