]>
git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/friends.js
3 const async
= require('async')
4 const config
= require('config')
5 const fs
= require('fs')
6 const request
= require('request')
8 const constants
= require('../initializers/constants')
9 const logger
= require('../helpers/logger')
10 const peertubeCrypto
= require('../helpers/peertubeCrypto')
11 const Pods
= require('../models/pods')
12 const requestsScheduler
= require('../lib/requestsScheduler')
13 const requests
= require('../helpers/requests')
14 const videos
= require('../lib/videos')
15 const Videos
= require('../models/videos')
17 const http
= config
.get('webserver.https') ? 'https' : 'http'
18 const host
= config
.get('webserver.host')
19 const port
= config
.get('webserver.port')
22 addVideoToFriends: addVideoToFriends
,
23 hasFriends: hasFriends
,
24 getMyCertificate: getMyCertificate
,
25 makeFriends: makeFriends
,
26 quitFriends: quitFriends
,
27 removeVideoToFriends: removeVideoToFriends
30 function addVideoToFriends (video
) {
31 // To avoid duplicates
32 const id
= video
.name
+ video
.magnetUri
33 // ensure namePath is null
35 requestsScheduler
.addRequest(id
, 'add', video
)
38 function hasFriends (callback
) {
39 Pods
.count(function (err
, count
) {
40 if (err
) return callback(err
)
42 const hasFriends
= (count
!== 0)
43 callback(null, hasFriends
)
47 function getMyCertificate (callback
) {
48 fs
.readFile(peertubeCrypto
.getCertDir() + 'peertube.pub', 'utf8', callback
)
51 function makeFriends (callback
) {
54 logger
.info('Make friends!')
55 getMyCertificate(function (err
, cert
) {
57 logger
.error('Cannot read public cert.')
61 const urls
= config
.get('network.friends')
63 async
.each(urls
, function (url
, callbackEach
) {
64 computeForeignPodsList(url
, podsScore
, callbackEach
)
66 if (err
) return callback(err
)
68 logger
.debug('Pods scores computed.', { podsScore: podsScore
})
69 const podsList
= computeWinningPods(urls
, podsScore
)
70 logger
.debug('Pods that we keep.', { podsToKeep: podsList
})
72 makeRequestsToWinningPods(cert
, podsList
, callback
)
77 function quitFriends (callback
) {
79 requestsScheduler
.deactivate()
80 // Flush pool requests
81 requestsScheduler
.forceSend()
83 Pods
.list(function (err
, pods
) {
84 if (err
) return callback(err
)
88 path: '/api/' + constants
.API_VERSION
+ '/pods/remove',
92 url: 'me' // Fake data
96 // Announce we quit them
97 requests
.makeMultipleRetryRequest(request
, pods
, function () {
98 Pods
.removeAll(function (err
) {
99 requestsScheduler
.activate()
101 if (err
) return callback(err
)
103 logger
.info('Broke friends, so sad :(')
105 Videos
.listFromRemotes(function (err
, videosList
) {
106 if (err
) return callback(err
)
108 videos
.removeRemoteVideos(videosList
, function (err
) {
110 logger
.error('Cannot remove remote videos.', { error: err
})
114 logger
.info('Removed all remote videos.')
123 function removeVideoToFriends (video
) {
124 // To avoid duplicates
125 const id
= video
.name
+ video
.magnetUri
126 requestsScheduler
.addRequest(id
, 'remove', video
)
129 // ---------------------------------------------------------------------------
131 module
.exports
= pods
133 // ---------------------------------------------------------------------------
135 function computeForeignPodsList (url
, podsScore
, callback
) {
136 // Let's give 1 point to the pod we ask the friends list
139 getForeignPodsList(url
, function (err
, foreignPodsList
) {
140 if (err
) return callback(err
)
141 if (foreignPodsList
.length
=== 0) return callback()
143 foreignPodsList
.forEach(function (foreignPod
) {
144 const foreignUrl
= foreignPod
.url
146 if (podsScore
[foreignUrl
]) podsScore
[foreignUrl
]++
147 else podsScore
[foreignUrl
] = 1
154 function computeWinningPods (urls
, podsScore
) {
155 // Build the list of pods to add
156 // Only add a pod if it exists in more than a half base pods
158 const baseScore
= urls
.length
/ 2
159 Object
.keys(baseScore
).forEach(function (pod
) {
160 if (podsScore
[pod
] > baseScore
) podsList
.push({ url: pod
})
166 function getForeignPodsList (url
, callback
) {
167 const path
= '/api/' + constants
.API_VERSION
+ '/pods'
169 request
.get(url
+ path
, function (err
, response
, body
) {
170 if (err
) return callback(err
)
172 callback(null, JSON
.parse(body
))
176 function makeRequestsToWinningPods (cert
, podsList
, callback
) {
177 // Stop pool requests
178 requestsScheduler
.deactivate()
179 // Flush pool requests
180 requestsScheduler
.forceSend()
182 // Get the list of our videos to send to our new friends
183 Videos
.listOwned(function (err
, videosList
) {
185 logger
.error('Cannot get the list of videos we own.')
190 url: http
+ '://' + host
+ ':' + port
,
195 requests
.makeMultipleRetryRequest(
196 { method: 'POST', path: '/api/' + constants
.API_VERSION
+ '/pods/', data: data
},
200 function eachRequest (err
, response
, body
, url
, pod
, callbackEachRequest
) {
201 // We add the pod if it responded correctly with its public certificate
202 if (!err
&& response
.statusCode
=== 200) {
203 Pods
.add({ url: pod
.url
, publicKey: body
.cert
, score: constants
.FRIEND_BASE_SCORE
}, function (err
) {
205 logger
.error('Error with adding %s pod.', pod
.url
, { error: err
})
206 return callbackEachRequest()
209 videos
.createRemoteVideos(body
.videos
, function (err
) {
211 logger
.error('Error with adding videos of pod.', pod
.url
, { error: err
})
212 return callbackEachRequest()
215 logger
.debug('Adding remote videos from %s.', pod
.url
, { videos: body
.videos
})
216 return callbackEachRequest()
220 logger
.error('Error with adding %s pod.', pod
.url
, { error: err
|| new Error('Status not 200') })
221 return callbackEachRequest()
225 function endRequests (err
) {
226 // Now we made new friends, we can re activate the pool of requests
227 requestsScheduler
.activate()
230 logger
.error('There was some errors when we wanted to make friends.')
234 logger
.debug('makeRequestsToWinningPods finished.')
235 return callback(null)