aboutsummaryrefslogblamecommitdiffhomepage
path: root/server/models/request-video-event.ts
blob: c615250290b9fb9fd3941b0d82fea2a56c7ad606 (plain) (tree)
1
2
3
4
5
6
7
8



                                                  
                               
 

                                                           






                                                                              
                                                                






                                        
                                                     


























































                                                                                                      


                       



















































































                                                                                     
/*
  Request Video events (likes, dislikes, views...)
*/

import { values } from 'lodash'

import { REQUEST_VIDEO_EVENT_TYPES } from '../initializers'
import { isVideoEventCountValid } from '../helpers'

// ---------------------------------------------------------------------------

module.exports = function (sequelize, DataTypes) {
  const RequestVideoEvent = sequelize.define('RequestVideoEvent',
    {
      type: {
        type: DataTypes.ENUM(values(REQUEST_VIDEO_EVENT_TYPES)),
        allowNull: false
      },
      count: {
        type: DataTypes.INTEGER,
        allowNull: false,
        validate: {
          countValid: function (value) {
            const res = isVideoEventCountValid(value)
            if (res === false) throw new Error('Video event count is not valid.')
          }
        }
      }
    },
    {
      updatedAt: false,
      indexes: [
        {
          fields: [ 'videoId' ]
        }
      ],
      classMethods: {
        associate,

        listWithLimitAndRandom,

        countTotalRequests,
        removeAll,
        removeByRequestIdsAndPod
      }
    }
  )

  return RequestVideoEvent
}

// ------------------------------ STATICS ------------------------------

function associate (models) {
  this.belongsTo(models.Video, {
    foreignKey: {
      name: 'videoId',
      allowNull: false
    },
    onDelete: 'CASCADE'
  })
}

function countTotalRequests (callback) {
  const query = {}
  return this.count(query).asCallback(callback)
}

function listWithLimitAndRandom (limitPods, limitRequestsPerPod, callback) {
  const self = this
  const Pod = this.sequelize.models.Pod

  // We make a join between videos and authors to find the podId of our video event requests
  const podJoins = 'INNER JOIN "Videos" ON "Videos"."authorId" = "Authors"."id" ' +
                   'INNER JOIN "RequestVideoEvents" ON "RequestVideoEvents"."videoId" = "Videos"."id"'

  Pod.listRandomPodIdsWithRequest(limitPods, 'Authors', podJoins, function (err, podIds) {
    if (err) return callback(err)

    // We don't have friends that have requests
    if (podIds.length === 0) return callback(null, [])

    const query = {
      order: [
        [ 'id', 'ASC' ]
      ],
      include: [
        {
          model: self.sequelize.models.Video,
          include: [
            {
              model: self.sequelize.models.Author,
              include: [
                {
                  model: self.sequelize.models.Pod,
                  where: {
                    id: {
                      $in: podIds
                    }
                  }
                }
              ]
            }
          ]
        }
      ]
    }

    self.findAll(query).asCallback(function (err, requests) {
      if (err) return callback(err)

      const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod)
      return callback(err, requestsGrouped)
    })
  })
}

function removeByRequestIdsAndPod (ids, podId, callback) {
  const query = {
    where: {
      id: {
        $in: ids
      }
    },
    include: [
      {
        model: this.sequelize.models.Video,
        include: [
          {
            model: this.sequelize.models.Author,
            where: {
              podId
            }
          }
        ]
      }
    ]
  }

  this.destroy(query).asCallback(callback)
}

function removeAll (callback) {
  // Delete all requests
  this.truncate({ cascade: true }).asCallback(callback)
}

// ---------------------------------------------------------------------------

function groupAndTruncateRequests (events, limitRequestsPerPod) {
  const eventsGrouped = {}

  events.forEach(function (event) {
    const pod = event.Video.Author.Pod

    if (!eventsGrouped[pod.id]) eventsGrouped[pod.id] = []

    if (eventsGrouped[pod.id].length < limitRequestsPerPod) {
      eventsGrouped[pod.id].push({
        id: event.id,
        type: event.type,
        count: event.count,
        video: event.Video,
        pod
      })
    }
  })

  return eventsGrouped
}