Nice BitTorrent跟踪器API?

时间:2011-07-27 12:04:44

标签: python perl api bittorrent

你知道Python或Perl的任何易于使用,整洁的API与BitTorrent Trackers交互吗?例如,我获取一个torrent文件,枚举文件中的所有跟踪器,并向跟踪器询问与下载文件相关的对等体的统计信息?

BitTorrent Tracker规范并不太复杂,但我不想重新发明轮子:)

请注意,我不想下载数据,只是为了获取一些统计数据(Net :: BitTorrent远远超过我的需要)

3 个答案:

答案 0 :(得分:3)

只是简单的命令行是不够的? :-)(Transmission)为您提供传输远程工具,该工具允许枚举跟踪器并使用一个命令获取对等统计信息。看看

     -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

好吧,要使用它,你必须使用传输作为你的torrent客户端,但如果你这样做,你可以用grep来做,这取决于你真正想要实现的目标。

答案 1 :(得分:2)

查看py-transmission

编辑:自从我写这篇文章以来,我发现如果您花时间学习基础知识,那么transmissionbt's RPC interface就会有很好的文档记录和用户友好性。

答案 2 :(得分:0)

我制作了Perl脚本以从.torrent文件中获取数据,汇集跟踪器并获取一些统计信息(文件哈希,连接到跟踪器的IP,文件大小等)。没有大科学,只有一些Perl-fu。要运行它,您需要:安装Perl模块 Bencode curl 传输 - 显示。调试垃圾被发送到 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";
                }
            }
        }
    }
}