1+ const peerid = require ( 'bittorrent-peerid' )
2+
13const attachHttpServer = require ( './attachHttp' )
24
35const get8Chars =
46 peerId => Buffer . from ( peerId , "hex" )
57 . toString ( )
68 . substring ( 0 , 8 )
79
8- function addPeerClient ( _client , peer ) {
10+ function addPeerClient ( _clients , peer ) {
911 const clientId = peer . client . client ;
1012 const client = _clients [ clientId ] || { } ;
1113 // If the client is not known show 8 chars from peerId as version
@@ -48,52 +50,75 @@ function printClients(clients) {
4850 return html + "</ul>" ;
4951}
5052
51- function addPeerId ( allPeers , peerId ) {
52- // Don't mark the peer as most recently used for stats
53- const peer = peers . peek ( peerId ) ;
53+ const countPeers =
54+ allPeers =>
55+ filterFunction => {
56+ let count = 0
57+ let key
5458
55- if ( peer == null ) return ; // peers.peek() can evict the peer
59+ for ( key in allPeers ) {
60+ if ( hasOwnProperty . call ( allPeers , key ) && filterFunction ( allPeers [ key ] ) ) {
61+ count ++
62+ } 0
63+ }
5664
57- allPeers [ peerId ] = {
58- ipv6 : peer . ip . includes ( ":" ) ,
59- ipv4 : ! peer . ip . includes ( ":" ) ,
60- seeder : peer . completee ,
61- leecher : ! peer . complete ,
62- peerId : peer . peerId ,
63- client : peerid ( peer . peerId ) ,
64- } ;
65+ return count
66+ }
6567
66- return allPeers
67- }
68+ const addPeer =
69+ peers =>
70+ ( allPeers , peerId ) => {
71+ // Don't mark the peer as most recently used for stats
72+ const peer = peers . peek ( peerId )
6873
69- function addTorrentStats ( allPeers , torrent ) {
70- const keys = torrent . peers . keys ;
74+ if ( peer == null ) return // peers.peek() can evict the peer
7175
72- const result = keys . reduce ( addPeerId , allPeers )
76+ allPeers [ peerId ] = {
77+ ipv4 : false ,
78+ ipv6 : false ,
79+ seeder : false ,
80+ leecher : false
81+ }
7382
74- return result
83+ if ( peer . ip . includes ( ':' ) ) allPeers [ peerId ] . ipv6 = true
84+ if ( ! peer . ip . includes ( ':' ) ) allPeers [ peerId ] . ipv4 = true
85+
86+ if ( peer . complete ) allPeers [ peerId ] . seeder = true
87+ if ( ! peer . complete ) allPeers [ peerId ] . leecher = true
88+
89+ allPeers [ peerId ] . peerId = peer . peerId
90+ allPeers [ peerId ] . client = peerid ( peer . peerId )
91+
92+ return allPeers
93+ }
94+
95+ const countActiveTorrents = torrents => {
96+ const hasKeys = ( torrent ) => ( torrent . peers . keys . length > 0 )
97+
98+ const activeTorrents = torrents . filter ( hasKeys , 0 )
99+ return activeTorrents . length
75100}
76101
102+ const addTorrentKeys = ( allPeers , torrent ) => {
103+ const peers = torrent . peers
104+ const keys = peers . keys
77105
78- const countPeersF =
79- peers =>
80- filterFunction =>
81- Object . values ( peers ) . filter ( filterFunction ) . length
106+ const result = keys . reduce ( addPeer ( peers ) , allPeers )
82107
83- const isActive = torrent => ( torrent . peers . keys . length > 0 )
84- const countActive = torrents => torrents . filter ( isActive ) . length
85- const isSeederOnly = peer => ( peer . seeder && peer . leecher === false ) ;
86- const isLeecherOnly = peer => ( peer . leecher && peer . seeder === false ) ;
87- const isSeederAndLeecher = peer => ( peer . seeder && peer . leecher ) ;
88- const isIPv4 = peer => peer . ipv4 ;
89- const isIPv6 = peer => peer . ipv6 ;
108+ return result
109+ }
90110
91- function getStats ( server ) {
92- const torrents = Object . values ( server . torrents ) ;
93- const allPeers = torrents . reduce ( addTorrentStats , { } )
111+ const getTheStats = server => {
112+ const torrents = Object . values ( server . torrents )
113+ const allPeers = torrents . reduce ( addTorrentKeys , { } )
94114
95- const countAllPeers = countPeersF ( allPeers ) ;
96- const activeTorrents = countActive ( torrents ) ;
115+ const activeTorrents = countActiveTorrents ( Object . values ( server . torrents ) )
116+ const isSeederOnly = peer => ( peer . seeder && peer . leecher === false )
117+ const isLeecherOnly = peer => ( peer . leecher && peer . seeder === false )
118+ const isSeederAndLeecher = peer => ( peer . seeder && peer . leecher )
119+ const isIPv4 = peer => peer . ipv4
120+ const isIPv6 = peer => peer . ipv6
121+ const countAllPeers = countPeers ( allPeers )
97122
98123 const stats = {
99124 torrents : torrents . length ,
@@ -104,34 +129,28 @@ function getStats(server) {
104129 peersSeederAndLeecher : countAllPeers ( isSeederAndLeecher ) ,
105130 peersIPv4 : countAllPeers ( isIPv4 ) ,
106131 peersIPv6 : countAllPeers ( isIPv6 ) ,
107- clients : groupByClient ( allPeers ) ,
108- } ;
132+ clients : groupByClient ( allPeers )
133+ }
109134
110- return stats ;
135+ return stats
111136}
112137
113- function setupStatsRoute ( server ) {
114- if ( ! server . http ) attachHttpServer ( server ) ;
115-
116- // Http handler for '/stats' route
117- server . http . on ( "request" , ( req , res ) => {
118- if ( res . headersSent ) return ;
138+ function setupStatsRoute ( server , onListening ) {
139+ if ( ! server . http ) attachHttpServer ( server , onListening ) ;
140+ // Http handler for '/stats' route
141+ server . http . on ( 'request' , ( req , res ) => {
142+ if ( res . headersSent ) return
119143
120- const stats = getStats ( server ) ;
144+ if ( req . method === 'GET' && ( req . url === '/stats' || req . url === '/stats.json' ) ) {
145+ const stats = getTheStats ( server )
121146
122- if (
123- req . url === "/stats.json" ||
124- req . headers . accept === "application/json"
125- ) {
126- res . setHeader ( "Content-Type" , "application/json" ) ;
127- res . end ( JSON . stringify ( stats ) ) ;
128- }
129- else if ( req . url === "/stats" ) {
130- const stats = getStats ( server ) ;
147+ if ( req . url === '/stats.json' || req . headers . accept === 'application/json' ) {
131148
132- res . setHeader ( "Content-Type" , "text/html" ) ;
133- res . end (
134- `
149+ res . setHeader ( 'Content-Type' , 'application/json' )
150+ res . end ( JSON . stringify ( stats ) )
151+ } else if ( req . url === '/stats' ) {
152+ res . setHeader ( 'Content-Type' , 'text/html' )
153+ res . end ( `
135154 <h1>${ stats . torrents } torrents (${ stats . activeTorrents } active)</h1>
136155 <h2>Connected Peers: ${ stats . peersAll } </h2>
137156 <h3>Peers Seeding Only: ${ stats . peersSeederOnly } </h3>
@@ -141,10 +160,10 @@ function setupStatsRoute(server) {
141160 <h3>IPv6 Peers: ${ stats . peersIPv6 } </h3>
142161 <h3>Clients:</h3>
143162 ${ printClients ( stats . clients ) }
144- ` . replace ( / ^ \s + / gm, "" )
145- ) ; // trim left
163+ ` . replace ( / ^ \s + / gm, '' ) ) // trim left
164+ }
146165 }
147- } ) ;
166+ } )
148167}
149168
150169module . exports = setupStatsRoute
0 commit comments