mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
d37e816cd1
@ -20,7 +20,7 @@
|
||||
<input type="text" id="node-input-name" placeholder="Comment">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-info"><i class="icon-file"></i> More</label>
|
||||
<label for="node-input-info" style="width: 100% !important;"><i class="icon-file"></i> More</label>
|
||||
<input type="hidden" id="node-input-info">
|
||||
<div style="height: 250px;" class="node-text-editor" id="node-input-info-editor" ></div>
|
||||
</div>
|
||||
|
@ -50,14 +50,15 @@
|
||||
<pre>foo=bar&this=that</pre>
|
||||
</p>
|
||||
<p>
|
||||
To send JSON encoded data, the content-type header of the request must be set to
|
||||
To send JSON encoded data to the node, the content-type header of the request must be set to
|
||||
<code>application/json</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Note: </b>This node does not send any response to the http request. This must be done within
|
||||
a subsequent Function node. The <a href="http://expressjs.com/api.html#res">Express response documentation</a>
|
||||
describes how this should be done.
|
||||
<pre>msg.res.send(200, 'Thanks for the request ');<br/>return msg;</pre>
|
||||
<b>Note: </b>This node does not send any response to the http request. This should be done with
|
||||
a subsequent HTTP Response node, or Function node.
|
||||
In the case of a Function node, the <a href="http://expressjs.com/api.html#res">Express response documentation</a>
|
||||
describes how this should be done. For example:
|
||||
<pre>msg.res.send(200, 'Thanks for the request ');<br/>return msg;</pre>
|
||||
</p>
|
||||
|
||||
</script>
|
||||
@ -81,5 +82,37 @@
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="http response">
|
||||
<div class="form-tips">The messages sent to this node must originate from an HTTP input node</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="http response">
|
||||
<p>Provides an response node for http requests received from an http input node.</p>
|
||||
<ul>
|
||||
<li><code>payload</code> is sent as the body of the reponse</li>
|
||||
<li><code>rc</code>, if set, is used as the response code (default: 200)</li>
|
||||
<li><code>headers</code>, if set, should be an object containing field/value
|
||||
pairs to be added as response headers.</li>
|
||||
</ul>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('http response',{
|
||||
category: 'output',
|
||||
color:"rgb(231, 231, 174)",
|
||||
defaults: {},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
align: "right",
|
||||
icon: "white-globe.png",
|
||||
label: function() {
|
||||
return "http"
|
||||
},
|
||||
labelStyle: function() {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -35,17 +35,33 @@ function HTTPIn(n) {
|
||||
} else if (this.method == "delete") {
|
||||
RED.app.delete(this.url,this.callback);
|
||||
}
|
||||
|
||||
this.on("close",function() {
|
||||
var routes = RED.app.routes[this.method];
|
||||
for (var i in routes) {
|
||||
if (routes[i].path == this.url) {
|
||||
routes.splice(i,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("http in",HTTPIn);
|
||||
|
||||
HTTPIn.prototype.close = function() {
|
||||
var routes = RED.app.routes[this.method];
|
||||
for (var i in routes) {
|
||||
if (routes[i].path == this.url) {
|
||||
routes.splice(i,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function HTTPOut(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
|
||||
this.on("input",function(msg) {
|
||||
if (msg.res) {
|
||||
if (msg.headers) {
|
||||
res.set(msg.headers);
|
||||
}
|
||||
var rc = msg.rc || 200;
|
||||
msg.res.send(rc,msg.payload);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RED.nodes.registerType("http response",HTTPOut);
|
||||
|
122
nodes/storage/67-leveldb.html
Normal file
122
nodes/storage/67-leveldb.html
Normal file
@ -0,0 +1,122 @@
|
||||
<!--
|
||||
Copyright 2013 IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="leveldbase">
|
||||
<div class="form-row">
|
||||
<label for="node-config-input-db"><i class="icon-briefcase"></i> Database</label>
|
||||
<input type="text" id="node-config-input-db" placeholder="database path/name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('leveldbase',{
|
||||
category: 'config',
|
||||
defaults: {
|
||||
db: {value:"",required:true}
|
||||
},
|
||||
label: function() {
|
||||
return this.db;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="leveldb in">
|
||||
<div class="form-row node-input-level">
|
||||
<label for="node-input-level"><i class="icon-briefcase"></i> Database</label>
|
||||
<input type="text" id="node-input-level">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="leveldb in">
|
||||
<p>Uses <a href="https://code.google.com/p/leveldb/" target="_new"><i>LevelDB</i></a> for a simple key value pair database.</p>
|
||||
<p>Use this node to <b>get</b>, or retrieve the data already saved in the database.</p>
|
||||
<p><b>msg.topic</b> must hold the <i>key</i> for the database, and the result is returned in <b>msg.payload</b>.</p>
|
||||
<p>If nothing is found for the key then <i>null</i> is returned,</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('leveldb in',{
|
||||
category: 'storage-input',
|
||||
color:"#dbb84d",
|
||||
defaults: {
|
||||
level: {type:"leveldbase",required:true},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "leveldb.png",
|
||||
label: function() {
|
||||
var levelNode = RED.nodes.node(this.level);
|
||||
return this.name||(levelNode?levelNode.label():"leveldb");
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/x-red" data-template-name="leveldb out">
|
||||
<div class="form-row node-input-level">
|
||||
<label for="node-input-level"><i class="icon-briefcase"></i> Database</label>
|
||||
<input type="text" id="node-input-level">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-operation"><i class="icon-wrench"></i> Operation</label>
|
||||
<select type="text" id="node-input-operation" style="display: inline-block; vertical-align: top;">
|
||||
<option value="store">Store</option>
|
||||
<option value="delete">Delete</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="Name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/x-red" data-help-name="leveldb out">
|
||||
<p>Uses <a href="https://code.google.com/p/leveldb/" target="_new"><i>LevelDB</i></a> for a simple key value pair database.</p>
|
||||
<p>Use this node to either <b>put</b> (store) the <b>msg.payload</b> to the named database file, using <b>msg.topic</b> as the key.</p>
|
||||
<p>To <b>delete</b> information select delete in the properties dialogue and again use <b>msg.topic</b> as the key.</b>.</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('leveldb out',{
|
||||
category: 'storage-output',
|
||||
color:"#dbb84d",
|
||||
defaults: {
|
||||
level: {type:"leveldbase",required:true},
|
||||
operation: {value:"store"},
|
||||
name: {value:""}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "leveldb.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
var levelNode = RED.nodes.node(this.level);
|
||||
return this.name||(levelNode?levelNode.label():"leveldb");
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
93
nodes/storage/67-leveldb.js
Normal file
93
nodes/storage/67-leveldb.js
Normal file
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Copyright 2013 IBM Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var RED = require("../../red/red");
|
||||
var lvldb = require('level');
|
||||
|
||||
function LevelNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.dbname = n.db;
|
||||
var node = this;
|
||||
lvldb(this.dbname, function(err, db) {
|
||||
if (err) node.error(err);
|
||||
node.db = db;
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("leveldbase",LevelNode);
|
||||
LevelNode.prototype.close = function() {
|
||||
this.db.close();
|
||||
}
|
||||
|
||||
function LevelDBNodeIn(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.level = n.level;
|
||||
this.levelConfig = RED.nodes.getNode(this.level);
|
||||
|
||||
if (this.levelConfig) {
|
||||
var node = this;
|
||||
node.on("input", function(msg) {
|
||||
if (typeof msg.topic === 'string') {
|
||||
node.levelConfig.db.get(msg.topic, function(err, value) {
|
||||
if (err) {
|
||||
//node.warn(err);
|
||||
// for some reason they treat nothing found as an error...
|
||||
msg.payload = null; // so we should return null
|
||||
}
|
||||
else { msg.payload = value; }
|
||||
node.send(msg);
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (typeof msg.topic !== 'string') node.error("msg.topic (the key is not defined");
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error("LevelDB database name not configured");
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("leveldb in",LevelDBNodeIn);
|
||||
|
||||
|
||||
function LevelDBNodeOut(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.level = n.level;
|
||||
this.operation = n.operation;
|
||||
this.levelConfig = RED.nodes.getNode(this.level);
|
||||
|
||||
if (this.levelConfig) {
|
||||
var node = this;
|
||||
node.on("input", function(msg) {
|
||||
if (typeof msg.topic === 'string') {
|
||||
if (node.operation === "delete") {
|
||||
node.levelConfig.db.del(msg.topic);
|
||||
}
|
||||
else {
|
||||
node.levelConfig.db.put(msg.topic, msg.payload, function(err) {
|
||||
if (err) node.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (typeof msg.topic !== 'string') node.error("msg.topic (the key is not defined");
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.error("LevelDB database name not configured");
|
||||
}
|
||||
}
|
||||
RED.nodes.registerType("leveldb out",LevelDBNodeOut);
|
@ -154,14 +154,22 @@ RED.view = function() {
|
||||
var dx = mousePos[0]-(mousedown_node.x+sc*mousedown_node.w/2);
|
||||
var delta = Math.sqrt(dy*dy+dx*dx);
|
||||
var scale = lineCurveScale;
|
||||
|
||||
var scaleY = 0;
|
||||
|
||||
if (delta < node_width) {
|
||||
scale = 0.75-0.75*((node_width-delta)/node_width);
|
||||
}
|
||||
if (dx*sc < 0) {
|
||||
scale += 2*(Math.min(5*node_width,Math.abs(dx))/(5*node_width));
|
||||
if (Math.abs(dy) < 3*node_height) {
|
||||
scaleY = ((dy>0)?0.5:-0.5)*(((3*node_height)-Math.abs(dy))/(3*node_height))*(Math.min(node_width,Math.abs(dx))/(node_width)) ;
|
||||
}
|
||||
}
|
||||
|
||||
drag_line.attr("d",
|
||||
"M "+(mousedown_node.x+sc*mousedown_node.w/2)+" "+(mousedown_node.y+y)+
|
||||
" C "+(mousedown_node.x+sc*(mousedown_node.w/2+node_width*scale))+" "+(mousedown_node.y+y)+" "+
|
||||
(mousePos[0]-sc*(scale)*node_width)+" "+mousePos[1]+" "+
|
||||
" C "+(mousedown_node.x+sc*(mousedown_node.w/2+node_width*scale))+" "+(mousedown_node.y+y+scaleY*node_height)+" "+
|
||||
(mousePos[0]-sc*(scale)*node_width)+" "+(mousePos[1]-scaleY*node_height)+" "+
|
||||
mousePos[0]+" "+mousePos[1]
|
||||
);
|
||||
|
||||
@ -796,19 +804,26 @@ RED.view = function() {
|
||||
var dx = (d.target.x-d.target.w/2)-(d.source.x+d.source.w/2);
|
||||
var delta = Math.sqrt(dy*dy+dx*dx);
|
||||
var scale = lineCurveScale;
|
||||
|
||||
var scaleY = 0;
|
||||
if (delta < node_width) {
|
||||
scale = 0.75-0.75*((node_width-delta)/node_width);
|
||||
}
|
||||
|
||||
|
||||
if (dx < 0) {
|
||||
scale += 2*(Math.min(5*node_width,Math.abs(dx))/(5*node_width));
|
||||
if (Math.abs(dy) < 3*node_height) {
|
||||
scaleY = ((dy>0)?0.5:-0.5)*(((3*node_height)-Math.abs(dy))/(3*node_height))*(Math.min(node_width,Math.abs(dx))/(node_width)) ;
|
||||
}
|
||||
}
|
||||
|
||||
d.x1 = d.source.x+d.source.w/2;
|
||||
d.y1 = d.source.y+y;
|
||||
d.x2 = d.target.x-d.target.w/2;
|
||||
d.y2 = d.target.y;
|
||||
|
||||
return "M "+(d.source.x+d.source.w/2)+" "+(d.source.y+y)+
|
||||
" C "+(d.source.x+d.source.w/2+scale*node_width)+" "+(d.source.y+y)+" "+
|
||||
(d.target.x-d.target.w/2-scale*node_width)+" "+d.target.y+" "+
|
||||
" C "+(d.source.x+d.source.w/2+scale*node_width)+" "+(d.source.y+y+scaleY*node_height)+" "+
|
||||
(d.target.x-d.target.w/2-scale*node_width)+" "+(d.target.y-scaleY*node_height)+" "+
|
||||
(d.target.x-d.target.w/2)+" "+d.target.y;
|
||||
})
|
||||
|
||||
|
@ -142,7 +142,6 @@ a.brand img {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
|
||||
#sidebar {
|
||||
background: #fff;
|
||||
}
|
||||
@ -315,19 +314,16 @@ a.brand img {
|
||||
.node_invalid {
|
||||
stroke: #ff0000;
|
||||
}
|
||||
|
||||
.node_selected {
|
||||
stroke: #ff7f0e;
|
||||
}
|
||||
|
||||
.node_highlighted {
|
||||
stroke: #ff0000;
|
||||
}
|
||||
|
||||
|
||||
.node_hovered {
|
||||
dstroke: #ff7f0e;
|
||||
}
|
||||
|
||||
.port_hovered {
|
||||
stroke: #ff7f0e;
|
||||
fill: #ff7f0e;
|
||||
@ -368,15 +364,16 @@ a.brand img {
|
||||
text-align: center;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#dialog {
|
||||
}
|
||||
|
||||
.container {
|
||||
}
|
||||
|
||||
.notification {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#notifications {
|
||||
z-index: 10000;
|
||||
width: 500px;
|
||||
@ -389,6 +386,7 @@ a.brand img {
|
||||
box-shadow: 0 0 1px 1px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
clear: both;
|
||||
margin-bottom: 7px;
|
||||
@ -415,7 +413,6 @@ button.input-append-right {
|
||||
padding-right: 4px !important;
|
||||
}
|
||||
|
||||
|
||||
.form-tips {
|
||||
background: lightgoldenrodyellow;
|
||||
font-size: 12px;
|
||||
@ -472,16 +469,25 @@ div.node-info {
|
||||
.dropdown-menu * a.active > .icon-ok {
|
||||
display: inline-block;
|
||||
}
|
||||
.dropdown-menu>li.disabled>a:hover>[class^="icon-"] {
|
||||
background-image: url("bootstrap/img/glyphicons-halflings.png") !important;
|
||||
}
|
||||
/** Fix for unreachable dropdown menu **/
|
||||
.dropdown-menu {
|
||||
width: 200px !important;
|
||||
}
|
||||
.dropdown-menu > li > a {
|
||||
padding-left: 28px ;
|
||||
text-indent: -8px ;
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
.navbar-fixed-top, .navbar-fixed-bottom {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.popover-title { display: none; }
|
||||
|
||||
|
||||
.dropdown-menu>li.disabled>a:hover>[class^="icon-"] {
|
||||
background-image: url("bootstrap/img/glyphicons-halflings.png") !important;
|
||||
}
|
||||
.ui-autocomplete {
|
||||
max-height: 250px;
|
||||
overflow-x: hidden;
|
||||
@ -552,8 +558,3 @@ div.node-info {
|
||||
border-radius:5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/** Fix for unreachable dropdown menu **/
|
||||
div.pull-right > ul.dropdown-menu > li.dropdown-submenu > ul {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user