diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3adea5b --- /dev/null +++ b/.gitignore @@ -0,0 +1,54 @@ +###Node### + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Commenting this out is preferred by some people, see +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- +node_modules + +# Users Environment Variables +.lock-wscript + + +###OSX### + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..aa465af --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 + +Initial release \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ae5a0d4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Heinrich Fenkart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c5eb5bd --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# multer-ftp + +FTP storage engine for multer. + +## Installation + +```sh +$ npm install --save multer-ftp +``` + +## Usage + +Basic usage example: + +```javascript +var multer = require('multer') +var FTPStorage = require('multer-ftp') + +var upload = multer({ + storage: new FTPStorage({ + basepath: '/remote/path', + ftp: { + host: 'example.com', + secure: true, // enables FTPS/FTP with TLS + user: 'user', + password: 'password' + } + }) +}) +``` + +For more FTP connection options see [`ftp` module `connect` method](https://github.com/mscdex/node-ftp#methods). + +--- + +By default random filenames are chosen (`crypto.randomBytes`), you can change this behavior however by using a custom `destination` function: + +```javascript +// Demonstrates destination that uses sha1 digest of file +var multer = require('multer') +var crypto = require('crypto') +var FTPStorage = require('multer-ftp') + +var upload = multer({ + storage: new FTPStorage({ + destination: function (req, file, options, callback) { + var digest = crypto.createHash('sha1') + + digest.setEncoding('hex') + + file.stream.pipe(digest) + + file.stream.on('end', function () { + digest.end() + callback(null, digest.read()) + }) + }, + ftp: { /* ... */ } + }) +}) +``` + +## Todo + +Write tests + +## License + +[MIT](LICENSE) \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..065e2a5 --- /dev/null +++ b/index.js @@ -0,0 +1,48 @@ +var Promise = require('bluebird') +var FTP = require('ftp') +var path = require('path') +var defaults = require('lodash.defaults') +var random = Promise.promisify(require('crypto').randomBytes) + +function getDestination (req, file, opts, cb) { + random(16).then(function(raw) { + cb(null, path.join(opts.basepath, raw.toString('hex') + path.extname(file.originalname))) + }, cb) +} + +function FTPStorage (opts) { + this.opts = defaults(opts, { + basepath: '', + destination: getDestination + }) + this.ftp = new FTP() + this.ready = new Promise(function (resolve, reject) { + this.ftp.on('ready', resolve) + }.bind(this)) + + this.ftp.connect(this.opts.ftp) +} + +FTPStorage.prototype._handleFile = function _handleFile (req, file, cb) { + this.ready.then(function () { + this.opts.destination(req, file, this.opts, function (err, destination) { + if (err) return cb(err) + + this.ftp.put(file.stream, destination, function (err) { + if (err) return cb(err) + + cb(null, { + path: destination + }) + }) + }.bind(this)) + }.bind(this)) +} + +FTPStorage.prototype._removeFile = function _removeFile(req, file, cb) { + this.ready.then(function () { + this.ftp.delete(file.path, cb) + }.bind(this)) +} + +module.exports = FTPStorage \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..377a4fc --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "multer-ftp", + "version": "1.0.0", + "description": "FTP storage engine for multer", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "multer", + "ftp" + ], + "author": "Heinrich Fenkart ", + "license": "MIT", + "dependencies": { + "bluebird": "^3.1.1", + "ftp": "^0.3.10", + "lodash.defaults": "^3.1.2" + } +}