home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / BitTorrent / download.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  11.3 KB  |  300 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. from zurllib import urlopen
  5. from urlparse import urljoin
  6. from btformats import check_message
  7. from Choker import Choker
  8. from Storage import Storage
  9. from StorageWrapper import StorageWrapper
  10. from Uploader import Upload
  11. from Downloader import Downloader
  12. from Connecter import Connecter
  13. from Encrypter import Encoder
  14. from RawServer import RawServer
  15. from Rerequester import Rerequester
  16. from DownloaderFeedback import DownloaderFeedback
  17. from RateMeasure import RateMeasure
  18. from CurrentRateMeasure import Measure
  19. from PiecePicker import PiecePicker
  20. from bencode import bencode, bdecode
  21. from __init__ import version
  22. from binascii import b2a_hex
  23. from sha import sha
  24. from os import path, makedirs
  25. from parseargs import parseargs, formatDefinitions
  26. from socket import error as socketerror
  27. from random import seed
  28. from threading import Thread, Event
  29. from time import time
  30.  
  31. try:
  32.     from os import getpid
  33. except ImportError:
  34.     
  35.     def getpid():
  36.         return 1
  37.  
  38.  
  39. defaults = [
  40.     ('max_uploads', 7, 'the maximum number of uploads to allow at once.'),
  41.     ('keepalive_interval', 120.0, 'number of seconds to pause between sending keepalives'),
  42.     ('download_slice_size', 2 ** 14, 'How many bytes to query for per request.'),
  43.     ('request_backlog', 5, 'how many requests to keep in a single pipe at once.'),
  44.     ('max_message_length', 2 ** 23, "maximum length prefix encoding you'll accept over the wire - larger values get the connection dropped."),
  45.     ('ip', '', 'ip to report you have to the tracker.'),
  46.     ('minport', 6881, 'minimum port to listen on, counts up if unavailable'),
  47.     ('maxport', 6999, 'maximum port to listen on'),
  48.     ('responsefile', '', 'file the server response was stored in, alternative to url'),
  49.     ('url', '', 'url to get file from, alternative to responsefile'),
  50.     ('saveas', '', 'local file name to save the file as, null indicates query user'),
  51.     ('timeout', 300.0, 'time to wait between closing sockets which nothing has been received on'),
  52.     ('timeout_check_interval', 60.0, 'time to wait between checking if any connections have timed out'),
  53.     ('max_slice_length', 2 ** 17, 'maximum length slice to send to peers, larger requests are ignored'),
  54.     ('max_rate_period', 20.0, 'maximum amount of time to guess the current rate estimate represents'),
  55.     ('bind', '', 'ip to bind to locally'),
  56.     ('upload_rate_fudge', 5.0, 'time equivalent of writing to kernel-level TCP buffer, for rate adjustment'),
  57.     ('display_interval', 0.5, 'time between updates of displayed information'),
  58.     ('rerequest_interval', 5 * 60, 'time to wait between requesting more peers'),
  59.     ('min_peers', 20, 'minimum number of peers to not do rerequesting'),
  60.     ('http_timeout', 60, 'number of seconds to wait before assuming that an http connection has timed out'),
  61.     ('max_initiate', 35, 'number of peers at which to stop initiating new connections'),
  62.     ('max_allow_in', 55, 'maximum number of connections to allow, after this new incoming connections will be immediately closed'),
  63.     ('check_hashes', 1, 'whether to check hashes on disk'),
  64.     ('max_upload_rate', 0, 'maximum kB/s to upload at, 0 means no limit'),
  65.     ('snub_time', 30.0, "seconds to wait for data to come in over a connection before assuming it's semi-permanently choked"),
  66.     ('spew', 0, 'whether to display diagnostic info to stdout'),
  67.     ('rarest_first_cutoff', 4, 'number of downloads at which to switch from random to rarest first'),
  68.     ('min_uploads', 4, 'the number of uploads to fill out to with extra optimistic unchokes'),
  69.     ('report_hash_failures', 0, "whether to inform the user that hash failures occur. They're non-fatal.")]
  70.  
  71. def download(params, filefunc, statusfunc, finfunc, errorfunc, doneflag, cols, pathFunc = None, paramfunc = None, spewflag = Event()):
  72.     if len(params) == 0:
  73.         errorfunc('arguments are -\n' + formatDefinitions(defaults, cols))
  74.         return None
  75.     
  76.     
  77.     try:
  78.         (config, args) = parseargs(params, defaults, 0, 1)
  79.         if args:
  80.             if config.get('responsefile', None) == None:
  81.                 raise ValueError, 'must have responsefile as arg or parameter, not both'
  82.             
  83.             if path.isfile(args[0]):
  84.                 config['responsefile'] = args[0]
  85.             else:
  86.                 config['url'] = args[0]
  87.         
  88.         if config['responsefile'] == '' == config['url'] == '':
  89.             raise ValueError, 'need responsefile or url'
  90.     except ValueError:
  91.         e = None
  92.         errorfunc('error: ' + str(e) + '\nrun with no args for parameter explanations')
  93.         return None
  94.  
  95.     
  96.     try:
  97.         if config['responsefile'] != '':
  98.             h = open(config['responsefile'], 'rb')
  99.         else:
  100.             h = urlopen(config['url'])
  101.         response = h.read()
  102.         h.close()
  103.     except IOError:
  104.         e = None
  105.         if config['responsefile'] != '' and config['responsefile'].find('Temporary Internet Files') != -1:
  106.             errorfunc("BitTorrent was passed a filename that doesn't exist.  " + 'Either clear your Temporary Internet Files or right-click the link ' + 'and save the .torrent to disk first.')
  107.         else:
  108.             errorfunc('problem getting response info - ' + str(e))
  109.         return None
  110.  
  111.     
  112.     try:
  113.         response = bdecode(response)
  114.         check_message(response)
  115.     except ValueError:
  116.         e = None
  117.         errorfunc('got bad file info - ' + str(e))
  118.         return None
  119.  
  120.     
  121.     try:
  122.         
  123.         def make(f, forcedir = False):
  124.             if not forcedir:
  125.                 f = path.split(f)[0]
  126.             
  127.             if f != '' and not path.exists(f):
  128.                 makedirs(f)
  129.             
  130.  
  131.         info = response['info']
  132.         if info.has_key('length'):
  133.             file_length = info['length']
  134.             file = filefunc(info['name'], file_length, config['saveas'], False)
  135.             if file is None:
  136.                 return None
  137.             
  138.             make(file)
  139.             files = [
  140.                 (file, file_length)]
  141.         else:
  142.             file_length = 0
  143.             for x in info['files']:
  144.                 file_length += x['length']
  145.             
  146.             file = filefunc(info['name'], file_length, config['saveas'], True)
  147.             if file is None:
  148.                 return None
  149.             
  150.             existing = 0
  151.             if path.exists(file):
  152.                 for x in info['files']:
  153.                     if path.exists(path.join(file, x['path'][0])):
  154.                         existing = 1
  155.                         continue
  156.                 
  157.                 if not existing:
  158.                     file = path.join(file, info['name'])
  159.                 
  160.             
  161.             make(file, True)
  162.             if pathFunc != None:
  163.                 pathFunc(file)
  164.             
  165.             files = []
  166.             for x in info['files']:
  167.                 n = file
  168.                 for i in x['path']:
  169.                     n = path.join(n, i)
  170.                 
  171.                 files.append((n, x['length']))
  172.                 make(n)
  173.     except OSError:
  174.         e = None
  175.         errorfunc("Couldn't allocate dir - " + str(e))
  176.         return None
  177.     
  178.  
  179.     finflag = Event()
  180.     ann = [
  181.         None]
  182.     myid = 'M' + version.replace('.', '-')
  183.     myid = myid + '-' * (8 - len(myid)) + b2a_hex(sha(repr(time()) + ' ' + str(getpid())).digest()[-6:])
  184.     seed(myid)
  185.     pieces = [ info['pieces'][x:x + 20] for x in xrange(0, len(info['pieces']), 20) ]
  186.     
  187.     def failed(reason, errorfunc = errorfunc, doneflag = doneflag):
  188.         doneflag.set()
  189.         if reason is not None:
  190.             errorfunc(reason)
  191.         
  192.  
  193.     rawserver = RawServer(doneflag, config['timeout_check_interval'], config['timeout'], errorfunc = errorfunc, maxconnects = config['max_allow_in'])
  194.     
  195.     try:
  196.         
  197.         try:
  198.             storage = Storage(files, open, path.exists, path.getsize)
  199.         except IOError:
  200.             []
  201.             e = []
  202.             []
  203.             errorfunc('trouble accessing files - ' + str(e))
  204.             return None
  205.         except:
  206.             []
  207.  
  208.         
  209.         def finished(finfunc = finfunc, finflag = finflag, ann = ann, storage = storage, errorfunc = errorfunc):
  210.             finflag.set()
  211.             
  212.             try:
  213.                 storage.set_readonly()
  214.             except (IOError, OSError):
  215.                 e = None
  216.                 errorfunc('trouble setting readonly at end - ' + str(e))
  217.  
  218.             if ann[0] is not None:
  219.                 ann[0](1)
  220.             
  221.             finfunc()
  222.  
  223.         rm = [
  224.             None]
  225.         
  226.         def data_flunked(amount, rm = rm, errorfunc = errorfunc, report_hash_failures = config['report_hash_failures']):
  227.             if rm[0] is not None:
  228.                 rm[0](amount)
  229.             
  230.             if report_hash_failures:
  231.                 errorfunc('a piece failed hash check, re-downloading it')
  232.             
  233.  
  234.         storagewrapper = StorageWrapper(storage, config['download_slice_size'], pieces, info['piece length'], finished, failed, statusfunc, doneflag, config['check_hashes'], data_flunked)
  235.     except ValueError:
  236.         []
  237.         e = []
  238.         []
  239.         failed('bad data - ' + str(e))
  240.     except IOError:
  241.         []
  242.         e = []
  243.         failed('IOError - ' + str(e))
  244.     except:
  245.         []
  246.  
  247.     e = 'maxport less than minport - no ports to check'
  248.     for listen_port in xrange(config['minport'], config['maxport'] + 1):
  249.         
  250.         try:
  251.             rawserver.bind(listen_port, config['bind'])
  252.         continue
  253.         except socketerror:
  254.             None if doneflag.isSet() else []
  255.             e = None if doneflag.isSet() else []
  256.             continue
  257.         
  258.  
  259.     else:
  260.         return None
  261.     choker = Choker(config['max_uploads'], rawserver.add_task, finflag.isSet, config['min_uploads'])
  262.     upmeasure = Measure(config['max_rate_period'], config['upload_rate_fudge'])
  263.     downmeasure = Measure(config['max_rate_period'])
  264.     
  265.     def make_upload(connection, choker = choker, storagewrapper = storagewrapper, max_slice_length = config['max_slice_length'], max_rate_period = config['max_rate_period'], fudge = config['upload_rate_fudge']):
  266.         return Upload(connection, choker, storagewrapper, max_slice_length, max_rate_period, fudge)
  267.  
  268.     ratemeasure = RateMeasure(storagewrapper.get_amount_left())
  269.     rm[0] = ratemeasure.data_rejected
  270.     picker = PiecePicker(len(pieces), config['rarest_first_cutoff'])
  271.     for i in xrange(len(pieces)):
  272.         if storagewrapper.do_I_have(i):
  273.             picker.complete(i)
  274.             continue
  275.         None if doneflag.isSet() else []<EXCEPTION MATCH>socketerror
  276.     
  277.     downloader = Downloader(storagewrapper, picker, config['request_backlog'], config['max_rate_period'], len(pieces), downmeasure, config['snub_time'], ratemeasure.data_came_in)
  278.     connecter = Connecter(make_upload, downloader, choker, len(pieces), upmeasure, config['max_upload_rate'] * 1024, rawserver.add_task)
  279.     infohash = sha(bencode(info)).digest()
  280.     encoder = Encoder(connecter, rawserver, myid, config['max_message_length'], rawserver.add_task, config['keepalive_interval'], infohash, config['max_initiate'])
  281.     rerequest = Rerequester(response['announce'], config['rerequest_interval'], rawserver.add_task, connecter.how_many_connections, config['min_peers'], encoder.start_connection, rawserver.add_task, storagewrapper.get_amount_left, upmeasure.get_total, downmeasure.get_total, listen_port, config['ip'], myid, infohash, config['http_timeout'], errorfunc, config['max_initiate'], doneflag, upmeasure.get_rate, downmeasure.get_rate, encoder.ever_got_incoming)
  282.     DownloaderFeedback(choker, rawserver.add_task, statusfunc, upmeasure.get_rate, downmeasure.get_rate, upmeasure.get_total, downmeasure.get_total, ratemeasure.get_time_left, ratemeasure.get_size_left, file_length, finflag, config['display_interval'], spewflag)
  283.     if paramfunc:
  284.         paramfunc({
  285.             'max_upload_rate': connecter.change_max_upload_rate,
  286.             'max_uploads': choker.change_max_uploads,
  287.             'listen_port': listen_port,
  288.             'peer_id': myid,
  289.             'info_hash': infohash,
  290.             'start_connection': encoder._start_connection })
  291.     
  292.     statusfunc({
  293.         'activity': 'connecting to peers' })
  294.     ann[0] = rerequest.announce
  295.     rerequest.begin()
  296.     rawserver.listen_forever(encoder)
  297.     storage.close()
  298.     rerequest.announce(2)
  299.  
  300.