rate.ts 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import * as express from 'express'
  2. import { UserVideoRateUpdate } from '../../../../shared'
  3. import { logger } from '../../../helpers/logger'
  4. import { VIDEO_RATE_TYPES } from '../../../initializers/constants'
  5. import { getRateUrl, sendVideoRateChange } from '../../../lib/activitypub'
  6. import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoUpdateRateValidator } from '../../../middlewares'
  7. import { AccountModel } from '../../../models/account/account'
  8. import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
  9. import { sequelizeTypescript } from '../../../initializers/database'
  10. const rateVideoRouter = express.Router()
  11. rateVideoRouter.put('/:id/rate',
  12. authenticate,
  13. asyncMiddleware(videoUpdateRateValidator),
  14. asyncRetryTransactionMiddleware(rateVideo)
  15. )
  16. // ---------------------------------------------------------------------------
  17. export {
  18. rateVideoRouter
  19. }
  20. // ---------------------------------------------------------------------------
  21. async function rateVideo (req: express.Request, res: express.Response) {
  22. const body: UserVideoRateUpdate = req.body
  23. const rateType = body.rating
  24. const videoInstance = res.locals.video
  25. const userAccount = res.locals.oauth.token.User.Account
  26. await sequelizeTypescript.transaction(async t => {
  27. const sequelizeOptions = { transaction: t }
  28. const accountInstance = await AccountModel.load(userAccount.id, t)
  29. const previousRate = await AccountVideoRateModel.load(accountInstance.id, videoInstance.id, t)
  30. let likesToIncrement = 0
  31. let dislikesToIncrement = 0
  32. if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
  33. else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
  34. // There was a previous rate, update it
  35. if (previousRate) {
  36. // We will remove the previous rate, so we will need to update the video count attribute
  37. if (previousRate.type === 'like') likesToIncrement--
  38. else if (previousRate.type === 'dislike') dislikesToIncrement--
  39. if (rateType === 'none') { // Destroy previous rate
  40. await previousRate.destroy(sequelizeOptions)
  41. } else { // Update previous rate
  42. previousRate.type = rateType
  43. previousRate.url = getRateUrl(rateType, userAccount.Actor, videoInstance)
  44. await previousRate.save(sequelizeOptions)
  45. }
  46. } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
  47. const query = {
  48. accountId: accountInstance.id,
  49. videoId: videoInstance.id,
  50. type: rateType,
  51. url: getRateUrl(rateType, userAccount.Actor, videoInstance)
  52. }
  53. await AccountVideoRateModel.create(query, sequelizeOptions)
  54. }
  55. const incrementQuery = {
  56. likes: likesToIncrement,
  57. dislikes: dislikesToIncrement
  58. }
  59. await videoInstance.increment(incrementQuery, sequelizeOptions)
  60. await sendVideoRateChange(accountInstance, videoInstance, likesToIncrement, dislikesToIncrement, t)
  61. logger.info('Account video rate for video %s of account %s updated.', videoInstance.name, accountInstance.name)
  62. })
  63. return res.type('json').status(204).end()
  64. }