Initial commits
This commit is contained in:
parent
a8dcc3e15a
commit
5b3d431488
|
@ -12,3 +12,5 @@ logs
|
|||
results
|
||||
|
||||
npm-debug.log
|
||||
.idea
|
||||
node_modules
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
var storage = require('pkgcloud').storage;
|
||||
|
||||
var client = storage.createClient({
|
||||
provider: 'rackspace',
|
||||
username: 'your-user-name',
|
||||
apiKey: 'your-api-key'
|
||||
});
|
||||
|
||||
// Container
|
||||
|
||||
client.getContainers(function (err, containers) { });
|
||||
client.createContainer(options, function (err, container) { });
|
||||
client.destroyContainer(containerName, function (err) { });
|
||||
client.getContainer(containerName, function (err, container) { });
|
||||
|
||||
// File
|
||||
|
||||
client.upload(options, function (err) { });
|
||||
client.download(options, function (err) { });
|
||||
client.getFiles(container, function (err, files) { });
|
||||
client.getFile(container, file, function (err, server) { });
|
||||
client.removeFile(container, file, function (err) { });
|
|
@ -0,0 +1,162 @@
|
|||
/**
|
||||
* File system based on storage provider
|
||||
*/
|
||||
|
||||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
async = require('async');
|
||||
|
||||
module.exports = FileSystemProvider;
|
||||
|
||||
function FileSystemProvider(options) {
|
||||
options = options || {};
|
||||
this.root = options.root;
|
||||
var stat = fs.statSync(this.root);
|
||||
if (!stat.isDirectory()) {
|
||||
throw new Error('Invalid directory: ' + this.root);
|
||||
}
|
||||
}
|
||||
|
||||
var namePattern = new RegExp('[^' + path.sep + '/]+');
|
||||
|
||||
function validateName(name, cb) {
|
||||
if (!name) {
|
||||
cb && process.nextTick(cb.bind(null, new Error('Invalid name: ' + name)));
|
||||
return false;
|
||||
}
|
||||
var match = namePattern.exec(name);
|
||||
if (match && match.index === 0 && match[0].length === name.length) {
|
||||
return true;
|
||||
} else {
|
||||
cb && process.nextTick(cb.bind(null, new Error('Invalid name: ' + name)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Container related functions
|
||||
FileSystemProvider.prototype.getContainers = function (cb) {
|
||||
var self = this;
|
||||
fs.readdir(self.root, function (err, files) {
|
||||
var dirs = [];
|
||||
var tasks = [];
|
||||
files.forEach(function (f) {
|
||||
tasks.push(fs.stat.bind(null, path.join(self.root, f)));
|
||||
});
|
||||
async.parallel(tasks, function (err, stats) {
|
||||
if (err) {
|
||||
cb && cb(err);
|
||||
} else {
|
||||
stats.forEach(function (stat, index) {
|
||||
if (stat.isDirectory()) {
|
||||
dirs.push(files[index]);
|
||||
}
|
||||
});
|
||||
cb && cb(err, dirs);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
FileSystemProvider.prototype.createContainer = function (options, cb) {
|
||||
var name = options.name;
|
||||
var mode = options.mode || 0777;
|
||||
validateName(name, cb) && fs.mkdir(path.join(this.root, name), options, cb);
|
||||
}
|
||||
|
||||
FileSystemProvider.prototype.destroyContainer = function (containerName, cb) {
|
||||
if(!validateName(containerName, cb)) return;
|
||||
|
||||
var dir = path.join(this.root, containerName);
|
||||
fs.readdir(dir, function (err, files) {
|
||||
var tasks = [];
|
||||
files.forEach(function (f) {
|
||||
tasks.push(fs.unlink.bind(null, f));
|
||||
});
|
||||
async.parallel(tasks, function (err) {
|
||||
if (err) {
|
||||
cb && cb(err);
|
||||
} else {
|
||||
fs.rmdir(dir, cb);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
FileSystemProvider.prototype.getContainer = function (containerName, cb) {
|
||||
if(!validateName(containerName, cb)) return;
|
||||
var dir = path.join(this.root, containerName);
|
||||
fs.stat(dir, cb);
|
||||
}
|
||||
|
||||
|
||||
// File related functions
|
||||
FileSystemProvider.prototype.upload = function (options, cb) {
|
||||
var container = options.container;
|
||||
if(!validateName(container, cb)) return;
|
||||
var file = options.remote;
|
||||
if(!validateName(file, cb)) return;
|
||||
var filePath = path.join(this.root, container, file);
|
||||
|
||||
var fileOpts = {flags: 'w+',
|
||||
encoding: null,
|
||||
mode: 0666 };
|
||||
|
||||
return fs.createWriteStream(filePath, fileOpts);
|
||||
}
|
||||
|
||||
FileSystemProvider.prototype.download = function (options, cb) {
|
||||
var container = options.container;
|
||||
if(!validateName(container, cb)) return;
|
||||
var file = options.remote;
|
||||
if(!validateName(file, cb)) return;
|
||||
|
||||
var filePath = path.join(this.root, container, file);
|
||||
|
||||
var fileOpts = {flags: 'r',
|
||||
autoClose: true };
|
||||
|
||||
return fs.createReadStream(filePath, fileOpts);
|
||||
|
||||
}
|
||||
|
||||
FileSystemProvider.prototype.getFiles = function (container, cb) {
|
||||
if(!validateName(container, cb)) return;
|
||||
var dir = path.join(this.root, container);
|
||||
fs.readdir(dir, function (err, files) {
|
||||
var dirs = [];
|
||||
var tasks = [];
|
||||
files.forEach(function (f) {
|
||||
tasks.push(fs.stat.bind(null, f));
|
||||
});
|
||||
async.parallel(tasks, function (err, stats) {
|
||||
if (err) {
|
||||
cb && cb(err);
|
||||
} else {
|
||||
stats.forEach(function (stat, index) {
|
||||
if (stat.isFile()) {
|
||||
dirs.push(files[index]);
|
||||
}
|
||||
});
|
||||
cb && cb(err, dirs);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
FileSystemProvider.prototype.getFile = function (container, file, cb) {
|
||||
if(!validateName(container, cb)) return;
|
||||
var container = options.container;
|
||||
if(!validateName(file, cb)) return;
|
||||
var filePath = path.join(this.root, container, file);
|
||||
fs.stat(filePath, cb);
|
||||
}
|
||||
|
||||
FileSystemProvider.prototype.removeFile = function (container, file, cb) {
|
||||
if(!validateName(container, cb)) return;
|
||||
var container = options.container;
|
||||
if(!validateName(file, cb)) return;
|
||||
|
||||
var filePath = path.join(this.root, container, file);
|
||||
fs.unlink(filePath, cb);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "asteroid-storage-service",
|
||||
"description": "Asteroid Storage Service",
|
||||
"version": "0.0.1",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "./node_modules/.bin/mocha --timeout 30000 test/*test.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"pkgcloud": "latest",
|
||||
"async": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "latest",
|
||||
"supertest": "latest"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/strongloop/asteroid-storage-service.git"
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
var FileSystemProvider = require('../lib/providers/file.js');
|
||||
|
||||
var assert = require('assert');
|
||||
var path = require('path');
|
||||
|
||||
describe('FileSystem based storage provider', function () {
|
||||
|
||||
var client = null;
|
||||
it('should require an existing directory as the root', function (done) {
|
||||
client = new FileSystemProvider({root: path.join(__dirname, 'storage')});
|
||||
process.nextTick(done);
|
||||
});
|
||||
|
||||
var client = null;
|
||||
it('should complain if the root directory doesn\'t exist', function (done) {
|
||||
try {
|
||||
client = new FileSystemProvider({root: path.join(__dirname, '_storage')});
|
||||
process.nextTick(done.bind(null, 'Error'));
|
||||
} catch (err) {
|
||||
// Should be here
|
||||
process.nextTick(done);
|
||||
}
|
||||
});
|
||||
|
||||
it('should return an empty list of containers', function (done) {
|
||||
client.getContainers(function (err, containers) {
|
||||
assert(!err);
|
||||
assert.equal(0, containers.length);
|
||||
done(err, containers);
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a new container', function (done) {
|
||||
client.createContainer({name: 'c1'}, function (err, container) {
|
||||
assert(!err);
|
||||
done(err, container);
|
||||
});
|
||||
});
|
||||
|
||||
it('should get a container c1', function (done) {
|
||||
client.getContainer('c1', function (err, container) {
|
||||
assert(!err);
|
||||
done(err, container);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not get a container c2', function (done) {
|
||||
client.getContainer('c2', function (err, container) {
|
||||
assert(err);
|
||||
done(null, container);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return one container', function (done) {
|
||||
client.getContainers(function (err, containers) {
|
||||
assert(!err);
|
||||
assert.equal(1, containers.length);
|
||||
done(err, containers);
|
||||
});
|
||||
});
|
||||
|
||||
it('should destroy a container c1', function (done) {
|
||||
client.destroyContainer('c1', function (err, container) {
|
||||
assert(!err);
|
||||
done(err, container);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not get a container c1 after destroy', function (done) {
|
||||
client.getContainer('c1', function (err, container) {
|
||||
assert(err);
|
||||
done(null, container);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
This is the test folder for file system based storage
|
||||
|
Loading…
Reference in New Issue