summaryrefslogtreecommitdiffstats
path: root/scripts/xdccget.pl
diff options
context:
space:
mode:
authorobfuscoder2014-10-16 14:47:21 +0200
committerObfuscoder2015-05-03 21:32:51 +0200
commit4c4175129851b1dc0a7857cac2bec935388c3140 (patch)
tree885f7671d307a21c7db698d94624ca59fbac1fa3 /scripts/xdccget.pl
parent0a0ba125acd8e929dfcd4809f900ce251b5ddc50 (diff)
downloadscripts.irssi.org-4c4175129851b1dc0a7857cac2bec935388c3140.tar.bz2
Update xdccget.pl with queue management and search
Update xdccget.pl with some queue management and search capabilities. (pausing, retries, max parallel downloads). Rework of help output.
Diffstat (limited to 'scripts/xdccget.pl')
-rw-r--r--scripts/xdccget.pl752
1 files changed, 526 insertions, 226 deletions
diff --git a/scripts/xdccget.pl b/scripts/xdccget.pl
index 9f16bda..b6d396c 100644
--- a/scripts/xdccget.pl
+++ b/scripts/xdccget.pl
@@ -1,70 +1,157 @@
-#
-# 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
+# Original version by Stefan "tommie" Tomanek <stefan@kann-nix.org>
+# Enhanced with max. download limits, retries, pausing, searching and other neat stuff by Obfuscoder (obfuscoder@obfusco.de)
+# You can find the script on GitHub: https://github.com/obfuscoder/irssi_scripts
+# Please report bugs to https://github.com/obfuscoder/irssi_scripts/issues
use strict;
-#use warnings;
+use warnings;
use vars qw($VERSION %IRSSI);
-$VERSION = "20040509";
+$VERSION = "20141016";
%IRSSI = (
- authors => "Stefan 'tommie' Tomanek",
- contact => "stefan\@pico.ruhr.de",
- name => "XDCCget",
- description => "advances downloading from XDCC bots",
+ authors => "Stefan 'tommie' Tomanek, Obfuscoder",
+ contact => "obfuscoder\@obfusco.de",
+ name => "xdccget",
+ description => "enhanced downloading, queing, searching from XDCC bots",
license => "GPLv2",
changed => "$VERSION",
- commands => "xdccget"
+ commands => "xdccget"
);
use Irssi 20020324;
-use vars qw(@queue $timer $debug %lists);
+use vars qw(@queue @completed %offers $timer $debug %lists);
+
+Irssi::settings_add_str($IRSSI{'name'}, 'xdccget_config_path', "$ENV{HOME}/.irssi");
+Irssi::settings_add_int($IRSSI{'name'}, 'xdccget_max_downloads', 2);
+Irssi::settings_add_int($IRSSI{'name'}, 'xdccget_retry_time', 5);
$debug=0;
+my $config_path = Irssi::settings_get_str('xdccget_config_path');
+my $max_downloads = Irssi::settings_get_int('xdccget_max_downloads');
+my $queue_file = "$config_path/xdccget.queue";
+sub saveQueue {
+ if (!open (QUEUE, q{>}, $queue_file)) {
+ print CLIENTCRAP "XDCCGET - ERROR! Cannot open queue file for saving at $queue_file. $!";
+ return;
+ }
+ foreach (@queue) {
+ print QUEUE $_->{net}."\t".$_->{nick}."\t".$_->{pack}."\t".$_->{filename}."\t".$_->{xdcc}."\n";
+ }
+ if (!close QUEUE) {
+ print CLIENTCRAP "XDCCGET - ERROR! Could not close queue file after saving at $queue_file. $!";
+ }
+}
+
+sub loadQueue {
+ @queue = ();
+ if (!open (QUEUE, q{<}, $queue_file)) {
+ print CLIENTCRAP "XDCCGET - Warning: Could open queue file for loading from $queue_file: $!";
+ return;
+ }
+ while (<QUEUE>) {
+ chomp;
+ my ($net, $nick, $pack, $desc, $xdcc) = split (/\t/);
+ if ($xdcc eq "") {
+ $xdcc = "xdcc";
+ }
+ my %transfer = (
+ 'nick' => $nick,
+ 'pack' => $pack,
+ 'status' => 'waiting',
+ 'net' => $net,
+ 'pos' => 0,
+ 'try' => 0,
+ 'etr' => 0,
+ 'timer' => undef,
+ 'xdcc' => $xdcc,
+ 'filename' => $desc,
+ );
+ push @queue, \%transfer;
+ }
+ if (!close QUEUE) {
+ print CLIENTCRAP "XDCCGET - ERROR! Could not close queue file after loading at $queue_file. $!";
+ }
+}
+
+sub debugFunc {
+ return unless ($debug);
+ my $funcname = shift (@_);
+ print CLIENTCRAP "XDCC-DEBUG - $funcname (". join(",",@_).")\n";
+}
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
+ Commands:
+
+ /xdccget queue <nickname> <number> [[-xdcc=<method>] <description>]
+ Queue the specified pack of the currently selected server and 'Nickname'.
+ The description will be shown in the queue.
+ With -xdcc=<method> it is possible to specify the method to be used in the request.
+ Default is 'xdcc' as in /msg <nickname> xdcc send <number>
+
+ /xdccget stat
+ /xdccget
+ /xdccget -l
+ List the download queue
+
+ /xdccget list <nickname>
+ Request the XDCC list of <nickname>
+
+ /xdccget cancel <number>
+ Cancel the download if currently downloading, request to being removed from queue
+ if queued by the XDCC offerer, or remove pack <number> from the download queue
+
+ /xdccget pause <number>
+ Pause pack <number> within the local queue. Resume with reset
+
+ /xdccget reset <number>
+ Reset pack <number> so that it is unpaused and --
+ if download slots are still available -- triggers a download request
+
+ /xdccget offers [<options>] <description search pattern>
+ Display all the announced offers matching the given pattern or options.
+ The announcements are continuously monitored by this script throughout all joined channels.
+
+ Options:
+ One or more of the following options can be used. Each option must start with a '-':
+
+ -server=<server pattern> only show offers announced by bots on servers matching this pattern
+ -channel=<channel pattern> only show offers announced by bots on channels matching this pattern
+ -nick=<nick pattern> only show offers announced by bots with nicks matching this pattern
+
+ Examples:
+ /xdccget offers iron.*bluray
+ /xdccget offers -nick=bot iron.*bluray
+ /xdccget offers -channel=beast-xdcc iron.*bluray
+
+ Regular expressions are used to match each of the parameters.
+
+ /xdccget help
+ Display this help
+
+ You can also simply use /x instead of /xdccget ;-)
+
+ Configuration:
+
+ xdccget_config_path
+ Path where this script is storing its files (queue and finished downloads).
+ Default is '\$HOME/.irssi'.
+
+ xdccget_max_downloads
+ Maximum number of parallel downloads. Default is 2. A download request which is queued
+ by the XDCC offer bot does not count against the limit. The next item in the download queue
+ is being requested as long as download slots are available. Also other downloads not controlled
+ by this script do not count either. It is also possible to exceed this limit if a bot sends the
+ previously requested and queued file while there are downloads running already.
+
+ xdccget_retry_time
+ Time in minutes between retries. Default is 5. Retries are necessary for full
+ offer queues of bots, bots being/becoming offline, or not getting the requested download or any
+ understandable message regarding the request. Please DO NOT set this value to less than 300
+ (5 minutes) or risk being banned from the channels for spamming the bots.
+
+ Please report bugs to https://github.com/obfuscoder/irssi_scripts/issues
";
my $text = '';
foreach (split(/\n/, $help)) {
@@ -79,8 +166,12 @@ sub draw_box ($$$$) {
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';
+ if (defined($text)) {
+ foreach (split(/\n/, $text)) {
+ $box .= '%R|%n '.$_."\n";
+ }
+ }
+ $box .= '%R`--<%n'.$footer.'%R>->%n';
$box =~ s/%.//g unless $colour;
return $box;
}
@@ -88,178 +179,229 @@ sub draw_box ($$$$) {
sub contains {
my ($item, @list) = @_;
foreach (@list) {
- ($item eq $_) && return 1;
+ ($item eq $_) && return 1;
}
return 0;
}
sub event_message_irc_notice {
+ debugFunc ("event_message_irc_notice", @_);
my ($server, $msg, $nick, $address, $target) = @_;
+ my $i;
$_ = $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();
+ for ($i=0; $i<= $#queue; $i++) {
+ if ($queue[$i] && lc($nick) eq lc($queue[$i]->{'nick'})) {
+ if (/Closing Connection/) {
+ print CLIENTCRAP "%R>>%n XDCC-Transfer closed";
+ # Is it a canceled transfer?
+ if ($queue[$i]->{'status'} eq 'canceling') {
+ $queue[$i]->{'status'} = 'cancelled';
+ } elsif ($queue[$i]->{'status'} ne 'paused') {
+ # We should try again unless we paused the queue item
+ $queue[$i]->{'status'} = 'waiting';
+ }
+ } elsif (/Transfer Completed/i) {
+ print CLIENTCRAP "%R>>%n XDCC-Transfer completed";
+ # Mark the transfer as completed
+ $queue[$i]->{'status'} = 'completed';
+ } elsif (/You already requested that pack/i) {
+ $queue[$i]->{'status'} = 'transferring';
+ } elsif (/You already have that item queued/i) {
+ $queue[$i]->{'status'} = 'queued';
+ } elsif (/Sending (?:You|u) (?:Your Queued )?Pack/i) {
+ $queue[$i]->{'status'} = 'transferring';
+ print CLIENTCRAP "%R>>%n XDCC-Transfer starting";
+ } elsif (/All Slots Full, Added (|you to the main )queue in position ([0-9]*)/i) {
+ $queue[$i]->{'pos'} = $2;
+ $queue[$i]->{'etr'} = 0;
+ $queue[$i]->{'status'} = 'queued';
+ } 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[$i]->{'pos'} = $3;
+ $queue[$i]->{'etr'} = time() + (($5*60)+$6)*60;
+ $queue[$i]->{'status'} = 'queued';
+ } elsif (/You have been queued for ([0-9]*?) hours ([0-9]*?) minutes, currently in main queue position ([0-9]*?) of ([0-9]*?)\./i) {
+ $queue[$i]->{'pos'} = $3;
+ $queue[$i]->{'status'} = 'queued';
+ } elsif (/You have been queued for ([0-9]*?) minutes, currently in main queue position ([0-9]*?) of ([0-9]*?)\./i) {
+ $queue[$i]->{'status'} = 'queued';
+ # FIXME unite somehow with regexp above
+ $queue[$i]->{'pos'} = $2;
+ } elsif (/It has been placed in queue slot #(\d+), it will send when sends are available/i) {
+ $queue[$i]->{'pos'} = $1;
+ $queue[$i]->{'status'} = 'queued';
+ } elsif (/Invalid Pack Number/i) {
+ $queue[$i]->{'status'} = 'invalid';
+ } elsif (/The Owner Has Requested That No New Connections Are Made/i ||
+ /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 ||
+ /you must be on a known channel/i) {
+ print CLIENTCRAP "Retrying ....\n";
+ my $retry = Irssi::settings_get_int('xdccget_retry_time')*60000;
+ $queue[$i]->{'status'} = 'retrying';
+ $queue[$i]->{'timer'} = Irssi::timeout_add($retry, 'retry_transfer', $i);
+ $queue[$i]->{'etr'} = time()+$retry/1000;
+ } elsif (/must be on a known channel/i) {
+ $server->command("WHOIS $nick");
+ $queue[$i]->{'status'} = 'joining';
+ } else { Irssi::print($_) if ($debug); }
+ process_queue();
+ last;
+ }
}
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;
- }
+ 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 {
+ debugFunc ("process_queue", @_);
+ my ($i, $j, $numdls);
+ $numdls = 0;
+ my $process;
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;
+ for ($i=0; $i<= $#queue; $i++) {
+ debugFunc (" - Item: $i -> ".$queue[$i]{'status'});
+ if ($queue[$i]{'status'} eq 'completed' ||
+ $queue[$i]{'status'} eq 'cancelled') {
+ push (@completed, $queue[$i]);
+ my $done_file = "$config_path/xdccdone.txt";
+ if (!open (DONEFILE, q{>>}, $done_file)) {
+ print CLIENTCRAP "XDCCGET - Warning: Could not open file for appending done queue entry at $done_file. $!";
+ } else {
+ print DONEFILE $queue[$i]{net}."\t".$queue[$i]{nick}."\t".$queue[$i]{pack}."\t".$queue[$i]{filename}."\t".$queue[$i]{'status'}."\n";
+ if (!close (DONEFILE)) {
+ print CLIENTCRAP "XDCCGET - Warning: Could not close file after appending done queue entry at $done_file. $!";
+ }
+ }
+ splice (@queue, $i, 1);
+ } else {
+ if ($queue[$i]{'status'} eq 'waiting') {
+ $process = 1;
+ for ($j=0; $j<$i; $j++) {
+ if ($queue[$i]{'nick'} eq $queue[$j]{'nick'}) {
+ $process = 0;
+ }
+ }
+ if ($numdls >= $max_downloads) {
+ $process = 0;
+ }
+ if ($process) {
+ my $server = Irssi::server_find_tag($queue[$i]{'net'});
+ if (defined($server)) {
+ $server->command('MSG '.$queue[$i]{'nick'}.' '.$queue[$i]{'xdcc'}.' send '.$queue[$i]{'pack'});
+ print CLIENTCRAP "%R>>%n XDCC Requesting queue item ".($i+1);
+ $queue[$i]->{'try'}++;
+ $queue[$i]->{'status'} = 'requested';
+ }
+ }
+ }
+ if ($queue[$i]{'status'} eq 'requested' ||
+ $queue[$i]{'status'} eq 'transferring') {
+ $numdls ++;
+ }
+ }
}
+ saveQueue();
}
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();
+ my ($numdls,$i);
+ $numdls = 0;
+ for ($i=0; $i<= $#queue; $i++) {
+ if ($queue[$i]{'status'} eq 'requested' ||
+ $queue[$i]{'status'} eq 'transferring') {
+ $numdls ++;
+ }
+ if (defined ($queue[$i]->{'timer'})) {
+ Irssi::timeout_remove($queue[$i]->{'timer'});
+ undef ($queue[$i]->{'timer'});
+ if ($queue[$i]->{'status'} eq 'retrying' && $numdls < $max_downloads) {
+ $queue[$i]->{'status'} = 'waiting';
+ process_queue();
+ }
+ }
}
}
sub queue_pack {
+ debugFunc ("queue_pack", @_);
my ($args, $server, $witem) = @_;
- my @args = split(/ /, $args, 2);
- my ($nick, $packs);
+ my @args = split(/ /, $args, 3);
+ my $xdcc = "xdcc";
+ my ($nick, $pack, $desc);
if (ref $witem && $witem->{type} eq 'QUERY' && $args[0] =~ /^\d+$/) {
- ($nick, $packs) = ($witem->{name}, $args[0]);
+ ($nick, $pack, $desc) = ($witem->{name}, $args[0], $args[1]);
} else {
- ($nick, $packs) = @args;
+ ($nick, $pack, $desc) = @args;
+ }
+ if ($desc =~ /^-xdcc=(.+?) (.+)$/) {
+ $xdcc = $1;
+ $desc = $2;
}
- 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;
+ my $status = 'waiting';
+ my $chatnet = $server->{tag};
+ my %transfer = ('nick' => $nick,
+ 'pack' => $pack,
+ 'status' => $status,
+ 'net' => $chatnet,
+ 'pos' => 0,
+ 'try' => 0,
+ 'etr' => 0,
+ 'timer' => undef,
+ 'xdcc' => $xdcc
+ );
+ if (defined $server->{tag} && defined $lists{lc $server->{tag}} && defined $lists{lc $server->{tag}}{lc $nick}{$_}) {
+ $transfer{filename} = $lists{lc $server->{tag}}{lc $nick}{$_};
}
- process_queue()
+ if (defined ($desc)) {
+ $transfer{filename} = $desc;
+ }
+ 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 $current = $_;
+ my $botname = $current->{'nick'};
+ my $ircnet = $current->{'net'};
+ my $pack = $current->{'pack'};
+ my $status = $current->{'status'};
+ my $info = '';
+ my $etr = '';
+ if ($current->{'status'} eq 'queued') {
+ 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'} eq 'retrying') {
+ 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++;
+ $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);
}
@@ -268,24 +410,49 @@ 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();
+ my $item = $queue[$_-1];
+ next if (!defined($item));
+
+ if ($item->{'status'} eq 'queued') {
+ # Remove the request 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'} = 'canceling';
+ #splice(@queue, $_,$_+1);
+ } elsif ($item->{'status'} eq 'transferring') {
+ $item->{'status'} = 'cancelled';
+ Irssi::command('dcc close get '.$item->{'nick'});
+ print CLIENTCRAP "%R>>>%n Transfer aborted";
+
+ } else {
+ debugFunc ("splice", $_);
+ splice(@queue, $_-1,1);
+ }
+ process_queue();
+ }
+}
+
+sub reset_pack {
+ foreach (@_) {
+ next if ($#queue < $_ || $_ < 0);
+ $queue[$_-1]->{'status'} = 'waiting';
+ }
+ process_queue();
+}
+
+sub pause_pack {
+ my $server = shift;
+ foreach (@_) {
+ next if ($#queue < $_ || $_ < 0);
+ if ($queue[$_-1]->{'status'} eq 'queued') {
+ $server->command('msg '.$queue[$_-1]->{'nick'}.' xdcc remove');
+ } elsif ($queue[$_-1]->{'status'} eq 'transferring') {
+ Irssi::command('dcc close get '.$queue[$_-1]->{'nick'});
+ }
+ $queue[$_-1]->{'status'} = 'paused';
}
+ process_queue();
}
sub list_packs ($$) {
@@ -298,53 +465,186 @@ sub cmd_xdccget {
my ($args, $server, $witem) = @_;
my @arg = split(/ /, $args);
- if ((scalar(@arg) == 0) or ($arg[0] eq '-l')) {
- list_xdcc_queue();
+ if ((scalar(@arg) == 0) or ($arg[0] eq '-l') or ($arg[0] eq 'stat')) {
+ list_xdcc_queue();
} elsif ($arg[0] eq 'queue') {
- # queue files
- shift @arg;
- queue_pack("@arg", $server, $witem);
+ # queue files
+ shift @arg;
+ queue_pack("@arg", $server, $witem);
} elsif ($arg[0] eq 'list' && defined $arg[1]) {
- list_packs($server, $arg[1]);
+ list_packs($server, $arg[1]);
} elsif ($arg[0] eq 'cancel') {
- shift @arg;
- cancel_pack(@arg);
+ shift @arg;
+ cancel_pack(@arg);
+ } elsif ($arg[0] eq 'reset') {
+ shift @arg;
+ reset_pack(@arg);
+ } elsif ($arg[0] eq 'pause') {
+ shift @arg;
+ pause_pack($server, @arg);
} elsif ($arg[0] eq 'help') {
- show_help();
+ show_help();
+ } elsif ($arg[0] eq 'offers') {
+ shift @arg;
+ show_offers(@arg);
}
}
sub event_private_message {
+ debugFunc ("event_private_message", @_);
my ($server, $text, $nick, $address) = @_;
event_message_irc_notice($server, $text, $nick, $address, undef);
}
sub event_no_such_nick {
+ debugFunc ("event_private_message", @_);
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();
+
+ my $i;
+ for ($i=0; $i<= $#queue; $i++) {
+ if ($nick eq $queue[$i]->{'nick'}) {
+ if ($queue[$i]->{'status'} eq 'requested' || $queue[$i]->{'status'} eq 'joining') {
+ my $retry = Irssi::settings_get_int('xdccget_retry_time')*60000;
+ $queue[$i]->{'status'} = 'retrying';
+ $queue[$i]->{'timer'} = Irssi::timeout_add($retry, 'retry_transfer', $i);
+ $queue[$i]->{'etr'} = time()+$retry/1000;
+ }
+ }
+ process_queue();
+ }
+}
+
+sub event_server_connected {
+ my ($server) = @_;
+ debugFunc ("SERVER CONNECTED: " . $server->{'tag'});
+
+ my $i;
+ for ($i=0; $i<= $#queue; $i++) {
+ $queue[$i]->{'status'} = 'waiting' if (lc($queue[$i]->{'net'}) eq lc($server->{'tag'}));
+ }
+ process_queue();
+}
+
+sub event_server_disconnected {
+ my ($server) = @_;
+ debugFunc ("SERVER DISCONNECTED: " . $server->{'tag'});
+
+ my $i;
+ for ($i=0; $i<= $#queue; $i++) {
+ $queue[$i]->{'status'} = 'waiting' if (lc($queue[$i]->{'net'}) eq lc($server->{'tag'}));
}
+ process_queue();
}
+sub show_offers {
+ my $server;
+ my $channel;
+ my $nick;
+ my $desc;
+ foreach (@_) {
+ if (/^-server=(.*?)$/) {
+ $server = $1;
+ } elsif (/^-channel=(.*?)$/) {
+ $channel = $1;
+ } elsif (/^-nick=(.*?)$/) {
+ $nick = $1;
+ } else {
+ $desc = $_;
+ }
+ }
+ my $text;
+ $text = "";
+ foreach my $s (keys %offers) {
+ next unless (!defined($server) || $s =~ /$server/i);
+ foreach my $c (keys %{$offers{$s}}) {
+ next unless (!defined($channel) || $c =~ /$channel/i);
+ foreach my $n (keys %{$offers{$s}{$c}}) {
+ next unless (defined($offers{$s}{$c}{$n}{'numpacks'}));
+ next unless (!defined($nick) || $n =~ /$nick/i);
+ my $text1 = "";
+ $text1 .= "$s $c $n - #$offers{$s}{$c}{$n}{'numpacks'}, Slots: $offers{$s}{$c}{$n}{'freeslots'}/$offers{$s}{$c}{$n}{'numslots'}";
+ $text1 .= ", Q: $offers{$s}{$c}{$n}{'posqueue'}/$offers{$s}{$c}{$n}{'numqueue'}" if (defined($offers{$s}{$c}{$n}{'posqueue'}));
+ $text1 .= ", Min: $offers{$s}{$c}{$n}{'minspeed'}" if (defined($offers{$s}{$c}{$n}{'minspeed'}));
+ $text1 .= ", Max: $offers{$s}{$c}{$n}{'maxspeed'}" if (defined($offers{$s}{$c}{$n}{'maxspeed'}));
+ $text1 .= ", Rec: $offers{$s}{$c}{$n}{'recspeed'}" if (defined($offers{$s}{$c}{$n}{'recspeed'}));
+ $text1 .= ", BW: $offers{$s}{$c}{$n}{'bwcurrent'}" if (defined($offers{$s}{$c}{$n}{'bwcurrent'}));
+ $text1 .= ", Rec: $offers{$s}{$c}{$n}{'bwrecord'}" if (defined($offers{$s}{$c}{$n}{'bwrecord'}));
+ $text1 .= ", Cap: $offers{$s}{$c}{$n}{'bwcapacity'}" if (defined($offers{$s}{$c}{$n}{'bwcapacity'}));
+ $text1 .= "\n";
+ my $text2 = "";
+ foreach my $p (sort {$a <=> $b} keys %{$offers{$s}{$c}{$n}{'packs'}}) {
+ next unless (!defined($desc) || $offers{$s}{$c}{$n}{'packs'}{$p}{'desc'} =~ /$desc/i);
+ $text2 .= " #$p x$offers{$s}{$c}{$n}{'packs'}{$p}{'numdl'} [$offers{$s}{$c}{$n}{'packs'}{$p}{'size'}] $offers{$s}{$c}{$n}{'packs'}{$p}{'desc'}\n";
+ }
+ next if (length($text2) == 0);
+ $text .= $text1.$text2;
+ }
+ }
+ }
+ print CLIENTCRAP draw_box("XDCCget", $text, "offers", 1);
+}
+
+sub event_message_public {
+ my ($server, $msg, $nick, $address, $target) = @_;
+
+ if ($msg =~ /.*?\*\*.*? (\d+) packs? .*?\*\*.*? (\d+) of (\d+) slots? open(?:, Queue: (\d+)\/(\d+))?(?:, Min: ((?:\d+|\.)+KB\/s))?(?:, Max: ((?:\d+|\.)+KB\/s))?(?:, Record: ((?:\d|\.)+KB\/s))?/i) {
+ $offers{$server->{'tag'}} = {} unless (defined($offers{$server->{'tag'}}));
+ $offers{$server->{'tag'}}{$target} = {} unless (defined($offers{$server->{'tag'}}{$target}));
+ $offers{$server->{'tag'}}{$target}{$nick} = {} unless (defined($offers{$server->{'tag'}}{$target}{$nick}));
+ $offers{$server->{'tag'}}{$target}{$nick}{'packs'} = {} unless (defined($offers{$server->{'tag'}}{$target}{$nick}{'packs'}));
+ $offers{$server->{'tag'}}{$target}{$nick}{'numpacks'} = $1 if (defined($1));
+ $offers{$server->{'tag'}}{$target}{$nick}{'freeslots'} = $2 if (defined($2));
+ $offers{$server->{'tag'}}{$target}{$nick}{'numslots'} = $3 if (defined($3));
+ $offers{$server->{'tag'}}{$target}{$nick}{'posqueue'} = $4 if (defined($4));
+ $offers{$server->{'tag'}}{$target}{$nick}{'numqueue'} = $5 if (defined($5));
+ $offers{$server->{'tag'}}{$target}{$nick}{'minspeed'} = $6 if (defined($6));
+ $offers{$server->{'tag'}}{$target}{$nick}{'maxspeed'} = $7 if (defined($7));
+ $offers{$server->{'tag'}}{$target}{$nick}{'recspeed'} = $8 if (defined($8));
+ }
+ if ($msg =~ /.*?\*\*.*? Bandwidth Usage .*?\*\*.*? Current: ((?:\d|\.)+KB\/s)(?:, Cap: ((?:\d|\.)+KB\/s))?(?:, Record: ((?:\d|\.)+KB\/s))?/) {
+ $offers{$server->{'tag'}} = {} unless (defined($offers{$server->{'tag'}}));
+ $offers{$server->{'tag'}}{$target} = {} unless (defined($offers{$server->{'tag'}}{$target}));
+ $offers{$server->{'tag'}}{$target}{$nick} = {} unless (defined($offers{$server->{'tag'}}{$target}{$nick}));
+ $offers{$server->{'tag'}}{$target}{$nick}{'packs'} = {} unless (defined($offers{$server->{'tag'}}{$target}{$nick}{'packs'}));
+ $offers{$server->{'tag'}}{$target}{$nick}{'bwcurrent'} = $1 if (defined($1));
+ $offers{$server->{'tag'}}{$target}{$nick}{'bwcapacity'} = $2 if (defined($2));
+ $offers{$server->{'tag'}}{$target}{$nick}{'bwrecord'} = $3 if (defined($3));
+ }
+
+ if ($msg =~ /\.*?#(\d+).*?\s+(\d+)x\s+\[\s*?((?:\d|\.)*(?:M|K|G))\]\s+(.+)/) {
+ $offers{$server->{'tag'}} = {} unless (defined($offers{$server->{'tag'}}));
+ $offers{$server->{'tag'}}{$target} = {} unless (defined($offers{$server->{'tag'}}{$target}));
+ $offers{$server->{'tag'}}{$target}{$nick} = {} unless (defined($offers{$server->{'tag'}}{$target}{$nick}));
+ $offers{$server->{'tag'}}{$target}{$nick}{'packs'} = {} unless (defined($offers{$server->{'tag'}}{$target}{$nick}{'packs'}));
+ $offers{$server->{'tag'}}{$target}{$nick}{'packs'}{$1} = {} unless (defined($offers{$server->{'tag'}}{$target}{$nick}{'packs'}{$1}));
+ $offers{$server->{'tag'}}{$target}{$nick}{'packs'}{$1}{'numdl'} = $2;
+ $offers{$server->{'tag'}}{$target}{$nick}{'packs'}{$1}{'size'} = $3;
+ $offers{$server->{'tag'}}{$target}{$nick}{'packs'}{$1}{'desc'} = $4;
+ }
+}
Irssi::command_bind('xdccget', \&cmd_xdccget);
-foreach my $cmd ('queue', 'cancel', 'list', 'help', 'list') {
+
+loadQueue();
+
+foreach my $cmd ('queue', 'cancel', 'list', 'help', 'stat','reset','offers', 'pause') {
Irssi::command_bind('xdccget '.$cmd => sub {
- cmd_xdccget("$cmd ".$_[0], $_[1], $_[2]); });
+ cmd_xdccget("$cmd ".$_[0], $_[1], $_[2]);
+ });
}
-
+Irssi::signal_add('message public', 'event_message_public');
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);
+Irssi::signal_add("event connected", "event_server_connected");
+Irssi::signal_add("server disconnected", "event_server_disconnected");
print CLIENTCRAP '%B>>%n '.$IRSSI{name}.' '.$VERSION.' loaded: /xdccget help for help';
+
+print "Configuration files are stored in $config_path";
+
+if ($#queue >= 0) {
+ process_queue();
+}