4 var async
= require('async')
5 var config
= require('config')
7 var request
= require('request')
9 var logger
= require('./logger')
10 var PodsDB
= require('./database').PodsDB
11 var utils
= require('./utils')
15 var http
= config
.get('webserver.https') ? 'https' : 'http'
16 var host
= config
.get('webserver.host')
17 var port
= config
.get('webserver.port')
19 // ----------- Constants -----------
26 // ----------- Private functions -----------
28 function getForeignPodsList (url
, callback
) {
29 var path
= '/api/' + global
.API_VERSION
+ '/pods'
31 request
.get(url
+ path
, function (err
, response
, body
) {
33 callback(JSON
.parse(body
))
37 function updatePodsScore (good_pods
, bad_pods
) {
38 logger
.info('Updating %d good pods and %d bad pods scores.', good_pods
.length
, bad_pods
.length
)
40 PodsDB
.update({ _id: { $in: good_pods
} }, { $inc: { score: PODS_SCORE
.BONUS
} }, { multi: true }).exec()
41 PodsDB
.update({ _id: { $in: bad_pods
} }, { $inc: { score: PODS_SCORE
.MALUS
} }, { multi: true }, function (err
) {
47 function removeBadPods () {
48 PodsDB
.remove({ score: 0 }, function (err
, result
) {
51 var number_removed
= result
.result
.n
52 if (number_removed
!== 0) logger
.info('Removed %d pod.', number_removed
)
56 // ----------- Public functions -----------
58 pods
.list = function (callback
) {
59 PodsDB
.find(function (err
, pods_list
) {
61 logger
.error('Cannot get the list of the pods.', { error: err
})
65 return callback(null, pods_list
)
70 pods
.add = function (data
, callback
) {
71 logger
.info('Adding pod: %s', data
.url
)
75 publicKey: data
.publicKey
,
76 score: global
.FRIEND_BASE_SCORE
79 PodsDB
.create(params
, function (err
, pod
) {
81 logger
.error('Cannot insert the pod.', { error: err
})
85 fs
.readFile(utils
.certDir
+ 'peertube.pub', 'utf8', function (err
, cert
) {
87 logger
.error('Cannot read cert file.', { error: err
})
91 return callback(null, { cert: cert
})
97 pods
.makeSecureRequest = function (data
, callback
) {
98 if (callback
=== undefined) callback = function () {}
100 PodsDB
.find({}, { _id: 1, url: 1, publicKey: 1 }).exec(function (err
, pods
) {
102 logger
.error('Cannot get the list of the pods.', { error: err
})
106 logger
.debug('Make multiple requests.')
119 utils
.makeMultipleRetryRequest(
124 function callbackEachPodFinished (err
, response
, body
, pod
, callback_each_pod_finished
) {
125 if (err
|| response
.statusCode
!== 200) {
126 bad_pods
.push(pod
._id
)
127 logger
.error('Error sending secure request to %s/%s pod.', pod
.url
, data
.path
, { error: err
})
129 good_pods
.push(pod
._id
)
132 return callback_each_pod_finished()
135 function callbackAllPodsFinished (err
) {
137 logger
.error('There was some errors when sending the video meta data.', { error: err
})
141 logger
.debug('Finished')
143 updatePodsScore(good_pods
, bad_pods
)
150 pods
.makeFriends = function (callback
) {
153 logger
.info('Make friends!')
154 fs
.readFile(utils
.certDir
+ 'peertube.pub', 'utf8', function (err
, cert
) {
156 logger
.error('Cannot read public cert.', { error: err
})
160 var urls
= config
.get('network.friends')
162 async
.each(urls
, computeForeignPodsList
, function () {
163 logger
.debug('Pods scores computed.', { pods_score: pods_score
})
164 var pods_list
= computeWinningPods(urls
, pods_score
)
165 logger
.debug('Pods that we keep computed.', { pods_to_keep: pods_list
})
167 logger
.debug('Make requests...')
168 makeRequestsToWinningPods(cert
, pods_list
)
172 // -----------------------------------------------------------------------
174 function computeForeignPodsList (url
, callback
) {
175 // Let's give 1 point to the pod we ask the friends list
178 getForeignPodsList(url
, function (foreign_pods_list
) {
179 if (foreign_pods_list
.length
=== 0) return callback()
181 async
.each(foreign_pods_list
, function (foreign_pod
, callback_each
) {
182 var foreign_url
= foreign_pod
.url
184 if (pods_score
[foreign_url
]) pods_score
[foreign_url
]++
185 else pods_score
[foreign_url
] = 1
194 function computeWinningPods (urls
, pods_score
) {
195 // Build the list of pods to add
196 // Only add a pod if it exists in more than a half base pods
198 var base_score
= urls
.length
/ 2
199 Object
.keys(pods_score
).forEach(function (pod
) {
200 if (pods_score
[pod
] > base_score
) pods_list
.push({ url: pod
})
206 function makeRequestsToWinningPods (cert
, pods_list
) {
208 url: http
+ '://' + host
+ ':' + port
,
212 utils
.makeMultipleRetryRequest(
213 { method: 'POST', path: '/api/' + global
.API_VERSION
+ '/pods/', data: data
},
217 function eachRequest (err
, response
, body
, pod
, callback_each_request
) {
218 // We add the pod if it responded correctly with its public certificate
219 if (!err
&& response
.statusCode
=== 200) {
220 pods
.add({ url: pod
.url
, publicKey: body
.cert
, score: global
.FRIEND_BASE_SCORE
}, function (err
) {
222 logger
.error('Error with adding %s pod.', pod
.url
, { error: err
})
225 return callback_each_request()
228 logger
.error('Error with adding %s pod.', pod
.url
, { error: err
|| new Error('Status not 200') })
229 return callback_each_request()
233 function endRequests (err
) {
235 logger
.error('There was some errors when we wanted to make friends.', { error: err
})
239 logger
.debug('makeRequestsToWinningPods finished.')
240 return callback(null)
246 module
.exports
= pods