36 |
kaklik |
1 |
# Written by Edward Keyes
|
|
|
2 |
# see LICENSE.txt for license information
|
|
|
3 |
|
|
|
4 |
from threading import Event
|
|
|
5 |
try:
|
|
|
6 |
True
|
|
|
7 |
except:
|
|
|
8 |
True = 1
|
|
|
9 |
False = 0
|
|
|
10 |
|
|
|
11 |
class Statistics_Response:
|
|
|
12 |
pass # empty class
|
|
|
13 |
|
|
|
14 |
|
|
|
15 |
class Statistics:
|
|
|
16 |
def __init__(self, upmeasure, downmeasure, connecter, httpdl,
|
|
|
17 |
ratelimiter, rerequest_lastfailed, fdatflag):
|
|
|
18 |
self.upmeasure = upmeasure
|
|
|
19 |
self.downmeasure = downmeasure
|
|
|
20 |
self.connecter = connecter
|
|
|
21 |
self.httpdl = httpdl
|
|
|
22 |
self.ratelimiter = ratelimiter
|
|
|
23 |
self.downloader = connecter.downloader
|
|
|
24 |
self.picker = connecter.downloader.picker
|
|
|
25 |
self.storage = connecter.downloader.storage
|
|
|
26 |
self.torrentmeasure = connecter.downloader.totalmeasure
|
|
|
27 |
self.rerequest_lastfailed = rerequest_lastfailed
|
|
|
28 |
self.fdatflag = fdatflag
|
|
|
29 |
self.fdatactive = False
|
|
|
30 |
self.piecescomplete = None
|
|
|
31 |
self.placesopen = None
|
|
|
32 |
self.storage_totalpieces = len(self.storage.hashes)
|
|
|
33 |
|
|
|
34 |
|
|
|
35 |
def set_dirstats(self, files, piece_length):
|
|
|
36 |
self.piecescomplete = 0
|
|
|
37 |
self.placesopen = 0
|
|
|
38 |
self.filelistupdated = Event()
|
|
|
39 |
self.filelistupdated.set()
|
|
|
40 |
frange = xrange(len(files))
|
|
|
41 |
self.filepieces = [[] for x in frange]
|
|
|
42 |
self.filepieces2 = [[] for x in frange]
|
|
|
43 |
self.fileamtdone = [0.0 for x in frange]
|
|
|
44 |
self.filecomplete = [False for x in frange]
|
|
|
45 |
self.fileinplace = [False for x in frange]
|
|
|
46 |
start = 0L
|
|
|
47 |
for i in frange:
|
|
|
48 |
l = files[i][1]
|
|
|
49 |
if l == 0:
|
|
|
50 |
self.fileamtdone[i] = 1.0
|
|
|
51 |
self.filecomplete[i] = True
|
|
|
52 |
self.fileinplace[i] = True
|
|
|
53 |
else:
|
|
|
54 |
fp = self.filepieces[i]
|
|
|
55 |
fp2 = self.filepieces2[i]
|
|
|
56 |
for piece in range(int(start/piece_length),
|
|
|
57 |
int((start+l-1)/piece_length)+1):
|
|
|
58 |
fp.append(piece)
|
|
|
59 |
fp2.append(piece)
|
|
|
60 |
start += l
|
|
|
61 |
|
|
|
62 |
|
|
|
63 |
def update(self):
|
|
|
64 |
s = Statistics_Response()
|
|
|
65 |
s.upTotal = self.upmeasure.get_total()
|
|
|
66 |
s.downTotal = self.downmeasure.get_total()
|
|
|
67 |
s.last_failed = self.rerequest_lastfailed()
|
|
|
68 |
s.external_connection_made = self.connecter.external_connection_made
|
|
|
69 |
if s.downTotal > 0:
|
|
|
70 |
s.shareRating = float(s.upTotal)/s.downTotal
|
|
|
71 |
elif s.upTotal == 0:
|
|
|
72 |
s.shareRating = 0.0
|
|
|
73 |
else:
|
|
|
74 |
s.shareRating = -1.0
|
|
|
75 |
s.torrentRate = self.torrentmeasure.get_rate()
|
|
|
76 |
s.torrentTotal = self.torrentmeasure.get_total()
|
|
|
77 |
s.numSeeds = self.picker.seeds_connected
|
|
|
78 |
s.numOldSeeds = self.downloader.num_disconnected_seeds()
|
|
|
79 |
s.numPeers = len(self.downloader.downloads)-s.numSeeds
|
|
|
80 |
s.numCopies = 0.0
|
|
|
81 |
for i in self.picker.crosscount:
|
|
|
82 |
if i==0:
|
|
|
83 |
s.numCopies+=1
|
|
|
84 |
else:
|
|
|
85 |
s.numCopies+=1-float(i)/self.picker.numpieces
|
|
|
86 |
break
|
|
|
87 |
if self.picker.done:
|
|
|
88 |
s.numCopies2 = s.numCopies + 1
|
|
|
89 |
else:
|
|
|
90 |
s.numCopies2 = 0.0
|
|
|
91 |
for i in self.picker.crosscount2:
|
|
|
92 |
if i==0:
|
|
|
93 |
s.numCopies2+=1
|
|
|
94 |
else:
|
|
|
95 |
s.numCopies2+=1-float(i)/self.picker.numpieces
|
|
|
96 |
break
|
|
|
97 |
s.discarded = self.downloader.discarded
|
|
|
98 |
s.numSeeds += self.httpdl.seedsfound
|
|
|
99 |
s.numOldSeeds += self.httpdl.seedsfound
|
|
|
100 |
if s.numPeers == 0 or self.picker.numpieces == 0:
|
|
|
101 |
s.percentDone = 0.0
|
|
|
102 |
else:
|
|
|
103 |
s.percentDone = 100.0*(float(self.picker.totalcount)/self.picker.numpieces)/s.numPeers
|
|
|
104 |
|
|
|
105 |
s.backgroundallocating = self.storage.bgalloc_active
|
|
|
106 |
s.storage_totalpieces = len(self.storage.hashes)
|
|
|
107 |
s.storage_active = len(self.storage.stat_active)
|
|
|
108 |
s.storage_new = len(self.storage.stat_new)
|
|
|
109 |
s.storage_dirty = len(self.storage.dirty)
|
|
|
110 |
numdownloaded = self.storage.stat_numdownloaded
|
|
|
111 |
s.storage_justdownloaded = numdownloaded
|
|
|
112 |
s.storage_numcomplete = self.storage.stat_numfound + numdownloaded
|
|
|
113 |
s.storage_numflunked = self.storage.stat_numflunked
|
|
|
114 |
s.storage_isendgame = self.downloader.endgamemode
|
|
|
115 |
|
|
|
116 |
s.peers_kicked = self.downloader.kicked.items()
|
|
|
117 |
s.peers_banned = self.downloader.banned.items()
|
|
|
118 |
|
|
|
119 |
try:
|
|
|
120 |
s.upRate = int(self.ratelimiter.upload_rate/1000)
|
|
|
121 |
assert s.upRate < 5000
|
|
|
122 |
except:
|
|
|
123 |
s.upRate = 0
|
|
|
124 |
s.upSlots = self.ratelimiter.slots
|
|
|
125 |
|
|
|
126 |
if self.piecescomplete is None: # not a multi-file torrent
|
|
|
127 |
return s
|
|
|
128 |
|
|
|
129 |
if self.fdatflag.isSet():
|
|
|
130 |
if not self.fdatactive:
|
|
|
131 |
self.fdatactive = True
|
|
|
132 |
else:
|
|
|
133 |
self.fdatactive = False
|
|
|
134 |
|
|
|
135 |
if self.piecescomplete != self.picker.numgot:
|
|
|
136 |
for i in xrange(len(self.filecomplete)):
|
|
|
137 |
if self.filecomplete[i]:
|
|
|
138 |
continue
|
|
|
139 |
oldlist = self.filepieces[i]
|
|
|
140 |
newlist = [ piece
|
|
|
141 |
for piece in oldlist
|
|
|
142 |
if not self.storage.have[piece] ]
|
|
|
143 |
if len(newlist) != len(oldlist):
|
|
|
144 |
self.filepieces[i] = newlist
|
|
|
145 |
self.fileamtdone[i] = (
|
|
|
146 |
(len(self.filepieces2[i])-len(newlist))
|
|
|
147 |
/float(len(self.filepieces2[i])) )
|
|
|
148 |
if not newlist:
|
|
|
149 |
self.filecomplete[i] = True
|
|
|
150 |
self.filelistupdated.set()
|
|
|
151 |
|
|
|
152 |
self.piecescomplete = self.picker.numgot
|
|
|
153 |
|
|
|
154 |
if ( self.filelistupdated.isSet()
|
|
|
155 |
or self.placesopen != len(self.storage.places) ):
|
|
|
156 |
for i in xrange(len(self.filecomplete)):
|
|
|
157 |
if not self.filecomplete[i] or self.fileinplace[i]:
|
|
|
158 |
continue
|
|
|
159 |
while self.filepieces2[i]:
|
|
|
160 |
piece = self.filepieces2[i][-1]
|
|
|
161 |
if self.storage.places[piece] != piece:
|
|
|
162 |
break
|
|
|
163 |
del self.filepieces2[i][-1]
|
|
|
164 |
if not self.filepieces2[i]:
|
|
|
165 |
self.fileinplace[i] = True
|
|
|
166 |
self.storage.set_file_readonly(i)
|
|
|
167 |
self.filelistupdated.set()
|
|
|
168 |
|
|
|
169 |
self.placesopen = len(self.storage.places)
|
|
|
170 |
|
|
|
171 |
s.fileamtdone = self.fileamtdone
|
|
|
172 |
s.filecomplete = self.filecomplete
|
|
|
173 |
s.fileinplace = self.fileinplace
|
|
|
174 |
s.filelistupdated = self.filelistupdated
|
|
|
175 |
|
|
|
176 |
return s
|
|
|
177 |
|