-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
96 lines (82 loc) · 2.29 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module.exports = TorrentLocation
var EventEmitter = require('events').EventEmitter
var rTorrent = require('./lib/parse_torrent')
var inherits = require('inherits')
var UdpTracker = require('bittorrent-udp-tracker')
var iplocation = require('iplocation')
inherits(TorrentLocation, EventEmitter)
/*
TODO:
1. test cases (done)
2. readme
*/
function TorrentLocation (filePath, peerId) {
var self = this
EventEmitter.call(self)
self.filePath = filePath
self.peerId = peerId || '01234567890123456789'
self.udpTrackers = []
self.stop = function () {
self.udpTrackers.forEach(function (tracker) {
if (tracker.destory) {
tracker.destory()
}
tracker.removeListener('error', onUdpTrackerError)
tracker.removeListener('update', onUdpTrackerUpdate)
})
self.removeAllListeners('error')
self.removeAllListeners('update')
}
function onUdpTrackerError (msg) {
this.removeListener('error', onUdpTrackerError)
this.removeListener('update', onUdpTrackerUpdate)
handleError.bind(self, msg)()
}
function onUdpTrackerUpdate (update) {
handleUpdate.bind(self, update)()
}
rTorrent(self.filePath, function (err, parseTorrent) {
if (err) {
self.emit('error', err.message)
self.stop()
return
}
self.infoHash = parseTorrent['infoHash']
self.announceUrl = parseTorrent['announce']
for (var i = 0; i < self.announceUrl.length; i++) {
var url = self.announceUrl[i]
if (isUDP(url)) {
var udpTracker = new UdpTracker(self.peerId, self.infoHash, url)
udpTracker.on('error', onUdpTrackerError)
udpTracker.on('update', onUdpTrackerUpdate)
udpTracker.announce(2, {})
self.udpTrackers.push(udpTracker)
}
}
})
}
function isUDP (url) {
return url.trim().indexOf('udp://') === 0
}
function handleError (msg) {
var self = this
self.emit('error', msg)
}
function handleUpdate (data) {
var self = this
data.peers = data.peers || []
if (!Array.isArray(data.peers)) {
data.peers = [data.peers]
}
data.peers.forEach(function (ip) {
iplocation(ip.split(':')[0], handleIpLocationResponse.bind(self))
})
}
function handleIpLocationResponse (err, res) {
var self = this
if (err) {
self.emit('error', err.toString())
} else {
self.emit('update', res)
}
}