import express from 'express' ; import { HttpStatusCode , UserVideoRateUpdate } from '@shared/models' ; import { logger } from '../../../helpers/logger' ; import { VIDEO_RATE_TYPES } from '../../../initializers/constants' ; import { sequelizeTypescript } from '../../../initializers/database' ; import { getLocalRateUrl , sendVideoRateChange } from '../../../lib/activitypub/video-rates' ; import { asyncMiddleware , asyncRetryTransactionMiddleware , authenticate , videoUpdateRateValidator } from '../../../middlewares' ; import { AccountModel } from '../../../models/account/account' ; import { AccountVideoRateModel } from '../../../models/account/account-video-rate' ; const rateVideoRouter = express . Router ( ) ; rateVideoRouter . put ( '/:id/rate' , authenticate , asyncMiddleware ( videoUpdateRateValidator ) , asyncRetryTransactionMiddleware ( rateVideo ) ) ; export { rateVideoRouter } ; async function rateVideo ( req , res ) { const body = req . body ; const rateType = body . rating ; const videoInstance = res . locals . videoAll ; const userAccount = res . locals . oauth . token . User . Account ; await sequelizeTypescript . transaction ( async ( t ) => { const sequelizeOptions = { transaction : t } ; const accountInstance = await AccountModel . load ( userAccount . id , t ) ; const previousRate = await AccountVideoRateModel . load ( accountInstance . id , videoInstance . id , t ) ; if ( rateType === 'none' && ! previousRate || previousRate ?. type === rateType ) return ; let likesToIncrement = 0 ; let dislikesToIncrement = 0 ; if ( rateType === VIDEO_RATE_TYPES . LIKE ) likesToIncrement ++ ; else if ( rateType === VIDEO_RATE_TYPES . DISLIKE ) dislikesToIncrement ++ ; if ( previousRate ) { if ( previousRate . type === 'like' ) likesToIncrement -- ; else if ( previousRate . type === 'dislike' ) dislikesToIncrement -- ; if ( rateType === 'none' ) { await previousRate . destroy ( sequelizeOptions ) ; } else { previousRate . type = rateType ; previousRate . url = getLocalRateUrl ( rateType , userAccount . Actor , videoInstance ) ; await previousRate . save ( sequelizeOptions ) ; } } else if ( rateType !== 'none' ) { const query = { accountId : accountInstance . id , videoId : videoInstance . id , type : rateType , url : getLocalRateUrl ( rateType , userAccount . Actor , videoInstance ) } ; await AccountVideoRateModel . create ( query , sequelizeOptions ) ; } const incrementQuery = { likes : likesToIncrement , dislikes : dislikesToIncrement } ; await videoInstance . increment ( incrementQuery , sequelizeOptions ) ; await sendVideoRateChange ( accountInstance , videoInstance , likesToIncrement , dislikesToIncrement , t ) ; logger . info ( 'Account video rate for video %s of account %s updated.' , videoInstance . name , accountInstance . name ) ; } ) ; return res . type ( 'json' ) . status ( HttpStatusCode . NO_CONTENT_204 ) . end ( ) ; }