aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/request-video-event.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/request-video-event.ts')
-rw-r--r--server/models/request-video-event.ts170
1 files changed, 170 insertions, 0 deletions
diff --git a/server/models/request-video-event.ts b/server/models/request-video-event.ts
new file mode 100644
index 000000000..c61525029
--- /dev/null
+++ b/server/models/request-video-event.ts
@@ -0,0 +1,170 @@
1/*
2 Request Video events (likes, dislikes, views...)
3*/
4
5import { values } from 'lodash'
6
7import { REQUEST_VIDEO_EVENT_TYPES } from '../initializers'
8import { isVideoEventCountValid } from '../helpers'
9
10// ---------------------------------------------------------------------------
11
12module.exports = function (sequelize, DataTypes) {
13 const RequestVideoEvent = sequelize.define('RequestVideoEvent',
14 {
15 type: {
16 type: DataTypes.ENUM(values(REQUEST_VIDEO_EVENT_TYPES)),
17 allowNull: false
18 },
19 count: {
20 type: DataTypes.INTEGER,
21 allowNull: false,
22 validate: {
23 countValid: function (value) {
24 const res = isVideoEventCountValid(value)
25 if (res === false) throw new Error('Video event count is not valid.')
26 }
27 }
28 }
29 },
30 {
31 updatedAt: false,
32 indexes: [
33 {
34 fields: [ 'videoId' ]
35 }
36 ],
37 classMethods: {
38 associate,
39
40 listWithLimitAndRandom,
41
42 countTotalRequests,
43 removeAll,
44 removeByRequestIdsAndPod
45 }
46 }
47 )
48
49 return RequestVideoEvent
50}
51
52// ------------------------------ STATICS ------------------------------
53
54function associate (models) {
55 this.belongsTo(models.Video, {
56 foreignKey: {
57 name: 'videoId',
58 allowNull: false
59 },
60 onDelete: 'CASCADE'
61 })
62}
63
64function countTotalRequests (callback) {
65 const query = {}
66 return this.count(query).asCallback(callback)
67}
68
69function listWithLimitAndRandom (limitPods, limitRequestsPerPod, callback) {
70 const self = this
71 const Pod = this.sequelize.models.Pod
72
73 // We make a join between videos and authors to find the podId of our video event requests
74 const podJoins = 'INNER JOIN "Videos" ON "Videos"."authorId" = "Authors"."id" ' +
75 'INNER JOIN "RequestVideoEvents" ON "RequestVideoEvents"."videoId" = "Videos"."id"'
76
77 Pod.listRandomPodIdsWithRequest(limitPods, 'Authors', podJoins, function (err, podIds) {
78 if (err) return callback(err)
79
80 // We don't have friends that have requests
81 if (podIds.length === 0) return callback(null, [])
82
83 const query = {
84 order: [
85 [ 'id', 'ASC' ]
86 ],
87 include: [
88 {
89 model: self.sequelize.models.Video,
90 include: [
91 {
92 model: self.sequelize.models.Author,
93 include: [
94 {
95 model: self.sequelize.models.Pod,
96 where: {
97 id: {
98 $in: podIds
99 }
100 }
101 }
102 ]
103 }
104 ]
105 }
106 ]
107 }
108
109 self.findAll(query).asCallback(function (err, requests) {
110 if (err) return callback(err)
111
112 const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod)
113 return callback(err, requestsGrouped)
114 })
115 })
116}
117
118function removeByRequestIdsAndPod (ids, podId, callback) {
119 const query = {
120 where: {
121 id: {
122 $in: ids
123 }
124 },
125 include: [
126 {
127 model: this.sequelize.models.Video,
128 include: [
129 {
130 model: this.sequelize.models.Author,
131 where: {
132 podId
133 }
134 }
135 ]
136 }
137 ]
138 }
139
140 this.destroy(query).asCallback(callback)
141}
142
143function removeAll (callback) {
144 // Delete all requests
145 this.truncate({ cascade: true }).asCallback(callback)
146}
147
148// ---------------------------------------------------------------------------
149
150function groupAndTruncateRequests (events, limitRequestsPerPod) {
151 const eventsGrouped = {}
152
153 events.forEach(function (event) {
154 const pod = event.Video.Author.Pod
155
156 if (!eventsGrouped[pod.id]) eventsGrouped[pod.id] = []
157
158 if (eventsGrouped[pod.id].length < limitRequestsPerPod) {
159 eventsGrouped[pod.id].push({
160 id: event.id,
161 type: event.type,
162 count: event.count,
163 video: event.Video,
164 pod
165 })
166 }
167 })
168
169 return eventsGrouped
170}