]>
Commit | Line | Data |
---|---|---|
4d4e5cd4 | 1 | import * as express from 'express' |
65fcc311 | 2 | import { waterfall } from 'async' |
d33242b0 | 3 | |
e02643f3 | 4 | import { database as db } from '../../../initializers/database' |
65fcc311 C |
5 | import { |
6 | logger, | |
7 | retryTransactionWrapper, | |
8 | startSerializableTransaction, | |
9 | commitTransaction, | |
10 | rollbackTransaction | |
11 | } from '../../../helpers' | |
12 | import { | |
13 | VIDEO_RATE_TYPES, | |
14 | REQUEST_VIDEO_EVENT_TYPES, | |
15 | REQUEST_VIDEO_QADU_TYPES | |
16 | } from '../../../initializers' | |
17 | import { | |
18 | addEventsToRemoteVideo, | |
19 | quickAndDirtyUpdatesVideoToFriends | |
20 | } from '../../../lib' | |
21 | import { | |
22 | authenticate, | |
23 | videoRateValidator | |
24 | } from '../../../middlewares' | |
25 | ||
26 | const rateVideoRouter = express.Router() | |
27 | ||
28 | rateVideoRouter.put('/:id/rate', | |
29 | authenticate, | |
30 | videoRateValidator, | |
d33242b0 C |
31 | rateVideoRetryWrapper |
32 | ) | |
33 | ||
34 | // --------------------------------------------------------------------------- | |
35 | ||
65fcc311 C |
36 | export { |
37 | rateVideoRouter | |
38 | } | |
d33242b0 C |
39 | |
40 | // --------------------------------------------------------------------------- | |
41 | ||
42 | function rateVideoRetryWrapper (req, res, next) { | |
43 | const options = { | |
44 | arguments: [ req, res ], | |
45 | errorMessage: 'Cannot update the user video rate.' | |
46 | } | |
47 | ||
65fcc311 | 48 | retryTransactionWrapper(rateVideo, options, function (err) { |
d33242b0 C |
49 | if (err) return next(err) |
50 | ||
51 | return res.type('json').status(204).end() | |
52 | }) | |
53 | } | |
54 | ||
55 | function rateVideo (req, res, finalCallback) { | |
56 | const rateType = req.body.rating | |
57 | const videoInstance = res.locals.video | |
58 | const userInstance = res.locals.oauth.token.User | |
59 | ||
60 | waterfall([ | |
65fcc311 | 61 | startSerializableTransaction, |
d33242b0 C |
62 | |
63 | function findPreviousRate (t, callback) { | |
64 | db.UserVideoRate.load(userInstance.id, videoInstance.id, t, function (err, previousRate) { | |
65 | return callback(err, t, previousRate) | |
66 | }) | |
67 | }, | |
68 | ||
69 | function insertUserRateIntoDB (t, previousRate, callback) { | |
70 | const options = { transaction: t } | |
71 | ||
72 | let likesToIncrement = 0 | |
73 | let dislikesToIncrement = 0 | |
74 | ||
65fcc311 C |
75 | if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++ |
76 | else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++ | |
d33242b0 C |
77 | |
78 | // There was a previous rate, update it | |
79 | if (previousRate) { | |
80 | // We will remove the previous rate, so we will need to remove it from the video attribute | |
65fcc311 C |
81 | if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement-- |
82 | else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement-- | |
d33242b0 C |
83 | |
84 | previousRate.type = rateType | |
85 | ||
86 | previousRate.save(options).asCallback(function (err) { | |
87 | return callback(err, t, likesToIncrement, dislikesToIncrement) | |
88 | }) | |
89 | } else { // There was not a previous rate, insert a new one | |
90 | const query = { | |
91 | userId: userInstance.id, | |
92 | videoId: videoInstance.id, | |
93 | type: rateType | |
94 | } | |
95 | ||
96 | db.UserVideoRate.create(query, options).asCallback(function (err) { | |
97 | return callback(err, t, likesToIncrement, dislikesToIncrement) | |
98 | }) | |
99 | } | |
100 | }, | |
101 | ||
102 | function updateVideoAttributeDB (t, likesToIncrement, dislikesToIncrement, callback) { | |
103 | const options = { transaction: t } | |
104 | const incrementQuery = { | |
105 | likes: likesToIncrement, | |
106 | dislikes: dislikesToIncrement | |
107 | } | |
108 | ||
109 | // Even if we do not own the video we increment the attributes | |
110 | // It is usefull for the user to have a feedback | |
111 | videoInstance.increment(incrementQuery, options).asCallback(function (err) { | |
112 | return callback(err, t, likesToIncrement, dislikesToIncrement) | |
113 | }) | |
114 | }, | |
115 | ||
116 | function sendEventsToFriendsIfNeeded (t, likesToIncrement, dislikesToIncrement, callback) { | |
117 | // No need for an event type, we own the video | |
118 | if (videoInstance.isOwned()) return callback(null, t, likesToIncrement, dislikesToIncrement) | |
119 | ||
120 | const eventsParams = [] | |
121 | ||
122 | if (likesToIncrement !== 0) { | |
123 | eventsParams.push({ | |
124 | videoId: videoInstance.id, | |
65fcc311 | 125 | type: REQUEST_VIDEO_EVENT_TYPES.LIKES, |
d33242b0 C |
126 | count: likesToIncrement |
127 | }) | |
128 | } | |
129 | ||
130 | if (dislikesToIncrement !== 0) { | |
131 | eventsParams.push({ | |
132 | videoId: videoInstance.id, | |
65fcc311 | 133 | type: REQUEST_VIDEO_EVENT_TYPES.DISLIKES, |
d33242b0 C |
134 | count: dislikesToIncrement |
135 | }) | |
136 | } | |
137 | ||
65fcc311 | 138 | addEventsToRemoteVideo(eventsParams, t, function (err) { |
d33242b0 C |
139 | return callback(err, t, likesToIncrement, dislikesToIncrement) |
140 | }) | |
141 | }, | |
142 | ||
143 | function sendQaduToFriendsIfNeeded (t, likesToIncrement, dislikesToIncrement, callback) { | |
144 | // We do not own the video, there is no need to send a quick and dirty update to friends | |
145 | // Our rate was already sent by the addEvent function | |
146 | if (videoInstance.isOwned() === false) return callback(null, t) | |
147 | ||
148 | const qadusParams = [] | |
149 | ||
150 | if (likesToIncrement !== 0) { | |
151 | qadusParams.push({ | |
152 | videoId: videoInstance.id, | |
65fcc311 | 153 | type: REQUEST_VIDEO_QADU_TYPES.LIKES |
d33242b0 C |
154 | }) |
155 | } | |
156 | ||
157 | if (dislikesToIncrement !== 0) { | |
158 | qadusParams.push({ | |
159 | videoId: videoInstance.id, | |
65fcc311 | 160 | type: REQUEST_VIDEO_QADU_TYPES.DISLIKES |
d33242b0 C |
161 | }) |
162 | } | |
163 | ||
65fcc311 | 164 | quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) { |
d33242b0 C |
165 | return callback(err, t) |
166 | }) | |
167 | }, | |
168 | ||
65fcc311 | 169 | commitTransaction |
d33242b0 C |
170 | |
171 | ], function (err, t) { | |
172 | if (err) { | |
173 | // This is just a debug because we will retry the insert | |
174 | logger.debug('Cannot add the user video rate.', { error: err }) | |
65fcc311 | 175 | return rollbackTransaction(err, t, finalCallback) |
d33242b0 C |
176 | } |
177 | ||
178 | logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username) | |
179 | return finalCallback(null) | |
180 | }) | |
181 | } |