-import express = require('express')
-import { waterfall } from 'async'
+import * as express from 'express'
-const db = require('../../../initializers/database')
+import { database as db } from '../../../initializers/database'
import {
logger,
- retryTransactionWrapper,
- startSerializableTransaction,
- commitTransaction,
- rollbackTransaction
+ retryTransactionWrapper
} from '../../../helpers'
import {
VIDEO_RATE_TYPES,
} from '../../../lib'
import {
authenticate,
- videoRateValidator
+ videoRateValidator,
+ asyncMiddleware
} from '../../../middlewares'
+import { UserVideoRateUpdate, VideoRateType } from '../../../../shared'
const rateVideoRouter = express.Router()
rateVideoRouter.put('/:id/rate',
authenticate,
videoRateValidator,
- rateVideoRetryWrapper
+ asyncMiddleware(rateVideoRetryWrapper)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-function rateVideoRetryWrapper (req, res, next) {
+async function rateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot update the user video rate.'
}
- retryTransactionWrapper(rateVideo, options, function (err) {
- if (err) return next(err)
+ await retryTransactionWrapper(rateVideo, options)
- return res.type('json').status(204).end()
- })
+ return res.type('json').status(204).end()
}
-function rateVideo (req, res, finalCallback) {
- const rateType = req.body.rating
+async function rateVideo (req: express.Request, res: express.Response) {
+ const body: UserVideoRateUpdate = req.body
+ const rateType = body.rating
const videoInstance = res.locals.video
const userInstance = res.locals.oauth.token.User
- waterfall([
- startSerializableTransaction,
-
- function findPreviousRate (t, callback) {
- db.UserVideoRate.load(userInstance.id, videoInstance.id, t, function (err, previousRate) {
- return callback(err, t, previousRate)
- })
- },
-
- function insertUserRateIntoDB (t, previousRate, callback) {
- const options = { transaction: t }
-
- let likesToIncrement = 0
- let dislikesToIncrement = 0
+ await db.sequelize.transaction(async t => {
+ const sequelizeOptions = { transaction: t }
+ const previousRate = await db.UserVideoRate.load(userInstance.id, videoInstance.id, t)
- if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
- else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
+ let likesToIncrement = 0
+ let dislikesToIncrement = 0
- // There was a previous rate, update it
- if (previousRate) {
- // We will remove the previous rate, so we will need to remove it from the video attribute
- if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement--
- else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
+ if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
+ else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
- previousRate.type = rateType
+ // There was a previous rate, update it
+ if (previousRate) {
+ // We will remove the previous rate, so we will need to update the video count attribute
+ if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement--
+ else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
- previousRate.save(options).asCallback(function (err) {
- return callback(err, t, likesToIncrement, dislikesToIncrement)
- })
- } else { // There was not a previous rate, insert a new one
- const query = {
- userId: userInstance.id,
- videoId: videoInstance.id,
- type: rateType
- }
+ if (rateType === 'none') { // Destroy previous rate
+ await previousRate.destroy()
+ } else { // Update previous rate
+ previousRate.type = rateType as VideoRateType
- db.UserVideoRate.create(query, options).asCallback(function (err) {
- return callback(err, t, likesToIncrement, dislikesToIncrement)
- })
+ await previousRate.save()
}
- },
-
- function updateVideoAttributeDB (t, likesToIncrement, dislikesToIncrement, callback) {
- const options = { transaction: t }
- const incrementQuery = {
- likes: likesToIncrement,
- dislikes: dislikesToIncrement
+ } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
+ const query = {
+ userId: userInstance.id,
+ videoId: videoInstance.id,
+ type: rateType
}
- // Even if we do not own the video we increment the attributes
- // It is usefull for the user to have a feedback
- videoInstance.increment(incrementQuery, options).asCallback(function (err) {
- return callback(err, t, likesToIncrement, dislikesToIncrement)
- })
- },
+ await db.UserVideoRate.create(query, sequelizeOptions)
+ }
- function sendEventsToFriendsIfNeeded (t, likesToIncrement, dislikesToIncrement, callback) {
- // No need for an event type, we own the video
- if (videoInstance.isOwned()) return callback(null, t, likesToIncrement, dislikesToIncrement)
+ const incrementQuery = {
+ likes: likesToIncrement,
+ dislikes: dislikesToIncrement
+ }
+
+ // Even if we do not own the video we increment the attributes
+ // It is useful for the user to have a feedback
+ await videoInstance.increment(incrementQuery, sequelizeOptions)
+
+ // Send a event to original pod
+ if (videoInstance.isOwned() === false) {
const eventsParams = []
})
}
- addEventsToRemoteVideo(eventsParams, t, function (err) {
- return callback(err, t, likesToIncrement, dislikesToIncrement)
- })
- },
-
- function sendQaduToFriendsIfNeeded (t, likesToIncrement, dislikesToIncrement, callback) {
- // We do not own the video, there is no need to send a quick and dirty update to friends
- // Our rate was already sent by the addEvent function
- if (videoInstance.isOwned() === false) return callback(null, t)
-
+ await addEventsToRemoteVideo(eventsParams, t)
+ } else { // We own the video, we need to send a quick and dirty update to friends to notify the counts changed
const qadusParams = []
if (likesToIncrement !== 0) {
})
}
- quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) {
- return callback(err, t)
- })
- },
-
- commitTransaction
-
- ], function (err, t) {
- if (err) {
- // This is just a debug because we will retry the insert
- logger.debug('Cannot add the user video rate.', { error: err })
- return rollbackTransaction(err, t, finalCallback)
+ await quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
}
-
- logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username)
- return finalCallback(null)
})
+
+ logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username)
}