Commit 8c3ae071 by Johannes Zellner

Support recursive put

1 parent 08b2ad7f
...@@ -4,11 +4,12 @@ ...@@ -4,11 +4,12 @@
var express = require('express'), var express = require('express'),
morgan = require('morgan'), morgan = require('morgan'),
path = require('path'),
compression = require('compression'), compression = require('compression'),
bodyParser = require('body-parser'), bodyParser = require('body-parser'),
lastMile = require('connect-lastmile'), lastMile = require('connect-lastmile'),
multipart = require('./src/multipart'), multipart = require('./src/multipart'),
files = require('./src/files.js'); files = require('./src/files.js')(path.resolve(__dirname, 'files'));
var app = express(); var app = express();
var router = new express.Router(); var router = new express.Router();
......
'use strict';
exports.login = login;
exports.put = put;
exports.get = get;
exports.del = del;
var superagent = require('superagent'),
config = require('./config'),
async = require('async'),
fs = require('fs'),
path = require('path');
require('colors');
var API = '/api/files/';
function checkConfig() {
if (!config.server()) {
console.log('You have run "login" first');
process.exit(1);
}
}
function collectFiles(filesOrFolders) {
var tmp = [];
filesOrFolders.forEach(function (filePath) {
var stat = fs.statSync(filePath);
if (stat.isFile()) {
tmp.push(filePath);
} else if (stat.isDirectory()) {
var files = fs.readdirSync(filePath).map(function (file) { return path.join(filePath, file); });
tmp = tmp.concat(collectFiles(files));
} else {
console.log('Skipping %s', filePath.cyan);
}
});
return tmp;
}
function login(server) {
console.log('Using server', server);
config.set('server', server);
}
function put(filePath, otherFilePaths) {
checkConfig();
var files = collectFiles([ filePath ].concat(otherFilePaths));
async.eachSeries(files, function (file, callback) {
var relativeFilePath = path.resolve(file).slice(process.cwd().length + 1);
console.log('Uploading file %s', relativeFilePath.cyan);
superagent.put(config.server() + API + relativeFilePath).attach('file', file).end(callback);
}, function (error) {
if (error) {
console.log('Failed to put file.', error);
process.exit(1);
}
console.log('Done');
});
}
function get(filePath) {
checkConfig();
var relativeFilePath = path.resolve(filePath).slice(process.cwd().length + 1);
superagent.get(config.server() + API + relativeFilePath).end(function (error, result) {
if (error) return console.log('Failed', result ? result.body : error);
if (result.body && result.body.entries) {
console.log('Files:');
result.body.entries.forEach(function (entry) {
console.log('\t %s', entry);
});
} else {
console.log(result.text);
}
});
}
function del(filePath) {
checkConfig();
var relativeFilePath = path.resolve(filePath).slice(process.cwd().length + 1);
superagent.del(config.server() + API + relativeFilePath).end(function (error, result) {
if (error) return console.log('Failed', result ? result.body : error);
console.log('Success', result.body);
});
}
/* jshint node:true */
'use strict';
var fs = require('fs'),
path = require('path'),
safe = require('safetydance'),
_ = require('underscore');
exports = module.exports = {
clear: clear,
set: set,
get: get,
unset: unset,
has: has,
// convenience
server: function () { return get('server'); }
};
var HOME = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
var CONFIG_FILE_PATH = path.join(HOME, '.surfer.json');
var gConfig = (function () {
return safe.JSON.parse(safe.fs.readFileSync(CONFIG_FILE_PATH)) || {};
})();
function save() {
fs.writeFileSync(CONFIG_FILE_PATH, JSON.stringify(gConfig, null, 4));
}
function clear() {
safe.fs.unlinkSync(CONFIG_FILE_PATH);
}
function set(key, value) {
if (typeof key === 'object') {
_.extend(gConfig, key);
} else {
safe.set(gConfig, key, value);
}
save();
}
function get(key) {
return safe.query(gConfig, key);
}
function unset(key /*, .... */) {
for (var i = 0; i < arguments.length; i++) {
gConfig = safe.unset(gConfig, arguments[i]);
}
save();
}
function has(key /*, ... */) {
for (var i = 0; i < arguments.length; i++) {
if (!(arguments[i] in gConfig)) return false;
}
return true;
}
...@@ -3,14 +3,18 @@ ...@@ -3,14 +3,18 @@
'use strict'; 'use strict';
var program = require('commander'), var program = require('commander'),
actions = require('./src/actions'); actions = require('./actions');
// Allow self signed certs! // Allow self signed certs!
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
program.version('0.1.0'); program.version('0.1.0');
program.command('put') program.command('login')
.description('Login to server')
.action(actions.login);
program.command('put <file> [files...]')
.description('Put a file') .description('Put a file')
.action(actions.put); .action(actions.put);
...@@ -23,3 +27,13 @@ program.command('del') ...@@ -23,3 +27,13 @@ program.command('del')
.action(actions.del); .action(actions.del);
program.parse(process.argv); program.parse(process.argv);
if (!process.argv.slice(2).length) {
program.outputHelp();
} else { // https://github.com/tj/commander.js/issues/338
var knownCommand = program.commands.some(function (command) { return command._name === process.argv[2]; });
if (!knownCommand) {
console.error('Unknown command: ' + process.argv[2]);
process.exit(1);
}
}
...@@ -10,20 +10,28 @@ ...@@ -10,20 +10,28 @@
"file", "file",
"server" "server"
], ],
"bin": {
"surfer": "./cli/surfer.js"
},
"author": "Johannes Zellner <johannes@nebulon.de>", "author": "Johannes Zellner <johannes@nebulon.de>",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"async": "^1.2.1",
"body-parser": "^1.13.1", "body-parser": "^1.13.1",
"colors": "^1.1.2",
"commander": "^2.8.1", "commander": "^2.8.1",
"compression": "^1.5.0", "compression": "^1.5.0",
"connect-lastmile": "0.0.10", "connect-lastmile": "0.0.10",
"connect-timeout": "^1.6.2", "connect-timeout": "^1.6.2",
"debug": "^2.2.0",
"ejs": "^2.3.1", "ejs": "^2.3.1",
"express": "^4.12.4", "express": "^4.12.4",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"morgan": "^1.6.0", "morgan": "^1.6.0",
"multiparty": "^4.1.2", "multiparty": "^4.1.2",
"rimraf": "^2.4.0", "rimraf": "^2.4.0",
"superagent": "^1.2.0" "safetydance": "0.0.16",
"superagent": "^1.2.0",
"underscore": "^1.8.3"
} }
} }
'use strict';
exports.put = put;
exports.get = get;
exports.del = del;
var superagent = require('superagent'),
path = require('path');
var server = 'http://localhost:3000/api/files/';
function put(filePath) {
var relativeFilePath = path.resolve(filePath).slice(process.cwd().length + 1);
superagent.put(server + relativeFilePath).attach('file', filePath).end(function (error, result) {
if (error) return console.log('Failed', result ? result.body : error);
console.log('Success', result.body);
});
}
function get(filePath) {
var relativeFilePath = path.resolve(filePath).slice(process.cwd().length + 1);
superagent.get(server + relativeFilePath).end(function (error, result) {
if (error) return console.log('Failed', result ? result.body : error);
console.log('Success', result.body);
});
}
function del(filePath) {
var relativeFilePath = path.resolve(filePath).slice(process.cwd().length + 1);
superagent.del(server + relativeFilePath).end(function (error, result) {
if (error) return console.log('Failed', result ? result.body : error);
console.log('Success', result.body);
});
}
...@@ -4,17 +4,22 @@ var fs = require('fs'), ...@@ -4,17 +4,22 @@ var fs = require('fs'),
path = require('path'), path = require('path'),
ejs = require('ejs'), ejs = require('ejs'),
rimraf = require('rimraf'), rimraf = require('rimraf'),
debug = require('debug')('files'),
mkdirp = require('mkdirp'), mkdirp = require('mkdirp'),
HttpError = require('connect-lastmile').HttpError, HttpError = require('connect-lastmile').HttpError,
HttpSuccess = require('connect-lastmile').HttpSuccess; HttpSuccess = require('connect-lastmile').HttpSuccess;
exports = module.exports = { var gBasePath;
get: get,
put: put, exports = module.exports = function (basePath) {
del: del gBasePath = basePath;
};
var FILE_BASE = path.resolve(__dirname, '../files'); return {
get: get,
put: put,
del: del
};
};
// http://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js // http://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js
function copyFile(source, target, cb) { function copyFile(source, target, cb) {
...@@ -54,9 +59,9 @@ function render(view, options) { ...@@ -54,9 +59,9 @@ function render(view, options) {
} }
function getAbsolutePath(filePath) { function getAbsolutePath(filePath) {
var absoluteFilePath = path.resolve(FILE_BASE, filePath); var absoluteFilePath = path.resolve(gBasePath, filePath);
if (absoluteFilePath.indexOf(FILE_BASE) !== 0) return null; if (absoluteFilePath.indexOf(gBasePath) !== 0) return null;
return absoluteFilePath; return absoluteFilePath;
} }
...@@ -68,7 +73,7 @@ function get(req, res, next) { ...@@ -68,7 +73,7 @@ function get(req, res, next) {
fs.stat(absoluteFilePath, function (error, result) { fs.stat(absoluteFilePath, function (error, result) {
if (error) return next(new HttpError(404, error)); if (error) return next(new HttpError(404, error));
console.log('get', absoluteFilePath); debug('get', absoluteFilePath);
if (result.isFile()) return res.sendfile(absoluteFilePath); if (result.isFile()) return res.sendfile(absoluteFilePath);
if (result.isDirectory()) return res.status(200).send({ entries: fs.readdirSync(absoluteFilePath) }); if (result.isDirectory()) return res.status(200).send({ entries: fs.readdirSync(absoluteFilePath) });
...@@ -88,7 +93,7 @@ function put(req, res, next) { ...@@ -88,7 +93,7 @@ function put(req, res, next) {
fs.stat(absoluteFilePath, function (error, result) { fs.stat(absoluteFilePath, function (error, result) {
if (error && error.code !== 'ENOENT') return next(new HttpError(500, error)); if (error && error.code !== 'ENOENT') return next(new HttpError(500, error));
console.log('put', absoluteFilePath, req.files.file); debug('put', absoluteFilePath, req.files.file);
if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories')); if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories'));
if (!result || result.isFile()) { if (!result || result.isFile()) {
...@@ -106,7 +111,7 @@ function del(req, res, next) { ...@@ -106,7 +111,7 @@ function del(req, res, next) {
var filePath = req.params[0]; var filePath = req.params[0];
var absoluteFilePath = getAbsolutePath(filePath); var absoluteFilePath = getAbsolutePath(filePath);
if (!absoluteFilePath) return next(new HttpError(404, 'Not found')); if (!absoluteFilePath) return next(new HttpError(404, 'Not found'));
if (absoluteFilePath.slice(FILE_BASE.length) === '') return next(new HttpError(403, 'Forbidden')); if (absoluteFilePath.slice(gBasePath.length) === '') return next(new HttpError(403, 'Forbidden'));
fs.stat(absoluteFilePath, function (error, result) { fs.stat(absoluteFilePath, function (error, result) {
if (error) return next(new HttpError(404, error)); if (error) return next(new HttpError(404, error));
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!