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