Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
36 kaklik 1
# Written by Bram Cohen
2
# see LICENSE.txt for license information
3
 
4
from cStringIO import StringIO
5
from urllib import quote
6
from threading import Event
7
 
8
try:
9
    True
10
except:
11
    True = 1
12
    False = 0
13
 
14
class DownloaderFeedback:
15
    def __init__(self, choker, httpdl, add_task, upfunc, downfunc,
16
            ratemeasure, leftfunc, file_length, finflag, sp, statistics,
17
            statusfunc = None, interval = None):
18
        self.choker = choker
19
        self.httpdl = httpdl
20
        self.add_task = add_task
21
        self.upfunc = upfunc
22
        self.downfunc = downfunc
23
        self.ratemeasure = ratemeasure
24
        self.leftfunc = leftfunc
25
        self.file_length = file_length
26
        self.finflag = finflag
27
        self.sp = sp
28
        self.statistics = statistics
29
        self.lastids = []
30
        self.spewdata = None
31
        self.doneprocessing = Event()
32
        self.doneprocessing.set()
33
        if statusfunc:
34
            self.autodisplay(statusfunc, interval)
35
 
36
 
37
    def _rotate(self):
38
        cs = self.choker.connections
39
        for id in self.lastids:
40
            for i in xrange(len(cs)):
41
                if cs[i].get_id() == id:
42
                    return cs[i:] + cs[:i]
43
        return cs
44
 
45
    def spews(self):
46
        l = []
47
        cs = self._rotate()
48
        self.lastids = [c.get_id() for c in cs]
49
        for c in cs:
50
            a = {}
51
            a['id'] = c.get_readable_id()
52
            a['ip'] = c.get_ip()
53
            a['optimistic'] = (c is self.choker.connections[0])
54
            if c.is_locally_initiated():
55
                a['direction'] = 'L'
56
            else:
57
                a['direction'] = 'R'
58
            u = c.get_upload()
59
            a['uprate'] = int(u.measure.get_rate())
60
            a['uinterested'] = u.is_interested()
61
            a['uchoked'] = u.is_choked()
62
            d = c.get_download()
63
            a['downrate'] = int(d.measure.get_rate())
64
            a['dinterested'] = d.is_interested()
65
            a['dchoked'] = d.is_choked()
66
            a['snubbed'] = d.is_snubbed()
67
            a['utotal'] = d.connection.upload.measure.get_total()
68
            a['dtotal'] = d.connection.download.measure.get_total()
69
            if len(d.connection.download.have) > 0:
70
                a['completed'] = float(len(d.connection.download.have)-d.connection.download.have.numfalse)/float(len(d.connection.download.have))
71
            else:
72
                a['completed'] = 1.0
73
            a['speed'] = d.connection.download.peermeasure.get_rate()
74
 
75
            l.append(a)                                               
76
 
77
        for dl in self.httpdl.get_downloads():
78
            if dl.goodseed:
79
                a = {}
80
                a['id'] = 'http seed'
81
                a['ip'] = dl.baseurl
82
                a['optimistic'] = False
83
                a['direction'] = 'L'
84
                a['uprate'] = 0
85
                a['uinterested'] = False
86
                a['uchoked'] = False
87
                a['downrate'] = int(dl.measure.get_rate())
88
                a['dinterested'] = True
89
                a['dchoked'] = not dl.active
90
                a['snubbed'] = not dl.active
91
                a['utotal'] = None
92
                a['dtotal'] = dl.measure.get_total()
93
                a['completed'] = 1.0
94
                a['speed'] = None
95
 
96
                l.append(a)
97
 
98
        return l
99
 
100
 
101
    def gather(self, displayfunc = None):
102
        s = {'stats': self.statistics.update()}
103
        if self.sp.isSet():
104
            s['spew'] = self.spews()
105
        else:
106
            s['spew'] = None
107
        s['up'] = self.upfunc()
108
        if self.finflag.isSet():
109
            s['done'] = self.file_length
110
            return s
111
        s['down'] = self.downfunc()
112
        obtained, desired = self.leftfunc()
113
        s['done'] = obtained
114
        s['wanted'] = desired
115
        if desired > 0:
116
            s['frac'] = float(obtained)/desired
117
        else:
118
            s['frac'] = 1.0
119
        if desired == obtained:
120
            s['time'] = 0
121
        else:
122
            s['time'] = self.ratemeasure.get_time_left(desired-obtained)
123
        return s        
124
 
125
 
126
    def display(self, displayfunc):
127
        if not self.doneprocessing.isSet():
128
            return
129
        self.doneprocessing.clear()
130
        stats = self.gather()
131
        if self.finflag.isSet():
132
            displayfunc(dpflag = self.doneprocessing,
133
                upRate = stats['up'],
134
                statistics = stats['stats'], spew = stats['spew'])
135
        elif stats['time'] is not None:
136
            displayfunc(dpflag = self.doneprocessing,
137
                fractionDone = stats['frac'], sizeDone = stats['done'],
138
                downRate = stats['down'], upRate = stats['up'],
139
                statistics = stats['stats'], spew = stats['spew'],
140
                timeEst = stats['time'])
141
        else:
142
            displayfunc(dpflag = self.doneprocessing,
143
                fractionDone = stats['frac'], sizeDone = stats['done'],
144
                downRate = stats['down'], upRate = stats['up'],
145
                statistics = stats['stats'], spew = stats['spew'])
146
 
147
 
148
    def autodisplay(self, displayfunc, interval):
149
        self.displayfunc = displayfunc
150
        self.interval = interval
151
        self._autodisplay()
152
 
153
    def _autodisplay(self):
154
        self.add_task(self._autodisplay, self.interval)
155
        self.display(self.displayfunc)