Skip to content

Commit

Permalink
Pipeline-ify configuration/themes/upload APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
halfdan committed Jul 22, 2015
1 parent 5c637dd commit ace5c06
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 76 deletions.
62 changes: 47 additions & 15 deletions core/server/api/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ var _ = require('lodash'),
config = require('../config'),
errors = require('../errors'),
Promise = require('bluebird'),
utils = require('./utils'),
pipeline = require('../utils/pipeline'),

configuration;

Expand Down Expand Up @@ -36,29 +38,59 @@ configuration = {
* @returns {Promise(Configurations)}
*/
browse: function browse() {
return Promise.resolve({configuration: _.map(getValidKeys(), function (value, key) {
return {
key: key,
value: value
};
})});
function formatResponse(keys) {
return {configuration: _.map(keys, function (value, key) {
return {
key: key,
value: value
};
})};
}

// Pipeline calls each task passing the result of one to be the arguments for the next
return pipeline([getValidKeys, formatResponse]);
},

/**
* ### Read
*
* Fetch a single configuration by key
* @param {{key}} options
* @returns {Promise<Configuration>} Configuration
*/
read: function read(options) {
var data = getValidKeys();
var tasks,
attrs = ['key'];

function fetchData(options) {
options.config = getValidKeys();
return options;
}

function validateOptions(options) {
if (_.has(options.config, options.data.key)) {
return options;
} else {
return Promise.reject(new errors.NotFoundError('Invalid key'));
}
}

if (_.has(data, options.key)) {
return Promise.resolve({configuration: [{
key: options.key,
value: data[options.key]
}]});
} else {
return Promise.reject(new errors.NotFoundError('Invalid key'));
function formatResponse(options) {
return {configuration: [{
key: options.data.key,
value: options.config[options.data.key]
}]};
}


tasks = [
utils.validate('configuration', {attrs: attrs}),
fetchData,
validateOptions,
formatResponse
];

return pipeline(tasks, options);

}
};

Expand Down
108 changes: 69 additions & 39 deletions core/server/api/themes.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ var Promise = require('bluebird'),
config = require('../config'),
errors = require('../errors'),
settings = require('./settings'),
utils = require('./utils'),
pipeline = require('../utils/pipeline'),
docName = 'themes',
themes;

/**
Expand All @@ -21,41 +24,57 @@ themes = {
* @returns {Promise(Themes)}
*/
browse: function browse(options) {
options = options || {};
var tasks;

return canThis(options.context).browse.theme().then(function () {
function handlePermissions(options) {
return canThis(options.context).browse.theme().then(function () {
return Promise.resolve();
}, function () {
return Promise.reject(new errors.NoPermissionError('You do not have permission to browse themes.'));
});
}

function fetchData() {
return Promise.all([
settings.read({key: 'activeTheme', context: {internal: true}}),
config.paths.availableThemes
]).then(function (result) {
var activeTheme = result[0].settings[0].value,
availableThemes = result[1],
themes = [],
themeKeys = Object.keys(availableThemes);

_.each(themeKeys, function (key) {
if (key.indexOf('.') !== 0
&& key !== '_messages'
&& key !== 'README.md'
) {
var item = {
uuid: key
};

if (availableThemes[key].hasOwnProperty('package.json')) {
item = _.merge(item, availableThemes[key]['package.json']);
}

item.active = item.uuid === activeTheme;

themes.push(item);
]);
}

// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName),
handlePermissions,
fetchData
];

// Pipeline calls each task passing the result of one to be the arguments for the next
return pipeline(tasks, options).then(function formatResponse(result) {
var activeTheme = result[0].settings[0].value,
availableThemes = result[1],
themes = [],
themeKeys = Object.keys(availableThemes);

_.each(themeKeys, function (key) {
if (key.indexOf('.') !== 0
&& key !== '_messages'
&& key !== 'README.md'
) {
var item = {
uuid: key
};

if (availableThemes[key].hasOwnProperty('package.json')) {
item = _.merge(item, availableThemes[key]['package.json']);
}
});

return {themes: themes};
item.active = item.uuid === activeTheme;

themes.push(item);
}
});
}, function () {
return Promise.reject(new errors.NoPermissionError('You do not have permission to browse themes.'));

return {themes: themes};
});
},

Expand All @@ -67,18 +86,21 @@ themes = {
* @returns {Promise(Theme)}
*/
edit: function edit(object, options) {
var themeName;
var tasks,
attrs = ['uuid'];

// Check whether the request is properly formatted.
if (!_.isArray(object.themes)) {
return Promise.reject({type: 'BadRequest', message: 'Invalid request.'});
function handlePermissions(options) {
return canThis(options.context).edit.theme().then(function () {
return options;
}, function () {
return Promise.reject(new errors.NoPermissionError('You do not have permission to edit themes.'));
});
}

themeName = object.themes[0].uuid;

return canThis(options.context).edit.theme().then(function () {
function editTheme(options) {
return themes.browse(options).then(function (availableThemes) {
var theme;
var theme,
themeName = object.themes[0].uuid;

// Check if the theme exists
theme = _.find(availableThemes.themes, function (currentTheme) {
Expand All @@ -97,9 +119,17 @@ themes = {
return {themes: [theme]};
});
});
}, function () {
return Promise.reject(new errors.NoPermissionError('You do not have permission to edit themes.'));
});
}

// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName, {attrs: attrs}),
handlePermissions,
editTheme
];

// Pipeline calls each task passing the result of one to be the arguments for the next
return pipeline(tasks, options);
}
};

Expand Down
58 changes: 37 additions & 21 deletions core/server/api/upload.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
var config = require('../config'),
Promise = require('bluebird'),
fs = require('fs-extra'),
storage = require('../storage'),
errors = require('../errors'),
utils = require('./utils'),
var config = require('../config'),
Promise = require('bluebird'),
fs = require('fs-extra'),
storage = require('../storage'),
errors = require('../errors'),
utils = require('./utils'),
pipeline = require('../utils/pipeline'),

upload;

Expand All @@ -22,27 +23,42 @@ upload = {
* @returns {Promise} Success
*/
add: function (options) {
var store = storage.getStorage(),
filepath;
var tasks,
attrs = ['uploadimage'];

// Check if a file was provided
if (!utils.checkFileExists(options, 'uploadimage')) {
return Promise.reject(new errors.NoPermissionError('Please select an image.'));
function validate(options) {
// Check if a file was provided
if (!utils.checkFileExists(options.data, 'uploadimage')) {
return Promise.reject(new errors.NoPermissionError('Please select an image.'));
}

// Check if the file is valid
if (!utils.checkFileIsValid(options.data.uploadimage, config.uploads.contentTypes, config.uploads.extensions)) {
return Promise.reject(new errors.UnsupportedMediaTypeError('Please select a valid image.'));
}

return options;
}

// Check if the file is valid
if (!utils.checkFileIsValid(options.uploadimage, config.uploads.contentTypes, config.uploads.extensions)) {
return Promise.reject(new errors.UnsupportedMediaTypeError('Please select a valid image.'));
function storeUpload(options) {
var store = storage.getStorage(),
filepath = options.data.uploadimage.path;

return store.save(options.data.uploadimage).then(function (url) {
return url;
}).finally(function () {
// Remove uploaded file from tmp location
return Promise.promisify(fs.unlink)(filepath);
});
}

filepath = options.uploadimage.path;
tasks = [
utils.validate('upload', {attrs: attrs}),
validate,
storeUpload
];

return store.save(options.uploadimage).then(function (url) {
return url;
}).finally(function () {
// Remove uploaded file from tmp location
return Promise.promisify(fs.unlink)(filepath);
});
return pipeline(tasks, options);
}
};

Expand Down
2 changes: 1 addition & 1 deletion core/test/integration/api/api_configuration_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('Configuration API', function () {
done();
}).catch(function (error) {
console.log(JSON.stringify(error));
done();
done(error);
}).catch(done);
});

Expand Down

0 comments on commit ace5c06

Please sign in to comment.