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