]>
Commit | Line | Data |
---|---|---|
69818c93 C |
1 | import * as Sequelize from 'sequelize' |
2 | ||
e02643f3 | 3 | import { database as db } from '../../initializers/database' |
4771e000 | 4 | import { AbstractRequestScheduler, RequestsObjects } from './abstract-request-scheduler' |
65fcc311 C |
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' | |
4771e000 C |
12 | import { RequestsVideoQaduGrouped, PodInstance } from '../../models' |
13 | import { RemoteQaduVideoRequest, RequestVideoQaduType } from '../../../shared' | |
14 | ||
15 | // We create a custom interface because we need "videos" attribute for our computations | |
16 | interface RequestsObjectsCustom<U> extends RequestsObjects<U> { | |
17 | [ id: string ]: { | |
18 | toPod: PodInstance | |
19 | endpoint: string | |
20 | ids: number[] // ids | |
21 | datas: U[] | |
22 | ||
23 | videos: { | |
0a6658fd C |
24 | [ uuid: string ]: { |
25 | uuid: string | |
4771e000 C |
26 | likes?: number |
27 | dislikes?: number | |
28 | views?: number | |
29 | } | |
30 | } | |
31 | } | |
32 | } | |
65fcc311 | 33 | |
69818c93 | 34 | export type RequestVideoQaduSchedulerOptions = { |
ee9e7b61 | 35 | type: RequestVideoQaduType |
0a6658fd | 36 | videoId: number |
69818c93 C |
37 | transaction?: Sequelize.Transaction |
38 | } | |
39 | ||
6fcd19ba | 40 | class RequestVideoQaduScheduler extends AbstractRequestScheduler<RequestsVideoQaduGrouped> { |
9e167724 C |
41 | constructor () { |
42 | super() | |
43 | ||
44 | // We limit the size of the requests | |
65fcc311 C |
45 | this.limitPods = REQUESTS_VIDEO_QADU_LIMIT_PODS |
46 | this.limitPerPod = REQUESTS_VIDEO_QADU_LIMIT_PER_POD | |
9e167724 C |
47 | |
48 | this.description = 'video QADU requests' | |
49 | } | |
50 | ||
51 | getRequestModel () { | |
52 | return db.RequestVideoQadu | |
53 | } | |
54 | ||
55 | getRequestToPodModel () { | |
56 | return db.RequestVideoQadu | |
57 | } | |
58 | ||
4771e000 C |
59 | buildRequestsObjects (requests: RequestsVideoQaduGrouped) { |
60 | const requestsToMakeGrouped: RequestsObjectsCustom<RemoteQaduVideoRequest> = {} | |
9e167724 C |
61 | |
62 | Object.keys(requests).forEach(toPodId => { | |
63 | requests[toPodId].forEach(data => { | |
64 | const request = data.request | |
65 | const video = data.video | |
66 | const pod = data.pod | |
67 | const hashKey = toPodId | |
68 | ||
69 | if (!requestsToMakeGrouped[hashKey]) { | |
70 | requestsToMakeGrouped[hashKey] = { | |
71 | toPod: pod, | |
65fcc311 | 72 | endpoint: REQUEST_VIDEO_QADU_ENDPOINT, |
9e167724 C |
73 | ids: [], // request ids, to delete them from the DB in the future |
74 | datas: [], // requests data | |
75 | videos: {} | |
76 | } | |
77 | } | |
78 | ||
d38b8281 C |
79 | // Maybe another attribute was filled for this video |
80 | let videoData = requestsToMakeGrouped[hashKey].videos[video.id] | |
0a6658fd | 81 | if (!videoData) videoData = { uuid: null } |
d38b8281 | 82 | |
9e167724 | 83 | switch (request.type) { |
65fcc311 | 84 | case REQUEST_VIDEO_QADU_TYPES.LIKES: |
9e167724 C |
85 | videoData.likes = video.likes |
86 | break | |
87 | ||
65fcc311 | 88 | case REQUEST_VIDEO_QADU_TYPES.DISLIKES: |
d38b8281 | 89 | videoData.dislikes = video.dislikes |
9e167724 C |
90 | break |
91 | ||
65fcc311 | 92 | case REQUEST_VIDEO_QADU_TYPES.VIEWS: |
9e167724 C |
93 | videoData.views = video.views |
94 | break | |
95 | ||
96 | default: | |
97 | logger.error('Unknown request video QADU type %s.', request.type) | |
98 | return | |
99 | } | |
100 | ||
0a6658fd C |
101 | // Do not forget the uuid so the remote pod can identify the video |
102 | videoData.uuid = video.uuid | |
9e167724 | 103 | requestsToMakeGrouped[hashKey].ids.push(request.id) |
f282639b C |
104 | |
105 | // Maybe there are multiple quick and dirty update for the same video | |
106 | // We use this hashmap to dedupe them | |
9e167724 C |
107 | requestsToMakeGrouped[hashKey].videos[video.id] = videoData |
108 | }) | |
109 | }) | |
110 | ||
f282639b | 111 | // Now we deduped similar quick and dirty updates, we can build our requests datas |
9e167724 | 112 | Object.keys(requestsToMakeGrouped).forEach(hashKey => { |
0a6658fd C |
113 | Object.keys(requestsToMakeGrouped[hashKey].videos).forEach(videoUUID => { |
114 | const videoData = requestsToMakeGrouped[hashKey].videos[videoUUID] | |
9e167724 C |
115 | |
116 | requestsToMakeGrouped[hashKey].datas.push({ | |
117 | data: videoData | |
118 | }) | |
119 | }) | |
120 | ||
121 | // We don't need it anymore, it was just to build our datas array | |
122 | delete requestsToMakeGrouped[hashKey].videos | |
123 | }) | |
124 | ||
125 | return requestsToMakeGrouped | |
126 | } | |
127 | ||
6fcd19ba | 128 | createRequest ({ type, videoId, transaction }: RequestVideoQaduSchedulerOptions) { |
69818c93 | 129 | const dbRequestOptions: Sequelize.BulkCreateOptions = {} |
9e167724 C |
130 | if (transaction) dbRequestOptions.transaction = transaction |
131 | ||
132 | // Send the update to all our friends | |
6fcd19ba | 133 | return db.Pod.listAllIds(transaction).then(podIds => { |
9e167724 C |
134 | const queries = [] |
135 | podIds.forEach(podId => { | |
136 | queries.push({ type, videoId, podId }) | |
137 | }) | |
138 | ||
6fcd19ba | 139 | return db.RequestVideoQadu.bulkCreate(queries, dbRequestOptions) |
9e167724 C |
140 | }) |
141 | } | |
142 | } | |
65fcc311 C |
143 | |
144 | // --------------------------------------------------------------------------- | |
145 | ||
146 | export { | |
147 | RequestVideoQaduScheduler | |
148 | } |