⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 track.py

📁 bittorrent source by python. please enjoy
💻 PY
📖 第 1 页 / 共 3 页
字号:
            for rr in xrange(len(self.cached[infohash])):                if rr != return_type:                    try:                        self.cached[infohash][rr][1].extend(vv[rr])                    except:                        pass        if len(cache[1]) < l_get_size:            peerdata = cache[1]            if not is_seed:                peerdata.extend(cache[2])            cache[1] = []            cache[2] = []        else:            if not is_seed:                peerdata = cache[2][l_get_size-rsize:]                del cache[2][l_get_size-rsize:]                rsize -= len(peerdata)            else:                peerdata = []            if rsize:                peerdata.extend(cache[1][-rsize:])                del cache[1][-rsize:]        if return_type == 2:            peerdata = ''.join(peerdata)        data['peers'] = peerdata        return data    def get(self, connection, path, headers):        ip = connection.get_ip()        nip = get_forwarded_ip(headers)        if nip and not self.only_local_override_ip:            ip = nip        paramslist = {}        def params(key, default = None, l = paramslist):            if l.has_key(key):                return l[key][0]            return default        try:            (scheme, netloc, path, pars, query, fragment) = urlparse(path)            if self.uq_broken == 1:                path = path.replace('+',' ')                query = query.replace('+',' ')            path = unquote(path)[1:]            for s in query.split('&'):                if s != '':                    i = s.index('=')                    kw = unquote(s[:i])                    paramslist.setdefault(kw, [])                    paramslist[kw] += [unquote(s[i+1:])]            if path == '' or path == 'index.html':                return self.get_infopage()            if path == 'scrape':                return self.get_scrape(paramslist)            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)            if path != 'announce':                return (404, 'Not Found', default_headers, alas)            # main tracker function            infohash = params('info_hash')            if not infohash:                raise ValueError, 'no info hash'            notallowed = self.check_allowed(infohash, paramslist)            if notallowed:                if NOISY:                    self._print_event( "get: NOT ALLOWED: info_hash=%s, %s" %                                       (infohash.encode('hex'). str(notallowed)) )                return notallowed            event = params('event')            rsize = self.add_data(infohash, event, ip, paramslist)        except ValueError, e:            print e            if NOISY:                self._print_exc( "get: ",e )            return (400, 'Bad Request',                    {'Content-Type': 'text/plain'},                    'you sent me garbage - ' + unicode(e.args[0]))        if params('compact'):            return_type = 2        elif params('no_peer_id'):            return_type = 1        else:            return_type = 0        data = self.peerlist(infohash, event=='stopped', not params('left'),                             return_type, rsize)        if paramslist.has_key('scrape'):            data['scrape'] = self.scrapedata(infohash, False)        return (200, 'OK', default_headers, bencode(data))    def natcheckOK(self, infohash, peerid, ip, port, not_seed):        bc = self.becache.setdefault(infohash,[[{}, {}], [{}, {}], [{}, {}]])        bc[0][not not_seed][peerid] = Bencached(bencode({'ip': ip, 'port': port,                                              'peer id': peerid}))        bc[1][not not_seed][peerid] = Bencached(bencode({'ip': ip, 'port': port}))        bc[2][not not_seed][peerid] = compact_peer_info(ip, port)    def natchecklog(self, peerid, ip, port, result):        print isotime(), '"!natcheck-%s:%i" %s %i 0 - -' % (            ip, quote(peerid), port, result)    def connectback_result(self, result, downloadid, peerid, ip, port):        record = self.downloads.get(downloadid, {}).get(peerid)        if ( record is None                 or (record['ip'] != ip and record.get('given ip') != ip)                 or record['port'] != port ):            if self.config['log_nat_checks']:                self.natchecklog(peerid, ip, port, 404)            return        if self.config['log_nat_checks']:            if result:                x = 200            else:                x = 503            self.natchecklog(peerid, ip, port, x)        if not record.has_key('nat'):            record['nat'] = int(not result)            if result:                self.natcheckOK(downloadid,peerid,ip,port,record['left'])        elif result and record['nat']:            record['nat'] = 0            self.natcheckOK(downloadid,peerid,ip,port,record['left'])        elif not result:            record['nat'] += 1    def save_dfile(self):        if self.save_pending:            return        self.save_pending = True        # if this is taking all the time, threading it won't help anyway because        # of the GIL        #state = bencode(self.state)        state = cPickle.dumps(self.state) # pickle handles Unicode.        df = ThreadedDeferred(wrap_task(self.rawserver.external_add_task),                              self._save_dfile, state)        def cb(r):            self.save_pending = False            if NOISY:                self._print_event( "save_dfile: Completed" )        def eb(etup):            self.save_pending = False            self._print_exc( "save_dfile: ", etup )        df.addCallbacks(cb, eb)    def _save_dfile(self, state):        exc_info = None        try:            h = open(self.dfile, 'wb')            h.write(state)            h.close()        except:            exc_info = sys.exc_info()        self.rawserver.external_add_task(self.save_dfile_interval, self.save_dfile)        if exc_info:            raise exc_info[0], exc_info[1], exc_info[2]    def parse_allowed(self):        if self.parse_pending:            return        self.parse_pending = True        df = ThreadedDeferred(wrap_task(self.rawserver.external_add_task),                              self._parse_allowed, daemon=True)        def eb(etup):            self.parse_pending = False            self._print_exc("parse_dir: ", etup)        df.addCallbacks(self._parse_allowed_finished, eb)    def _parse_allowed(self):        def errfunc(message, exc_info=None):            # logging broken .torrent files would be useful but could confuse            # programs parsing log files            m = "parse_dir: %s" % message            if exc_info:                self._print_exc(m, exc_info)            else:                self._print_event(m)            pass        r = parsedir(self.allowed_dir, self.allowed, self.allowed_dir_files,                     self.allowed_dir_blocked, errfunc, include_metainfo = False)        # register the call to parse a dir.        self.rawserver.external_add_task(self.parse_dir_interval,                                         self.parse_allowed)        return r    def _parse_allowed_finished(self, r):        self.parse_pending = False        ( self.allowed, self.allowed_dir_files, self.allowed_dir_blocked,          added, removed ) = r        if NOISY:            self._print_event("_parse_allowed_finished: removals: %s" %                              str(removed))        for infohash in added:            self.downloads.setdefault(infohash, {})            self.completed.setdefault(infohash, 0)            self.seedcount.setdefault(infohash, 0)        self.state['allowed'] = self.allowed        self.state['allowed_dir_files'] = self.allowed_dir_files    def delete_peer(self, infohash, peerid):        dls = self.downloads[infohash]        peer = dls[peerid]        if not peer['left']:            self.seedcount[infohash] -= 1        if not peer.get('nat', -1):            l = self.becache[infohash]            y = not peer['left']            for x in l:                del x[y][peerid]        del self.times[infohash][peerid]        del dls[peerid]    def expire_downloaders(self):        for infohash, peertimes in self.times.iteritems():            items = peertimes.items()            for myid, t in items:                if t < self.prevtime:                    self.delete_peer(infohash, myid)        self.prevtime = time()        if self.keep_dead != 1:            items = self.downloads.items()            for key, peers in items:                if len(peers) == 0 and (self.allowed is None or                                        key not in self.allowed):                    del self.times[key]                    del self.downloads[key]                    del self.seedcount[key]        self.rawserver.add_task(self.timeout_downloaders_interval,                                self.expire_downloaders)    def _print_event(self, message):        print datetime.datetime.utcnow().isoformat(), message    def _print_exc(self, note, etup):        print datetime.datetime.utcnow().isoformat(), note, ':'        traceback.print_exception(*etup)def track(args):    assert type(args) == list and \           len([x for x in args if type(x)==str])==len(args)    config = {}    defaults = get_defaults('bittorrent-tracker')   # hard-coded defaults.    try:        config, files = parse_configuration_and_args(defaults,           'bittorrent-tracker', args, 0, 0 )    except ValueError, e:        print _("error: ") + unicode(e.args[0])        print _("run with -? for parameter explanations")        return    except BTFailure, e:        print _("error: ") + unicode(e.args[0])        print _("run with -? for parameter explanations")        return    if config['dfile']=="":        config['dfile'] = decode_from_filesystem(            os.path.join(platform.get_temp_dir(), efs2(u"dfile") +            str(os.getpid())))    config = Preferences().initWithDict(config)    ef = lambda e: errorfunc(logging.WARNING, e)    platform.write_pid_file(config['pid'], ef)    t = None    try:        r = RawServer(config)        t = Tracker(config, r)        try:            #DEBUG            print "track: create_serversocket, port=", config['port']            #END            s = r.create_serversocket(config['port'], config['bind'], True)            handler = HTTPHandler(t.get, config['min_time_between_log_flushes'])            r.start_listening(s, handler)        except socket.error, e:            print ("Unable to open port %d.  Use a different port?" %                   config['port'])            return        r.listen_forever()    finally:        if t: t.save_dfile()        print _("# Shutting down: ") + isotime()def size_format(s):    return str(Size(s))def errorfunc( level, text ):    print "%s: %s" % (logging.getLevelName(level), text)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -