コード例 #1
0
ファイル: track.py プロジェクト: AchillesA/BitTornado
    def get_scrape(self, paramslist):
        fs = {}
        if 'info_hash' in paramslist:
            if self.config['scrape_allowed'] not in ['specific', 'full']:
                return (400, 'Not Authorized', {'Content-Type': 'text/plain',
                                                'Pragma': 'no-cache'},
                        bencode({'failure reason': 'specific scrape function '
                                 'is not available with this tracker.'}))
            for hash in paramslist['info_hash']:
                if self.allowed is not None:
                    if hash in self.allowed:
                        fs[hash] = self.scrapedata(hash)
                elif hash in self.downloads:
                    fs[hash] = self.scrapedata(hash)
        else:
            if self.config['scrape_allowed'] != 'full':
                return (400, 'Not Authorized', {'Content-Type': 'text/plain',
                                                'Pragma': 'no-cache'},
                        bencode({'failure reason': 'full scrape function is '
                                 'not available with this tracker.'}))
            if self.allowed is not None:
                keys = self.allowed.iterkeys()
            else:
                keys = self.downloads.iterkeys()
            for hash in keys:
                fs[hash] = self.scrapedata(hash)

        return (200, 'OK', {'Content-Type': 'text/plain'},
                bencode({'files': fs}))
コード例 #2
0
ファイル: track.py プロジェクト: AchillesA/BitTornado
 def natcheckOK(self, infohash, peerid, ip, port, peer):
     seed = not peer['left']
     bc = self.becache.setdefault(infohash, self.cache_default)
     cp = compact_peer_info(ip, port)
     reqc = peer['requirecrypto']
     bc[2][seed][peerid] = (cp, chr(reqc))
     if peer['supportcrypto']:
         bc[1][seed][peerid] = cp
     if not reqc:
         bc[0][seed][peerid] = cp
         if not self.config['compact_reqd']:
             bc[3][seed][peerid] = Bencached(
                 bencode({'ip': ip, 'port': port, 'peer id': peerid}))
             bc[4][seed][peerid] = Bencached(
                 bencode({'ip': ip, 'port': port}))
コード例 #3
0
ファイル: ConfigDir.py プロジェクト: dontnod/bittornado
 def writeTorrentData(self, torrent, data):
     """Add a torrent data file to cache"""
     self.torrentDataBuffer[torrent] = data
     fname = os.path.join(self.dir_datacache, hexlify(torrent).decode())
     try:
         with open(fname, 'wb') as f:
             f.write(bencode(data))
         return True
     except (IOError, TypeError, KeyError):
         self.deleteTorrentData(torrent)
         return False
コード例 #4
0
ファイル: ConfigDir.py プロジェクト: AchillesA/BitTornado
 def writeTorrentData(self, torrent, data):
     """Add a torrent data file to cache"""
     self.torrentDataBuffer[torrent] = data
     fname = os.path.join(self.dir_datacache, hexlify(torrent))
     try:
         with open(fname, 'wb') as f:
             f.write(bencode(data))
         return True
     except (IOError, TypeError, KeyError):
         self.deleteTorrentData(torrent)
         return False
コード例 #5
0
ファイル: track.py プロジェクト: AchillesA/BitTornado
    def check_allowed(self, infohash, paramslist):
        if self.aggregator_key is not None and not (
                'password' in paramslist
                and paramslist['password'][0] == self.aggregator_key):
            return (200, 'Not Authorized', {'Content-Type': 'text/plain',
                                            'Pragma': 'no-cache'},
                    bencode({'failure reason': 'Requested download is not '
                             'authorized for use with this tracker.'}))

        if self.allowed is not None:
            if infohash not in self.allowed:
                return (200, 'Not Authorized', {'Content-Type': 'text/plain',
                                                'Pragma': 'no-cache'},
                        bencode({'failure reason': 'Requested download is not '
                                 'authorized for use with this tracker.'}))
            if self.config['allowed_controls']:
                if 'failure reason' in self.allowed[infohash]:
                    return (
                        200, 'Not Authorized', {'Content-Type': 'text/plain',
                                                'Pragma': 'no-cache'},
                        bencode({'failure reason':
                                 self.allowed[infohash]['failure reason']}))

        if 'tracker' in paramslist:
            # turned off or contacted self
            if self.config['multitracker_allowed'] == 'none' or \
                    paramslist['peer_id'][0] == self.trackerid:
                return (200, 'Not Authorized', {'Content-Type': 'text/plain',
                                                'Pragma': 'no-cache'},
                        bencode({'failure reason': 'disallowed'}))

            if self.config['multitracker_allowed'] == 'autodetect' and \
                    'announce-list' not in self.allowed[infohash]:
                return (200, 'Not Authorized', {'Content-Type': 'text/plain',
                                                'Pragma': 'no-cache'},
                        bencode({'failure reason': 'Requested download is not '
                                 'authorized for multitracker use.'}))

        return None
コード例 #6
0
ファイル: parsedir.py プロジェクト: dontnod/bittornado
def parse_torrent(path, return_metainfo=False):
    """Load and derive metadata from torrent file

    Parameters
        str     - path of file to parse
        bool    - parsed metadata to include full torrent data

    Returns
        {str: *}
                - torrent file metadata
        str     - sha hash of encoded info dict
    """
    fname = os.path.basename(path)

    data = MetaInfo.read(path)

    # Validate and hash info dict
    info = data['info']
    check_info(info)
    infohash = hashlib.sha1(bencode(info)).digest()

    single = 'length' in info

    torrentinfo = {
        'path':
        path,
        'file':
        fname,
        'name':
        info.get('name', fname),
        'numfiles':
        1 if single else len(info['files']),
        'length':
        info['length'] if single else sum(li['length'] for li in info['files']
                                          if 'length' in li)
    }

    for key in ('failure reason', 'warning message', 'announce-list'):
        if key in data:
            torrentinfo[key] = data[key]

    if return_metainfo:
        torrentinfo['metainfo'] = data

    return torrentinfo, infohash
コード例 #7
0
    def writeTorrent(self, data, torrent, version=-1):
        """Write data to a torrent file

        If no version is provided, create a new version"""
        torrent = hexlify(torrent)
        fname = os.path.join(self.dir_torrentcache, torrent)

        if version == -1:
            try:
                version = max(self.getTorrentVariations(torrent)) + 1
            except ValueError:
                version = 0
        if version:
            fname += '.' + str(version)
        try:
            with open(fname, 'wb') as f:
                f.write(bencode(data))
        except (IOError, TypeError, KeyError):
            return None

        return version
コード例 #8
0
ファイル: ConfigDir.py プロジェクト: AchillesA/BitTornado
    def writeTorrent(self, data, torrent, version=-1):
        """Write data to a torrent file

        If no version is provided, create a new version"""
        torrent = hexlify(torrent)
        fname = os.path.join(self.dir_torrentcache, torrent)

        if version == -1:
            try:
                version = max(self.getTorrentVariations(torrent)) + 1
            except ValueError:
                version = 0
        if version:
            fname += '.' + str(version)
        try:
            with open(fname, 'wb') as f:
                f.write(bencode(data))
        except (IOError, TypeError, KeyError):
            return None

        return version
コード例 #9
0
ファイル: parsedir.py プロジェクト: AchillesA/BitTornado
def parse_torrent(path, return_metainfo=False):
    """Load and derive metadata from torrent file

    Parameters
        str     - path of file to parse
        bool    - parsed metadata to include full torrent data

    Returns
        {str: *}
                - torrent file metadata
        str     - sha hash of encoded info dict
    """
    fname = os.path.basename(path)

    data = MetaInfo.read(path)

    # Validate and hash info dict
    info = data['info']
    check_info(info)
    infohash = hashlib.sha1(bencode(info)).digest()

    single = 'length' in info

    torrentinfo = {
        'path':     path,
        'file':     fname,
        'name':     info.get('name', fname),
        'numfiles': 1 if single else len(info['files']),
        'length':   info['length'] if single else sum(
            li['length'] for li in info['files'] if 'length' in li)
    }

    for key in ('failure reason', 'warning message', 'announce-list'):
        if key in data:
            torrentinfo[key] = data[key]

    if return_metainfo:
        torrentinfo['metainfo'] = data

    return torrentinfo, infohash
