summaryrefslogtreecommitdiffstats
path: root/BitTorrent/DownloaderFeedback.py
diff options
context:
space:
mode:
Diffstat (limited to 'BitTorrent/DownloaderFeedback.py')
-rw-r--r--BitTorrent/DownloaderFeedback.py139
1 files changed, 139 insertions, 0 deletions
diff --git a/BitTorrent/DownloaderFeedback.py b/BitTorrent/DownloaderFeedback.py
new file mode 100644
index 0000000..6c16c90
--- /dev/null
+++ b/BitTorrent/DownloaderFeedback.py
@@ -0,0 +1,139 @@
+# The contents of this file are subject to the BitTorrent Open Source License
+# Version 1.1 (the License). You may not copy or use this file, in either
+# source code or executable form, except in compliance with the License. You
+# may obtain a copy of the License at http://www.bittorrent.com/license/.
+#
+# Software distributed under the License is distributed on an AS IS basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+
+# Written by Bram Cohen, Uoti Urpala
+
+from __future__ import division
+
+
+class DownloaderFeedback(object):
+
+ def __init__(self, choker, upfunc, upfunc2, downfunc, uptotal, downtotal,
+ remainingfunc, leftfunc, file_length, finflag, downloader,
+ files, ever_got_incoming, rerequester):
+ self.downloader = downloader
+ self.picker = downloader.picker
+ self.storage = downloader.storage
+ self.choker = choker
+ self.upfunc = upfunc
+ self.upfunc2 = upfunc2
+ self.downfunc = downfunc
+ self.uptotal = uptotal
+ self.downtotal = downtotal
+ self.remainingfunc = remainingfunc
+ self.leftfunc = leftfunc
+ self.file_length = file_length
+ self.finflag = finflag
+ self.files = files
+ self.ever_got_incoming = ever_got_incoming
+ self.rerequester = rerequester
+ self.lastids = []
+
+ def _rotate(self):
+ cs = self.choker.connections
+ for peerid in self.lastids:
+ for i in xrange(len(cs)):
+ if cs[i].id == peerid:
+ return cs[i:] + cs[:i]
+ return cs
+
+ def collect_spew(self):
+ l = [ ]
+ cs = self._rotate()
+ self.lastids = [c.id for c in cs]
+ for c in cs:
+ rec = {}
+ rec['id'] = c.id
+ rec["ip"] = c.ip
+ rec["is_optimistic_unchoke"] = (c is self.choker.connections[0])
+ if c.locally_initiated:
+ rec["initiation"] = "L"
+ else:
+ rec["initiation"] = "R"
+ u = c.upload
+ rec["upload"] = (u.measure.get_total(), int(u.measure.get_rate()),
+ u.interested, u.choked)
+
+ d = c.download
+ rec["download"] = (d.measure.get_total(),int(d.measure.get_rate()),
+ d.interested, d.choked, d.is_snubbed())
+ rec['completed'] = 1 - d.have.numfalse / len(d.have)
+ rec['speed'] = d.connection.download.peermeasure.get_rate()
+ l.append(rec)
+ return l
+
+ def get_statistics(self, spewflag=False, fileflag=False):
+ status = {}
+ numSeeds = 0
+ numPeers = 0
+ for d in self.downloader.downloads:
+ if d.have.numfalse == 0:
+ numSeeds += 1
+ else:
+ numPeers += 1
+ status['numSeeds'] = numSeeds
+ status['numPeers'] = numPeers
+ status['trackerSeeds'] = self.rerequester.tracker_num_seeds
+ status['trackerPeers'] = self.rerequester.tracker_num_peers
+ status['upRate'] = self.upfunc()
+ status['upRate2'] = self.upfunc2()
+ status['upTotal'] = self.uptotal()
+ status['ever_got_incoming'] = self.ever_got_incoming()
+ missingPieces = 0
+ numCopyList = []
+ numCopies = 0
+ for i in self.picker.crosscount:
+ missingPieces += i
+ if missingPieces == 0:
+ numCopies += 1
+ else:
+ fraction = 1 - missingPieces / self.picker.numpieces
+ numCopyList.append(fraction)
+ if fraction == 0 or len(numCopyList) >= 3:
+ break
+ numCopies -= numSeeds
+ if self.picker.numgot == self.picker.numpieces:
+ numCopies -= 1
+ status['numCopies'] = numCopies
+ status['numCopyList'] = numCopyList
+ status['discarded'] = self.downloader.discarded_bytes
+ status['storage_numcomplete'] = self.storage.stat_numfound + \
+ self.storage.stat_numdownloaded
+ status['storage_dirty'] = len(self.storage.stat_dirty)
+ status['storage_active'] = len(self.storage.stat_active)
+ status['storage_new'] = len(self.storage.stat_new)
+ status['storage_numflunked'] = self.storage.stat_numflunked
+
+ if spewflag:
+ status['spew'] = self.collect_spew()
+ status['bad_peers'] = self.downloader.bad_peers
+ if fileflag:
+ undl = self.storage.storage.undownloaded
+ unal = self.storage.storage.unallocated
+ status['files_left'] = [undl[fname] for fname in self.files]
+ status['files_allocated'] = [not unal[fn] for fn in self.files]
+ if self.finflag.isSet():
+ status['downRate'] = 0
+ status['downTotal'] = self.downtotal()
+ status['fractionDone'] = 1
+ return status
+ timeEst = self.remainingfunc()
+ status['timeEst'] = timeEst
+
+ if self.file_length > 0:
+ fractionDone = 1 - self.leftfunc() / self.file_length
+ else:
+ fractionDone = 1
+ status.update({
+ "fractionDone" : fractionDone,
+ "downRate" : self.downfunc(),
+ "downTotal" : self.downtotal()
+ })
+ return status