Frage

Ich möchte (schnell) stellte ein Programm / Skript zusammen, um die Dateigruppe aus einer Torrent-Datei zu lesen. Ich mag dann diesen Satz verwenden, um alle Dateien aus einem bestimmten Verzeichnis zu löschen, die den Strom nicht gehören.

Alle Empfehlungen auf eine handliche Bibliothek für diesen Index aus der .torrent-Datei zu lesen? Während ich ihm nicht widersprechen, ich will nicht tief in die Bittorrent-spec zu graben und eine Last von Code von Grund auf für diesen einfachen Zweck rollen.

Ich habe keine Vorliebe für die Sprache.

War es hilfreich?

Lösung

Effbot hat Ihre Frage beantwortet . Dies ist der komplette Code, um die Liste der Dateien von .torrent-Datei (Python 2.4 +) zu lesen:

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"])

Andere Tipps

würde ich rasterbar des verwenden libtorrent , die eine kleine und schnelle C ++ Bibliothek ist.
Iterieren die Dateien können Sie den torrent_info Klasse (begin_files (), end_files ()).

Es gibt auch eine Python-Schnittstelle libtorrent:

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

bencode.py von dem ursprünglichen Magistrale BitTorrent 5.x-Client ( http://download.bittorrent.com/dl/BitTorrent-5.2.2.tar.gz ) würden Sie so ziemlich die Referenz-Implementierung in Python geben.

Es hat eine Importabhängigkeit von dem BTL-Paket, aber das ist einfach leicht zu entfernen. Sie würden dann sehen bencode.bdecode (filecontent) [ 'info'] [ 'Dateien'].

Aufbauend auf den Ideen oben, ich habe folgende:

~> 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 "$*"

Sie werden Berechtigungen festlegen möchten in geeigneter Weise das Shell-Skript ausführbar zu machen:

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

Hope, das hilft jemand:)

Hier ist der Code von Konstantins Antwort oben, leicht modifiziert, um Unicode-Zeichen in Torrent-Dateinamen und Dateigruppe Dateinamen in torrent info zu behandeln:

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"])
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top