[Debtorrent-commits] r75 - /debtorrent/branches/http-listen/DebTorrent/BT1/HTTPDownloader.py

camrdale-guest at users.alioth.debian.org camrdale-guest at users.alioth.debian.org
Fri Jun 1 02:07:41 UTC 2007


Author: camrdale-guest
Date: Fri Jun  1 02:07:36 2007
New Revision: 75

URL: http://svn.debian.org/wsvn/debtorrent/?sc=1&rev=75
Log:
Documented the HTTPDownloader before modifying it.

Modified:
    debtorrent/branches/http-listen/DebTorrent/BT1/HTTPDownloader.py

Modified: debtorrent/branches/http-listen/DebTorrent/BT1/HTTPDownloader.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/branches/http-listen/DebTorrent/BT1/HTTPDownloader.py?rev=75&op=diff
==============================================================================
--- debtorrent/branches/http-listen/DebTorrent/BT1/HTTPDownloader.py (original)
+++ debtorrent/branches/http-listen/DebTorrent/BT1/HTTPDownloader.py Fri Jun  1 02:07:36 2007
@@ -1,8 +1,20 @@
 # Written by John Hoffman
 # Modified by Cameron Dale
 # see LICENSE.txt for license information
-
+#
 # $Id$
+
+"""Manage downloading pieces over HTTP.
+
+ at type EXPIRE_TIME: C{int}
+ at var EXPIRE_TIME: number of seconds after which disconnected seeds are expired
+    (not used)
+ at type VERSION: C{string}
+ at var VERSION: the UserAgent identifier sent to all sites
+ at type haveall: L{haveComplete}
+ at var haveall: instance of the seed's bitfield
+
+"""
 
 from DebTorrent.CurrentRateMeasure import Measure
 from random import randint
@@ -22,14 +34,80 @@
 VERSION = product_name+'/'+version_short
 
 class haveComplete:
+    """Dummy class similar to L{Debtorrent.bitfield.Bitfield}.
+    
+    This class represents the HTTP seed's bitfield, which is always complete
+    and has every piece because it is a seed.
+    
+    """
     def complete(self):
+        """Dummy function to always return true."""
         return True
     def __getitem__(self, x):
+        """Dummy function to always return true."""
         return True
 haveall = haveComplete()
 
 class SingleDownload:
+    """Control HTTP downloads from a single site.
+    
+    @type downloader: L{HTTPDownloader}
+    @ivar downloader: the collection of all HTTP downloads
+    @type baseurl: C{string}
+    @ivar baseurl: the complete URL to append download info to
+    @type netloc: C{string}
+    @ivar netloc: the webserver address and port to connect to 
+        (from the L{baseurl}
+    @type connection: C{HTTPConnection}
+    @ivar connection: the connection to the HTTP server
+    @type seedurl: C{string}
+    @ivar seedurl: the path component from the L{baseurl}
+    @type measure: L{DebTorrent.CurrentRateMeasure.Measure}
+    @ivar measure: tracks the download rate from the site
+    @type index: C{int}
+    @ivar index: the piece index currently being downloaded
+    @type url: C{string}
+    @ivar url: the URL to request from the site
+    @type requests: C{list} of requests
+    @ivar requests: a list of the requests for a piece's ranges
+    @type request_size: C{int}
+    @ivar request_size: the total size of all requests
+    @type endflag: C{boolean}
+    @ivar endflag: unknown
+    @type error: C{string}
+    @ivar error: the error received from the server
+    @type retry_period: C{int}
+    @ivar retry_period: the time to wait before making another request
+    @type _retry_period: C{int}
+    @ivar _retry_period: the server-specified time to wait before making
+        another request
+    @type errorcount: C{int}
+    @ivar errorcount: the number of download errors that have occurred since
+        the last successful download from the site
+    @type goodseed: C{boolean}
+    @ivar goodseed: whether there has been a successful download from the seed
+    @type active: C{boolean}
+    @ivar active: whether there is a download underway
+    @type cancelled: C{boolean}
+    @ivar cancelled: whether the download has been cancelled
+    @type received_data: C{string}
+    @ivar received_data: the data returned from the most recent request
+    @type connection_status: C{int}
+    @ivar connection_status: the status code returned by the server for the 
+        most recent request
+    
+    """
+    
     def __init__(self, downloader, url):
