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" : {
|
||||
"nodes" : {
|
||||
"xmpp": "92-xmpp.js",
|
||||
"my-debounce": "my-debounce.js"
|
||||
"my-debounce": "my-debounce.js",
|
||||
"command-parse": "command-parse.js"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue