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