コード例 #10
0
ファイル: test_bencode.py プロジェクト: kaulie/BitTornado
    def test_bencode(self):
        """Test encoding of encodable and unencodable data structures"""
        self.assertEqual(bencode(4), b'i4e')
        self.assertEqual(bencode(0), b'i0e')
        self.assertEqual(bencode(-10), b'i-10e')
        self.assertEqual(bencode(12345678901234567890),
                         b'i12345678901234567890e')
        self.assertEqual(bencode(''), b'0:')
        self.assertEqual(bencode('abc'), b'3:abc')
        self.assertEqual(bencode('1234567890'), b'10:1234567890')
        self.assertEqual(bencode([]), b'le')
        self.assertEqual(bencode([1, 2, 3]), b'li1ei2ei3ee')
        self.assertEqual(bencode([['Alice', 'Bob'], [2, 3]]),
                         b'll5:Alice3:Bobeli2ei3eee')
        self.assertEqual(bencode({}), b'de')
        self.assertEqual(bencode({'age': 25, 'eyes': 'blue'}),
                         b'd3:agei25e4:eyes4:bluee')
        self.assertEqual(bencode({'spam.mp3': {'author': 'Alice',
                                               'length': 100000}}),
                         b'd8:spam.mp3d6:author5:Alice6:lengthi100000eee')
        self.assertRaises(TypeError, bencode, {1: 'foo'})
        self.assertRaises(TypeError, bencode, {'foo': 1.0})

        cached = Bencached.cache({'age': 25})
        self.assertEqual(bencode(cached), cached.bencoded)

        self.assertEqual(bencode(''), bencode(b''))
コード例 #11
0
    def test_bencode(self):
        """Test encoding of encodable and unencodable data structures"""
        self.assertEqual(bencode(4), b'i4e')
        self.assertEqual(bencode(0), b'i0e')
        self.assertEqual(bencode(-10), b'i-10e')
        self.assertEqual(bencode(12345678901234567890),
                         b'i12345678901234567890e')
        self.assertEqual(bencode(''), b'0:')
        self.assertEqual(bencode('abc'), b'3:abc')
        self.assertEqual(bencode('1234567890'), b'10:1234567890')
        self.assertEqual(bencode([]), b'le')
        self.assertEqual(bencode([1, 2, 3]), b'li1ei2ei3ee')
        self.assertEqual(bencode([['Alice', 'Bob'], [2, 3]]),
                         b'll5:Alice3:Bobeli2ei3eee')
        self.assertEqual(bencode({}), b'de')
        self.assertEqual(bencode({
            'age': 25,
            'eyes': 'blue'
        }), b'd3:agei25e4:eyes4:bluee')
        self.assertEqual(
            bencode({'spam.mp3': {
                'author': 'Alice',
                'length': 100000
            }}), b'd8:spam.mp3d6:author5:Alice6:lengthi100000eee')
        self.assertRaises(TypeError, bencode, {1: 'foo'})
        self.assertRaises(TypeError, bencode, {'foo': 1.0})

        cached = Bencached.cache({'age': 25})
        self.assertEqual(bencode(cached), cached.bencoded)

        self.assertEqual(bencode(''), bencode(b''))
