| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- #!/usr/bin/perl
- ################################################################################
- # $Id: ttools.pl 2823 2007-04-07 08:37:43Z warion $
- # $Revision: 2823 $
- # $Date: 2007-04-07 03:37:43 -0500 (Sat, 07 Apr 2007) $
- ################################################################################
- # #
- # LICENSE #
- # #
- # This program is free software; you can redistribute it and/or #
- # modify it under the terms of the GNU General Public License (GPL) #
- # as published by the Free Software Foundation; either version 2 #
- # of the License, or (at your option) any later version. #
- # #
- # This program is distributed in the hope that it will be useful, #
- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- # GNU General Public License for more details. #
- # #
- # To read the license please visit http://www.gnu.org/copyleft/gpl.html #
- # #
- # #
- ################################################################################
- # #
- # Requirements : #
- # * Digest::SHA1 ( perl -MCPAN -e "install Digest::SHA1" ) #
- # * LWP::UserAgent ( perl -MCPAN -e "install LWP::UserAgent" ) #
- # #
- ################################################################################
- use strict;
- ################################################################################
- # timeout for url-get
- my $TIMEOUT = 5;
- # Internal Vars
- my ($VERSION, $DIR, $PROG, $EXTENSION, $USAGE);
- #-------------------------------------------------------------------------------
- # Main
- #-------------------------------------------------------------------------------
- # init some vars
- $VERSION =
- do { my @r = (q$Revision: 2823 $ =~ /\d+/g); sprintf "%d"."%02d" x $#r, @r };
- ($DIR=$0) =~ s/([^\/\\]*)$//;
- ($PROG=$1) =~ s/\.([^\.]*)$//;
- $EXTENSION=$1;
- # main-"switch"
- SWITCH: {
- $_ = shift @ARGV;
- /info|.*-i/ && do { # --- info ---
- loadModules();
- torrentInfo(shift @ARGV);
- exit;
- };
- /scrape|.*-s/ && do { # --- scrape ---
- loadModules();
- torrentScrape(shift @ARGV);
- exit;
- };
- /check/ && do { # --- check ---
- check();
- exit;
- };
- /.*(version|-v).*/ && do { # --- version ---
- printVersion();
- exit;
- };
- /.*(help|-h).*/ && do { # --- help ---
- printUsage();
- exit;
- };
- printUsage();
- exit;
- }
- #===============================================================================
- # Subs
- #===============================================================================
- #------------------------------------------------------------------------------#
- # Sub: torrentInfo #
- # Parameters: string with path to torrent-meta-file #
- # Return: null #
- #------------------------------------------------------------------------------#
- sub torrentInfo {
- my $torrentFile = shift;
- if (!(defined $torrentFile)) {
- printUsage();
- exit;
- }
- if (!(-f $torrentFile)) {
- print "Error : ".$torrentFile." is no file\n";
- exit;
- }
- my $torrent = new Net::BitTorrent::File($torrentFile);
- if (!(defined $torrent)) {
- print "Error loading torrent-meta-file ".$torrentFile."\n";
- exit;
- }
- # hash
- my $hash = $torrent->info_hash();
- $hash =~ s/(.)/sprintf("%02x",ord($1))/egs;
- print "hash : ".lc($hash)."\n";
- # name
- print "name : ".$torrent->name()."\n";
- # announce
- print "announce : ".$torrent->announce()."\n";
- # files + size
- my $info = $torrent->info();
- my $torrentSize = 0;
- print "file(s) : \n";
- if (defined($info->{'files'})) {
- foreach my $fileEntry (@{$info->{'files'}}) {
- $torrentSize += $fileEntry->{'length'};
- if (ref($fileEntry->{'path'}) eq 'ARRAY') {
- print " ".$info->{'name'}.'/'.$fileEntry->{'path'}->[0]." (".$fileEntry->{'length'}.")\n";
- } else {
- print " ".$info->{'name'}.'/'.$fileEntry->{'path'}." (".$fileEntry->{'length'}.")\n";
- }
- }
- } else {
- $torrentSize += $info->{'length'},
- print " ".$info->{'name'}." (".$info->{'length'}.")\n";
- }
- print "size : ".$torrentSize."\n";
- }
- #------------------------------------------------------------------------------#
- # Sub: torrentScrape #
- # Parameters: string with path to torrent-meta-file #
- # Return: null #
- #------------------------------------------------------------------------------#
- sub torrentScrape {
- my $torrentFile = shift;
- if (!(defined $torrentFile)) {
- printUsage();
- exit;
- }
- if (!(-f $torrentFile)) {
- print "Error : ".$torrentFile." is no file\n";
- exit;
- }
- my $torrent = new Net::BitTorrent::File($torrentFile);
- if (!(defined $torrent)) {
- print "Error loading torrent-meta-file ".$torrentFile."\n";
- exit;
- }
- # get hash
- my $hash = $torrent->info_hash();
- $hash =~ s/(.)/sprintf("%02x",ord($1))/egs;
- $hash = lc($hash);
- # get scrape url
- my $scrapeUrl;
- if ((index($torrent->announce(), "/announce")) > 0) {
- $scrapeUrl = $torrent->announce();
- $scrapeUrl =~ s#/announce#/scrape#ig;
- } else {
- print "Error : could not get scrape-url\n";
- exit;
- }
- # get scrape info
- my $res = getUrl($scrapeUrl);
- if (!($res->is_success)) {
- print "Error : could not fetch scrape-infos : ".$res->status_line()."\n";
- exit;
- }
- # decode data
- my $info;
- eval {
- $info = Convert::Bencode::bdecode($res->content);
- };
- if ($@) {
- print "Error : cant decode info-data : ".$@."\n";
- exit;
- }
- # check result
- if (!(defined $info)) {
- print "Error in tracker-response.\n";
- exit;
- }
- if (!(ref($info) eq 'HASH')) {
- print "Error in tracker-response.\n";
- exit;
- }
- if (!(exists($info->{'files'}))) {
- print "Error : tracker-response did not contain files.\n";
- exit;
- }
- # process response
- foreach my $fileEntry (%{$info->{'files'}}) {
- my $t = $info->{'files'}{$fileEntry};
- my $fileHash = $fileEntry;
- $fileHash =~ s/(.)/sprintf("%02x",ord($1))/egs;
- $fileHash = lc($fileHash);
- if ($fileHash eq $hash) {
- print $t->{'complete'}." seeder(s), ";
- print $t->{'incomplete'}." leecher(s).\n";
- exit;
- }
- }
- # error
- print "Error : tracker-response did not contain requested info.\n";
- exit;
- }
- #------------------------------------------------------------------------------#
- # Sub: getUrl #
- # Parameters: string with url #
- # Return: res #
- #------------------------------------------------------------------------------#
- sub getUrl() {
- my $url = shift;
- my $ua = LWP::UserAgent->new(
- 'agent' => $PROG.$EXTENSION."/".$VERSION,
- 'timeout' => $TIMEOUT
- );
- return $ua->get($url);
- }
- #------------------------------------------------------------------------------#
- # Sub: loadModules #
- # Arguments: null #
- # Returns: null #
- #------------------------------------------------------------------------------#
- sub loadModules {
- # load Digest::SHA1
- if (eval "require Digest::SHA1") {
- Digest::SHA1->import();
- } else {
- print STDERR "Error : cant load perl-module Digest::SHA1 : ".$@."\n";
- exit;
- }
- # load LWP::UserAgent
- if (eval "require LWP::UserAgent") {
- LWP::UserAgent->import();
- } else {
- print STDERR "Error : cant load perl-module LWP::UserAgent : ".$@."\n";
- exit;
- }
- # load Convert::Bencode
- if (eval "require Convert::Bencode") {
- Convert::Bencode->import();
- } else {
- print STDERR "Error : cant load perl-module Convert::Bencode : ".$@."\n";
- exit;
- }
- # load Net::BitTorrent::File
- if (eval "require Net::BitTorrent::File") {
- Net::BitTorrent::File->import();
- } else {
- print STDERR "Error : cant load perl-module Net::BitTorrent::File : ".$@."\n";
- exit;
- }
- }
- #------------------------------------------------------------------------------#
- # Sub: check #
- # Arguments: Null #
- # Returns: info on system requirements #
- #------------------------------------------------------------------------------#
- sub check {
- print "checking requirements...\n";
- # 1. perl-modules
- print "1. perl-modules\n";
- my @mods = ('Digest::SHA1', 'LWP::UserAgent', 'Convert::Bencode', 'Net::BitTorrent::File');
- foreach my $mod (@mods) {
- if (eval "require $mod") {
- print " - ".$mod."\n";
- next;
- } else {
- print "Error : cant load module ".$mod."\n";
- # Turn on Autoflush;
- $| = 1;
- print "Should we try to install the module with CPAN ? (y|n) ";
- my $answer = "";
- chomp($answer=<STDIN>);
- $answer = lc($answer);
- if ($answer eq "y") {
- exec('perl -MCPAN -e "install '.$mod.'"');
- }
- exit;
- }
- }
- # done
- print "done.\n";
- }
- #------------------------------------------------------------------------------#
- # Sub: printVersion #
- # Arguments: Null #
- # Returns: Version Information #
- #------------------------------------------------------------------------------#
- sub printVersion {
- print $PROG.".".$EXTENSION." Version ".$VERSION."\n";
- }
- #------------------------------------------------------------------------------#
- # Sub: printUsage #
- # Parameters: null #
- # Return: null #
- #------------------------------------------------------------------------------#
- sub printUsage {
- print <<"USAGE";
- $PROG.$EXTENSION (Revision $VERSION)
- Usage: $PROG.$EXTENSION operation path-to-torrent-meta-file
- $PROG.$EXTENSION check
- $PROG.$EXTENSION version
- $PROG.$EXTENSION help
- Operations :
- -i : decode and print out torrent-info.
- -s : get scrape-info and print out seeders + leechers.
- Examples:
- $PROG.$EXTENSION -i /foo/bar.torrent
- $PROG.$EXTENSION -s /foo/bar.torrent
- USAGE
- }
- # EOF
|