+        """Initialize the instance.
+        
+        @type downloader: L{HTTPDownloader}
+        @param downloader: the collection of all HTTP downloads
+        @type url: C{string}
+        @param url: the base URL to append download info to
+        
+        """
+        
         self.downloader = downloader
         self.baseurl = url
         try:
@@ -69,6 +147,13 @@
         self.resched(randint(2,10))
 
     def resched(self, len = None):
+        """(Re)Schedule a download from the HTTP seed.
+        
+        @type len: C{int}
+        @param len: the amount of time to wait before doing the download (seconds)
+        
+        """
+        
         if len is None:
             len = self.retry_period
         if self.errorcount > 3:
@@ -76,12 +161,27 @@
         self.downloader.rawserver.add_task(self.download, len)
 
     def _want(self, index):
+        """Determine whether the piece is needed.
+        
+        @type index: C{int}
+        @param index: the piece index
+        @rtype: C{boolean}
+        @return: whether the piece is needed
+        
+        """
+        
         if self.endflag:
             return self.downloader.storage.do_I_have_requests(index)
         else:
             return self.downloader.storage.is_unstarted(index)
 
     def download(self):
+        """Start a request for a piece.
+        
+        Finds a new piece to download from the picker, creates the URL for the
+        request, and then starts the request.
+        
+        """
         self.cancelled = False
         if self.downloader.picker.am_I_complete():
             self.downloader.downloads.remove(self)
@@ -105,6 +205,12 @@
             self.active = True
 
     def _request(self):
+        """Do the request.
+        
+        Send the request to the server and wait for the response. Then 
+        process the response and save the result.
+        
+        """
         import encodings.ascii
         import encodings.punycode
         import encodings.idna
@@ -130,6 +236,7 @@
         self.downloader.rawserver.add_task(self.request_finished)
 
     def request_finished(self):
+        """Process the completed request and schedule another."""
         self.active = False
         if self.error is not None:
             if self.goodseed:
@@ -149,6 +256,16 @@
         self.resched()
 
     def _got_data(self):
+        """Process the returned data from the request.
+        
+        Update the rate measures, pass the data to the storage, mark the piece
+        as complete.
+        
+        @rtype: C[boolean}
+        @return: whether the data was good
+        
+        """
+        
         if self.connection_status == 503:   # seed is busy
             try:
                 self.retry_period = max(int(self.received_data),5)
@@ -179,6 +296,7 @@
         return True
     
     def _get_requests(self):
+        """Get the requests for a piece."""
         self.requests = []
         self.request_size = 0L
         while self.downloader.storage.do_I_have_requests(self.index):
@@ -188,6 +306,13 @@
         self.requests.sort()
 
     def _fulfill_requests(self):
+        """Pass the downloaded data to the storage.
+        
+        @rtype: C{boolean}
+        @return: whether the piece was successfully received (hash checked)
+        
+        """
+        
         start = 0L
         success = True
         while self.requests:
@@ -200,11 +325,19 @@
         return success
 
     def _release_requests(self):
+        """Release any pending requests for piece ranges."""
         for begin, length in self.requests:
             self.downloader.storage.request_lost(self.index, begin, length)
         self.requests = []
 
     def _request_ranges(self):
+        """Build a list of ranges to request from the site.
+        
+        @rtype: C{string}
+        @return: the comma separated ranges to request
+        
+        """
+        
         s = ''
         begin, length = self.requests[0]
         for begin1, length1 in self.requests[1:]:
