def get_deferred_host_ip(): global _host_ip global _host_ip_callbacks global _host_ip_cachetime if hasattr(reactor, 'ident'): assert reactor.ident == thread.get_ident() if _host_ip is not 'unknown' and _host_ip_cachetime + CACHE_TIME > bttime(): return defer.succeed(_host_ip) if get_route_ip: ip = get_route_ip() if ip: _host_ip = ip _host_ip_cachetime = bttime() return defer.succeed(_host_ip) df = defer.Deferred() if not _host_ip_callbacks: def connect(ip): factory = RecorderFactory() factory.protocol = RecorderProtocol if hasattr(reactor, 'limiter'): reactor.connectTCP(ip, 80, factory, urgent=True) else: reactor.connectTCP(ip, 80, factory) rdf = reactor.resolve("ip.bittorrent.com") rdf.addCallback(connect) rdf.addErrback(lambda e : _got_result(None)) _host_ip_callbacks.append(df) return df
def __init__(self, max_rate_period, fudge=5): self.max_rate_period = max_rate_period self.ratesince = bttime() - fudge self.last = self.ratesince self.rate = 0.0 self.total = 0 self.when_next_expected = bttime() + fudge
def get_host_ip(): """ Blocking version, do not use from reactor thread! """ global _host_ip global _host_ip_callbacks global _host_ip_cachetime if hasattr(reactor, 'ident'): assert reactor.ident != thread.get_ident() if _host_ip is not 'unknown' and _host_ip_cachetime + CACHE_TIME > bttime(): return _host_ip if get_route_ip: ip = get_route_ip() if ip: _host_ip = ip _host_ip_cachetime = bttime() return _host_ip try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) # what moron decided to make try/except/finally not work? # Guido van Rossum. try: s.connect(("ip.bittorrent.com", 80)) endpoint = s.getsockname() _host_ip = endpoint[0] _host_ip_cachetime = bttime() s.send("GET /myip HTTP/1.0\r\n\r\n") except (socket.error, socket.timeout), e: try: _host_ip = socket.gethostbyname(socket.gethostname()) except socket.error, e: pass
def data_came_in(self, amount): if not self.got_anything: self.got_anything = True self.start = bttime() - 2 self.last = self.start self.left -= amount return self.update(bttime(), amount)
def add_amount(self, amount): """ add number of bytes received """ if not self.got_anything: self.got_anything = True self.start = bttime() - 2 self.last = self.start self.left -= amount return self.update(bttime(), amount)
def recv_datagram(self, buf): current_time = bttime() icmp = buf[20:] # removes IP header. Assumes IPv4. blech. type = ord(icmp[0]) if type == ICMP_TTL_EXPIRED: type = IP_TTL_EXPIRED_TRANSIT # type (1 byte), code (1 byte), chksum (2 bytes) # unused(4 bytes) # original internet header (20) # first 8 bytes of original ICMP (type,code,chksum,id,seq) icmp = icmp[4+4+20:] # strips outer header. elif type == ICMP_ECHO_REPLY: pass else: return # ignore other ICMP messages # parse ICMP echo reply (orig_type,code,chksum,id,seqno) = \ struct.unpack("!BBHHH",icmp[0:8]) # find appropriate deferred. If found then remove it from dfs. df = self._find_and_remove(id,seqno) # callback the appropriate deferred after adjusting to millisecs. if df is not None: rtt = current_time - df.timestamp rtt *= 1000 if debug: print "Reply from %s: id=%s, seqno=%u, time=%.3f ms" %\ (addr[0], id, seqno, rtt) df.callback( (addr[0], type, rtt) )
def send_echo_request(self, id, addr, ttl, timeout): self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl) if not self.files.has_key(id): raise Fault(8002, "asked to send ICMP echo request for id not open.") file = self.files[id] type = ICMP_ECHO_REQUEST buf = struct.pack("!BBHHH", ICMP_ECHO_REQUEST, 0x00, 0x0000, id, file.seqno ) sum = self._calc_checksum(buf) buf = struct.pack("!BBHHH", ICMP_ECHO_REQUEST, 0x00, sum, id, file.seqno ) df = Deferred() df.seqno = file.seqno file.seqno += 1 df.id = id if not self.dfs.has_key(df.id): self.dfs[df.id] = [df] else: self.dfs[df.id].append(df) # deferreds for this id. df.timestamp = bttime() self.sock.sendto(buf, (addr,22)) reactor.callLater( timeout, self._handle_timeout, df.id, df.seqno ) return df
def _postrequest(self, data=None, failure=None): #self.errorfunc(logging.INFO, 'postrequest(%s): %s d:%s f:%s' % # (self.__class__.__name__, self.current_started, # bool(data), bool(failure))) self.current_started = None self.last_time = bttime() if self.dead: return if failure is not None: if failure.type == twisted.internet.error.TimeoutError: m = _("Timeout while contacting server.") else: m = failure.getErrorMessage() self.errorfunc(logging.WARNING, self._make_errormsg(m)) self._fail(failure.exc_info()) return try: r = bdecode(data) if LOG_RESPONSE: self.errorfunc(logging.INFO, 'tracker said: %r' % r) check_peers(r) except BTFailure, e: if data: self.errorfunc(logging.ERROR, _("bad data from tracker (%r)") % data, exc_info=sys.exc_info()) self._fail() return
def recv_datagram(self, buf): current_time = bttime() icmp = buf[20:] # removes IP header. Assumes IPv4. blech. type = ord(icmp[0]) if type == ICMP_TTL_EXPIRED: type = IP_TTL_EXPIRED_TRANSIT # type (1 byte), code (1 byte), chksum (2 bytes) # unused(4 bytes) # original internet header (20) # first 8 bytes of original ICMP (type,code,chksum,id,seq) icmp = icmp[4 + 4 + 20:] # strips outer header. elif type == ICMP_ECHO_REPLY: pass else: return # ignore other ICMP messages # parse ICMP echo reply (orig_type,code,chksum,id,seqno) = \ struct.unpack("!BBHHH",icmp[0:8]) # find appropriate deferred. If found then remove it from dfs. df = self._find_and_remove(id, seqno) # callback the appropriate deferred after adjusting to millisecs. if df is not None: rtt = current_time - df.timestamp rtt *= 1000 if debug: print "Reply from %s: id=%s, seqno=%u, time=%.3f ms" %\ (addr[0], id, seqno, rtt) df.callback((addr[0], type, rtt))
def send_echo_request(self, id, addr, ttl, timeout): self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl) if not self.files.has_key(id): raise Fault(8002, "asked to send ICMP echo request for id not open.") file = self.files[id] type = ICMP_ECHO_REQUEST buf = struct.pack("!BBHHH", ICMP_ECHO_REQUEST, 0x00, 0x0000, id, file.seqno) sum = self._calc_checksum(buf) buf = struct.pack("!BBHHH", ICMP_ECHO_REQUEST, 0x00, sum, id, file.seqno) df = Deferred() df.seqno = file.seqno file.seqno += 1 df.id = id if not self.dfs.has_key(df.id): self.dfs[df.id] = [df] else: self.dfs[df.id].append(df) # deferreds for this id. df.timestamp = bttime() self.sock.sendto(buf, (addr, 22)) reactor.callLater(timeout, self._handle_timeout, df.id, df.seqno) return df
def get_time_left(self): if not self.got_anything: return None t = bttime() if t - self.last > 15: self.update(t, 0) return self.remaining
def _dump_torrents(self): assert self.resume_from_torrent_config self.last_save_time = bttime() r = [] def write_entry(infohash, t): r.append(' '.join( (infohash.encode('hex'), str(t.uptotal), str(t.downtotal)))) r.append('BitTorrent UI state file, version 5') r.append('Queued torrents') for t in self.torrents.values(): write_entry(t.metainfo.infohash, self.torrents[t.metainfo.infohash]) r.append('End') f = None try: path = os.path.join(self.data_dir, 'ui_state') f = file(path + '.new', 'wb') f.write('\n'.join(r) + '\n') f.close() shutil.move(path + '.new', path) except Exception, e: self.logger.error(_("Could not save UI state: ") + str_exc(e)) if f is not None: f.close()
def time_until_rate(self, newrate): if self.rate <= newrate: return 0 t = bttime() - self.ratesince # as long as the newrate is lower than rate, we wait # longer before throttling. return ((self.rate * t) / newrate) - t
def got_piece(self, index, begin, piece): req = (index, begin, len(piece)) if req not in self.active_requests: self.multidownload.discarded_bytes += len(piece) if self.connection.uses_fast_extension: self.connection.close() return self.active_requests.remove(req) # we still give the peer credit in endgame, since we did request # the piece (it was in active_requests) self.fire_useful_received_listeners(len(piece)) if self.multidownload.storage.endgame: if req not in self.multidownload.all_requests: self.multidownload.discarded_bytes += len(piece) return self.multidownload.all_requests.remove(req) for d in self.multidownload.downloads: if d.interested: if not d.choked and req in d.active_requests: d.connection.send_cancel(*req) if not self.connection.uses_fast_extension: d.active_requests.remove(req) d.fix_download_endgame() else: self._request_more() self.last = bttime() df = self.multidownload.storage.write(index, begin, piece, self.guard) df.addCallback(self._got_piece, index)
def _got_result(ip): global _host_ip global _host_ip_callbacks global _host_ip_cachetime global _thread_running if hasattr(reactor, 'ident'): assert reactor.ident == thread.get_ident() if _thread_running: return if ip is None: t = threading.Thread(target=_resolve) t.setDaemon(True) _thread_running = True t.start() return if ip is not 'unknown': _host_ip = ip _host_ip_cachetime = bttime() l = _host_ip_callbacks _host_ip_callbacks = [] for df in l: df.callback(_host_ip)
def print_rate(self, size): self.total += size this_time = bttime() start_delta = this_time - self.start_time this_delta = this_time - self.last_time if start_delta > 0 and this_delta > 0: print "UPLOAD: This:", size / this_delta, "Total:", self.total / start_delta self.last_time = this_time
def update_rate(self, amount): self.total += amount t = bttime() if t < self.when_next_expected and amount == 0: return self.rate self.rate = (self.rate * (self.last - self.ratesince) + amount) / (t - self.ratesince) self.last = t self.ratesince = max(self.ratesince, t - self.max_rate_period) self.when_next_expected = t + min((amount / max(self.rate, 0.0001)), 5)
def __init__(self, left): self.start = None self.last = None self.rate = 0 self.remaining = None self.left = left self.broke = False self.got_anything = False self.when_next_expected = bttime() + 5
def _affect_rate(self, type, std, max_std, rate, set): rate = self._method_stddev(type, std, max_std, rate) rock_bottom = False if rate <= 4096: if debug: print "Rock bottom" rock_bottom = True rate = 4096 set(int(rate)) if stats: print "BandwidthManager._affect_rate(%f)" % rate self.rfp.write("%d %d" % (bttime(), int(rate))) self.sdevfp.write("%d %f" % (bttime(), std)) return rock_bottom
def _affect_rate(self, type, std, max_std, rate, set): rate = self._method_stddev(type, std, max_std, rate) rock_bottom = False if rate <= 4096: if debug: print "Rock bottom" rock_bottom = True rate = 4096 set(int(rate)) if stats: print "BandwidthManager._affect_rate(%f)" % rate self.rfp.write( "%d %d" % (bttime(),int(rate)) ) self.sdevfp.write( "%d %f" % (bttime(), std ) ) return rock_bottom
def __init__(self, *args, **kwargs): self.resolution = 1000 self.grouped = DictWithLists() self.missing_known = False self.last_time = bttime() self.last_update = -1 SimpleDownloadGauge.__init__(self, *args, **kwargs) self.transfering_color = self.gauge_theme["transferring color"] self.missing_color = self.gauge_theme["missing color"] self.SetValue(None, redraw=False)
def _check(self): assert not self.dead #self.errorfunc(logging.INFO, 'check: ' + str(self.current_started)) if self.current_started is not None: if (bttime() - self.current_started) >= 58: self.errorfunc( logging.WARNING, _("Tracker announce still not complete " "%d seconds after starting it") % int(bttime() - self.current_started)) return if self.peerid is None: self.peerid = self.wanted_peerid self.url = self._makeurl(self.peerid, self.port) self._announce('started') return if self.peerid != self.wanted_peerid: # _announce will clean up these up = self.up down = self.down self._announce('stopped') self.peerid = None self.previous_up = up() self.previous_down = down() return '''download finished''' if self.finish: self.finish = False self._announce('completed') return if self.fail_wait is not None: if self.last_time + self.fail_wait <= bttime(): self._announce() return if self.last_time > bttime() - self.config['rerequest_interval']: return if self.ever_got_incoming(): getmore = self.howmany() <= self.config['min_peers'] / 3 else: getmore = self.howmany() < self.config['min_peers'] if getmore or bttime() - self.last_time > self.announce_interval: self._announce()
def add_amount(self, amount): """ add number of bytes received """ self.total += amount t = bttime() if t < self.when_next_expected and amount == 0: return self.rate self.rate = (self.rate * (self.last - self.ratesince) + amount) / (t - self.ratesince) self.last = t self.ratesince = max(self.ratesince, t - self.max_rate_period) self.when_next_expected = t + min((amount / max(self.rate, 0.0001)), 5)
def _announce(self, event=None): assert not self.dead self.current_started = bttime() self.errorfunc(logging.INFO, 'announce: ' + str(bttime() - self.current_started)) s = ('%s&uploaded=%s&downloaded=%s&left=%s' % (self.url, str(self.up()*self.config.get('lie',1) - self.previous_up), str(self.down() - self.previous_down), str(self.amount_left()))) if self.last is not None: s += '&last=' + quote(str(self.last)) if self.trackerid is not None: s += '&trackerid=' + quote(str(self.trackerid)) if self.howmany() >= self.config['max_initiate']: s += '&numwant=0' else: s += '&compact=1' if event is not None: s += '&event=' + event self._rerequest(s)
def __call__(self): new_time = bttime() delta_time = new_time - self.last_time # if last time was more than a second ago, we can't give a clear # approximation since rate is in tokens per second. delta_time = min(delta_time, 1.0) if delta_time <= 0: return 0 tokens = self.rate * delta_time self.last_time = new_time return tokens
def get_deferred_host_ips(): global _host_ips global _host_ips_cachetime assert reactor.ident == thread.get_ident() if _host_ips is not None and _host_ips_cachetime + CACHE_TIME > bttime(): return defer.succeed(_host_ips) df = get_deferred_host_ip() finaldf = defer.Deferred() df.addCallback(_get_deferred_host_ips2, finaldf) return finaldf
def _check(self): assert not self.dead #self.errorfunc(logging.INFO, 'check: ' + str(self.current_started)) if self.current_started is not None: if (bttime() - self.current_started) >= 58: self.errorfunc(logging.WARNING, _("Tracker announce still not complete " "%d seconds after starting it") % int(bttime() - self.current_started)) return if self.peerid is None: self.peerid = self.wanted_peerid self.url = self._makeurl(self.peerid, self.port) self._announce('started') return if self.peerid != self.wanted_peerid: # _announce will clean up these up = self.up down = self.down self._announce('stopped') self.peerid = None self.previous_up = up() self.previous_down = down() return if self.finish: self.finish = False self._announce('completed') return if self.fail_wait is not None: if self.last_time + self.fail_wait <= bttime(): self._announce() return if self.last_time > bttime() - self.config['rerequest_interval']: return if self.ever_got_incoming(): getmore = self.howmany() <= self.config['min_peers'] / 3 else: getmore = self.howmany() < self.config['min_peers'] if getmore or bttime() - self.last_time > self.announce_interval: self._announce()
def get_deferred_host_ips(): global _host_ips global _host_ips_cachetime if hasattr(reactor, 'ident'): assert reactor.ident == thread.get_ident() if _host_ips is not None and _host_ips_cachetime + CACHE_TIME > bttime(): return defer.succeed(_host_ips) df = get_deferred_host_ip() finaldf = defer.Deferred() df.addCallback(_get_deferred_host_ips2, finaldf) return finaldf
def connection_made(self, s): set_timeout_metrics(bttime() - self.start) addr = (s.ip, s.port) #print 'connection made', addr del self.parent.pending_connections[addr] con = self._make_connector(s) self.parent._add_connection(con) # if the pending queue filled and put the remaining connections # into the spare list, this will push more connections in to pending self.parent.replace_connection()
def send_message(self, message): if message not in self.messages.keys(): #print 'bad message', message return new_state = self.messages[message] if self.transitions.has_key(self.mystate): if self.transitions[self.mystate].has_key(message): new_state = self.transitions[self.mystate][message] # special pre-natted timeout logic if new_state == 'pre-natted': if (self.mystate == 'pre-natted' and bttime() - self.start_time > self.time_to_nat): # go to natted state after a while new_state = 'natted' elif self.mystate != 'pre-natted': # start pre-natted timer self.start_time = bttime() if new_state != self.mystate: #print 'changing state from', self.mystate, 'to', new_state self.mystate = new_state self.change_state()
def get_deferred_host_ip(): global _host_ip global _host_ip_callbacks global _host_ip_cachetime if hasattr(reactor, 'ident'): assert reactor.ident == thread.get_ident() if _host_ip is not 'unknown' and _host_ip_cachetime + CACHE_TIME > bttime( ): return defer.succeed(_host_ip) if get_route_ip: ip = get_route_ip() if ip: _host_ip = ip _host_ip_cachetime = bttime() return defer.succeed(_host_ip) df = defer.Deferred() if not _host_ip_callbacks: def connect(ip): factory = RecorderFactory() factory.protocol = RecorderProtocol if hasattr(reactor, 'limiter'): reactor.connectTCP(ip, 80, factory, urgent=True) else: reactor.connectTCP(ip, 80, factory) rdf = reactor.resolve("ip.bittorrent.com") rdf.addCallback(connect) rdf.addErrback(lambda e: _got_result(None)) _host_ip_callbacks.append(df) return df
def SetValue(self, percent, state=None, data=None, redraw=True): # only draw if progress moved .01% or it's been REFRESH_MAX_SEC seconds if self.percent != None: if (percent < (self.percent + 0.0001) and bttime() < (self.last_time + REFRESH_MAX_SEC)): return self.last_time = bttime() if not redraw: return p_dirty = False if self.percent != percent: p_dirty = True self.percent = percent missing_known = state == "running" if self.missing_known != missing_known: p_dirty = True self.missing_known = missing_known if not data: # no data. allow future SetValues to continue passing # until we get something self.last_time = 0 - REFRESH_MAX_SEC # draw an empty bar data = (0, -1, {}) length, update, piece_states = data self.resolution = length if p_dirty or update != self.last_update: self.grouped = piece_states self.redraw() self.last_update = update
def SetValue(self, percent, state = None, data = None, redraw=True): # only draw if progress moved .01% or it's been REFRESH_MAX_SEC seconds if self.percent != None: if (percent < (self.percent + 0.0001) and bttime() < (self.last_time + REFRESH_MAX_SEC)): return self.last_time = bttime() if not redraw: return p_dirty = False if self.percent != percent: p_dirty = True self.percent = percent missing_known = state == "running" if self.missing_known != missing_known: p_dirty = True self.missing_known = missing_known if not data: # no data. allow future SetValues to continue passing # until we get something self.last_time = 0 - REFRESH_MAX_SEC # draw an empty bar data = (0, -1, {}) length, update, piece_states = data self.resolution = length if p_dirty or update != self.last_update: self.grouped = piece_states self.redraw() self.last_update = update
def get_host_ip(): """ Blocking version, do not use from reactor thread! """ global _host_ip global _host_ip_callbacks global _host_ip_cachetime if hasattr(reactor, 'ident'): assert reactor.ident != thread.get_ident() if _host_ip is not 'unknown' and _host_ip_cachetime + CACHE_TIME > bttime( ): return _host_ip if get_route_ip: ip = get_route_ip() if ip: _host_ip = ip _host_ip_cachetime = bttime() return _host_ip try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) # what moron decided to make try/except/finally not work? # Guido van Rossum. try: s.connect(("ip.bittorrent.com", 80)) endpoint = s.getsockname() _host_ip = endpoint[0] _host_ip_cachetime = bttime() s.send("GET /myip HTTP/1.0\r\n\r\n") except (socket.error, socket.timeout), e: try: _host_ip = socket.gethostbyname(socket.gethostname()) except socket.error, e: pass
def __init__(self, config): self.started = 0 self.multitorrent = None self.config = config self.torrents = {} self.external_torrents = [] self.installer_to_launch_at_exit = None self.logger = logging.getLogger("UI") self.logger.setLevel(logging.INFO) self.next_autoupdate_nag = bttime() def gui_wrap(_f, *args, **kwargs): f(*args, **kwargs) self.gui_wrap = gui_wrap self.open_external_torrents_deferred = None
def __init__(self, config): self.started = 0 self.multitorrent = None self.config = config self.torrents = {} self.external_torrents = [] self.installer_to_launch_at_exit = None self.logger = logging.getLogger('UI') self.logger.setLevel(logging.INFO) self.next_autoupdate_nag = bttime() def gui_wrap(_f, *args, **kwargs): f(*args, **kwargs) self.gui_wrap = gui_wrap self.open_external_torrents_deferred = None
def connection_made(self, s): t = bttime() - self.start set_timeout_metrics(t) addr = (s.ip, s.port) if debug: self.parent.logger.warning('connection made: %s %s' % (addr, t)) del self.parent.pending_connections[addr] self._abort_timeout() con = self._make_connector(s) self.parent._add_connection(con) # if the pending queue filled and put the remaining connections # into the spare list, this will push more connections in to pending self.parent.replace_connection()
def connection_made(self, s): t = bttime() - self.start set_timeout_metrics(t) addr = (s.ip, s.port) if debug: self.parent.logger.warning("connection made: %s %s" % (addr, t)) del self.parent.pending_connections[addr] self._abort_timeout() con = self._make_connector(s) self.parent._add_connection(con) # if the pending queue filled and put the remaining connections # into the spare list, this will push more connections in to pending self.parent.replace_connection()
def _announce(self, event=None, request_key_hash_list=None): print "announce" assert not self.dead self.current_started = bttime() #self.errorfunc(logging.INFO, 'announce: ' + # str(bttime() - self.current_started)) s1 = '%s&' % (self.url) query_string_of_url = s1[s1.index("?") + 1:] #only the query string is signed in case of micropayments, not the url s2 = ('uploaded=%s&downloaded=%s&left=%s' % (str(self.up() * self.config.get('lie', 1) - self.previous_up), str(self.down() - self.previous_down), str(self.amount_left()))) if self.last is not None: s2 += '&last=' + quote(str(self.last)) if self.trackerid is not None: s2 += '&trackerid=' + quote(str(self.trackerid)) if self.howmany() >= self.config['max_initiate']: s2 += '&numwant=0' else: s2 += '&compact=1' if event is not None: s2 += '&event=' + event if self.micropayments: s2 += '&cn=' + quote( self.pk_tools.get_common_name_from_cert(self.certificate)) if request_key_hash_list is not None and self.micropayments: print("announce request keyhahslist: %s", quote(str(request_key_hash_list))) s2 += '&requestkeyhashlist=' + quote( str(request_key_hash_list )) #actually a peer id of whom to request the hash_list if ((event is not None and event == "started") or request_key_hash_list is not None) and self.micropayments: print "first part of url: %s" % s1 print "querystring to sign: %s%s" % (query_string_of_url, s2) s2 += '&sig=' + quote( str( self.pk_tools.get_sha_signature_tls( self.private_key, query_string_of_url + s2))) self._rerequest(s1 + s2)
def _announce(self, event=None): assert not self.dead self.current_started = bttime() #self.errorfunc(logging.INFO, 'announce: ' + # str(bttime() - self.current_started)) s = ('%s&uploaded=%s&downloaded=%s&left=%s' % (self.url, str(self.up() * self.config.get('lie', 1) - self.previous_up), str(self.down() - self.previous_down), str(self.amount_left()))) if self.last is not None: s += '&last=' + quote(str(self.last)) if self.trackerid is not None: s += '&trackerid=' + quote(str(self.trackerid)) if self.howmany() >= self.config['max_initiate']: s += '&numwant=0' else: s += '&compact=1' if event is not None: s += '&event=' + event self._rerequest(s)
def got_piece(self, index, begin, piece): req = (index, begin, len(piece)) if req not in self.active_requests: self.multidownload.discarded_bytes += len(piece) if self.connector.uses_fast_extension: # getting a piece we sent a cancel for # is just like receiving a reject self.got_reject_request(*req) return self.active_requests.remove(req) # we still give the peer credit in endgame, since we did request # the piece (it was in active_requests) self.fire_useful_received_listeners(len(piece)) if self.multidownload.rm.endgame: if req not in self.multidownload.all_requests: self.multidownload.discarded_bytes += len(piece) return self.multidownload.all_requests.remove(req) for d in self.multidownload.downloads: if d.interested: if not d.choked and req in d.active_requests: d.connector.send_cancel(*req) d.active_requests.remove(req) if d.connector.uses_fast_extension: d.expecting_reject.add(req) d.fix_download_endgame() else: self._request_more() self.last = bttime() df = self.multidownload.storage.write(index, begin, piece, self.guard) df.addCallback(self._got_piece, index) df.addErrback(self.multidownload.errorfunc)
def _dump_torrents(self): assert self.resume_from_torrent_config self.last_save_time = bttime() r = [] def write_entry(infohash, t): r.append(' '.join((infohash.encode('hex'), str(t.uptotal), str(t.downtotal)))) r.append('BitTorrent UI state file, version 5') r.append('Queued torrents') for t in self.torrents.values(): write_entry(t.metainfo.infohash, self.torrents[t.metainfo.infohash]) r.append('End') f = None try: path = os.path.join(self.data_dir, 'ui_state') f = file(path+'.new', 'wb') f.write('\n'.join(r) + '\n') f.close() shutil.move(path+'.new', path) except Exception, e: self.logger.error(_("Could not save UI state: ") + str_exc(e)) if f is not None: f.close()
def get_remaining_time(self): return max(0, self.last_time - bttime())
def set_rate(self, rate): self.rate = rate # clear the history since the rate has changed and it could be way off self.last_time = bttime()