]>
Commit | Line | Data |
---|---|---|
d33242b0 C |
1 | 'use strict' |
2 | ||
3 | const express = require('express') | |
4 | const waterfall = require('async/waterfall') | |
5 | ||
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') | |
15 | ||
16 | const router = express.Router() | |
17 | ||
18 | router.put('/:id/rate', | |
19 | oAuth.authenticate, | |
20 | validatorsVideos.videoRate, | |
21 | rateVideoRetryWrapper | |
22 | ) | |
23 | ||
24 | // --------------------------------------------------------------------------- | |
25 | ||
26 | module.exports = router | |
27 | ||
28 | // --------------------------------------------------------------------------- | |
29 | ||
30 | function rateVideoRetryWrapper (req, res, next) { | |
31 | const options = { | |
32 | arguments: [ req, res ], | |
33 | errorMessage: 'Cannot update the user video rate.' | |
34 | } | |
35 | ||
36 | databaseUtils.retryTransactionWrapper(rateVideo, options, function (err) { | |
37 | if (err) return next(err) | |
38 | ||
39 | return res.type('json').status(204).end() | |
40 | }) | |
41 | } | |
42 | ||
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 | |
47 | ||
48 | waterfall([ | |
49 | databaseUtils.startSerializableTransaction, | |
50 | ||
51 | function findPreviousRate (t, callback) { | |
52 | db.UserVideoRate.load(userInstance.id, videoInstance.id, t, function (err, previousRate) { | |
53 | return callback(err, t, previousRate) | |
54 | }) | |
55 | }, | |
56 | ||
57 | function insertUserRateIntoDB (t, previousRate, callback) { | |
58 | const options = { transaction: t } | |
59 | ||
60 | let likesToIncrement = 0 | |
61 | let dislikesToIncrement = 0 | |
62 | ||
63 | if (rateType === constants.VIDEO_RATE_TYPES.LIKE) likesToIncrement++ | |
64 | else if (rateType === constants.VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++ | |
65 | ||
66 | // There was a previous rate, update it | |
67 | if (previousRate) { | |
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-- | |
71 | ||
72 | previousRate.type = rateType | |
73 | ||
74 | previousRate.save(options).asCallback(function (err) { | |
75 | return callback(err, t, likesToIncrement, dislikesToIncrement) | |
76 | }) | |
77 | } else { // There was not a previous rate, insert a new one | |
78 | const query = { | |
79 | userId: userInstance.id, | |
80 | videoId: videoInstance.id, | |
81 | type: rateType | |
82 | } | |
83 | ||
84 | db.UserVideoRate.create(query, options).asCallback(function (err) { | |
85 | return callback(err, t, likesToIncrement, dislikesToIncrement) | |
86 | }) | |
87 | } | |
88 | }, | |
89 | ||
90 | function updateVideoAttributeDB (t, likesToIncrement, dislikesToIncrement, callback) { | |
91 | const options = { transaction: t } | |
92 | const incrementQuery = { | |
93 | likes: likesToIncrement, | |
94 | dislikes: dislikesToIncrement | |
95 | } | |
96 | ||
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) | |
101 | }) | |
102 | }, | |
103 | ||
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) | |
107 | ||
108 | const eventsParams = [] | |
109 | ||
110 | if (likesToIncrement !== 0) { | |
111 | eventsParams.push({ | |
112 | videoId: videoInstance.id, | |
113 | type: constants.REQUEST_VIDEO_EVENT_TYPES.LIKES, | |
114 | count: likesToIncrement | |
115 | }) | |
116 | } | |
117 | ||
118 | if (dislikesToIncrement !== 0) { | |
119 | eventsParams.push({ | |
120 | videoId: videoInstance.id, | |
121 | type: constants.REQUEST_VIDEO_EVENT_TYPES.DISLIKES, | |
122 | count: dislikesToIncrement | |
123 | }) | |
124 | } | |
125 | ||
126 | friends.addEventsToRemoteVideo(eventsParams, t, function (err) { | |
127 | return callback(err, t, likesToIncrement, dislikesToIncrement) | |
128 | }) | |
129 | }, | |
130 | ||
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) | |
135 | ||
136 | const qadusParams = [] | |
137 | ||
138 | if (likesToIncrement !== 0) { | |
139 | qadusParams.push({ | |
140 | videoId: videoInstance.id, | |
141 | type: constants.REQUEST_VIDEO_QADU_TYPES.LIKES | |
142 | }) | |
143 | } | |
144 | ||
145 | if (dislikesToIncrement !== 0) { | |
146 | qadusParams.push({ | |
147 | videoId: videoInstance.id, | |
148 | type: constants.REQUEST_VIDEO_QADU_TYPES.DISLIKES | |
149 | }) | |
150 | } | |
151 | ||
152 | friends.quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) { | |
153 | return callback(err, t) | |
154 | }) | |
155 | }, | |
156 | ||
157 | databaseUtils.commitTransaction | |
158 | ||
159 | ], function (err, t) { | |
160 | if (err) { | |
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) | |
164 | } | |
165 | ||
166 | logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username) | |
167 | return finalCallback(null) | |
168 | }) | |
169 | } |