@@ -223,9 +356,67 @@
         
     
 class HTTPDownloader:
+    """Collection of all the HTTP downloads.
+    
+    @type storage: L{StorageWrapper.StorageWrapper}
+    @ivar storage: the piece storage instance
+    @type picker: L{PiecePicker.PiecePicker}
+    @ivar picker: the piece choosing instance
+    @type rawserver: L{Debtorrent.RawServer.RawServer}
+    @ivar rawserver: the server
+    @type finflag: C{Threading.Event}
+    @ivar finflag: the flag indicating when the download is complete
+    @type errorfunc: C{method}
+    @ivar errorfunc: the method to call when an error occurs
+    @type peerdownloader: L{Downloader.Downloader}
+    @ivar peerdownloader: the instance of the collection of normal downloaders
+    @type infohash: C{string}
+    @ivar infohash: the info hash
+    @type max_rate_period: C{float}
+    @ivar max_rate_period: maximum amount of time to guess the current 
+            rate estimate represents
+    @type gotpiecefunc: C{method}
+    @ivar gotpiecefunc: the method to call when a piece comes in
+    @type measurefunc: C{method}
+    @ivar measurefunc: the method to call to add downloaded data to the total
+        download rate measurement
+    @type downloads: C{list} of L{SingleDownload}
+    @ivar downloads: the list of all current download connections to sites
+    @type seedsfound: C{int}
+    @ivar seedsfound: the number of seeds successfully downloaded from
+    
+    """
+    
     def __init__(self, storage, picker, rawserver,
                  finflag, errorfunc, peerdownloader,
                  max_rate_period, infohash, measurefunc, gotpiecefunc):
+        """Initialize the instance.
+        
+        @type storage: L{StorageWrapper.StorageWrapper}
+        @param storage: the piece storage instance
+        @type picker: L{PiecePicker.PiecePicker}
+        @param picker: the piece choosing instance
+        @type rawserver: L{Debtorrent.RawServer.RawServer}
+        @param rawserver: the server
+        @type finflag: C{Threading.Event}
+        @param finflag: the flag indicating when the download is complete
+        @type errorfunc: C{method}
+        @param errorfunc: the method to call when an error occurs
+        @type peerdownloader: L{Downloader.Downloader}
+        @param peerdownloader: the instance of the collection of normal downloaders
+        @type max_rate_period: C{float}
+        @param max_rate_period: maximum amount of time to guess the current 
+            rate estimate represents
+        @type infohash: C{string}
+        @param infohash: the info hash
+        @type measurefunc: C{method}
+        @param measurefunc: the method to call to add downloaded data to the total
+            download rate measurement
+        @type gotpiecefunc: C{method}
+        @param gotpiecefunc: the method to call when a piece comes in
+        
+        """
+        
         self.storage = storage
         self.picker = picker
         self.rawserver = rawserver
@@ -240,15 +431,38 @@
         self.seedsfound = 0
 
     def make_download(self, url):
+        """Create a new download from a site.
+        
+        @type url: C{string}
+        @param url: the base URL to use for downloading from that site
+        @rtype: L{SingleDownload}
+        @return: the SingleDownload instance created
+        
+        """
+        
         self.downloads.append(SingleDownload(self, url))
         return self.downloads[-1]
 
     def get_downloads(self):
+        """Get the list of all current downloads.
+        
+        @rtype: C{list} of L{SingleDownload}
+        @return: all current downloads from sites
+        
+        """
+        
         if self.finflag.isSet():
             return []
         return self.downloads
 
     def cancel_piece_download(self, pieces):
+        """Cancel any active downloads for the pieces.
+        
+        @type pieces: C{list} of C{int}
+        @param pieces: the list of pieces to cancel downloads of
+        
+        """
+        
         for d in self.downloads:
             if d.active and d.index in pieces:
                 d.cancelled = True




More information about the Debtorrent-commits mailing list