コード例 #12
0
def run(scrwin, errlist, params):
    doneflag = threading.Event()
    d = CursesDisplayer(scrwin, errlist, doneflag)
    try:
        while 1:
            configdir = ConfigDir('downloadcurses')
            defaultsToIgnore = ['responsefile', 'url', 'priority']
            configdir.setDefaults(defaults, defaultsToIgnore)
            configdefaults = configdir.loadConfig()
            defaults.append(
                ('save_options', 0, 'whether to save the current options as '
                 'the new default configuration (only for btdownloadcurses.py)'
                 ))
            try:
                config = parse_params(params, configdefaults)
            except ValueError as e:
                d.error('error: {}\nrun with no args for parameter '
                        'explanations'.format(e))
                break
            if not config:
                d.error(get_usage(defaults, d.fieldw, configdefaults))
                break
            if config['save_options']:
                configdir.saveConfig(config)
            configdir.deleteOldCacheData(config['expire_cache_data'])

            myid = createPeerID()
            random.seed(myid)

            rawserver = RawServer(
                doneflag, config['timeout_check_interval'], config['timeout'],
                ipv6_enable=config['ipv6_enabled'], failfunc=d.failed,
                errorfunc=d.error)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    listen_port = rawserver.find_and_bind(
                        config['minport'], config['maxport'], config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type, randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        d.error('WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    d.error("Couldn't listen - " + str(e))
                    d.failed()
                    return

            response = get_response(config['responsefile'], config['url'],
                                    d.error)
            if not response:
                break

            infohash = hashlib.sha1(bencode(response['info'])).digest()

            dow = BT1Download(
                d.display, d.finished, d.error, d.error, doneflag, config,
                response, infohash, myid, rawserver, listen_port, configdir)

            if not dow.saveAs(d.chooseFile):
                break

            if not dow.initFiles(old_style=True):
                break
            if not dow.startEngine():
                dow.shutdown()
                break
            dow.startRerequester()
            dow.autoStats()

            if not dow.am_I_finished():
                d.display(activity='connecting to peers')
            rawserver.listen_forever(dow.getPortHandler())
            d.display(activity='shutting down')
            dow.shutdown()
            break

    except KeyboardInterrupt:
        # ^C to exit...
        pass
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not d.done:
        d.failed()
コード例 #13
0
ファイル: track.py プロジェクト: AchillesA/BitTornado
    def get(self, connection, path, headers):
        real_ip = connection.get_ip()
        ip = real_ip
        if is_ipv4(ip):
            ipv4 = True
        else:
            try:
                ip = ipv6_to_ipv4(ip)
                ipv4 = True
            except ValueError:
                ipv4 = False

        if self.allowed_IPs and ip not in self.allowed_IPs or \
                self.banned_IPs and ip in self.banned_IPs:
            return (400, 'Not Authorized', {'Content-Type': 'text/plain',
                                            'Pragma': 'no-cache'},
                    bencode({'failure reason':
                             'your IP is not allowed on this tracker'}))

        nip = get_forwarded_ip(headers)
        if nip and not self.only_local_override_ip:
            ip = nip
            try:
                ip = to_ipv4(ip)
                ipv4 = True
            except ValueError:
                ipv4 = False

        paramslist = {}

        def params(key, default=None, l=paramslist):
            if key in l:
                return l[key][0]
            return default

        try:
            (_, _, path, _, query, _) = urlparse(path)
            if self.uq_broken == 1:
                path = path.replace('+', ' ')
                query = query.replace('+', ' ')
            path = urllib.unquote(path)[1:]
            for s in query.split('&'):
                if s:
                    i = s.index('=')
                    kw = urllib.unquote(s[:i])
                    paramslist.setdefault(kw, [])
                    paramslist[kw] += [urllib.unquote(s[i + 1:])]

            if path == '' or path == 'index.html':
                return self.get_infopage()
            if path == 'file':
                return self.get_file(params('info_hash'))
            if path == 'favicon.ico' and self.favicon is not None:
                return (200, 'OK', {'Content-Type': 'image/x-icon'},
                        self.favicon)

            # automated access from here on

            if path in ('scrape', 'scrape.php', 'tracker.php/scrape'):
                return self.get_scrape(paramslist)

            if path not in ('announce', 'announce.php',
                            'tracker.php/announce'):
                return (404, 'Not Found', {'Content-Type': 'text/plain',
                                           'Pragma': 'no-cache'}, alas)

            # main tracker function

            #filtered = self.Filter.check(real_ip, paramslist, headers)
            #if filtered:
            #    return (400, 'Not Authorized', {'Content-Type': 'text/plain',
            #                                    'Pragma': 'no-cache'},
            #            bencode({'failure reason': filtered}))

            infohash = params('info_hash')
            if not infohash:
                raise ValueError('no info hash')

            notallowed = self.check_allowed(infohash, paramslist)
            if notallowed:
                return notallowed

            event = params('event')

            rsize = self.add_data(infohash, event, ip, paramslist)

        except ValueError as e:
            return (400, 'Bad Request', {'Content-Type': 'text/plain'},
                    'you sent me garbage - ' + str(e))

        if self.aggregate_forward and 'tracker' not in paramslist:
            self.aggregate_senddata(query)

        if self.is_aggregator:      # don't return peer data here
            return (200, 'OK', {'Content-Type': 'text/plain',
                                'Pragma': 'no-cache'},
                    bencode({'response': 'OK'}))

        if params('compact') and ipv4:
            if params('requirecrypto'):
                return_type = 1
            elif params('supportcrypto'):
                return_type = 2
            else:
                return_type = 0
        elif self.config['compact_reqd'] and ipv4:
            return (400, 'Bad Request', {'Content-Type': 'text/plain'},
                    'your client is outdated, please upgrade')
        elif params('no_peer_id'):
            return_type = 4
        else:
            return_type = 3

        data = self.peerlist(infohash, event == 'stopped',
                             params('tracker'), not params('left'),
                             return_type, rsize, params('supportcrypto'))

        if 'scrape' in paramslist:    # deprecated
            data['scrape'] = self.scrapedata(infohash, False)

        if self.dedicated_seed_id:
            if params('seed_id') == self.dedicated_seed_id and \
                    params('left') == 0:
                self.is_seeded[infohash] = True
            if params('check_seeded') and self.is_seeded.get(infohash):
                data['seeded'] = 1

        return (200, 'OK', {'Content-Type': 'text/plain',
                            'Pragma': 'no-cache'},
                bencode(data))
コード例 #14
0
ファイル: track.py プロジェクト: AchillesA/BitTornado
 def save_state(self):
     self.rawserver.add_task(self.save_state, self.save_dfile_interval)
     with open(self.dfile, 'wb') as h:
         h.write(bencode(self.state))
コード例 #15
0
def run(scrwin, errlist, params):
    doneflag = threading.Event()
    d = CursesDisplayer(scrwin, errlist, doneflag)
    try:
        while 1:
            configdir = ConfigDir('downloadcurses')
            defaultsToIgnore = ['responsefile', 'url', 'priority']
            configdir.setDefaults(defaults, defaultsToIgnore)
            configdefaults = configdir.loadConfig()
            defaults.append(
                ('save_options', 0, 'whether to save the current options as '
                 'the new default configuration (only for btdownloadcurses.py)'
                 ))
            try:
                config = parse_params(params, configdefaults)
            except ValueError as e:
                d.error('error: {}\nrun with no args for parameter '
                        'explanations'.format(e))
                break
            if not config:
                d.error(get_usage(defaults, d.fieldw, configdefaults))
                break
            if config['save_options']:
                configdir.saveConfig(config)
            configdir.deleteOldCacheData(config['expire_cache_data'])

            myid = createPeerID()
            random.seed(myid)

            rawserver = RawServer(
                doneflag, config['timeout_check_interval'], config['timeout'],
                ipv6_enable=config['ipv6_enabled'], failfunc=d.failed,
                errorfunc=d.error)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    listen_port = rawserver.find_and_bind(
                        config['minport'], config['maxport'], config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type, randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        d.error('WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    d.error("Couldn't listen - " + str(e))
                    d.failed()
                    return

            response = get_response(config['responsefile'], config['url'],
                                    d.error)
            if not response:
                break

            infohash = hashlib.sha1(bencode(response['info'])).digest()

            dow = BT1Download(
                d.display, d.finished, d.error, d.error, doneflag, config,
                response, infohash, myid, rawserver, listen_port, configdir)

            if not dow.saveAs(d.chooseFile):
                break

            if not dow.initFiles(old_style=True):
                break
            if not dow.startEngine():
                dow.shutdown()
                break
            dow.startRerequester()
            dow.autoStats()

            if not dow.am_I_finished():
                d.display(activity='connecting to peers')
            rawserver.listen_forever(dow.getPortHandler())
            d.display(activity='shutting down')
            dow.shutdown()
            break

    except KeyboardInterrupt:
        # ^C to exit...
        pass
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not d.done:
        d.failed()
コード例 #16
0
def run(params):
    h = HeadlessDisplayer()
    while 1:
        configdir = ConfigDir('downloadheadless')
        defaultsToIgnore = ['metafile', 'url', 'priority']
        configdir.setDefaults(defaults, defaultsToIgnore)
        configdefaults = configdir.loadConfig()
        defaults.append(
            ('save_options', 0, 'whether to save the current options as the '
             'new default configuration (only for btdownloadheadless.py)'))
        try:
            config = parse_params(params, configdefaults)
        except ValueError as e:
            print('error: {}\n'.format(e),
                  'run with no args for parameter explanations')
            break
        if not config:
            print(get_usage(defaults, 80, configdefaults))
            break
        if config['save_options']:
            configdir.saveConfig(config)
        configdir.deleteOldCacheData(config['expire_cache_data'])

        myid = createPeerID()
        random.seed(myid)

        doneflag = threading.Event()

        def disp_exception(text):
            print(text)
        rawserver = RawServer(
            doneflag, config['timeout_check_interval'], config['timeout'],
            ipv6_enable=config['ipv6_enabled'], failfunc=h.failed,
            errorfunc=disp_exception)
        upnp_type = UPnP_test(config['upnp_nat_access'])
        while True:
            try:
                listen_port = rawserver.find_and_bind(
                    config['minport'], config['maxport'], config['bind'],
                    ipv6_socket_style=config['ipv6_binds_v4'],
                    upnp=upnp_type, randomizer=config['random_port'])
                break
            except socket.error as e:
                if upnp_type and e == UPnP_ERROR:
                    print('WARNING: COULD NOT FORWARD VIA UPnP')
                    upnp_type = 0
                    continue
                print("error: Couldn't listen - ", e)
                h.failed()
                return

        metainfo = get_metainfo(config['metafile'], config['url'], h.error)
        if not metainfo:
            break

        infohash = hashlib.sha1(bencode(metainfo['info'])).digest()

        dow = BT1Download(
            h.display, h.finished, h.error, disp_exception, doneflag, config,
            metainfo, infohash, myid, rawserver, listen_port, configdir)

        if not dow.saveAs(h.chooseFile, h.newpath):
            break

        if not dow.initFiles(old_style=True):
            break
        if not dow.startEngine():
            dow.shutdown()
            break
        dow.startRerequester()
        dow.autoStats()

        if not dow.am_I_finished():
            h.display(activity='connecting to peers')
        rawserver.listen_forever(dow.getPortHandler())
        h.display(activity='shutting down')
        dow.shutdown()
        break
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not h.done:
        h.failed()
コード例 #17
0
def run(scrwin, errlist, params):
    doneflag = threading.Event()
    d = CursesDisplayer(scrwin, errlist, doneflag)
    try:
        while 1:
            configdir = ConfigDir("downloadcurses")
            defaultsToIgnore = ["metafile", "url", "priority"]
            configdir.setDefaults(defaults, defaultsToIgnore)
            configdefaults = configdir.loadConfig()
            defaults.append(
                (
                    "save_options",
                    0,
                    "whether to save the current options as "
                    "the new default configuration (only for btdownloadcurses.py)",
                )
            )
            try:
                config = parse_params(params, configdefaults)
            except ValueError as e:
                d.error("error: {}\nrun with no args for parameter " "explanations".format(e))
                break
            if not config:
                d.error(get_usage(defaults, d.fieldw, configdefaults))
                break
            if config["save_options"]:
                configdir.saveConfig(config)
            configdir.deleteOldCacheData(config["expire_cache_data"])

            myid = createPeerID()
            random.seed(myid)

            rawserver = RawServer(
                doneflag,
                config["timeout_check_interval"],
                config["timeout"],
                ipv6_enable=config["ipv6_enabled"],
                failfunc=d.failed,
                errorfunc=d.error,
            )

            upnp_type = UPnP_test(config["upnp_nat_access"])
            while True:
                try:
                    listen_port = rawserver.find_and_bind(
                        config["minport"],
                        config["maxport"],
                        config["bind"],
                        ipv6_socket_style=config["ipv6_binds_v4"],
                        upnp=upnp_type,
                        randomizer=config["random_port"],
                    )
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        d.error("WARNING: COULD NOT FORWARD VIA UPnP")
                        upnp_type = 0
                        continue
                    d.error("Couldn't listen - " + str(e))
                    d.failed()
                    return

            metainfo = get_metainfo(config["metafile"], config["url"], d.error)
            if not metainfo:
                break

            infohash = hashlib.sha1(bencode(metainfo["info"])).digest()

            dow = BT1Download(
                d.display,
                d.finished,
                d.error,
                d.error,
                doneflag,
                config,
                metainfo,
                infohash,
                myid,
                rawserver,
                listen_port,
                configdir,
            )

            if not dow.saveAs(d.chooseFile):
                break

            if not dow.initFiles(old_style=True):
                break
            if not dow.startEngine():
                dow.shutdown()
                break
            dow.startRerequester()
            dow.autoStats()

            if not dow.am_I_finished():
                d.display(activity="connecting to peers")
            rawserver.listen_forever(dow.getPortHandler())
            d.display(activity="shutting down")
            dow.shutdown()
            break

    except KeyboardInterrupt:
        # ^C to exit...
        pass
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not d.done:
        d.failed()
コード例 #18
0
def run(params):
    h = HeadlessDisplayer()
    while 1:
        configdir = ConfigDir('downloadheadless')
        defaultsToIgnore = ['metafile', 'url', 'priority']
        configdir.setDefaults(defaults, defaultsToIgnore)
        configdefaults = configdir.loadConfig()
        defaults.append(
            ('save_options', 0, 'whether to save the current options as the '
             'new default configuration (only for btdownloadheadless.py)'))
        try:
            config = parse_params(params, configdefaults)
        except ValueError as e:
            print('error: {}\n'.format(e),
                  'run with no args for parameter explanations')
            break
        if not config:
            print(get_usage(defaults, 80, configdefaults))
            break
        if config['save_options']:
            configdir.saveConfig(config)
        configdir.deleteOldCacheData(config['expire_cache_data'])

        myid = createPeerID()
        random.seed(myid)

        doneflag = threading.Event()

        def disp_exception(text):
            print(text)

        rawserver = RawServer(doneflag,
                              config['timeout_check_interval'],
                              config['timeout'],
                              ipv6_enable=config['ipv6_enabled'],
                              failfunc=h.failed,
                              errorfunc=disp_exception)
        upnp_type = UPnP_test(config['upnp_nat_access'])
        while True:
            try:
                listen_port = rawserver.find_and_bind(
                    config['minport'],
                    config['maxport'],
                    config['bind'],
                    ipv6_socket_style=config['ipv6_binds_v4'],
                    upnp=upnp_type,
                    randomizer=config['random_port'])
                break
            except socket.error as e:
                if upnp_type and e == UPnP_ERROR:
                    print('WARNING: COULD NOT FORWARD VIA UPnP')
                    upnp_type = 0
                    continue
                print("error: Couldn't listen - ", e)
                h.failed()
                return

        metainfo = get_metainfo(config['metafile'], config['url'], h.error)
        if not metainfo:
            break

        infohash = hashlib.sha1(bencode(metainfo['info'])).digest()

        dow = BT1Download(h.display, h.finished, h.error, disp_exception,
                          doneflag, config, metainfo, infohash, myid,
                          rawserver, listen_port, configdir)

        if not dow.saveAs(h.chooseFile, h.newpath):
            break

        if not dow.initFiles(old_style=True):
            break
        if not dow.startEngine():
            dow.shutdown()
            break
        dow.startRerequester()
        dow.autoStats()

        if not dow.am_I_finished():
            h.display(activity='connecting to peers')
        rawserver.listen_forever(dow.getPortHandler())
        h.display(activity='shutting down')
        dow.shutdown()
        break
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not h.done:
        h.failed()
コード例 #19
0
NAME, EXT = os.path.splitext(os.path.basename(sys.argv[0]))
VERSION = '20130326'

print('{} {} - decode BitTorrent metainfo files'.format(NAME, VERSION))
print()

if len(sys.argv) == 1:
    print('{} file1.torrent file2.torrent file3.torrent ...'.format(
        sys.argv[0]))
    print()
    sys.exit(2)  # common exit code for syntax error

for metainfo_name in sys.argv[1:]:
    metainfo = MetaInfo.read(metainfo_name)
    info = metainfo['info']
    info_hash = hashlib.sha1(bencode(info))

    print('metainfo file.:', os.path.basename(metainfo_name))
    print('info hash.....:', info_hash.hexdigest())
    piece_length = info['piece length']
    if 'length' in info:
        # let's assume we just have a file
        print('file name.....:', info['name'])
        file_length = info['length']
        name = 'file size.....:'
    else:
        # let's assume we have a directory structure
        print('directory name:', info['name'])
        print('files.........:')
        file_length = 0
        for file in info['files']:
コード例 #20
0
NAME, EXT = os.path.splitext(os.path.basename(sys.argv[0]))
VERSION = '20130326'

print('{} {} - decode BitTorrent metainfo files'.format(NAME, VERSION))
print()

if len(sys.argv) == 1:
    print('{} file1.torrent file2.torrent file3.torrent ...'.format(
          sys.argv[0]))
    print()
    sys.exit(2)     # common exit code for syntax error

for metainfo_name in sys.argv[1:]:
    metainfo = MetaInfo.read(metainfo_name)
    info = metainfo['info']
    info_hash = hashlib.sha1(bencode(info))

    print('metainfo file.:', os.path.basename(metainfo_name))
    print('info hash.....:', info_hash.hexdigest())
    piece_length = info['piece length']
    if 'length' in info:
        # let's assume we just have a file
        print('file name.....:', info['name'])
        file_length = info['length']
        name = 'file size.....:'
    else:
        # let's assume we have a directory structure
        print('directory name:', info['name'])
        print('files.........:')
        file_length = 0
        for file in info['files']: