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

📄 track.py

📁 bittorrent source by python. please enjoy
💻 PY
📖 第 1 页 / 共 3 页
字号:
# The contents of this file are subject to the BitTorrent Open Source License# Version 1.1 (the License).  You may not copy or use this file, in either# source code or executable form, except in compliance with the License.  You# may obtain a copy of the License at http://www.bittorrent.com/license/.## Software distributed under the License is distributed on an AS IS basis,# WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License# for the specific language governing rights and limitations under the# License.# Written by Bram Cohen and John Hoffmanimport sysimport osimport signalimport reimport cPickleimport loggingimport datetimefrom urlparse import urlparsefrom traceback import print_excfrom time import time, gmtime, strftime, localtimefrom random import shufflefrom types import StringType, IntType, LongType, ListType, DictTypefrom binascii import b2a_hexfrom cStringIO import StringIOfrom BitTorrent.translation import _from BitTorrent.obsoletepythonsupport import *from BitTorrent import platform, BTFailurefrom BitTorrent.platform import decode_from_filesystem, efs2from BitTorrent.defer import DeferredEvent, ThreadedDeferredfrom BitTorrent.yielddefer import wrap_taskfrom BitTorrent.configfile import parse_configuration_and_argsfrom BitTorrent.RawServer_twisted import RawServerfrom BitTorrent.HTTPHandler import HTTPHandlerfrom BitTorrent.parsedir import parsedirfrom BitTorrent.NatCheck import NatCheckfrom BitTorrent.bencode import bencode, bdecode, Bencachedfrom BitTorrent.zurllib import quote, unquotefrom BitTorrent import versionfrom BitTorrent.prefs import Preferencesfrom BitTorrent.defaultargs import get_defaultsfrom BitTorrent.UI import Sizeimport socketimport threadingimport tracebackNOISY = False# code duplication because ow.MAX_INCOMPLETE = 100if os.name == 'nt':    from BitTorrent.platform import win_version_num    # starting in XP SP2 the incomplete outgoing connection limit was set to 10    if win_version_num >= (2, 5, 1, 2, 0):        MAX_INCOMPLETE = 10def statefiletemplate(x):    if type(x) != DictType:        raise ValueError    for cname, cinfo in x.iteritems():        if cname == 'peers':            for y in cinfo.itervalues():      # The 'peers' key is a dictionary of SHA hashes (torrent ids)                 if type(y) != DictType:   # ... for the active torrents, and each is a dictionary                     raise ValueError                 for peerid, info in y.iteritems(): # ... of client ids interested in that torrent                     if (len(peerid) != 20):                         raise ValueError                     if type(info) != DictType:  # ... each of which is also a dictionary                         raise ValueError # ... which has an IP, a Port, and a Bytes Left count for that client for that torrent                     if type(info.get('ip', '')) != StringType:                         raise ValueError                     port = info.get('port')                     if type(port) not in (IntType, LongType) or port < 0:                         raise ValueError                     left = info.get('left')                     if type(left) not in (IntType, LongType) or left < 0:                         raise ValueError        elif cname == 'completed':            if (type(cinfo) != DictType): # The 'completed' key is a dictionary of SHA hashes (torrent ids)                raise ValueError          # ... for keeping track of the total completions per torrent            for y in cinfo.itervalues():      # ... each torrent has an integer value                if type(y) not in (IntType,LongType):                    raise ValueError      # ... for the number of reported completions for that torrent        elif cname == 'allowed':            if (type(cinfo) != DictType): # a list of info_hashes and included data                raise ValueError            if x.has_key('allowed_dir_files'):                adlist = [z[1] for z in x['allowed_dir_files'].itervalues()]                for y in cinfo.iterkeys():        # and each should have a corresponding key here                    if not y in adlist:                        raise ValueError        elif cname == 'allowed_dir_files':            if (type(cinfo) != DictType): # a list of files, their attributes and info hashes                raise ValueError            dirkeys = {}            for y in cinfo.itervalues():      # each entry should have a corresponding info_hash                if not y[1]:                    continue                if not x['allowed'].has_key(y[1]):                    raise ValueError                if dirkeys.has_key(y[1]): # and each should have a unique info_hash                    raise ValueError                dirkeys[y[1]] = 1alas = _("your file may exist elsewhere in the universe\nbut alas, not here\n")def isotime():    #return strftime('%Y-%m-%d %H:%M UTC', gmtime(secs))    return datetime.datetime.utcnow().isoformat()http_via_filter = re.compile(' for ([0-9.]+)\Z')def _get_forwarded_ip(headers):    if headers.has_key('http_x_forwarded_for'):        header = headers['http_x_forwarded_for']        try:            x,y = header.split(',')        except:            return header        if not is_local_ip(x):            return x        return y    if headers.has_key('http_client_ip'):        return headers['http_client_ip']    if headers.has_key('http_via'):        x = http_via_filter.search(headers['http_via'])        try:            return x.group(1)        except:            pass    if headers.has_key('http_from'):        return headers['http_from']    return Nonedef get_forwarded_ip(headers):    x = _get_forwarded_ip(headers)    if x is None or not is_valid_ipv4(x) or is_local_ip(x):        return None    return xdef compact_peer_info(ip, port):    try:        s = ( ''.join([chr(int(i)) for i in ip.split('.')])              + chr((port & 0xFF00) >> 8) + chr(port & 0xFF) )        if len(s) != 6:            s = ''    except:        s = ''  # not a valid IP, must be a domain name    return sdef is_valid_ipv4(ip):    a = ip.split('.')    if len(a) != 4:        return False    try:        for x in a:            chr(int(x))        return True    except:        return Falsedef is_local_ip(ip):    try:        v = [int(x) for x in ip.split('.')]        if v[0] == 10 or v[0] == 127 or v[:2] in ([192, 168], [169, 254]):            return 1        if v[0] == 172 and v[1] >= 16 and v[1] <= 31:            return 1    except ValueError:        return 0default_headers = {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}class Tracker(object):    def __init__(self, config, rawserver):        self.config = config        self.response_size = config['response_size']        self.max_give = config['max_give']        self.dfile = efs2(config['dfile'])        self.natcheck = config['nat_check']        favicon = config['favicon']        self.favicon = None        if favicon:            try:                h = open(favicon,'r')                self.favicon = h.read()                h.close()            except:                errorfunc(logging.WARNING,                          _("specified favicon file -- %s -- does not exist.") %                          favicon)        self.rawserver = rawserver        self.cached = {}    # format: infohash: [[time1, l1, s1], [time2, l2, s2], [time3, l3, s3]]        self.cached_t = {}  # format: infohash: [time, cache]        self.times = {}        self.state = {}        self.seedcount = {}        self.save_pending = False        self.parse_pending = False        self.only_local_override_ip = config['only_local_override_ip']        if self.only_local_override_ip == 2:            self.only_local_override_ip = not config['nat_check']        if os.path.exists(self.dfile):            try:                h = open(self.dfile, 'rb')                ds = h.read()                h.close()                try:                    tempstate = cPickle.loads(ds)                except:                    tempstate = bdecode(ds)  # backwards-compatibility.                if not tempstate.has_key('peers'):                    tempstate = {'peers': tempstate}                statefiletemplate(tempstate)                self.state = tempstate            except:                errorfunc(logging.WARNING,                          _("statefile %s corrupt; resetting") % self.dfile)        self.downloads = self.state.setdefault('peers', {})        self.completed = self.state.setdefault('completed', {})        self.becache = {}   # format: infohash: [[l1, s1], [l2, s2], [l3, s3]]        for infohash, ds in self.downloads.iteritems():            self.seedcount[infohash] = 0            for x, y in ds.iteritems():                if not y.get('nat', -1):                    ip = y.get('given_ip')                    if not (ip and self.allow_local_override(y['ip'], ip)):                        ip = y['ip']                    self.natcheckOK(infohash, x, ip, y['port'], y['left'])                if not y['left']:                    self.seedcount[infohash] += 1        for infohash in self.downloads:            self.times[infohash] = {}            for peerid in self.downloads[infohash]:                self.times[infohash][peerid] = 0        self.reannounce_interval = config['reannounce_interval']        self.save_dfile_interval = config['save_dfile_interval']        self.show_names = config['show_names']        rawserver.add_task(self.save_dfile_interval, self.save_dfile)        self.prevtime = time()        self.timeout_downloaders_interval = config['timeout_downloaders_interval']        rawserver.add_task(self.timeout_downloaders_interval, self.expire_downloaders)        self.logfile = None        self.log = None        if (config['logfile'] != '') and (config['logfile'] != '-'):            try:                self.logfile = config['logfile']                self.log = open(self.logfile, 'a')                sys.stdout = self.log                print _("# Log Started: "), isotime()            except:                 print _("**warning** could not redirect stdout to log file: "), sys.exc_info()[0]        if config['hupmonitor']:            def huphandler(signum, frame, self = self):                try:                    self.log.close ()                    self.log = open(self.logfile, 'a')                    sys.stdout = self.log                    print _("# Log reopened: "), isotime()                except:                    print _("***warning*** could not reopen logfile")            signal.signal(signal.SIGHUP, huphandler)        self.allow_get = config['allow_get']        if config['allowed_dir'] != '':            self.allowed_dir = config['allowed_dir']            self.parse_dir_interval = config['parse_dir_interval']            self.allowed = self.state.setdefault('allowed', {})            self.allowed_dir_files = self.state.setdefault('allowed_dir_files', {})            self.allowed_dir_blocked = {}            self.parse_allowed()        else:            try:                del self.state['allowed']            except:                pass            try:                del self.state['allowed_dir_files']            except:                pass            self.allowed = None        self.uq_broken = unquote('+') != ' '        self.keep_dead = config['keep_dead']    def allow_local_override(self, ip, given_ip):        return is_valid_ipv4(given_ip) and (            not self.only_local_override_ip or is_local_ip(ip) )    def get_infopage(self):        try:            if not self.config['show_infopage']:                return (404, 'Not Found', default_headers, alas)            red = self.config['infopage_redirect']            if red != '':

⌨️ 快捷键说明

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