문제

(신속하게) 프로그램/스크립트를 모아서 .torrent 파일에서 파일 세트를 읽고 싶습니다. 그런 다음 해당 세트를 사용하여 급류에 속하지 않는 특정 디렉토리에서 파일을 삭제하고 싶습니다.

.torrent 파일 에서이 색인을 읽을 수있는 편리한 라이브러리의 권장 사항이 있습니까? 나는 그것에 반대하지 않는 동안, 나는 Bittorrent 사양을 깊이 파고 들고이 간단한 목적을 위해 많은 코드를 처음부터 롤링하고 싶지 않습니다.

나는 언어를 선호하지 않습니다.

도움이 되었습니까?

해결책

Effbot은 귀하의 질문에 답변했습니다. 다음은 .torrent 파일 (Python 2.4+)의 파일 목록을 읽을 수있는 전체 코드입니다.

import re

def tokenize(text, match=re.compile("([idel])|(\d+):|(-?\d+)").match):
    i = 0
    while i < len(text):
        m = match(text, i)
        s = m.group(m.lastindex)
        i = m.end()
        if m.lastindex == 2:
            yield "s"
            yield text[i:i+int(s)]
            i = i + int(s)
        else:
            yield s

def decode_item(next, token):
    if token == "i":
        # integer: "i" value "e"
        data = int(next())
        if next() != "e":
            raise ValueError
    elif token == "s":
        # string: "s" value (virtual tokens)
        data = next()
    elif token == "l" or token == "d":
        # container: "l" (or "d") values "e"
        data = []
        tok = next()
        while tok != "e":
            data.append(decode_item(next, tok))
            tok = next()
        if token == "d":
            data = dict(zip(data[0::2], data[1::2]))
    else:
        raise ValueError
    return data

def decode(text):
    try:
        src = tokenize(text)
        data = decode_item(src.next, src.next())
        for token in src: # look for more tokens
            raise SyntaxError("trailing junk")
    except (AttributeError, ValueError, StopIteration):
        raise SyntaxError("syntax error")
    return data

if __name__ == "__main__":
    data = open("test.torrent", "rb").read()
    torrent = decode(data)
    for file in torrent["info"]["files"]:
        print "%r - %d bytes" % ("/".join(file["path"]), file["length"])

다른 팁

나는 Rasterbar를 사용합니다 libtorrent 작고 빠른 C ++ 라이브러리입니다.
파일을 반복하려면 사용할 수 있습니다 Torrent_info 클래스 (begin_files (), end_files ()).

또한 a 파이썬 인터페이스 libtorrent의 경우 :

import libtorrent
info = libtorrent.torrent_info('test.torrent')
for f in info.files():
    print "%s - %s" % (f.path, f.size)

원래 Mainline Bittorrent 5.x 클라이언트의 Bencode.py (http://download.bittorrent.com/dl/bittorrent-5.2.2.tar.gz)는 Python에서 거의 참조 구현을 제공합니다.

BTL 패키지에 대한 가져 오기 의존성이 있지만 사소하게 제거하기 쉽습니다. 그런 다음 Bencode.bdecode (filecontent) [ 'info'] [ 'files']를 살펴 봅니다.

위의 아이디어를 확장하면 다음을 수행했습니다.

~> cd ~/bin

~/bin> ls torrent*
torrent-parse.py  torrent-parse.sh

~/bin> cat torrent-parse.py
# torrent-parse.py
import sys
import libtorrent

# get the input torrent file
if (len(sys.argv) > 1):
    torrent = sys.argv[1]
else:
    print "Missing param: torrent filename"
    sys.exit()
# get names of files in the torrent file
info = libtorrent.torrent_info(torrent);
for f in info.files():
    print "%s - %s" % (f.path, f.size)

~/bin> cat torrent-parse.sh
#!/bin/bash
if [ $# -lt 1 ]; then
  echo "Missing param: torrent filename"
  exit 0
fi

python torrent-parse.py "$*"

쉘 스크립트를 실행할 수 있도록 권한을 적절하게 설정하고 싶을 것입니다.

~/bin> chmod a+x torrent-parse.sh

이것이 누군가를 돕기를 바랍니다 :)

위의 Constantine의 답변의 코드는 다음과 같습니다. 토런트 파일 이름과 Fileset Filename의 유니 코드 문자를 처리하도록 약간 수정되었습니다.

import re

def tokenize(text, match=re.compile("([idel])|(\d+):|(-?\d+)").match):
    i = 0
    while i < len(text):
        m = match(text, i)
        s = m.group(m.lastindex)
        i = m.end()
        if m.lastindex == 2:
            yield "s"
            yield text[i:i+int(s)]
            i = i + int(s)
        else:
            yield s

def decode_item(next, token):
    if token == "i":
        # integer: "i" value "e"
        data = int(next())
        if next() != "e":
            raise ValueError
    elif token == "s":
        # string: "s" value (virtual tokens)
        data = next()
    elif token == "l" or token == "d":
        # container: "l" (or "d") values "e"
        data = []
        tok = next()
        while tok != "e":
            data.append(decode_item(next, tok))
            tok = next()
        if token == "d":
            data = dict(zip(data[0::2], data[1::2]))
    else:
        raise ValueError
    return data

def decode(text):
    try:
        src = tokenize(text)
        data = decode_item(src.next, src.next())
        for token in src: # look for more tokens
            raise SyntaxError("trailing junk")
    except (AttributeError, ValueError, StopIteration):
        raise SyntaxError("syntax error")
    return data

n = 0
if __name__ == "__main__":
    data = open("C:\\Torrents\\test.torrent", "rb").read()
    torrent = decode(data)
    for file in torrent["info"]["files"]:
        n = n + 1
        filenamepath = file["path"]     
        print str(n) + " -- " + ', '.join(map(str, filenamepath))
        fname = ', '.join(map(str, filenamepath))

        print fname + " -- " + str(file["length"])
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top