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