diff options
Diffstat (limited to 'server/controllers/api/remote')
-rw-r--r-- | server/controllers/api/remote/videos.js | 108 |
1 files changed, 103 insertions, 5 deletions
diff --git a/server/controllers/api/remote/videos.js b/server/controllers/api/remote/videos.js index 79b503d4d..39c9579c1 100644 --- a/server/controllers/api/remote/videos.js +++ b/server/controllers/api/remote/videos.js | |||
@@ -38,6 +38,13 @@ router.post('/qadu', | |||
38 | remoteVideosQadu | 38 | remoteVideosQadu |
39 | ) | 39 | ) |
40 | 40 | ||
41 | router.post('/events', | ||
42 | signatureValidators.signature, | ||
43 | secureMiddleware.checkSignature, | ||
44 | videosValidators.remoteEventsVideos, | ||
45 | remoteVideosEvents | ||
46 | ) | ||
47 | |||
41 | // --------------------------------------------------------------------------- | 48 | // --------------------------------------------------------------------------- |
42 | 49 | ||
43 | module.exports = router | 50 | module.exports = router |
@@ -84,6 +91,84 @@ function remoteVideosQadu (req, res, next) { | |||
84 | return res.type('json').status(204).end() | 91 | return res.type('json').status(204).end() |
85 | } | 92 | } |
86 | 93 | ||
94 | function remoteVideosEvents (req, res, next) { | ||
95 | const requests = req.body.data | ||
96 | const fromPod = res.locals.secure.pod | ||
97 | |||
98 | eachSeries(requests, function (request, callbackEach) { | ||
99 | const eventData = request.data | ||
100 | |||
101 | processVideosEventsRetryWrapper(eventData, fromPod, callbackEach) | ||
102 | }, function (err) { | ||
103 | if (err) logger.error('Error managing remote videos.', { error: err }) | ||
104 | }) | ||
105 | |||
106 | return res.type('json').status(204).end() | ||
107 | } | ||
108 | |||
109 | function processVideosEventsRetryWrapper (eventData, fromPod, finalCallback) { | ||
110 | const options = { | ||
111 | arguments: [ eventData, fromPod ], | ||
112 | errorMessage: 'Cannot process videos events with many retries.' | ||
113 | } | ||
114 | |||
115 | databaseUtils.retryTransactionWrapper(processVideosEvents, options, finalCallback) | ||
116 | } | ||
117 | |||
118 | function processVideosEvents (eventData, fromPod, finalCallback) { | ||
119 | waterfall([ | ||
120 | databaseUtils.startSerializableTransaction, | ||
121 | |||
122 | function findVideo (t, callback) { | ||
123 | fetchOwnedVideo(eventData.remoteId, function (err, videoInstance) { | ||
124 | return callback(err, t, videoInstance) | ||
125 | }) | ||
126 | }, | ||
127 | |||
128 | function updateVideoIntoDB (t, videoInstance, callback) { | ||
129 | const options = { transaction: t } | ||
130 | |||
131 | let columnToUpdate | ||
132 | |||
133 | switch (eventData.eventType) { | ||
134 | case constants.REQUEST_VIDEO_EVENT_TYPES.VIEWS: | ||
135 | columnToUpdate = 'views' | ||
136 | break | ||
137 | |||
138 | case constants.REQUEST_VIDEO_EVENT_TYPES.LIKES: | ||
139 | columnToUpdate = 'likes' | ||
140 | break | ||
141 | |||
142 | case constants.REQUEST_VIDEO_EVENT_TYPES.DISLIKES: | ||
143 | columnToUpdate = 'dislikes' | ||
144 | break | ||
145 | |||
146 | default: | ||
147 | return callback(new Error('Unknown video event type.')) | ||
148 | } | ||
149 | |||
150 | const query = {} | ||
151 | query[columnToUpdate] = eventData.count | ||
152 | |||
153 | videoInstance.increment(query, options).asCallback(function (err) { | ||
154 | return callback(err, t) | ||
155 | }) | ||
156 | }, | ||
157 | |||
158 | databaseUtils.commitTransaction | ||
159 | |||
160 | ], function (err, t) { | ||
161 | if (err) { | ||
162 | console.log(err) | ||
163 | logger.debug('Cannot process a video event.', { error: err }) | ||
164 | return databaseUtils.rollbackTransaction(err, t, finalCallback) | ||
165 | } | ||
166 | |||
167 | logger.info('Remote video event processed for video %s.', eventData.remoteId) | ||
168 | return finalCallback(null) | ||
169 | }) | ||
170 | } | ||
171 | |||
87 | function quickAndDirtyUpdateVideoRetryWrapper (videoData, fromPod, finalCallback) { | 172 | function quickAndDirtyUpdateVideoRetryWrapper (videoData, fromPod, finalCallback) { |
88 | const options = { | 173 | const options = { |
89 | arguments: [ videoData, fromPod ], | 174 | arguments: [ videoData, fromPod ], |
@@ -98,7 +183,7 @@ function quickAndDirtyUpdateVideo (videoData, fromPod, finalCallback) { | |||
98 | databaseUtils.startSerializableTransaction, | 183 | databaseUtils.startSerializableTransaction, |
99 | 184 | ||
100 | function findVideo (t, callback) { | 185 | function findVideo (t, callback) { |
101 | fetchVideo(fromPod.host, videoData.remoteId, function (err, videoInstance) { | 186 | fetchRemoteVideo(fromPod.host, videoData.remoteId, function (err, videoInstance) { |
102 | return callback(err, t, videoInstance) | 187 | return callback(err, t, videoInstance) |
103 | }) | 188 | }) |
104 | }, | 189 | }, |
@@ -264,7 +349,7 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { | |||
264 | databaseUtils.startSerializableTransaction, | 349 | databaseUtils.startSerializableTransaction, |
265 | 350 | ||
266 | function findVideo (t, callback) { | 351 | function findVideo (t, callback) { |
267 | fetchVideo(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) { | 352 | fetchRemoteVideo(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) { |
268 | return callback(err, t, videoInstance) | 353 | return callback(err, t, videoInstance) |
269 | }) | 354 | }) |
270 | }, | 355 | }, |
@@ -317,7 +402,7 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { | |||
317 | 402 | ||
318 | function removeRemoteVideo (videoToRemoveData, fromPod, callback) { | 403 | function removeRemoteVideo (videoToRemoveData, fromPod, callback) { |
319 | // We need the instance because we have to remove some other stuffs (thumbnail etc) | 404 | // We need the instance because we have to remove some other stuffs (thumbnail etc) |
320 | fetchVideo(fromPod.host, videoToRemoveData.remoteId, function (err, video) { | 405 | fetchRemoteVideo(fromPod.host, videoToRemoveData.remoteId, function (err, video) { |
321 | // Do not return the error, continue the process | 406 | // Do not return the error, continue the process |
322 | if (err) return callback(null) | 407 | if (err) return callback(null) |
323 | 408 | ||
@@ -334,7 +419,7 @@ function removeRemoteVideo (videoToRemoveData, fromPod, callback) { | |||
334 | } | 419 | } |
335 | 420 | ||
336 | function reportAbuseRemoteVideo (reportData, fromPod, callback) { | 421 | function reportAbuseRemoteVideo (reportData, fromPod, callback) { |
337 | db.Video.load(reportData.videoRemoteId, function (err, video) { | 422 | fetchOwnedVideo(reportData.videoRemoteId, function (err, video) { |
338 | if (err || !video) { | 423 | if (err || !video) { |
339 | if (!err) err = new Error('video not found') | 424 | if (!err) err = new Error('video not found') |
340 | 425 | ||
@@ -362,7 +447,20 @@ function reportAbuseRemoteVideo (reportData, fromPod, callback) { | |||
362 | }) | 447 | }) |
363 | } | 448 | } |
364 | 449 | ||
365 | function fetchVideo (podHost, remoteId, callback) { | 450 | function fetchOwnedVideo (id, callback) { |
451 | db.Video.load(id, function (err, video) { | ||
452 | if (err || !video) { | ||
453 | if (!err) err = new Error('video not found') | ||
454 | |||
455 | logger.error('Cannot load owned video from id.', { error: err, id }) | ||
456 | return callback(err) | ||
457 | } | ||
458 | |||
459 | return callback(null, video) | ||
460 | }) | ||
461 | } | ||
462 | |||
463 | function fetchRemoteVideo (podHost, remoteId, callback) { | ||
366 | db.Video.loadByHostAndRemoteId(podHost, remoteId, function (err, video) { | 464 | db.Video.loadByHostAndRemoteId(podHost, remoteId, function (err, video) { |
367 | if (err || !video) { | 465 | if (err || !video) { |
368 | if (!err) err = new Error('video not found') | 466 | if (!err) err = new Error('video not found') |