X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fcontrollers%2Fapi%2Fremote%2Fvideos.js;h=39c9579c1a21fd3c5346b9b6f3c4b5a7184b8656;hb=e4c87ec26962e359d1c70b03ed188a3f19d6a25b;hp=f8b4949cdc131b3b91a6c54c56ca74c83e7f14a1;hpb=cddadde81f91219204cec1f4057a191c02a70894;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/controllers/api/remote/videos.js b/server/controllers/api/remote/videos.js index f8b4949cd..39c9579c1 100644 --- a/server/controllers/api/remote/videos.js +++ b/server/controllers/api/remote/videos.js @@ -31,6 +31,20 @@ router.post('/', remoteVideos ) +router.post('/qadu', + signatureValidators.signature, + secureMiddleware.checkSignature, + videosValidators.remoteQaduVideos, + remoteVideosQadu +) + +router.post('/events', + signatureValidators.signature, + secureMiddleware.checkSignature, + videosValidators.remoteEventsVideos, + remoteVideosEvents +) + // --------------------------------------------------------------------------- module.exports = router @@ -62,6 +76,151 @@ function remoteVideos (req, res, next) { return res.type('json').status(204).end() } +function remoteVideosQadu (req, res, next) { + const requests = req.body.data + const fromPod = res.locals.secure.pod + + eachSeries(requests, function (request, callbackEach) { + const videoData = request.data + + quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod, callbackEach) + }, function (err) { + if (err) logger.error('Error managing remote videos.', { error: err }) + }) + + return res.type('json').status(204).end() +} + +function remoteVideosEvents (req, res, next) { + const requests = req.body.data + const fromPod = res.locals.secure.pod + + eachSeries(requests, function (request, callbackEach) { + const eventData = request.data + + processVideosEventsRetryWrapper(eventData, fromPod, callbackEach) + }, function (err) { + if (err) logger.error('Error managing remote videos.', { error: err }) + }) + + return res.type('json').status(204).end() +} + +function processVideosEventsRetryWrapper (eventData, fromPod, finalCallback) { + const options = { + arguments: [ eventData, fromPod ], + errorMessage: 'Cannot process videos events with many retries.' + } + + databaseUtils.retryTransactionWrapper(processVideosEvents, options, finalCallback) +} + +function processVideosEvents (eventData, fromPod, finalCallback) { + waterfall([ + databaseUtils.startSerializableTransaction, + + function findVideo (t, callback) { + fetchOwnedVideo(eventData.remoteId, function (err, videoInstance) { + return callback(err, t, videoInstance) + }) + }, + + function updateVideoIntoDB (t, videoInstance, callback) { + const options = { transaction: t } + + let columnToUpdate + + switch (eventData.eventType) { + case constants.REQUEST_VIDEO_EVENT_TYPES.VIEWS: + columnToUpdate = 'views' + break + + case constants.REQUEST_VIDEO_EVENT_TYPES.LIKES: + columnToUpdate = 'likes' + break + + case constants.REQUEST_VIDEO_EVENT_TYPES.DISLIKES: + columnToUpdate = 'dislikes' + break + + default: + return callback(new Error('Unknown video event type.')) + } + + const query = {} + query[columnToUpdate] = eventData.count + + videoInstance.increment(query, options).asCallback(function (err) { + return callback(err, t) + }) + }, + + databaseUtils.commitTransaction + + ], function (err, t) { + if (err) { + console.log(err) + logger.debug('Cannot process a video event.', { error: err }) + return databaseUtils.rollbackTransaction(err, t, finalCallback) + } + + logger.info('Remote video event processed for video %s.', eventData.remoteId) + return finalCallback(null) + }) +} + +function quickAndDirtyUpdateVideoRetryWrapper (videoData, fromPod, finalCallback) { + const options = { + arguments: [ videoData, fromPod ], + errorMessage: 'Cannot update quick and dirty the remote video with many retries.' + } + + databaseUtils.retryTransactionWrapper(quickAndDirtyUpdateVideo, options, finalCallback) +} + +function quickAndDirtyUpdateVideo (videoData, fromPod, finalCallback) { + waterfall([ + databaseUtils.startSerializableTransaction, + + function findVideo (t, callback) { + fetchRemoteVideo(fromPod.host, videoData.remoteId, function (err, videoInstance) { + return callback(err, t, videoInstance) + }) + }, + + function updateVideoIntoDB (t, videoInstance, callback) { + const options = { transaction: t } + + if (videoData.views) { + videoInstance.set('views', videoData.views) + } + + if (videoData.likes) { + videoInstance.set('likes', videoData.likes) + } + + if (videoData.dislikes) { + videoInstance.set('dislikes', videoData.dislikes) + } + + videoInstance.save(options).asCallback(function (err) { + return callback(err, t) + }) + }, + + databaseUtils.commitTransaction + + ], function (err, t) { + if (err) { + logger.debug('Cannot quick and dirty update the remote video.', { error: err }) + return databaseUtils.rollbackTransaction(err, t, finalCallback) + } + + logger.info('Remote video %s quick and dirty updated', videoData.name) + return finalCallback(null) + }) +} + // Handle retries on fail function addRemoteVideoRetryWrapper (videoToCreateData, fromPod, finalCallback) { const options = { @@ -190,7 +349,7 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { databaseUtils.startSerializableTransaction, function findVideo (t, callback) { - fetchVideo(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) { + fetchRemoteVideo(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) { return callback(err, t, videoInstance) }) }, @@ -243,7 +402,7 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { function removeRemoteVideo (videoToRemoveData, fromPod, callback) { // We need the instance because we have to remove some other stuffs (thumbnail etc) - fetchVideo(fromPod.host, videoToRemoveData.remoteId, function (err, video) { + fetchRemoteVideo(fromPod.host, videoToRemoveData.remoteId, function (err, video) { // Do not return the error, continue the process if (err) return callback(null) @@ -260,7 +419,7 @@ function removeRemoteVideo (videoToRemoveData, fromPod, callback) { } function reportAbuseRemoteVideo (reportData, fromPod, callback) { - db.Video.load(reportData.videoRemoteId, function (err, video) { + fetchOwnedVideo(reportData.videoRemoteId, function (err, video) { if (err || !video) { if (!err) err = new Error('video not found') @@ -288,7 +447,20 @@ function reportAbuseRemoteVideo (reportData, fromPod, callback) { }) } -function fetchVideo (podHost, remoteId, callback) { +function fetchOwnedVideo (id, callback) { + db.Video.load(id, function (err, video) { + if (err || !video) { + if (!err) err = new Error('video not found') + + logger.error('Cannot load owned video from id.', { error: err, id }) + return callback(err) + } + + return callback(null, video) + }) +} + +function fetchRemoteVideo (podHost, remoteId, callback) { db.Video.loadByHostAndRemoteId(podHost, remoteId, function (err, video) { if (err || !video) { if (!err) err = new Error('video not found')