3 const express
= require('express')
4 const waterfall
= require('async/waterfall')
6 const constants
= require('../../../initializers/constants')
7 const db
= require('../../../initializers/database')
8 const logger
= require('../../../helpers/logger')
9 const friends
= require('../../../lib/friends')
10 const middlewares
= require('../../../middlewares')
11 const oAuth
= middlewares
.oauth
12 const validators
= middlewares
.validators
13 const validatorsVideos
= validators
.videos
14 const databaseUtils
= require('../../../helpers/database-utils')
16 const router
= express
.Router()
18 router
.put('/:id/rate',
20 validatorsVideos
.videoRate
,
24 // ---------------------------------------------------------------------------
26 module
.exports
= router
28 // ---------------------------------------------------------------------------
30 function rateVideoRetryWrapper (req
, res
, next
) {
32 arguments: [ req
, res
],
33 errorMessage: 'Cannot update the user video rate.'
36 databaseUtils
.retryTransactionWrapper(rateVideo
, options
, function (err
) {
37 if (err
) return next(err
)
39 return res
.type('json').status(204).end()
43 function rateVideo (req
, res
, finalCallback
) {
44 const rateType
= req
.body
.rating
45 const videoInstance
= res
.locals
.video
46 const userInstance
= res
.locals
.oauth
.token
.User
49 databaseUtils
.startSerializableTransaction
,
51 function findPreviousRate (t
, callback
) {
52 db
.UserVideoRate
.load(userInstance
.id
, videoInstance
.id
, t
, function (err
, previousRate
) {
53 return callback(err
, t
, previousRate
)
57 function insertUserRateIntoDB (t
, previousRate
, callback
) {
58 const options
= { transaction: t
}
60 let likesToIncrement
= 0
61 let dislikesToIncrement
= 0
63 if (rateType
=== constants
.VIDEO_RATE_TYPES
.LIKE
) likesToIncrement
++
64 else if (rateType
=== constants
.VIDEO_RATE_TYPES
.DISLIKE
) dislikesToIncrement
++
66 // There was a previous rate, update it
68 // We will remove the previous rate, so we will need to remove it from the video attribute
69 if (previousRate
.type
=== constants
.VIDEO_RATE_TYPES
.LIKE
) likesToIncrement
--
70 else if (previousRate
.type
=== constants
.VIDEO_RATE_TYPES
.DISLIKE
) dislikesToIncrement
--
72 previousRate
.type
= rateType
74 previousRate
.save(options
).asCallback(function (err
) {
75 return callback(err
, t
, likesToIncrement
, dislikesToIncrement
)
77 } else { // There was not a previous rate, insert a new one
79 userId: userInstance
.id
,
80 videoId: videoInstance
.id
,
84 db
.UserVideoRate
.create(query
, options
).asCallback(function (err
) {
85 return callback(err
, t
, likesToIncrement
, dislikesToIncrement
)
90 function updateVideoAttributeDB (t
, likesToIncrement
, dislikesToIncrement
, callback
) {
91 const options
= { transaction: t
}
92 const incrementQuery
= {
93 likes: likesToIncrement
,
94 dislikes: dislikesToIncrement
97 // Even if we do not own the video we increment the attributes
98 // It is usefull for the user to have a feedback
99 videoInstance
.increment(incrementQuery
, options
).asCallback(function (err
) {
100 return callback(err
, t
, likesToIncrement
, dislikesToIncrement
)
104 function sendEventsToFriendsIfNeeded (t
, likesToIncrement
, dislikesToIncrement
, callback
) {
105 // No need for an event type, we own the video
106 if (videoInstance
.isOwned()) return callback(null, t
, likesToIncrement
, dislikesToIncrement
)
108 const eventsParams
= []
110 if (likesToIncrement
!== 0) {
112 videoId: videoInstance
.id
,
113 type: constants
.REQUEST_VIDEO_EVENT_TYPES
.LIKES
,
114 count: likesToIncrement
118 if (dislikesToIncrement
!== 0) {
120 videoId: videoInstance
.id
,
121 type: constants
.REQUEST_VIDEO_EVENT_TYPES
.DISLIKES
,
122 count: dislikesToIncrement
126 friends
.addEventsToRemoteVideo(eventsParams
, t
, function (err
) {
127 return callback(err
, t
, likesToIncrement
, dislikesToIncrement
)
131 function sendQaduToFriendsIfNeeded (t
, likesToIncrement
, dislikesToIncrement
, callback
) {
132 // We do not own the video, there is no need to send a quick and dirty update to friends
133 // Our rate was already sent by the addEvent function
134 if (videoInstance
.isOwned() === false) return callback(null, t
)
136 const qadusParams
= []
138 if (likesToIncrement
!== 0) {
140 videoId: videoInstance
.id
,
141 type: constants
.REQUEST_VIDEO_QADU_TYPES
.LIKES
145 if (dislikesToIncrement
!== 0) {
147 videoId: videoInstance
.id
,
148 type: constants
.REQUEST_VIDEO_QADU_TYPES
.DISLIKES
152 friends
.quickAndDirtyUpdatesVideoToFriends(qadusParams
, t
, function (err
) {
153 return callback(err
, t
)
157 databaseUtils
.commitTransaction
159 ], function (err
, t
) {
161 // This is just a debug because we will retry the insert
162 logger
.debug('Cannot add the user video rate.', { error: err
})
163 return databaseUtils
.rollbackTransaction(err
, t
, finalCallback
)
166 logger
.info('User video rate for video %s of user %s updated.', videoInstance
.name
, userInstance
.username
)
167 return finalCallback(null)