aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api/videos/rate.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/controllers/api/videos/rate.ts')
-rw-r--r--server/controllers/api/videos/rate.ts205
1 files changed, 93 insertions, 112 deletions
diff --git a/server/controllers/api/videos/rate.ts b/server/controllers/api/videos/rate.ts
index 6ddc69817..354c3d8f9 100644
--- a/server/controllers/api/videos/rate.ts
+++ b/server/controllers/api/videos/rate.ts
@@ -1,5 +1,4 @@
1import * as express from 'express' 1import * as express from 'express'
2import * as Promise from 'bluebird'
3 2
4import { database as db } from '../../../initializers/database' 3import { database as db } from '../../../initializers/database'
5import { 4import {
@@ -17,7 +16,8 @@ import {
17} from '../../../lib' 16} from '../../../lib'
18import { 17import {
19 authenticate, 18 authenticate,
20 videoRateValidator 19 videoRateValidator,
20 asyncMiddleware
21} from '../../../middlewares' 21} from '../../../middlewares'
22import { UserVideoRateUpdate, VideoRateType } from '../../../../shared' 22import { UserVideoRateUpdate, VideoRateType } from '../../../../shared'
23 23
@@ -26,7 +26,7 @@ const rateVideoRouter = express.Router()
26rateVideoRouter.put('/:id/rate', 26rateVideoRouter.put('/:id/rate',
27 authenticate, 27 authenticate,
28 videoRateValidator, 28 videoRateValidator,
29 rateVideoRetryWrapper 29 asyncMiddleware(rateVideoRetryWrapper)
30) 30)
31 31
32// --------------------------------------------------------------------------- 32// ---------------------------------------------------------------------------
@@ -37,126 +37,107 @@ export {
37 37
38// --------------------------------------------------------------------------- 38// ---------------------------------------------------------------------------
39 39
40function rateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { 40async function rateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
41 const options = { 41 const options = {
42 arguments: [ req, res ], 42 arguments: [ req, res ],
43 errorMessage: 'Cannot update the user video rate.' 43 errorMessage: 'Cannot update the user video rate.'
44 } 44 }
45 45
46 retryTransactionWrapper(rateVideo, options) 46 await retryTransactionWrapper(rateVideo, options)
47 .then(() => res.type('json').status(204).end()) 47
48 .catch(err => next(err)) 48 return res.type('json').status(204).end()
49} 49}
50 50
51function rateVideo (req: express.Request, res: express.Response) { 51async function rateVideo (req: express.Request, res: express.Response) {
52 const body: UserVideoRateUpdate = req.body 52 const body: UserVideoRateUpdate = req.body
53 const rateType = body.rating 53 const rateType = body.rating
54 const videoInstance = res.locals.video 54 const videoInstance = res.locals.video
55 const userInstance = res.locals.oauth.token.User 55 const userInstance = res.locals.oauth.token.User
56 56
57 return db.sequelize.transaction(t => { 57 await db.sequelize.transaction(async t => {
58 return db.UserVideoRate.load(userInstance.id, videoInstance.id, t) 58 const sequelizeOptions = { transaction: t }
59 .then(previousRate => { 59 const previousRate = await db.UserVideoRate.load(userInstance.id, videoInstance.id, t)
60 const options = { transaction: t } 60
61 61 let likesToIncrement = 0
62 let likesToIncrement = 0 62 let dislikesToIncrement = 0
63 let dislikesToIncrement = 0 63
64 64 if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
65 if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++ 65 else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
66 else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++ 66
67 67 // There was a previous rate, update it
68 let promise: Promise<any> 68 if (previousRate) {
69 69 // We will remove the previous rate, so we will need to update the video count attribute
70 // There was a previous rate, update it 70 if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement--
71 if (previousRate) { 71 else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
72 // We will remove the previous rate, so we will need to update the video count attribute 72
73 if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement-- 73 if (rateType === 'none') { // Destroy previous rate
74 else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement-- 74 await previousRate.destroy()
75 75 } else { // Update previous rate
76 if (rateType === 'none') { // Destroy previous rate 76 previousRate.type = rateType as VideoRateType
77 promise = previousRate.destroy() 77
78 } else { // Update previous rate 78 await previousRate.save()
79 previousRate.type = rateType as VideoRateType 79 }
80 80 } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
81 promise = previousRate.save() 81 const query = {
82 } 82 userId: userInstance.id,
83 } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate 83 videoId: videoInstance.id,
84 const query = { 84 type: rateType
85 userId: userInstance.id, 85 }
86 videoId: videoInstance.id, 86
87 type: rateType 87 await db.UserVideoRate.create(query, sequelizeOptions)
88 } 88 }
89 89
90 promise = db.UserVideoRate.create(query, options) 90 const incrementQuery = {
91 } else { 91 likes: likesToIncrement,
92 promise = Promise.resolve() 92 dislikes: dislikesToIncrement
93 } 93 }
94 94
95 return promise.then(() => ({ likesToIncrement, dislikesToIncrement })) 95 // Even if we do not own the video we increment the attributes
96 }) 96 // It is useful for the user to have a feedback
97 .then(({ likesToIncrement, dislikesToIncrement }) => { 97 await videoInstance.increment(incrementQuery, sequelizeOptions)
98 const options = { transaction: t } 98
99 const incrementQuery = { 99 // Send a event to original pod
100 likes: likesToIncrement, 100 if (videoInstance.isOwned() === false) {
101 dislikes: dislikesToIncrement 101
102 } 102 const eventsParams = []
103 103
104 // Even if we do not own the video we increment the attributes 104 if (likesToIncrement !== 0) {
105 // It is usefull for the user to have a feedback 105 eventsParams.push({
106 return videoInstance.increment(incrementQuery, options).then(() => ({ likesToIncrement, dislikesToIncrement })) 106 videoId: videoInstance.id,
107 }) 107 type: REQUEST_VIDEO_EVENT_TYPES.LIKES,
108 .then(({ likesToIncrement, dislikesToIncrement }) => { 108 count: likesToIncrement
109 // No need for an event type, we own the video 109 })
110 if (videoInstance.isOwned()) return { likesToIncrement, dislikesToIncrement } 110 }
111 111
112 const eventsParams = [] 112 if (dislikesToIncrement !== 0) {
113 113 eventsParams.push({
114 if (likesToIncrement !== 0) { 114 videoId: videoInstance.id,
115 eventsParams.push({ 115 type: REQUEST_VIDEO_EVENT_TYPES.DISLIKES,
116 videoId: videoInstance.id, 116 count: dislikesToIncrement
117 type: REQUEST_VIDEO_EVENT_TYPES.LIKES, 117 })
118 count: likesToIncrement 118 }
119 }) 119
120 } 120 await addEventsToRemoteVideo(eventsParams, t)
121 121 } else { // We own the video, we need to send a quick and dirty update to friends to notify the counts changed
122 if (dislikesToIncrement !== 0) { 122 const qadusParams = []
123 eventsParams.push({ 123
124 videoId: videoInstance.id, 124 if (likesToIncrement !== 0) {
125 type: REQUEST_VIDEO_EVENT_TYPES.DISLIKES, 125 qadusParams.push({
126 count: dislikesToIncrement 126 videoId: videoInstance.id,
127 }) 127 type: REQUEST_VIDEO_QADU_TYPES.LIKES
128 } 128 })
129 129 }
130 return addEventsToRemoteVideo(eventsParams, t).then(() => ({ likesToIncrement, dislikesToIncrement })) 130
131 }) 131 if (dislikesToIncrement !== 0) {
132 .then(({ likesToIncrement, dislikesToIncrement }) => { 132 qadusParams.push({
133 // We do not own the video, there is no need to send a quick and dirty update to friends 133 videoId: videoInstance.id,
134 // Our rate was already sent by the addEvent function 134 type: REQUEST_VIDEO_QADU_TYPES.DISLIKES
135 if (videoInstance.isOwned() === false) return undefined 135 })
136 136 }
137 const qadusParams = [] 137
138 138 await quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
139 if (likesToIncrement !== 0) { 139 }
140 qadusParams.push({
141 videoId: videoInstance.id,
142 type: REQUEST_VIDEO_QADU_TYPES.LIKES
143 })
144 }
145
146 if (dislikesToIncrement !== 0) {
147 qadusParams.push({
148 videoId: videoInstance.id,
149 type: REQUEST_VIDEO_QADU_TYPES.DISLIKES
150 })
151 }
152
153 return quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
154 })
155 })
156 .then(() => logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username))
157 .catch(err => {
158 // This is just a debug because we will retry the insert
159 logger.debug('Cannot add the user video rate.', err)
160 throw err
161 }) 140 })
141
142 logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username)
162} 143}