Skip to content

Commit

Permalink
Resolves #1 Added the ability to define destinations in the files inp…
Browse files Browse the repository at this point in the history
…ut array.
  • Loading branch information
teastman committed Oct 2, 2017
1 parent 6e4ea95 commit 9af18dd
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 51 deletions.
39 changes: 33 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,47 @@ Usage

This node allows you to download one or more files within a single connection.

**Files**

The file paths may be defined in one of a number of ways.
- `msg.`: A variable on the msg object that contains an array of Strings.
- `flow.`: A variable on the flow context object that contains an array of Strings.
- `global.`: A variable on the global context object that contains an array of Strings.
- `json`: A JSON array of Strings.
- `msg.`: A variable on the msg object that contains an array of Strings or source Objects.
- `flow.`: A variable on the flow context object that contains an array of Strings or source Objects.
- `global.`: A variable on the global context object that contains an array of Strings or source Objects.
- `json`: A JSON array of Strings or source Objects.
- `string`: A singular path String.

The destination path may be defined in one of a number of ways.
**ex:**

~~~~
global.test = ["/path/to/ftp.file", "/path/to/another/ftp.file"];
// or
global.test = [
{
"src": "/path/to/ftp.file",
"dest": "/path/to/local.file"
}, {
"src": "/path/to/another/ftp.file",
"dest": "/path/to/another/local.file"
}
];
~~~~

**Directory**

The directory path may be defined in one of a number of ways.
- `msg.`: A variable on the msg object that contains a local path String.
- `flow.`: A variable on the flow context object that contains a local path String
- `global.`: A variable on the global context object that contains a local path String
- `string`: A singular local path String.

As an output an Array of local file path Strings is places in `msg.payload`
The files defined in the files field will be downloaded into the directory field, if the files field is an array of
objects with dest fields set. The final destination will be `directory + "/" + file.dest`

**Output**

An Array of local file path Strings is placed in `msg.payload`

Acknowledgements
----------------
Expand Down
45 changes: 31 additions & 14 deletions ftp-download.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@
<input type="text" id="node-input-files" placeholder="Filenames">
</div>
<div class="form-row">
<label for="node-input-destination"><i class="fa fa-folder"></i> <span data-i18n="download.destination"></span></label>
<input type="text" id="node-input-destination" placeholder="Local Folder">
<label for="node-input-directory"><i class="fa fa-folder"></i> <span data-i18n="download.directory"></span></label>
<input type="text" id="node-input-directory" placeholder="Local Folder">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="download.name"></span></label>
Expand All @@ -91,25 +91,41 @@
<p>Downloads files from an FTP server to a local directory.</p>
<h3>Details</h3>
<p>This node will connect to the specified 'server' and attempt to download all file paths defined in the 'File(s)'
field and place them in the 'Destination' directory. This occurs within a single connection, so if any of the files
field and place them in the 'directory' directory. This occurs within a single connection, so if any of the files
fail, an error will be thrown and the rest will fail.</p>

<h3>Inputs</h3>
<p>The 'File(s)' input may be defined from the following sources.</p>
<dl class="message-properties">
<dt>msg.</dt>
<dd>A variable on the msg, must be an Array of path Strings.</dd>
<dd>A variable on the msg, must be an Array of path Strings or source Objects.</dd>
<dt>flow.</dt>
<dd>A variable in the flow context, must be an Array of path Strings.</dd>
<dd>A variable in the flow context, must be an Array of path Strings or source Objects.</dd>
<dt>global.</dt>
<dd>A variable in the global context, must be an Array of path Strings.</dd>
<dd>A variable in the global context, must be an Array of path Strings or source Objects.</dd>
<dt>json</dt>
<dd>An Array of path strings.</dd>
<dd>An Array of path strings or source Objects.</dd>
<dt>string</dt>
<dd>A single path string.</dd>
</dl>

<p>The 'Destination' input may be defined from the following sources.</p>
<code>
global.test = ["/path/to/ftp.file", "/path/to/another/ftp.file"];
</code>
or
<code>
global.test = [
{
"src": "/path/to/ftp.file",
"dest": "/path/to/local.file"
}, {
"src": "/path/to/another/ftp.file",
"dest": "/path/to/another/local.file"
}
];
</code>

<p>The 'directory' input may be defined from the following sources.</p>
<dl class="message-properties">
<dt>msg.</dt>
<dd>A variable on the msg, must be a local path.</dd>
Expand All @@ -121,14 +137,15 @@ <h3>Inputs</h3>
<dd>A single local path string.</dd>
</dl>

<p>Reads a list of file paths from the File(s) input
<p>Reads a list of file paths from the File(s) input. The files defined in the files field will be downloaded into the directory field, if the files field is an array of
objects with dest fields set. The final destination will be `directory + "/" + file.dest`</p>

