【问题标题】:Nice BitTorrent tracker API?不错的 BitTorrent 跟踪器 API?
【发布时间】:2012-08-11 11:22:20
【问题描述】:

您知道任何易于使用、简洁的 Python 或 Perl API 以与 BitTorrent Trackers 交互吗?例如,我拿一个 torrent 文件,枚举文件中的所有 tracker,然后向 tracker 询问与下载文件相关的 peer 的统计信息?

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

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

【问题讨论】:

标签: python perl api bittorrent


【解决方案1】:

简单的命令行还不够吗? :-) (Transmission) 为您提供 transmission-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

嗯,要使用它,您必须使用传输作为您的 torrent 客户端,但如果您这样做了,那么您可以使用 grep 来完成,这取决于您真正想要实现的目标。

【讨论】:

  • 它不在标准的 Ubuntu 软件包中:apt-get install transmission-cli transmission-common transmission-daemontransmission-show 也很有用
  • 问题:transmission-remote 给出Unexpected response: <h1>401: Unauthorized</h1>Unauthorized Useroded 错误,即使跟踪器不需要身份验证...
  • 这不是跟踪器的问题 - 查看有关在配置守护进程中配置访问列表和远程管理访问权限的文档,也许您只是想关闭它们?检查 ~/.config/transmission 或 /etc/transmission-daemon(取决于您如何启动它)中的 settings.json 以获取 rpc-* 选项。注意,如果您将它作为守护进程运行,仅在 /etc 中编辑配置是不够的 - 您需要重新加载服务传输守护进程,因为它会在退出时悄悄地覆盖 settings.conf。检查是否可以使用 rpc 访问 localhost:9091 默认情况下
  • 一定要试试transmission-remote host:9091 --auth=username:password -l (用户名和密码通过传输接口或者settings.json配置)
【解决方案2】:

看看py-transmission

编辑:自从我写了这篇文章后,我发现transmissionbt's RPC interface 的文档非常好,并且如果您花时间学习基础知识,那么用户友好性就足够了。

【讨论】:

    【解决方案3】:

    我编写了 Perl 脚本来从 .torrent 文件中获取数据、汇集跟踪器并获取一些统计信息(文件哈希、连接到跟踪器的 IP、文件大小等)。没有什么大科学,只是一些 Perl-fu。要运行它,您需要:安装 Perl 模块 Bencodecurltransmission-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";
                    }
                }
            }
        }
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多