diff options
| author | Alexander Færøy | 2014-05-31 13:10:46 +0200 | 
|---|---|---|
| committer | Alexander Færøy | 2014-05-31 13:10:46 +0200 | 
| commit | 2d0759e6ca5767b48bcc85bf38c2c43d5f0b63b1 (patch) | |
| tree | 1c5e6d817c88e67b46e216a50e0aef5428bf63df /scripts/xdccget.pl | |
| parent | 2d080422d79d1fd49d6c5528593ccaaff9bfc583 (diff) | |
| download | scripts.irssi.org-2d0759e6ca5767b48bcc85bf38c2c43d5f0b63b1.tar.bz2 | |
Import scripts from scripts.irssi.org
Diffstat (limited to 'scripts/xdccget.pl')
| -rw-r--r-- | scripts/xdccget.pl | 350 | 
1 files changed, 350 insertions, 0 deletions
| diff --git a/scripts/xdccget.pl b/scripts/xdccget.pl new file mode 100644 index 0000000..9f16bda --- /dev/null +++ b/scripts/xdccget.pl @@ -0,0 +1,350 @@ +# +# by Stefan "tommie" Tomanek <stefan@kann-nix.org> +# +# History: +# +# 26.02.2002 +# *first release, report bugs :) +# +# 01.03.2002 +# *CHanged to GPL +# +# 08.03.200 +# *some bugfixes +# +# 13.04.2002 +# *major improvements +# *cosmetic changes +#  +# 14.04.2002 +# *internal redesign +# *feature enhancements +# +# 17.04.2002 +# * improved queuing code +# * changed to $server->{tag} +# * improved communication with server +# +# 21.04.2002 +# *improved ETA listing +# +# 27.04.2002 +# *handling of gone bots added +# +# 28.04.2002 +# *fixed handling of servers that are not in an ircnet + +use strict; +#use warnings; + +use vars qw($VERSION %IRSSI); +$VERSION = "20040509"; +%IRSSI = ( +    authors     => "Stefan 'tommie' Tomanek", +    contact     => "stefan\@pico.ruhr.de", +    name        => "XDCCget", +    description => "advances downloading from XDCC bots", +    license     => "GPLv2", +    changed     => "$VERSION", +    commands	=> "xdccget" +); + +use Irssi 20020324; + +use vars qw(@queue $timer $debug %lists); + +$debug=0; + +sub show_help() { +    my $help="XDCCget $VERSION +/xdccget queue Nickname <number> <number>... +    Queue the specified packs of the server 'Nickname' +/xdccget list +    List the download queue +/xdccget cancel <number> +    Remove pack <number> from the local queue +/xdccget help +    Display this help +"; +    my $text = ''; +    foreach (split(/\n/, $help)) { +        $_ =~ s/^\/(.*)$/%9\/$1%9/; +        $text .= $_."\n"; +    } +    print CLIENTCRAP &draw_box("XDCCget", $text, "help", 1); +} + +sub draw_box ($$$$) { +    my ($title, $text, $footer, $colour) = @_; +    my $box = ''; +    my $exp_flags = Irssi::EXPAND_FLAG_IGNORE_EMPTY | Irssi::EXPAND_FLAG_IGNORE_REPLACES; +    $box .= '%R,--[%n%9%U'.$title.'%U%9%R]%n'."\n"; +    foreach (split(/\n/, $text)) {                                                      $box .= '%R|%n '.$_."\n"; +    }                                                                               $box .= '%R`--<%n'.$footer.'%R>->%n'; +    $box =~ s/%.//g unless $colour; +    return $box; +} + +sub contains { +    my ($item, @list) = @_; +    foreach (@list) { +	    ($item eq $_) && return 1; +    } +    return 0; +} + +sub event_message_irc_notice { +    my ($server, $msg, $nick, $address, $target) = @_; +    $_ = $msg; +    if ($queue[0] &&  $nick eq $queue[0]->{'nick'}) { +	if (/\*\*\* Closing Connection:/) { +	    print CLIENTCRAP "%R>>%n XDCC-Transfer closed"; +	    # Is it a canceled transger? +	    if ($queue[0]->{'status'} == 5) { +		$queue[0]->{'status'} = 4; +	    } else { +		# We should try again +		$queue[0]->{'status'} = 0; +	    } +	} elsif (/\*\*\* Transfer Completed/i) { +    	    print CLIENTCRAP "%R>>%n XDCC-Transfer completed"; +	    # Mark the transfer as completed +	    $queue[0]->{'status'} = 4; +	} elsif (/\*\*\* You already requested that pack/i) { +	    $queue[0]->{'status'} = 4; +	} elsif (/\*\*\* Sending You Pack/i || /\*\*\* Sending You Your Queued Pack|DCC Send .*? \(.*?\)/i) { +	    $queue[0]->{'status'} = 3; +	    print CLIENTCRAP "%R>>%n XDCC-Transfer starting"; +	} elsif (/\*\*\* All Slots Full, Added (|you to the main )queue in position ([0-9]*)/i) { +	    $queue[0]->{'pos'} = $2; +	    $queue[0]->{'etr'} = 0; +	    $queue[0]->{'status'} = 2; +	} elsif (/You have been queued for ([0-9]*?) hr ([0-9]*?) min, currently in main queue position ([0-9]*?) of ([0-9]*?)\.  Estimated remaining time is ([0-9]*?) hr ([0-9]*?) min or (less|more)\./i) { +	    $queue[0]->{'pos'} = $3; +	    $queue[0]->{'etr'} = time() + (($5*60)+$6)*60; +	    $queue[0]->{'status'} = 2; +	} elsif (/You have been queued for ([0-9]*?) hours ([0-9]*?) minutes, currently in main queue position ([0-9]*?) of ([0-9]*?)\./i) { +	    $queue[0]->{'pos'} = $3; +	    $queue[0]->{'status'} = 2; +	} elsif (/You have been queued for ([0-9]*?) minutes, currently in main queue position ([0-9]*?) of ([0-9]*?)\./) { +	    $queue[0]->{'status'} = 2; +	    # FIXME unite somehow with regexp above +	    $queue[0]->{'pos'} = $2; +	} elsif (/It has been placed in queue slot #(\d+), it will send when sends are available/) { +	    $queue[0]->{'pos'} = $1; +	    $queue[0]->{'status'} = 2; +	} elsif (/\*\*\* Invalid Pack Number/) { +	    $queue[0]->{'status'} = 4; +	} elsif (/\*\*\* The Owner Has Requested That No New Connections Are Made/) { +	    $queue[0]->{'status'} = 4; +	} elsif (/\*\*\* All Slots Full,(| Main) queue of size [0-9]* is Full, Try Again Later/i || /\*\*\* You can only have 1 transfer at a time/i) { +	    if (Irssi::settings_get_int('xdccget_retry_time') > 0) { +		my $retry = Irssi::settings_get_int('xdccget_retry_time')*1000; +		$queue[0]->{'status'} = 6; +		$queue[0]->{'timer'} = Irssi::timeout_add($retry, 'retry_transfer', undef); +		$queue[0]->{'etr'} = time()+$retry/1000; +	    } else { +		$queue[0]->{'status'} = 4; +	    } +	} elsif (/Removed you from the queue/) { +	    $queue[0]->{'status'} = 4; +	} else { Irssi::print($_) if ($debug); } +	 +	process_queue(); +    } +    if (/#(\d+).+?\d+x \[ *(<?\d+.*?)\] +(.*)$/) { +	my ($pack, $size, $name) = ($1, $2, $3); +    	if (defined $lists{lc $server->{tag}}{lc $nick}) { +	    $lists{lc $server->{tag}}{lc $nick}{$pack} = $name; +	} +	foreach (@queue) { +	    next unless lc $nick eq lc $_->{nick}; +	    next unless lc $server->{tag} eq lc $_->{net}; +	    next unless $_->{pack} eq $pack; +	    $_->{filename} = $name; +	} +    } +} + +sub process_queue { +    unless (scalar(@queue) > 0) {return 0}; +    my %current = %{$queue[0]}; +    shift @queue if ( $current{'status'} == 4 ); +    unless (scalar(@queue) > 0) {return 0}; +    %current = %{$queue[0]}; +    if ( $current{'status'} == 0 ) { +	my $server = Irssi::server_find_tag($current{'net'}); +    	$server->command('MSG '.$current{'nick'}.' xdcc send '.$current{'pack'}); +	$queue[0]->{'try'}++; +	$queue[0]->{'status'} = 1; +    } +} + +sub retry_transfer { +    if (defined $queue[0] && $queue[0]->{'status'} == 6) { +	Irssi::timeout_remove($queue[0]->{'timer'}); +	#print CLIENTCRAP "%R>>%n Retrying XDCC-transfer..."; +	$queue[0]->{'status'} = 0; +	process_queue(); +    } +} + +sub queue_pack { +    my ($args, $server, $witem) = @_; +    my @args = split(/ /, $args, 2); +    my ($nick, $packs); +    if (ref $witem && $witem->{type} eq 'QUERY' && $args[0] =~ /^\d+$/) { +	($nick, $packs) = ($witem->{name}, $args[0]); +    } else { +	($nick, $packs) = @args; +    } +    my @packs = split(/ /, $packs); +    foreach (@packs) { +	# 0: Waiting, 1: Processing, 2: Doenloading +	my $status = 0; +	my $chatnet = $server->{tag}; +	my %transfer = ('nick'    => $nick, +			'pack'    => $_, +			'status'  => $status, +			'net'     => $chatnet, +			'pos'     => 0, +			'try'     => 0, +			'etr'     => 0, +			'timer'   => undef, +			); +	if (defined $lists{lc $server->{tag}}{lc $nick}{$_}) { +	    $transfer{filename} = $lists{lc $server->{tag}}{lc $nick}{$_}; +	} +	push @queue, \%transfer; +    } +    process_queue() +} + +sub list_xdcc_queue { +    my $text; +    my %progress = (0=>'waiting', +		    1=>'requesting', +		    2=>'queued', +		    3=>'transferring', +		    4=>'completed', +		    5=>'canceling', +		    6=>'retrying'); +    my $i = 1; +    foreach (@queue) { +	my $current = $_; +	my $botname = $current->{'nick'}; +	my $ircnet = $current->{'net'}; +	my $pack = $current->{'pack'}; +	my $status = $progress{$current->{'status'}}; +	my $info = ''; +	my $etr = ''; +	if ($current->{'status'}==2) { +	    my $time = $current->{'etr'}-time(); +            my $hours = int($time / (60*60)); +            my $minutes = int( ($time-($hours*60*60))/60 ); +            my $seconds = int( ($time-($hours*60*60)-($minutes*60))  ); + +            $etr = '('.$hours.' hours, '.$minutes.' minutes and '.$seconds.' seconds remaining)' if ($current->{'etr'} > 0); +	    $info = "[".$current->{'pos'}."]".' '.$etr; +	} elsif ($current->{'status'}==6) { +	    my $time = $current->{'etr'}-time(); +	    my $hours = int($time / (60*60)); +	    my $minutes = int( ($time-($hours*60*60))/60 ); +	    my $seconds = int( ($time-($hours*60*60)-($minutes*60))  ); +	     +	    $etr = '('.$hours.' hours, '.$minutes.' minutes and '.$seconds.' seconds remaining)' if ($current->{'etr'} > 0); +	    $info = '['.$current->{'try'}.']'.' '.$etr; +	} +	$text .= "%9".$i."%9 ".$botname."<".$ircnet.">: Pack ".$pack; +	$text .= " (".$current->{filename}.")" if defined $current->{filename}; +	$text .= " => ".$status.' '.$info; +	$text .= "\n"; +	$i++; +    } +    print CLIENTCRAP draw_box("XDCCget", $text, "queued packs", 1); +} + +sub cancel_pack { +    my (@numbers) = @_; +    @numbers = sort {$b cmp $a} @numbers; +    foreach (@numbers) { +	my $item = @queue->[$_-1]; + +	if ($item->{'status'} == 2) { +	    # Remove the order from the bots queue +	    my $server = Irssi::server_find_tag($item->{'net'}); +	    $server->command('MSG '.$item->{'nick'}.' xdcc remove'); +	    print CLIENTCRAP "%R>>>%n Removing pack ".$_." from server queue"; +	    $item->{'status'} = 5; +	    #splice(@queue, $_,$_+1); +	} elsif ($item->{'status'} == 3) { +	    $item->{'status'} = 5; +	    Irssi::command('DCC close get '.$item->{'nick'}); +	    print CLIENTCRAP "%R>>>%n Transfer aborted, waiting for acknowledgement"; +	} else { +	    splice(@queue, $_-1, $_); +	} +	process_queue(); +    } +} + +sub list_packs ($$) { +    my ($server, $bot) = @_; +    $server->command('MSG '.$bot.' xdcc list'); +    $lists{lc $server->{tag}}{lc $bot} = {}; +} + +sub cmd_xdccget { +    my ($args, $server, $witem) = @_; +    my @arg = split(/ /, $args); + +    if ((scalar(@arg) == 0) or ($arg[0] eq '-l')) { +	list_xdcc_queue(); +    } elsif ($arg[0] eq 'queue') { +	# queue files +	shift @arg; +	queue_pack("@arg", $server, $witem); +    } elsif ($arg[0] eq 'list' && defined $arg[1]) { +	list_packs($server, $arg[1]); +    } elsif ($arg[0] eq 'cancel') { +	shift @arg; +	cancel_pack(@arg); +    } elsif ($arg[0] eq 'help') { +	show_help(); +    } +} + +sub event_private_message { +    my ($server, $text, $nick, $address) = @_; +    event_message_irc_notice($server, $text, $nick, $address, undef); +} + +sub event_no_such_nick { +    my ($server, $args, $sender_nick, $sender_address) = @_; +    my ($myself, $nick) = split(/ /, $args, 3); +     +    unless (scalar(@queue) == 0) { +	if ($nick eq $queue[0]->{'nick'}) { +	    if ($queue[0]->{'status'} == 1 || $queue[0]->{'status'} == 5) { +		$queue[0]->{'status'} = 4; +	    } +	} +	process_queue(); +    } +} + + +Irssi::command_bind('xdccget', \&cmd_xdccget); +foreach my $cmd ('queue', 'cancel', 'list', 'help', 'list') { +    Irssi::command_bind('xdccget '.$cmd => sub { +                        cmd_xdccget("$cmd ".$_[0], $_[1], $_[2]); }); +} + + +Irssi::signal_add('message irc notice', 'event_message_irc_notice'); +Irssi::signal_add("message private", "event_private_message"); +Irssi::signal_add("event 401", "event_no_such_nick"); + +Irssi::settings_add_int($IRSSI{'name'}, 'xdccget_retry_time', 30); + +print CLIENTCRAP '%B>>%n '.$IRSSI{name}.' '.$VERSION.' loaded: /xdccget help for help'; | 
