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

📄 makemetafile.py

📁 bittorrent source by python. please enjoy
💻 PY
字号:
#!/usr/bin/env python# 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 Cohenfrom __future__ import divisionimport osimport sysimport mathfrom BitTorrent.hash import shafrom time import timefrom threading import Eventfrom BitTorrent.translation import _from BitTorrent.bencode import bencode, bdecodefrom BitTorrent.btformats import check_infofrom BitTorrent.parseargs import parseargs, printHelpfrom BitTorrent.obsoletepythonsupport import *from BitTorrent.platform import decode_from_filesystem, get_filesystem_encoding, read_language_filefrom BitTorrent import BTFailurefrom khashmir.node import Nodefrom khashmir.ktable import KTablefrom khashmir.util import packPeers, compact_peer_infoignore = ['core', 'CVS', 'Thumbs.db', 'desktop.ini']from ConvertedMetainfo import noncharacter_translatedef dummy(v):    passminimum_piece_len_pow2 = 15 # minimum piece size is 2**15 = 32KBdef size_to_piece_len_pow2(size):    num_pieces_pow2 = 11 # 2**num_pieces_pow2 = desired number of pieces    return max(minimum_piece_len_pow2, int(round(math.log(size, 2)) - num_pieces_pow2))def make_meta_files(url,                    files,                    flag=Event(),                    progressfunc=dummy,                    filefunc=dummy,                    piece_len_pow2=0,                    target=None,                    title=None,                    comment=None,                    use_tracker=True,                    data_dir = None):    if len(files) > 1 and target:        raise BTFailure(_("You can't specify the name of the .torrent file "                          "when generating multiple torrents at once"))    files.sort()    ext = '.torrent'    togen = []    for f in files:        if not f.endswith(ext):            togen.append(f)    sizes = []    for f in togen:        sizes.append(calcsize(f))    total = sum(sizes)    subtotal = [0]    def callback(x):        subtotal[0] += x        progressfunc(subtotal[0] / total)    for i, f in enumerate(togen):        if flag.isSet():            break        if sizes[i] < 1:            continue # duh, skip empty files/directories        t = os.path.split(f)        if t[1] == '':            f = t[0]        filefunc(f)        if piece_len_pow2 > 0:            my_piece_len_pow2 = piece_len_pow2        else:            my_piece_len_pow2 = size_to_piece_len_pow2(sizes[i])        if use_tracker:            make_meta_file(f, url, flag=flag, progress=callback,                           piece_len_exp=my_piece_len_pow2, target=target,                           title=title, comment=comment)        else:            make_meta_file_dht(f, url, flag=flag, progress=callback,                           piece_len_exp=my_piece_len_pow2, target=target,                           title=title, comment=comment,                           data_dir=data_dir)def make_meta_file(path, url, piece_len_exp, flag=Event(), progress=dummy,                   title=None, comment=None, target=None):    data = {'announce': url.strip(), 'creation date': int(time())}    piece_length = 2 ** piece_len_exp    a, b = os.path.split(path)    if not target:        if b == '':            f = a + '.torrent'        else:            f = os.path.join(a, b + '.torrent')    else:        f = target    info = makeinfo(path, piece_length, flag, progress)    if flag.isSet():        return    check_info(info)    h = file(f, 'wb')    data['info'] = info    # TODO: encoding    lang = read_language_file()    if lang:        data['locale'] = lang    if title:        data['title'] = title    if comment:        data['comment'] = comment    h.write(bencode(data))    h.close()def make_meta_file_dht(path, nodes, piece_len_exp, flag=Event(), progress=dummy,                   title=None, comment=None, target=None,                   data_dir=None):    # if nodes is empty, then get them out of the routing table in data_dir    # else, expect nodes to be a string of comma seperated <ip>:<port> pairs    # this has a lot of duplicated code from make_meta_file    piece_length = 2 ** piece_len_exp    a, b = os.path.split(path)    if not target:        if b == '':            f = a + '.torrent'        else:            f = os.path.join(a, b + '.torrent')    else:        f = target    info = makeinfo(path, piece_length, flag, progress)    if flag.isSet():        return    check_info(info)    info_hash = sha(bencode(info)).digest()    if not nodes:        x = open(os.path.join(data_dir, 'routing_table'), 'rb')        d = bdecode(x.read())        x.close()        t = KTable(Node().initWithDict({'id':d['id'], 'host':'127.0.0.1','port': 0}))        for n in d['rt']:            t.insertNode(Node().initWithDict(n))        nodes = [(node.host, node.port) for node in t.findNodes(info_hash) if node.host != '127.0.0.1']    else:        nodes = [(a[0], int(a[1])) for a in [node.strip().split(":") for node in nodes.split(",")]]    data = {'nodes': nodes, 'creation date': int(time())}    h = file(f, 'wb')    data['info'] = info    if title:        data['title'] = title    if comment:        data['comment'] = comment    h.write(bencode(data))    h.close()def calcsize(path):    total = 0    for s in subfiles(os.path.abspath(path)):        total += os.path.getsize(s[1])    return totaldef makeinfo(path, piece_length, flag, progress):    def to_utf8(name):        if isinstance(name, unicode):            u = name        else:            try:                u = decode_from_filesystem(name)            except Exception, e:                raise BTFailure(_('Could not convert file/directory name "%s" to '                                  'Unicode (%s). Either the assumed filesystem '                                  'encoding "%s" is wrong or the filename contains '                                  'illegal bytes.') % (name, unicode(e.args[0]), get_filesystem_encoding()))        if u.translate(noncharacter_translate) != u:            raise BTFailure(_('File/directory name "%s" contains reserved '                              'unicode values that do not correspond to '                              'characters.') % name)        return u.encode('utf-8')    path = os.path.abspath(path)    if os.path.isdir(path):        subs = subfiles(path)        subs.sort()        pieces = []        sh = sha()        done = 0        fs = []        totalsize = 0.0        totalhashed = 0        for p, f in subs:            totalsize += os.path.getsize(f)        for p, f in subs:            pos = 0            size = os.path.getsize(f)            p2 = [to_utf8(name) for name in p]            fs.append({'length': size, 'path': p2})            h = file(f, 'rb')            while pos < size:                a = min(size - pos, piece_length - done)                sh.update(h.read(a))                if flag.isSet():                    return                done += a                pos += a                totalhashed += a                if done == piece_length:                    pieces.append(sh.digest())                    done = 0                    sh = sha()                progress(a)            h.close()        if done > 0:            pieces.append(sh.digest())        return {'pieces': ''.join(pieces),            'piece length': piece_length, 'files': fs,            'name': to_utf8(os.path.split(path)[1])}    else:        size = os.path.getsize(path)        pieces = []        p = 0        h = file(path, 'rb')        while p < size:            x = h.read(min(piece_length, size - p))            if flag.isSet():                return            pieces.append(sha(x).digest())            p += piece_length            if p > size:                p = size            progress(min(piece_length, size - p))        h.close()        return {'pieces': ''.join(pieces),            'piece length': piece_length, 'length': size,            'name': to_utf8(os.path.split(path)[1])}def subfiles(d):    r = []    stack = [([], d)]    while stack:        p, n = stack.pop()        if os.path.isdir(n):            for s in os.listdir(n):                if s not in ignore and not s.startswith('.'):                    stack.append((p + [s], os.path.join(n, s)))        else:            r.append((p, n))    return r

⌨️ 快捷键说明

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