Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
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