#!/usr/bin/perl

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# 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.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.



## This is a basic attempt at an autoget-style script for Xchat

## To use it, create a text file for each user you wish to leech 
## from, and populate it with your requests(ie the lines you would 
## normally type/paste to the channel) , one per line.
##
## New in 0.4 is the <max queue> arguement to "/xget start", this 
## allows you to specify how many files to place in the server's
## queue. Default value is 1, but this can be raised for more 
## aggressive leeching.

## Load this script up ( /load /path/xget.pl), and type /xget

## Created by pete@undernet, modified by reflous@undernet
## For up-to-date version, questions, bugs, etc find me (pete) in 
## #mp3uk_chat on Undernet.

## VERSION 0.4 (18/01/2004)
##
## dcc_recv_complete_handler forgot to ignore the case of $nick -
## caused problems downloading from some users
##

## Show debug window ? 0 or 1

$DEBUG_MODE = 1;



## Nothing to edit below here


IRC::register("Xget", "0.4", "", "");
IRC::add_command_handler("xget", "xget");


## I always get these bindings wrong ...
IRC::add_print_handler("DCC RECV Timeout", "dcc_recv_fail_handler");
IRC::add_print_handler("DCC RECV Complete", "dcc_recv_complete_handler");
IRC::add_print_handler("DCC RECV Abort", "dcc_recv_fail_handler");

IRC::print("[Xget] Xget loaded. Type /xget for more information.");



# Initialization / Global vars


## open debug window if enabled
if ($DEBUG_MODE >= 1) {
  IRC::command("/query xget_dbg");
}


sub xget {

	($command, $args, $args1, $args2, $args3) = split(/ /, @_[0]);

	if ($command eq '') {

    IRC::command ("/echo  ~~~~~~~~~~~~~~~~~~~~~~~~~~");
    IRC::command ("/echo  Xget 0.4  * pete\@undernet");
    IRC::command ("/echo       mod reflous\@undernet");
    IRC::command ("/echo                            ");
    IRC::command ("/echo     /xget start <filename> <channel> <nick> <max queue>: start autogetting files from this list");
    IRC::command ("/echo     /xget stop <filename> : stop autogetting <filename>");
    IRC::command ("/echo     /xget allstop : stop autogetting all");
    IRC::command ("/echo     /xget stats    : stats stuff");
    IRC::command ("/echo  ~~~~~~~~~~~~~~~~~~~~~~~~~~");

	} elsif ($command eq 'start') {

#		push (@watching, $args);
		$channels{$args} = $args1;
#		$list2nick{$args} = $args2;
		$initial_requests = $args3 || 1;
		$nick2list{$args2} = $args;
		open (LIST, "< $args") || IRC::print "[xget] whoops, can't open $args";

		for (1..$initial_requests) {
	
			$line = <LIST>;

			## Attempt to chop off any file info crap
			## shouldn't matter anyway (pete)
			    $line =~ s/\s*::.*$//g;
	
			IRC::command ("/msg $args1 $line");

			&debug_msg("xget: command=$command filename=$args channel=$args1 nick=$args2 msg=$args1" );

		}

                close LIST;


	} elsif ($command eq 'stop') {

	    delete $nick2list{$args};
#		delete $watching[$args]

	} elsif ($command eq 'allstop') {
    
	    %nick2list = ();

	} elsif ($command eq 'stats') { 

	    $downloads = 0;

	    open ( STATS, "<$LOGFILE" );
	    while ( <STATS> ) {
	      chomp;
	      $downloads++ if /downloaded/
	    }

  	    close STATS;

	    IRC::print "[xget] you've downloaded $downloads files";
	}

	return 1;
}

###

sub dcc_recv_complete_handler {
  $xchat_feedback = shift;

foreach (@_){ 

	&debug_msg( "---> $_");
}

  if ($xchat_feedback =~ m/^(.*?)\.(MP3|mp3|zip|jpg|m3u|gif)\s+(.*?\.\S+)\s+(\S+)\s+(\d+)/) {
    $filename = $1 . '.' . $2;
    $download_location = $3;
    $nick = $4;
    $nick =~ tr/A-Z/a-z/;
    $cps = $5;
  } else {
    &debug_msg( "dcc_recv_complete_handler: didn't parse $xchat_feedback" );
  }


  &debug_msg( "dcc_recv_complete_handler: filename=$filename, nick=$nick, cps=$cps" );

	if ( defined $nick2list{lc $nick} ) {
  		LOG("\tdownloaded\t$nick\t$filename\t$cps");

  		  open (IN, "< $nick2list{$nick}") || IRC::print "[xget] problems opening $nick2list{$nick}";
  		  chomp (@linez = <IN>);
  		  close IN;
    
   		  $newrequest = @linez[1];
    		  shift @linez;
    
	   	  open (OUT, "> $nick2list{$nick}") || IRC::print "[xget] can't write to $nick2list{$nick}";
    		  foreach (@linez) { print OUT "$_\n"}
   		   close OUT;
    
		## Attempt to chop off any file info crap
    		$channels{$nick2list{$nick}} =~ s/\s*::.*$//g;

    		IRC::command("/msg $channels{$nick2list{$nick}} $newrequest");
    		&debug_msg( "dcc_recv_complete_handler: getting $newrequest" );

	} else {
    		# download but not from list
	}

}

sub dcc_recv_fail_handler {

  ($filename, $nick, undef, undef) = split(/ /, @_[0]);

  &debug_msg( "dcc_recv_fail_handler: filename=$filename, nick=$nick" );  

	## re-request file in 3 minutes
	push (@rereq, "$channels{$nick2list{$nick}} !$nick $filename");
	IRC::add_timeout_handler(180000, "rerequest");		
}

sub rerequest {

	if ($request_line = shift(@rereq)) {
	
		IRC::command("/msg $request_line");
	}
}
	
#### Debug Managment

sub prefix {
  my $now = localtime;

  join "", map { "[$now] $_\n" } split /\n/, join "", @_;
}

sub debug_msg() {
	if ($DEBUG_MODE == 0) { return 0; }
	my $debug_msg = shift;
	my $dbgline = prefix($debug_msg);
	IRC::print_with_channel("\00304dbg:\00305 $dbgline", "xget_dbg");
}

sub LOG {
  my $log_msg = shift;
  open (LOG, "| cat >> $LOGFILE") || IRC::print "[xget] problems opening $LOGFILE";
  print LOG prefix $log_msg . "\n";
  close (LOG);
}


