diff --git a/lib/cli.js b/lib/cli.js index 7488af5e..f63f9459 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -400,6 +400,9 @@ program .option('-r, --storage-url ' , 'URL to storage client' , String) + .option('--storage-plugin-image-url ' + , 'URL to image storage plugin' + , String) .option('-u, --connect-sub ' , 'sub endpoint' , cliutil.list) @@ -418,6 +421,9 @@ program if (!options.storageUrl) { this.missingArgument('--storage-url') } + if (!options.storagePluginImageUrl) { + this.missingArgument('--storage-plugin-image-url') + } if (!options.connectSub) { this.missingArgument('--connect-sub') } @@ -431,6 +437,7 @@ program , ssid: options.ssid , authUrl: options.authUrl , storageUrl: options.storageUrl + , storagePluginImageUrl: options.storagePluginImageUrl , endpoints: { sub: options.connectSub , push: options.connectPush @@ -484,10 +491,6 @@ program , 'port (or $PORT)' , Number , process.env.PORT || 7100) - .option('--public-ip ' - , 'public ip for global access' - , String - , ip()) .option('--save-dir ' , 'where to save files' , String @@ -495,7 +498,6 @@ program .action(function(options) { require('./roles/storage/temp')({ port: options.port - , publicIp: options.publicIp , saveDir: options.saveDir }) }) @@ -586,6 +588,10 @@ program , 'storage port' , Number , 7102) + .option('--storage-plugin-image-port ' + , 'storage image plugin port' + , Number + , 7103) .option('--provider ' , 'provider name (or os.hostname())' , String @@ -676,6 +682,8 @@ program , '--auth-url', util.format('http://localhost:%d/', options.authPort) , '--storage-url' , util.format('http://localhost:%d/', options.storagePort) + , '--storage-plugin-image-url' + , util.format('http://localhost:%d/', options.storagePluginImagePort) , '--connect-sub', options.bindAppPub , '--connect-push', options.bindAppPull ].concat((function() { @@ -691,6 +699,14 @@ program 'storage-temp' , '--port', options.storagePort ]) + + // image processor + , procutil.fork(__filename, [ + 'storage-plugin-image' + , '--port', options.storagePluginImagePort + , '--storage-url' + , util.format('http://localhost:%d/', options.storagePort) + ]) ] function shutdown() { diff --git a/lib/roles/app.js b/lib/roles/app.js index c8642d5a..71c2b1f7 100644 --- a/lib/roles/app.js +++ b/lib/roles/app.js @@ -74,13 +74,13 @@ module.exports = function(options) { })) // Proxied requests must come before any body parsers - app.post('/api/v1/resources', function(req, res) { + app.all('/api/v1/s/image/*', function(req, res) { proxy.web(req, res, { - target: options.storageUrl + target: options.storagePluginImageUrl }) }) - app.get('/api/v1/resources/:id', function(req, res) { + app.all('/api/v1/s/*', function(req, res) { proxy.web(req, res, { target: options.storageUrl }) diff --git a/lib/roles/device/plugins/screenshot.js b/lib/roles/device/plugins/screenshot.js index 533db64f..4d23bdbe 100644 --- a/lib/roles/device/plugins/screenshot.js +++ b/lib/roles/device/plugins/screenshot.js @@ -31,7 +31,7 @@ module.exports = syrup.serial() ))) } else { - resolve(storage.store(res, { + resolve(storage.store('image', res, { filename: util.format('%s.png', options.serial) , contentType: 'image/png' , knownLength: +res.headers['content-length'] diff --git a/lib/roles/device/support/storage.js b/lib/roles/device/support/storage.js index 492ea996..6815c80c 100644 --- a/lib/roles/device/support/storage.js +++ b/lib/roles/device/support/storage.js @@ -11,11 +11,11 @@ module.exports = syrup.serial() var log = logger.createLogger('device:support:storage') var plugin = Object.create(null) - plugin.store = function(stream, meta) { + plugin.store = function(type, stream, meta) { var resolver = Promise.defer() var req = request.post({ - url: util.format('%sapi/v1/resources', options.storageUrl) + url: util.format('%sapi/v1/s/%s', options.storageUrl, type) } , function(err, res, body) { if (err) { @@ -32,7 +32,7 @@ module.exports = syrup.serial() else { try { var result = JSON.parse(body) - log.info('Uploaded to %s', result.resources.file.url) + log.info('Uploaded to %s', result.resources.file.href) resolver.resolve(result.resources.file) } catch (err) { diff --git a/lib/roles/storage/plugins/image/index.js b/lib/roles/storage/plugins/image/index.js index 8f7304e6..40a30d34 100644 --- a/lib/roles/storage/plugins/image/index.js +++ b/lib/roles/storage/plugins/image/index.js @@ -1,9 +1,6 @@ var http = require('http') -var util = require('util') var express = require('express') -var Promise = require('bluebird') -var gm = require('gm') var logger = require('../../../../util/logger') @@ -21,8 +18,8 @@ module.exports = function(options) { app.set('case sensitive routing', true) app.set('trust proxy', true) - app.get('/api/v1/resources/:id/*', function(req, res) { - get(req.params.id, options) + app.get('/api/v1/s/image/:id/*', function(req, res) { + get(req.url, options) .then(function(stream) { return transform(stream, { crop: parseCrop(req.query.crop) diff --git a/lib/roles/storage/plugins/image/task/get.js b/lib/roles/storage/plugins/image/task/get.js index 32214dec..73a12ea2 100644 --- a/lib/roles/storage/plugins/image/task/get.js +++ b/lib/roles/storage/plugins/image/task/get.js @@ -1,11 +1,12 @@ var util = require('util') var http = require('http') +var url = require('url') var Promise = require('bluebird') -module.exports = function(id, options) { +module.exports = function(path, options) { return new Promise(function(resolve, reject) { - http.get(util.format('%sapi/v1/resources/%s', options.storageUrl, id)) + http.get(url.resolve(options.storageUrl, path)) .on('response', function(res) { if (res.statusCode !== 200) { reject(new Error(util.format('HTTP %d', res.statusCode))) diff --git a/lib/roles/storage/temp.js b/lib/roles/storage/temp.js index 297bf3e4..a4a28379 100644 --- a/lib/roles/storage/temp.js +++ b/lib/roles/storage/temp.js @@ -7,11 +7,10 @@ var formidable = require('formidable') var Promise = require('bluebird') var logger = require('../../util/logger') -var requtil = require('../../util/requtil') var Storage = require('../../util/storage') module.exports = function(options) { - var log = logger.createLogger('storage-temp') + var log = logger.createLogger('storage:temp') , app = express() , server = http.createServer(app) , storage = new Storage() @@ -24,7 +23,7 @@ module.exports = function(options) { log.info('Cleaning up inactive resource "%s"', id) }) - app.post('/api/v1/resources', function(req, res) { + app.post('/api/v1/s/:type', function(req, res) { var form = new formidable.IncomingForm() Promise.promisify(form.parse, form)(req) .spread(function(fields, files) { @@ -45,10 +44,12 @@ module.exports = function(options) { storedFiles.forEach(function(file) { mapped[file.field] = { date: new Date() - , url: util.format( - 'http://%s:%s/api/v1/resources/%s%s' - , options.publicIp - , options.port + , type: req.params.type + , id: file.id + , name: file.name + , href: util.format( + '/api/v1/s/%s/%s%s' + , req.params.type , file.id , file.name ? util.format('/%s', path.basename(file.name)) @@ -60,14 +61,6 @@ module.exports = function(options) { })() }) }) - .catch(requtil.ValidationError, function(err) { - res.status(400) - .json({ - success: false - , error: 'ValidationError' - , validationErrors: err.errors - }) - }) .catch(function(err) { log.error('Error storing resource', err.stack) res.status(500) @@ -78,18 +71,7 @@ module.exports = function(options) { }) }) - app.get('/api/v1/resources/:id', function(req, res) { - var file = storage.retrieve(req.params.id) - if (file) { - res.set('Content-Type', file.type) - res.sendfile(file.path) - } - else { - res.send(404) - } - }) - - app.get('/api/v1/resources/:id/*', function(req, res) { + app.get('/api/v1/s/:type/:id/*', function(req, res) { var file = storage.retrieve(req.params.id) if (file) { res.set('Content-Type', file.type) diff --git a/res/app/control-panes/screenshots/screenshots.jade b/res/app/control-panes/screenshots/screenshots.jade index 74935255..053f5680 100644 --- a/res/app/control-panes/screenshots/screenshots.jade +++ b/res/app/control-panes/screenshots/screenshots.jade @@ -26,6 +26,6 @@ li(ng-repeat='shot in screenshots').cursor-select h5 {{ shot.body.date | date:'yyyy/MM/dd HH:mm:ss' }} a(ng-href='{{ shot.body.url }}', target='_blank') - img(ng-src='{{ shot.body.url + shotSizeUrlParameter() }}') + img(ng-src='{{ shot.body.href + shotSizeUrlParameter() }}') .clearfix