<h3>Outputs</h3>
<p>Sets <code>msg.payload</code> to be an Array of local path strings where the downloaded files were stored.</p>

<h3>References</h3>
<ul>
<li><a href="">GitHub</a> - node-red-contrib-ftp-download repository</li>
<li><a href="https://github.com/teastman/node-red-contrib-ftp-download">GitHub</a> - node-red-contrib-ftp-download repository</li>
</ul>
</script>

Expand All @@ -138,10 +155,10 @@ <h3>References</h3>
defaults: {
server: {type: 'ftp-download-server', required: true},
files: {value: ''},
destination: {value: ''},
directory: {value: ''},
name: {value: ''},
filesType: { value:"str" },
destinationType: { value:"str" }
directoryType: { value:"str" }
},
inputs: 1,
outputs: 1,
Expand All @@ -152,11 +169,11 @@ <h3>References</h3>
},
oneditprepare: function () {
$("#node-input-files").typedInput({default:this.filesType||'str',types: ["str", "json", "msg", "flow", "global"]});
$("#node-input-destination").typedInput({default:this.destinationType||'str',types: ["str", "msg", "flow", "global"]});
$("#node-input-directory").typedInput({default:this.directoryType||'str',types: ["str", "msg", "flow", "global"]});
},
oneditsave: function() {
this.filesType = $("#node-input-files").typedInput('type');
this.destinationType = $("#node-input-destination").typedInput('type');
this.directoryType = $("#node-input-directory").typedInput('type');
}
});
</script>
62 changes: 33 additions & 29 deletions ftp-download.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ module.exports = function (RED) {
node.server = n.server;
node.serverConfig = RED.nodes.getNode(node.server);
node.files = n.files;
node.destination = n.destination;
node.directory = n.directory;
node.filesType = n.filesType || "str";
node.destinationType = n.destinationType || "str";
node.directoryType = n.directoryType || "str";

let fileList = [];
let destination = "";
let directory = "";

node.on('input', (msg) => {

Expand Down Expand Up @@ -88,33 +88,24 @@ module.exports = function (RED) {
return;
}

// Load the destination from the appropriate variable.
// Load the directory from the appropriate variable.
try {
switch (node.destinationType) {
switch (node.directoryType) {
case 'msg':
destination = msg[node.destination];
directory = msg[node.directory];
break;
case 'flow':
destination = flow.get(node.destination);
directory = flow.get(node.directory);
break;
case 'global':
destination = global.get(node.destination);
directory = global.get(node.directory);
break;
default:
destination = node.destination;
directory = node.directory;
}
}
catch (err) {
node.error("Could not load destination variable, type: " + node.destinationType + " location: " + node.destination, msg);
return;
}

// Assert we have access to write to the destination
try {
fs.accessSync(destination, fs.constants.W_OK);
}
catch (err) {
node.error("Lacking permission to write files to " + destination, msg);
node.error("Could not load directory variable, type: " + node.directoryType + " location: " + node.directory, msg);
return;
}

Expand All @@ -134,8 +125,8 @@ module.exports = function (RED) {
.catch((err) => {
msg.payload = {
fileList: fileList,
destination: destination,
error: err
directory: directory,
caught: err
};
node.error("FTP download failed", msg);
})
Expand All @@ -144,22 +135,35 @@ module.exports = function (RED) {
function download(file) {
return (filePaths) => new Promise((resolve, reject) => {
try {
conn.get(file, (err, stream) => {
let source = file;
if(typeof file.src === "string")
source = file.src;

let destination = path.join(directory, path.basename(source));
if(typeof file.dest === "string"){
destination = path.join(directory, file.dest);
}

conn.get(source, (err, stream) => {
if (err)
reject({"paths": filePaths, "error": err});

filePaths.push(destination);
try {
if (err)
throw err;
let filePath = path.join(destination, path.basename(file));
filePaths.push(filePath);
let writestream = fs.createWriteStream(destination);
writestream.on('error', (err) => {
reject({"paths": filePaths, "error": err});
});
stream.once('finish', () => resolve(filePaths));
stream.pipe(fs.createWriteStream(filePath));
stream.pipe(writestream);
}
catch (error) {
reject(error);
reject({"paths": filePaths, "error": error});
}
});
}
catch (error) {
reject(error);
reject({"paths": filePaths, "error": error});
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion locales/en-US/ftp-download.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"download": {
"server": "Server",
"files": "File(s)",
"destination": "Destination",
"directory": "Directory",
"name": "Name"
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-red-contrib-ftp-download",
"version": "1.0.1",
"version": "1.0.2",
"description": "A Node-RED node for FTP downloading.",
"dependencies": {
"ftp": "0.x"
Expand Down Expand Up @@ -31,3 +31,4 @@
}
]
}

0 comments on commit 9af18dd

Please sign in to comment.