2008-11-27

Torrent to XML

В azureus/vulze есть замечательная фишка - импорт и экспорт торрентов.
Интересно было поставить флажок private на торрент - не пересчитывая хеш многогигабайтной раздачи.
На самом деле это было просто - был нюанс - требовалось удалить строчку с infohash - она не входит в итоговый торрент-файл, но вызывает сообщение об изменении секции info.

Исходники не понравились, зато догадался поискать внимательнее в CPAN.
Итог - несколько скриптов на одном "движке".
1. Скрипт torrent2xml или toXML.pl
#!/usr/bin/perl

use strict;
use Convert::Bencode qw(bencode bdecode);

use XML::Dumper;
use MIME::Base64;

undef $/;
foreach our $ARG (@ARGV)
{
open ARG;binmode ARG;$_=;close ARG;

my $t = bdecode($_);

${$t}{'info'}{'pieces'}=encode_base64(${$t}{'info'}{'pieces'},'');

$_= pl2xml($t);
s/ memory_address="0x[\da-f]+"//g;
open OUT,'>'.$ARG.'.xml'; print OUT;close OUT;
}


2. Скрипт xml2torrent или toTo.pl
#!/usr/bin/perl

use strict;
use Convert::Bencode qw(bencode bdecode);

use XML::Dumper;
use MIME::Base64;

undef $/;
foreach our $ARG (@ARGV)
{
open ARG;$_=;close ARG;
my $t = xml2pl($_);
${$t}{'info'}{'pieces'}=decode_base64(${$t}{'info'}{'pieces'});

my $name=$ARG;
$name.='.torrent' unless $name=~s/\.xml$//;

rename $name,$name.'~' if -f $name && !-f $name.'~';

open OUT,'>'.$name;binmode OUT;syswrite OUT,bencode($t);close OUT;
}


3. Общий скрипт "издевательства" над torrent файлами - добавляйте функциональность какую хотите.
#!/usr/bin/perl

use strict;
use Convert::Bencode qw(bencode bdecode);

undef $/;
foreach our $ARG (@ARGV)
{
open ARG;binmode ARG;$_=;close ARG;

my $t = bdecode($_);
# printf "%s: Processing %u bytes\n",$ARG,length($_);
my $mod=0;

${$t}{'info'}{'private'}=1, $mod=1 if ${$t}{'info'}{'private'} ne '1';
foreach my $key qw/private azureus_properties/
{
delete(${$t}{$key}), $mod=1 if exists ${$t}{$key};
}
if ($mod)
{
rename $ARG,$ARG.'~' unless -f $ARG.'~';

open OUT,'>'.$ARG;binmode OUT;syswrite OUT,bencode($t);close OUT;
print "Modified: $ARG\n"
} else {print "Unchanged: $ARG\n"}
}

Данная реализация убирает ключи private, azureus_properties вне секции info,
и в секции info добавляет флаг private.

Можно менять url анонсера, комментарии менять и делать другие нужные вещи..
Да. Не забудьте поставить модуль:
cpan Convert::Bencode

Сейчас думаю как бы интегрировать в торренты tiger-hash (TTH из DC++) и вообще сделать считалку torrent файлов :)
Для души..