aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-02-26 18:57:33 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-02-26 20:01:26 +0100
commite4c87ec26962e359d1c70b03ed188a3f19d6a25b (patch)
tree26fe20e6f600bc6f6f569dde2171b0a2346b135c /server/controllers
parent9e167724f7e933f41d9ea2e1c31772bf4c560a28 (diff)
downloadPeerTube-e4c87ec26962e359d1c70b03ed188a3f19d6a25b.tar.gz
PeerTube-e4c87ec26962e359d1c70b03ed188a3f19d6a25b.tar.zst
PeerTube-e4c87ec26962e359d1c70b03ed188a3f19d6a25b.zip
Server: implement video views
Diffstat (limited to 'server/controllers')
-rw-r--r--server/controllers/api/remote/videos.js108
-rw-r--r--server/controllers/api/videos.js3
2 files changed, 106 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
41router.post('/events',
42 signatureValidators.signature,
43 secureMiddleware.checkSignature,
44 videosValidators.remoteEventsVideos,
45 remoteVideosEvents
46)
47
41// --------------------------------------------------------------------------- 48// ---------------------------------------------------------------------------
42 49
43module.exports = router 50module.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
94function 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
109function 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
118function 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
87function quickAndDirtyUpdateVideoRetryWrapper (videoData, fromPod, finalCallback) { 172function 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
318function removeRemoteVideo (videoToRemoveData, fromPod, callback) { 403function 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
336function reportAbuseRemoteVideo (reportData, fromPod, callback) { 421function 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
365function fetchVideo (podHost, remoteId, callback) { 450function 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
463function 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')
diff --git a/server/controllers/api/videos.js b/server/controllers/api/videos.js
index 9f4bbb7b7..d64ed4e4e 100644
--- a/server/controllers/api/videos.js
+++ b/server/controllers/api/videos.js
@@ -333,6 +333,9 @@ function getVideo (req, res, next) {
333 // For example, only add a view when a user watch a video during 30s etc 333 // For example, only add a view when a user watch a video during 30s etc
334 friends.quickAndDirtyUpdateVideoToFriends(videoInstance.id, constants.REQUEST_VIDEO_QADU_TYPES.VIEWS) 334 friends.quickAndDirtyUpdateVideoToFriends(videoInstance.id, constants.REQUEST_VIDEO_QADU_TYPES.VIEWS)
335 }) 335 })
336 } else {
337 // Just send the event to our friends
338 friends.addEventToRemoteVideo(videoInstance.id, constants.REQUEST_VIDEO_EVENT_TYPES.VIEWS)
336 } 339 }
337 340
338 // Do not wait the view system 341 // Do not wait the view system