Server: add video language attribute
[oweals/peertube.git] / server / models / request.js
1 'use strict'
2
3 const values = require('lodash/values')
4
5 const constants = require('../initializers/constants')
6
7 // ---------------------------------------------------------------------------
8
9 module.exports = function (sequelize, DataTypes) {
10   const Request = sequelize.define('Request',
11     {
12       request: {
13         type: DataTypes.JSON,
14         allowNull: false
15       },
16       endpoint: {
17         type: DataTypes.ENUM(values(constants.REQUEST_ENDPOINTS)),
18         allowNull: false
19       }
20     },
21     {
22       classMethods: {
23         associate,
24
25         listWithLimitAndRandom,
26
27         countTotalRequests,
28         removeAll,
29         removeWithEmptyTo
30       }
31     }
32   )
33
34   return Request
35 }
36
37 // ------------------------------ STATICS ------------------------------
38
39 function associate (models) {
40   this.belongsToMany(models.Pod, {
41     foreignKey: {
42       name: 'requestId',
43       allowNull: false
44     },
45     through: models.RequestToPod,
46     onDelete: 'CASCADE'
47   })
48 }
49
50 function countTotalRequests (callback) {
51   // We need to include Pod because there are no cascade delete when a pod is removed
52   // So we could count requests that do not have existing pod anymore
53   const query = {
54     include: [ this.sequelize.models.Pod ]
55   }
56
57   return this.count(query).asCallback(callback)
58 }
59
60 function listWithLimitAndRandom (limitPods, limitRequestsPerPod, callback) {
61   const self = this
62   const Pod = this.sequelize.models.Pod
63
64   Pod.listRandomPodIdsWithRequest(limitPods, 'RequestToPods', function (err, podIds) {
65     if (err) return callback(err)
66
67     // We don't have friends that have requests
68     if (podIds.length === 0) return callback(null, [])
69
70     // The first x requests of these pods
71     // It is very important to sort by id ASC to keep the requests order!
72     const query = {
73       order: [
74         [ 'id', 'ASC' ]
75       ],
76       include: [
77         {
78           model: self.sequelize.models.Pod,
79           where: {
80             id: {
81               $in: podIds
82             }
83           }
84         }
85       ]
86     }
87
88     self.findAll(query).asCallback(function (err, requests) {
89       if (err) return callback(err)
90
91       const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod)
92       return callback(err, requestsGrouped)
93     })
94   })
95 }
96
97 function removeAll (callback) {
98   // Delete all requests
99   this.truncate({ cascade: true }).asCallback(callback)
100 }
101
102 function removeWithEmptyTo (callback) {
103   if (!callback) callback = function () {}
104
105   const query = {
106     where: {
107       id: {
108         $notIn: [
109           this.sequelize.literal('SELECT "requestId" FROM "RequestToPods"')
110         ]
111       }
112     }
113   }
114
115   this.destroy(query).asCallback(callback)
116 }
117
118 // ---------------------------------------------------------------------------
119
120 function groupAndTruncateRequests (requests, limitRequestsPerPod) {
121   const requestsGrouped = {}
122
123   requests.forEach(function (request) {
124     request.Pods.forEach(function (pod) {
125       if (!requestsGrouped[pod.id]) requestsGrouped[pod.id] = []
126
127       if (requestsGrouped[pod.id].length < limitRequestsPerPod) {
128         requestsGrouped[pod.id].push({
129           request,
130           pod
131         })
132       }
133     })
134   })
135
136   return requestsGrouped
137 }