Skip to content

Commit e5ea03d

Browse files
Merge pull request #1 from michaelblight/dev
First version
2 parents 1a2c449 + abceb8f commit e5ea03d

File tree

4 files changed

+198
-2
lines changed

4 files changed

+198
-2
lines changed

README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,22 @@
1-
# node-red-contrib-rsync
2-
Node for rsyncwrapper
1+
# rsync for Node-Red
2+
3+
This node is a wrapper around the [rsyncwrapper](https://www.npmjs.com/package/rsyncwrapper) module, which is a wrapper around rsync.
4+
5+
It requires that rsync is already installed. If using the Docker image for Node-Red, you can create your own image with rsync
6+
installed using the following dockerfile:
7+
8+
**
9+
10+
FROM nodered/node-red-docker
11+
12+
USER root
13+
14+
RUN apt-get update && apt-get -y install rsync
15+
16+
CMD ["npm", "start", "--", "--userDir", "/data"]
17+
18+
You can then create the image using the following command:
19+
20+
sudo docker build -t node-red-rsync .
21+
22+
And then replace the reference to the standard Node-Red image "nodered/node-red-docker" with your newly created one "node-red-rsync".

package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "node-red-contrib-rsync",
3+
"version": "1.0.0",
4+
"description": "Node Red wrapper for rsync",
5+
"main": "rsync-wrapper.js",
6+
"scripts": {
7+
"test": "echo \"No test specified\""
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/michaelblight/node-red-contrib-rsync.git"
12+
},
13+
"keywords": [
14+
"node",
15+
"red",
16+
"rsync"
17+
],
18+
"author": "Michael Blight",
19+
"license": "Apache-2.0",
20+
"bugs": {
21+
"url": "https://github.com/michaelblight/node-red-contrib-rsync/issues"
22+
},
23+
"homepage": "https://github.com/michaelblight/node-red-contrib-rsync#readme",
24+
"dependencies": {
25+
"rsyncwrapper": "^3.0.0"
26+
}, "node-red" : {
27+
"nodes": {
28+
"rsync": "rsync-wrapper.js"
29+
}
30+
}
31+
}

rsync-wrapper.html

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<script type="text/javascript">
2+
RED.nodes.registerType('rsync', {
3+
category: 'advanced',
4+
color: '#a6bbcf',
5+
defaults: {
6+
name: { value: ""},
7+
source: { value: "" },
8+
destination: { value: "" },
9+
verbose: { value: "" },
10+
recursive: { value: "" },
11+
},
12+
inputs: 1,
13+
outputs: 2,
14+
icon: "file.png",
15+
label: function() {
16+
return this.name || "rsync";
17+
}
18+
});
19+
</script>
20+
21+
<script type="text/x-red" data-template-name="rsync">
22+
<div class="form-row">
23+
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
24+
<input type="text" id="node-input-name" placeholder="Name">
25+
</div>
26+
<div class="form-row">
27+
<label for="node-input-source"><i class="fa fa-file-text-o"></i> Source</label>
28+
<input type="text" id="node-input-source" placeholder="Source">
29+
</div>
30+
<div class="form-row">
31+
<label for="node-input-destination"><i class="fa fa-file-text-o"></i> Destination</label>
32+
<input type="text" id="node-input-destination" placeholder="Destination">
33+
</div>
34+
<div class="form-row">
35+
<label for="node-input-verbose"><i class="fa fa-bug"></i> Verbose</label>
36+
<input type="checkbox" id="node-input-verbose" style="display: inline-block; width: auto; vertical-align: top;">
37+
</div>
38+
<div class="form-row">
39+
<label for="node-input-recursive"><i class="fa fa-bug"></i> Recursive</label>
40+
<input type="checkbox" id="node-input-recursive" style="display: inline-block; width: auto; vertical-align: top;">
41+
</div>
42+
</script>
43+
44+
<script type="text/x-red" data-help-name="rsync">
45+
<p>Uses rsyncwrapper to call rsync.</p>
46+
<p>The node can be configured with the source and destination, as well as the options below.</p>
47+
<p>When configured through the dialog, the source can only be a single folder or filename. However, when configured
48+
through msg, the source can also be an array of folders or filenames.</p>
49+
50+
<h3>Inputs</h3>
51+
<p>The following can be overridden by including them in the input msg</p>
52+
<dl class="message-properties">
53+
<dt>source
54+
<span class="property-type">string or array</span>
55+
</dt>
56+
<dd>The folder or filename to copy from. Can also be an array of folders and filenames.</dd>
57+
<dt>destination
58+
<span class="property-type">string</span>
59+
</dt>
60+
<dd>The folder or filename to copy to.</dd>
61+
<dt>verbose
62+
<span class="property-type">boolean</span>
63+
</dt>
64+
<dd>Include verbose flag on rsync command.</dd>
65+
<dt>recursive
66+
<span class="property-type">boolean</span>
67+
</dt>
68+
<dd>Recursively copy child folders.</dd>
69+
</dl>
70+
<h3>Outputs</h3>
71+
<dl class="message-properties">
72+
The resulting message will be sent to the first output if successfully, or the second output upon failure. The message will contain
73+
all of the input properties, as well as the following as appropriate:
74+
75+
<dt>error
76+
<span class="property-type">string</span>
77+
</dt>
78+
<dt>stdout
79+
<span class="property-type">string</span>
80+
</dt>
81+
<dt>stderr
82+
<span class="property-type">string</span>
83+
</dt>
84+
<dt>cmd
85+
<span class="property-type">string</span>
86+
<dd>The command line as sent to rsync.</dd>
87+
</dt>
88+
</script>

rsync-wrapper.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const rsync = require('rsyncwrapper')
2+
3+
module.exports = function(RED) {
4+
function rsyncNode(n) {
5+
RED.nodes.createNode(this, n);
6+
this.source = n.source
7+
this.destination = n.destination
8+
this.verbose = n.verbose
9+
this.recursive = n.recursive
10+
var node = this;
11+
12+
node.on('input', function(msg) {
13+
rsyncRun(node, msg);
14+
});
15+
}
16+
17+
RED.nodes.registerType("rsync", rsyncNode);
18+
19+
function rsyncRun(node, msg) {
20+
var source = typesOrDefault(['string', 'array'], msg.source, node.source)
21+
var destination = typesOrDefault(['string'], msg.destination, node.destination)
22+
var verbose = trueOrDefault(msg.verbose, node.verbose === true)
23+
var recursive = trueOrDefault(msg.recursive, node.recursive === true)
24+
25+
var args = []
26+
if (verbose === true) args.push('-v')
27+
28+
var options = {
29+
src: source,
30+
dest: destination,
31+
recursive: recursive,
32+
args: args,
33+
}
34+
35+
rsync(options, function(error, stdout, stderr, cmd) {
36+
if (error !== null) msg.error = error
37+
if (stdout !== "") msg.stdout = stdout
38+
if (stderr !== "") msg.stderr = stderr
39+
msg.cmd = cmd
40+
if (error) {
41+
node.send([null, msg])
42+
} else {
43+
node.send([msg, null])
44+
}
45+
})
46+
}
47+
48+
function typesOrDefault(types, v, d) {
49+
var t = typeof v
50+
if (Array.isArray(v)) t = 'array'
51+
return (types.includes(t)) ? v : d
52+
}
53+
54+
function trueOrDefault(v, d) {
55+
return (v === true) ? v : d
56+
}
57+
}

0 commit comments

Comments
 (0)