]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/controllers/api/videos/rate.ts
require -> import
[github/Chocobozzz/PeerTube.git] / server / controllers / api / videos / rate.ts
CommitLineData
4d4e5cd4 1import * as express from 'express'
65fcc311 2import { waterfall } from 'async'
d33242b0 3
e02643f3 4import { database as db } from '../../../initializers/database'
65fcc311
C
5import {
6 logger,
7 retryTransactionWrapper,
8 startSerializableTransaction,
9 commitTransaction,
10 rollbackTransaction
11} from '../../../helpers'
12import {
13 VIDEO_RATE_TYPES,
14 REQUEST_VIDEO_EVENT_TYPES,
15 REQUEST_VIDEO_QADU_TYPES
16} from '../../../initializers'
17import {
18 addEventsToRemoteVideo,
19 quickAndDirtyUpdatesVideoToFriends
20} from '../../../lib'
21import {
22 authenticate,
23 videoRateValidator
24} from '../../../middlewares'
25
26const rateVideoRouter = express.Router()
27
28rateVideoRouter.put('/:id/rate',
29 authenticate,
30 videoRateValidator,
d33242b0
C
31 rateVideoRetryWrapper
32)
33
34// ---------------------------------------------------------------------------
35
65fcc311
C
36export {
37 rateVideoRouter
38}
d33242b0
C
39
40// ---------------------------------------------------------------------------
41
42function 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
55function 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}