From a6fd2b30bf717eec14972a2175354781f5f43e77 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 30 Dec 2016 12:53:41 +0100 Subject: Server: move remote routes in their own directory --- server/controllers/api/index.js | 8 +- server/controllers/api/remote.js | 237 -------------------------------- server/controllers/api/remote/index.js | 16 +++ server/controllers/api/remote/videos.js | 237 ++++++++++++++++++++++++++++++++ server/helpers/utils.js | 5 + 5 files changed, 261 insertions(+), 242 deletions(-) delete mode 100644 server/controllers/api/remote.js create mode 100644 server/controllers/api/remote/index.js create mode 100644 server/controllers/api/remote/videos.js diff --git a/server/controllers/api/index.js b/server/controllers/api/index.js index 4cb65ed55..f13ff922c 100644 --- a/server/controllers/api/index.js +++ b/server/controllers/api/index.js @@ -2,6 +2,8 @@ const express = require('express') +const utils = require('../../helpers/utils') + const router = express.Router() const clientsController = require('./clients') @@ -18,7 +20,7 @@ router.use('/requests', requestsController) router.use('/users', usersController) router.use('/videos', videosController) router.use('/ping', pong) -router.use('/*', badRequest) +router.use('/*', utils.badRequest) // --------------------------------------------------------------------------- @@ -29,7 +31,3 @@ module.exports = router function pong (req, res, next) { return res.send('pong').status(200).end() } - -function badRequest (req, res, next) { - res.type('json').status(400).end() -} diff --git a/server/controllers/api/remote.js b/server/controllers/api/remote.js deleted file mode 100644 index be5e6dc98..000000000 --- a/server/controllers/api/remote.js +++ /dev/null @@ -1,237 +0,0 @@ -'use strict' - -const eachSeries = require('async/eachSeries') -const express = require('express') -const waterfall = require('async/waterfall') - -const db = require('../../initializers/database') -const middlewares = require('../../middlewares') -const secureMiddleware = middlewares.secure -const validators = middlewares.validators.remote -const logger = require('../../helpers/logger') - -const router = express.Router() - -router.post('/videos', - validators.signature, - secureMiddleware.checkSignature, - validators.remoteVideos, - remoteVideos -) - -// --------------------------------------------------------------------------- - -module.exports = router - -// --------------------------------------------------------------------------- - -function remoteVideos (req, res, next) { - const requests = req.body.data - const fromPod = res.locals.secure.pod - - // We need to process in the same order to keep consistency - // TODO: optimization - eachSeries(requests, function (request, callbackEach) { - const videoData = request.data - - switch (request.type) { - case 'add': - addRemoteVideo(videoData, fromPod, callbackEach) - break - - case 'update': - updateRemoteVideo(videoData, fromPod, callbackEach) - break - - case 'remove': - removeRemoteVideo(videoData, fromPod, callbackEach) - break - - default: - logger.error('Unkown remote request type %s.', request.type) - } - }, function (err) { - if (err) logger.error('Error managing remote videos.', { error: err }) - }) - - // We don't need to keep the other pod waiting - return res.type('json').status(204).end() -} - -function addRemoteVideo (videoToCreateData, fromPod, finalCallback) { - logger.debug('Adding remote video "%s".', videoToCreateData.name) - - waterfall([ - - function startTransaction (callback) { - db.sequelize.transaction().asCallback(function (err, t) { - return callback(err, t) - }) - }, - - function findOrCreateAuthor (t, callback) { - const name = videoToCreateData.author - const podId = fromPod.id - // This author is from another pod so we do not associate a user - const userId = null - - db.Author.findOrCreateAuthor(name, podId, userId, t, function (err, authorInstance) { - return callback(err, t, authorInstance) - }) - }, - - function findOrCreateTags (t, author, callback) { - const tags = videoToCreateData.tags - - db.Tag.findOrCreateTags(tags, t, function (err, tagInstances) { - return callback(err, t, author, tagInstances) - }) - }, - - function createVideoObject (t, author, tagInstances, callback) { - const videoData = { - name: videoToCreateData.name, - remoteId: videoToCreateData.remoteId, - extname: videoToCreateData.extname, - infoHash: videoToCreateData.infoHash, - description: videoToCreateData.description, - authorId: author.id, - duration: videoToCreateData.duration, - createdAt: videoToCreateData.createdAt, - updatedAt: videoToCreateData.updatedAt - } - - const video = db.Video.build(videoData) - - return callback(null, t, tagInstances, video) - }, - - function generateThumbnail (t, tagInstances, video, callback) { - db.Video.generateThumbnailFromData(video, videoToCreateData.thumbnailData, function (err) { - if (err) { - logger.error('Cannot generate thumbnail from data.', { error: err }) - return callback(err) - } - - return callback(err, t, tagInstances, video) - }) - }, - - function insertVideoIntoDB (t, tagInstances, video, callback) { - const options = { - transaction: t - } - - video.save(options).asCallback(function (err, videoCreated) { - return callback(err, t, tagInstances, videoCreated) - }) - }, - - function associateTagsToVideo (t, tagInstances, video, callback) { - const options = { transaction: t } - - video.setTags(tagInstances, options).asCallback(function (err) { - return callback(err, t) - }) - } - - ], function (err, t) { - if (err) { - logger.error('Cannot insert the remote video.') - - // Abort transaction? - if (t) t.rollback() - - return finalCallback(err) - } - - // Commit transaction - t.commit() - - return finalCallback() - }) -} - -function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { - logger.debug('Updating remote video "%s".', videoAttributesToUpdate.name) - - waterfall([ - - function startTransaction (callback) { - db.sequelize.transaction().asCallback(function (err, t) { - return callback(err, t) - }) - }, - - function findVideo (t, callback) { - db.Video.loadByHostAndRemoteId(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) { - if (err || !videoInstance) { - logger.error('Cannot load video from host and remote id.', { error: err.message }) - return callback(err) - } - - return callback(null, t, videoInstance) - }) - }, - - function findOrCreateTags (t, videoInstance, callback) { - const tags = videoAttributesToUpdate.tags - - db.Tag.findOrCreateTags(tags, t, function (err, tagInstances) { - return callback(err, t, videoInstance, tagInstances) - }) - }, - - function updateVideoIntoDB (t, videoInstance, tagInstances, callback) { - const options = { transaction: t } - - videoInstance.set('name', videoAttributesToUpdate.name) - videoInstance.set('description', videoAttributesToUpdate.description) - videoInstance.set('infoHash', videoAttributesToUpdate.infoHash) - videoInstance.set('duration', videoAttributesToUpdate.duration) - videoInstance.set('createdAt', videoAttributesToUpdate.createdAt) - videoInstance.set('updatedAt', videoAttributesToUpdate.updatedAt) - videoInstance.set('extname', videoAttributesToUpdate.extname) - - videoInstance.save(options).asCallback(function (err) { - return callback(err, t, videoInstance, tagInstances) - }) - }, - - function associateTagsToVideo (t, videoInstance, tagInstances, callback) { - const options = { transaction: t } - - videoInstance.setTags(tagInstances, options).asCallback(function (err) { - return callback(err, t) - }) - } - - ], function (err, t) { - if (err) { - logger.error('Cannot update the remote video.') - - // Abort transaction? - if (t) t.rollback() - - return finalCallback(err) - } - - // Commit transaction - t.commit() - - return finalCallback() - }) -} - -function removeRemoteVideo (videoToRemoveData, fromPod, callback) { - // We need the instance because we have to remove some other stuffs (thumbnail etc) - db.Video.loadByHostAndRemoteId(fromPod.host, videoToRemoveData.remoteId, function (err, video) { - if (err || !video) { - logger.error('Cannot load video from host and remote id.', { error: err.message }) - return callback(err) - } - - logger.debug('Removing remote video %s.', video.remoteId) - video.destroy().asCallback(callback) - }) -} diff --git a/server/controllers/api/remote/index.js b/server/controllers/api/remote/index.js new file mode 100644 index 000000000..2947632d5 --- /dev/null +++ b/server/controllers/api/remote/index.js @@ -0,0 +1,16 @@ +'use strict' + +const express = require('express') + +const utils = require('../../../helpers/utils') + +const router = express.Router() + +const videosRemoteController = require('./videos') + +router.use('/videos', videosRemoteController) +router.use('/*', utils.badRequest) + +// --------------------------------------------------------------------------- + +module.exports = router diff --git a/server/controllers/api/remote/videos.js b/server/controllers/api/remote/videos.js new file mode 100644 index 000000000..87c49bff9 --- /dev/null +++ b/server/controllers/api/remote/videos.js @@ -0,0 +1,237 @@ +'use strict' + +const eachSeries = require('async/eachSeries') +const express = require('express') +const waterfall = require('async/waterfall') + +const db = require('../../../initializers/database') +const middlewares = require('../../../middlewares') +const secureMiddleware = middlewares.secure +const validators = middlewares.validators.remote +const logger = require('../../../helpers/logger') + +const router = express.Router() + +router.post('/', + validators.signature, + secureMiddleware.checkSignature, + validators.remoteVideos, + remoteVideos +) + +// --------------------------------------------------------------------------- + +module.exports = router + +// --------------------------------------------------------------------------- + +function remoteVideos (req, res, next) { + const requests = req.body.data + const fromPod = res.locals.secure.pod + + // We need to process in the same order to keep consistency + // TODO: optimization + eachSeries(requests, function (request, callbackEach) { + const videoData = request.data + + switch (request.type) { + case 'add': + addRemoteVideo(videoData, fromPod, callbackEach) + break + + case 'update': + updateRemoteVideo(videoData, fromPod, callbackEach) + break + + case 'remove': + removeRemoteVideo(videoData, fromPod, callbackEach) + break + + default: + logger.error('Unkown remote request type %s.', request.type) + } + }, function (err) { + if (err) logger.error('Error managing remote videos.', { error: err }) + }) + + // We don't need to keep the other pod waiting + return res.type('json').status(204).end() +} + +function addRemoteVideo (videoToCreateData, fromPod, finalCallback) { + logger.debug('Adding remote video "%s".', videoToCreateData.name) + + waterfall([ + + function startTransaction (callback) { + db.sequelize.transaction().asCallback(function (err, t) { + return callback(err, t) + }) + }, + + function findOrCreateAuthor (t, callback) { + const name = videoToCreateData.author + const podId = fromPod.id + // This author is from another pod so we do not associate a user + const userId = null + + db.Author.findOrCreateAuthor(name, podId, userId, t, function (err, authorInstance) { + return callback(err, t, authorInstance) + }) + }, + + function findOrCreateTags (t, author, callback) { + const tags = videoToCreateData.tags + + db.Tag.findOrCreateTags(tags, t, function (err, tagInstances) { + return callback(err, t, author, tagInstances) + }) + }, + + function createVideoObject (t, author, tagInstances, callback) { + const videoData = { + name: videoToCreateData.name, + remoteId: videoToCreateData.remoteId, + extname: videoToCreateData.extname, + infoHash: videoToCreateData.infoHash, + description: videoToCreateData.description, + authorId: author.id, + duration: videoToCreateData.duration, + createdAt: videoToCreateData.createdAt, + updatedAt: videoToCreateData.updatedAt + } + + const video = db.Video.build(videoData) + + return callback(null, t, tagInstances, video) + }, + + function generateThumbnail (t, tagInstances, video, callback) { + db.Video.generateThumbnailFromData(video, videoToCreateData.thumbnailData, function (err) { + if (err) { + logger.error('Cannot generate thumbnail from data.', { error: err }) + return callback(err) + } + + return callback(err, t, tagInstances, video) + }) + }, + + function insertVideoIntoDB (t, tagInstances, video, callback) { + const options = { + transaction: t + } + + video.save(options).asCallback(function (err, videoCreated) { + return callback(err, t, tagInstances, videoCreated) + }) + }, + + function associateTagsToVideo (t, tagInstances, video, callback) { + const options = { transaction: t } + + video.setTags(tagInstances, options).asCallback(function (err) { + return callback(err, t) + }) + } + + ], function (err, t) { + if (err) { + logger.error('Cannot insert the remote video.') + + // Abort transaction? + if (t) t.rollback() + + return finalCallback(err) + } + + // Commit transaction + t.commit() + + return finalCallback() + }) +} + +function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { + logger.debug('Updating remote video "%s".', videoAttributesToUpdate.name) + + waterfall([ + + function startTransaction (callback) { + db.sequelize.transaction().asCallback(function (err, t) { + return callback(err, t) + }) + }, + + function findVideo (t, callback) { + db.Video.loadByHostAndRemoteId(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) { + if (err || !videoInstance) { + logger.error('Cannot load video from host and remote id.', { error: err.message }) + return callback(err) + } + + return callback(null, t, videoInstance) + }) + }, + + function findOrCreateTags (t, videoInstance, callback) { + const tags = videoAttributesToUpdate.tags + + db.Tag.findOrCreateTags(tags, t, function (err, tagInstances) { + return callback(err, t, videoInstance, tagInstances) + }) + }, + + function updateVideoIntoDB (t, videoInstance, tagInstances, callback) { + const options = { transaction: t } + + videoInstance.set('name', videoAttributesToUpdate.name) + videoInstance.set('description', videoAttributesToUpdate.description) + videoInstance.set('infoHash', videoAttributesToUpdate.infoHash) + videoInstance.set('duration', videoAttributesToUpdate.duration) + videoInstance.set('createdAt', videoAttributesToUpdate.createdAt) + videoInstance.set('updatedAt', videoAttributesToUpdate.updatedAt) + videoInstance.set('extname', videoAttributesToUpdate.extname) + + videoInstance.save(options).asCallback(function (err) { + return callback(err, t, videoInstance, tagInstances) + }) + }, + + function associateTagsToVideo (t, videoInstance, tagInstances, callback) { + const options = { transaction: t } + + videoInstance.setTags(tagInstances, options).asCallback(function (err) { + return callback(err, t) + }) + } + + ], function (err, t) { + if (err) { + logger.error('Cannot update the remote video.') + + // Abort transaction? + if (t) t.rollback() + + return finalCallback(err) + } + + // Commit transaction + t.commit() + + return finalCallback() + }) +} + +function removeRemoteVideo (videoToRemoveData, fromPod, callback) { + // We need the instance because we have to remove some other stuffs (thumbnail etc) + db.Video.loadByHostAndRemoteId(fromPod.host, videoToRemoveData.remoteId, function (err, video) { + if (err || !video) { + logger.error('Cannot load video from host and remote id.', { error: err.message }) + return callback(err) + } + + logger.debug('Removing remote video %s.', video.remoteId) + video.destroy().asCallback(callback) + }) +} diff --git a/server/helpers/utils.js b/server/helpers/utils.js index 9f27671b6..7e0c9823c 100644 --- a/server/helpers/utils.js +++ b/server/helpers/utils.js @@ -5,11 +5,16 @@ const crypto = require('crypto') const logger = require('./logger') const utils = { + badRequest, cleanForExit, generateRandomString, isTestInstance } +function badRequest (req, res, next) { + res.type('json').status(400).end() +} + function generateRandomString (size, callback) { crypto.pseudoRandomBytes(size, function (err, raw) { if (err) return callback(err) -- cgit v1.2.3