Type functions
[oweals/peertube.git] / server / lib / request / request-video-qadu-scheduler.ts
1 import * as Sequelize from 'sequelize'
2
3 import { database as db } from '../../initializers/database'
4 import { BaseRequestScheduler } from './base-request-scheduler'
5 import { logger } from '../../helpers'
6 import {
7   REQUESTS_VIDEO_QADU_LIMIT_PODS,
8   REQUESTS_VIDEO_QADU_LIMIT_PER_POD,
9   REQUEST_VIDEO_QADU_ENDPOINT,
10   REQUEST_VIDEO_QADU_TYPES
11 } from '../../initializers'
12
13 export type RequestVideoQaduSchedulerOptions = {
14   type: string
15   videoId: string
16   transaction?: Sequelize.Transaction
17 }
18
19 class RequestVideoQaduScheduler extends BaseRequestScheduler {
20   constructor () {
21     super()
22
23     // We limit the size of the requests
24     this.limitPods = REQUESTS_VIDEO_QADU_LIMIT_PODS
25     this.limitPerPod = REQUESTS_VIDEO_QADU_LIMIT_PER_POD
26
27     this.description = 'video QADU requests'
28   }
29
30   getRequestModel () {
31     return db.RequestVideoQadu
32   }
33
34   getRequestToPodModel () {
35     return db.RequestVideoQadu
36   }
37
38   buildRequestObjects (requests: { [ toPodId: number ]: any }[]) {
39     const requestsToMakeGrouped = {}
40
41     Object.keys(requests).forEach(toPodId => {
42       requests[toPodId].forEach(data => {
43         const request = data.request
44         const video = data.video
45         const pod = data.pod
46         const hashKey = toPodId
47
48         if (!requestsToMakeGrouped[hashKey]) {
49           requestsToMakeGrouped[hashKey] = {
50             toPod: pod,
51             endpoint: REQUEST_VIDEO_QADU_ENDPOINT,
52             ids: [], // request ids, to delete them from the DB in the future
53             datas: [], // requests data
54             videos: {}
55           }
56         }
57
58         // Maybe another attribute was filled for this video
59         let videoData = requestsToMakeGrouped[hashKey].videos[video.id]
60         if (!videoData) videoData = {}
61
62         switch (request.type) {
63           case REQUEST_VIDEO_QADU_TYPES.LIKES:
64             videoData.likes = video.likes
65             break
66
67           case REQUEST_VIDEO_QADU_TYPES.DISLIKES:
68             videoData.dislikes = video.dislikes
69             break
70
71           case REQUEST_VIDEO_QADU_TYPES.VIEWS:
72             videoData.views = video.views
73             break
74
75           default:
76             logger.error('Unknown request video QADU type %s.', request.type)
77             return
78         }
79
80         // Do not forget the remoteId so the remote pod can identify the video
81         videoData.remoteId = video.id
82         requestsToMakeGrouped[hashKey].ids.push(request.id)
83
84         // Maybe there are multiple quick and dirty update for the same video
85         // We use this hashmap to dedupe them
86         requestsToMakeGrouped[hashKey].videos[video.id] = videoData
87       })
88     })
89
90     // Now we deduped similar quick and dirty updates, we can build our requests datas
91     Object.keys(requestsToMakeGrouped).forEach(hashKey => {
92       Object.keys(requestsToMakeGrouped[hashKey].videos).forEach(videoId => {
93         const videoData = requestsToMakeGrouped[hashKey].videos[videoId]
94
95         requestsToMakeGrouped[hashKey].datas.push({
96           data: videoData
97         })
98       })
99
100       // We don't need it anymore, it was just to build our datas array
101       delete requestsToMakeGrouped[hashKey].videos
102     })
103
104     return requestsToMakeGrouped
105   }
106
107   createRequest ({ type, videoId, transaction }: RequestVideoQaduSchedulerOptions, callback: (err: Error) => void) {
108     const dbRequestOptions: Sequelize.BulkCreateOptions = {}
109     if (transaction) dbRequestOptions.transaction = transaction
110
111     // Send the update to all our friends
112     db.Pod.listAllIds(transaction, function (err, podIds) {
113       if (err) return callback(err)
114
115       const queries = []
116       podIds.forEach(podId => {
117         queries.push({ type, videoId, podId })
118       })
119
120       return db.RequestVideoQadu.bulkCreate(queries, dbRequestOptions).asCallback(callback)
121     })
122   }
123 }
124
125 // ---------------------------------------------------------------------------
126
127 export {
128   RequestVideoQaduScheduler
129 }