Хороший API-интерфейс BitTorrent-трекера? - PullRequest
2 голосов
/ 27 июля 2011

Знаете ли вы какой-либо простой в использовании, удобный API для Python или Perl для взаимодействия с BitTorrent-трекерами? Например, я беру торрент-файл, перечисляю все трекеры в файле и спрашиваю у трекера статистику пиров, связанных с загруженным файлом?

Спецификация BitTorrent Tracker не слишком сложна, но я не хочу изобретать велосипед :))

Обратите внимание, что я не хочу загружать данные, просто чтобы получить некоторую статистику (Net :: BitTorrent гораздо больше, чем мне нужно)

Ответы [ 3 ]

3 голосов
/ 27 июля 2011

Просто простой командной строки не достаточно?:-) ( Transmission ) предоставляет вам translation-remote инструмент, который позволяет перечислять трекеры и получать статистику пиров с помощью одной команды.Посмотрите на

     -pi --peer-info
         List the current torrent's connected peers.  In the `status' section of the list, the following shorthand is used:
               D: Downloading from this peer
               d: We would download from this peer if they would let us
               E: Encrypted connection
               I: Peer is an incoming connection
               K: Peer has unchoked us, but we're not interested
               O: Optimistic unchoked
               U: Uploading to peer
               u: We would upload to this peer if they asked
               X: Peer was discovered through Peer Exchange (PEX)
               ?: We unchoked this peer, but they're not interested
...

     -si --session-info
         List session information from the server

Ну, чтобы использовать его, вы должны использовать передачу в качестве торрент-клиента, но если вы это сделаете, вы можете сделать это с помощью grep, это зависит от того, чего вы действительно хотите достичь.

2 голосов
/ 31 марта 2012

Посмотрите на py-transmission

Редактировать: С тех пор как я написал это, я обнаружил, что RPC-интерфейс translationbt чрезвычайно хорошо документирован и достаточно удобен для пользователя, еслиВы нашли время, чтобы изучить основы.

0 голосов
/ 28 июля 2011

Я создал скрипт Perl для получения данных из файлов .torrent, объединения трекеров и получения некоторой статистики (хэш файла, IP-адрес, связанный с трекером, размер файла и т. Д.). Никакой большой науки, только немного Perl-fu. Для его запуска вам понадобятся: Perl-модуль Bencode , curl и Transmission-Show . Отладочный мусор отправляется на stderr , а правильный вывод на stdout .

#!/usr/bin/perl

use Bencode qw( bencode bdecode );
use Data::Dumper;

use warnings;
use strict;

my $G_PEER_ID = "hfgdbvnchdgfhvnfbghf";
my $G_MAX_TIME = 20;

sub peer_decode
{
    my $d = shift;
    my @a = split '', $d;
#    printf ">>%d %d<<\n", length($d), scalar(@a);

    my @ret;

    while(@a) {
        my $ip = sprintf "%d.%d.%d.%d" ,
                unpack('C',shift(@a)),
                unpack('C',shift(@a)),
                unpack('C',shift(@a)),
                unpack('C',shift(@a));
        my $port = sprintf "%d", 256 * unpack('C',shift(@a))
                                     + unpack('C',shift(@a));

#        printf "%d $ip $port\n",scalar(@a);
        push @ret, $ip;
    }
    return \@ret;
}


sub get_tracker_data_from_file
{
    my $fname = shift;

    my $ret = {};

    my $c = `transmission-show $fname`;

    print STDERR "$c\n";

    if ( $c =~ /^\s+Hash:\s*(\S+)/mg ) {
        $ret->{'hash'} = $1;
    }

    if ( $c =~ /^\s+Total Size:\s*(.+)$/mg ) {
        $ret->{'size'} = $1;
    }

    my @g;
    @g = ($c =~ /Tier \#\d+[\n\r\s]+(\S+)/gm);
    if ( @g ) {
        $ret->{'tiers'} = \@g;
    }

    return $ret;

}

sub get_peer_ips
{
    my $hash = shift;
    my $tracker = shift;

    my $ret = undef;

    $hash =~ s/(..)/\%$1/g;
    $tracker =~ s/\/$//;

    my $c = "curl -m $G_MAX_TIME -s '$tracker?info_hash=$hash&peer_id=$G_PEER_ID&uploaded=0&downloaded=0&left=1'";
    print STDERR "$c\n";

    my $w = `$c`;
    return undef if not $w;
    printf STDERR "%s\n" , Dumper($w);
    return undef if $w =~ /<\s*html\s*>/gi;

    $w = bdecode($w, 1);

    if ( defined $w->{'peers'} ) {
        $ret = peer_decode($w->{'peers'});
    }
    return $ret;
}

# -- main

my @files = @ARGV;

if ( not @files ) {
    print <<END
    usage: $0 <file1.torrent> <file2.torrent> ...

    (c) http://stackoverflow.com/users/497208
END
}

for my $fname ( @files ) {
    printf STDERR "File: %s\n", $fname;

    my $tr = get_tracker_data_from_file($fname);
    printf STDERR "%s\n", Dumper $tr;

    my $hash = undef;
    $hash = $tr->{'hash'} if defined $tr->{'hash'};
    exit if not defined $hash;

    my $size = undef;
    if ( defined $tr->{'size'} ) {
        $size = $tr->{'size'};
    }
    else {
        $size = "?";
    }

    if ( defined $tr->{'tiers'} ) {
    #    shift @{$tr->{'tiers'}} for (1..5);
        for my $tracker ( @{$tr->{'tiers'}} ) {

            my $ips = get_peer_ips( $hash, $tracker);
            printf STDERR "%s\n", Dumper $ips;

            if ( defined $ips ) {
                for my $ip ( @$ips ) {
                    my $c = sprintf "%s; %16s; %s; %s", $hash, $ip, $size, $tracker;
                    printf STDERR "$c\n";
                    printf "$c\n";
                }
            }
        }
    }
}
...