#!/usr/local/bin/perl --

##########################################################################
##
##   inndelay.pl: Delay between post and reception of usenet articles. 
##
##  version: 1.0.2
##
##  Date: 05-04-97
##
##  Copyright (c) 1997, Fabien TASSIN (tassin@eerie.fr).
##
##########################################################################
##
## ABSOLUTELY NO WARRANTY WITH THIS PACKAGE. USE IT AT YOUR OWN RISKS.
##
## Usage: send a part of your history file to inndelay.pl
##
##        tail -10000 /var/news/etc/history | inndelay.pl
##     or
##        inndelay.pl history_extract
##
## This will produce a GIF file (see $out below)
##
## To obtain good results, do not forget to synchronize your clock (with
## xntp for example) before using this tool. 
##
## Notes : You need the Perl graphic library GD.pm (1.14 or more)
##         GD is available on all good CPAN ftp sites :
##             [CPAN_DIR]/authors/id/LDS/GD-1.14.tar.gz
##           or directly to :
##             http://www-genome.wi.mit.edu/pub/software/WWW/GD.html
##
## Report : please report bugs directly to the author.
##          Be sure your are using the latest version of this script.
##          (check ftp://ftp.eerie.fr/pub/usenet/inndelay/)
##
##########################################################################

# Name of the graph
$out = "./inndelay.gif";

###############################################
## THERE'S NOTHING TO CHANGE AFTER THIS LINE ##
###############################################
 
$version = "1.0.2";

BEGIN
{
  eval "use GD;";
  $::HAVE_GD = ($@ eq "");
};
 
unless ($HAVE_GD)
{
  printf STDERR <<EOF;
ERROR: can't make graph.
 
You need the Perl graphic library GD.pm (1.14 or more)
GD is available on all CPAN mirrors, e.g.:
    ftp://ftp.eerie.fr/pub/perl/CPAN/authors/id/LDS/GD-1.14.tar.gz
or directly to :
    http://www-genome.wi.mit.edu/pub/software/WWW/GD.html
EOF
  #'
  exit (1);
}

# Size of the graph
($xmax, $ymax) = (640, 240);

$prec = 0.01;
$t = log (10);
while (<>)
{
  $max++;
  unless (/^<[^>]+>\s+(\d+)\~.*[^\~]+\~(\d+)\s+\S+/)
  {
    $cancel++;
    next;
  }
  $d = $1 - $2;
  if ($d < 0)
  {
    $future++;
    next;
  }
  if (($d == 0) || (/\scontrol/))
  {
    $cancel++;
    next;
  }

  $done++;
  if ($d < 45)
  {
    $l = $d;
  }
  else
  {
    $l = sprintf "%.2f", log ($d) / $t; # look at $prec to know the precision
    # trunc again
    $l = sprintf "%d", 10 ** $l;
  }
  # and finally store
  $ll{$l}++;
}

$min_x = 0;
$max_x = 0;
$max_y = 0;
foreach $v (sort (keys (%ll)))
{
  $max_x = $v if ($max_x < $v);
  $max_y = $ll{"$v"} if ($max_y < $ll{"$v"});
}
$max_x = log ($max_x) / log (10);

$c = sprintf "%.1f%%", $max_y / $done * 100;

($ml, $mr, $mt, $mb) = (gdSmallFont->width * length ("$c") + 12, 30,
			gdSmallFont->height * 2 + 35, 40);

$image = new GD::Image ($xmax, $ymax);

$white = $image->colorAllocate (255, 255, 255);
$black = $image->colorAllocate (  0,   0,   0);
$blue  = $image->colorAllocate (  0,   0, 255);
$image->setStyle ($black, $black, gdTransparent, gdTransparent, 
		  gdTransparent, gdTransparent, gdTransparent);

$s = "Delay between post and reception";
$image->string (gdMediumBoldFont,
		($xmax - length ($s) * gdMediumBoldFont->width) / 2,
		$ymax - gdMediumBoldFont->height - 5, $s, $black);
$image->string (gdSmallFont, $ml, 5, 
		sprintf ("Number of articles: %10d", $max), $black);
$image->string (gdSmallFont, $ml, 7 + gdSmallFont->height, 
		sprintf ("Processed:          %10d (%.1f%%)",
		$done, $done / $max * 100), $black);
$image->string (gdSmallFont, $xmax / 2, 5, 
		sprintf ("Posted in the future: %10d (%.1f%%)",
			 $future, $future / $max * 100), $black);
$image->string (gdSmallFont, $xmax / 2, 7 + gdSmallFont->height, 
		sprintf ("Cancelled or Expired: %10d (%.1f%%)",
                $cancel, $cancel / $max * 100), $black);
$image->rectangle ($ml, $mt, $xmax - $mr, $ymax - $mb, $black);
$image->line ($ml - 3, $ymax - $mb, $ml, $ymax - $mb, $black);
$image->string (gdSmallFont, $ml - length ("0%") * gdSmallFont->width - 5,
		$ymax - $mb - gdSmallFont->height / 2, "0%", $black);
$image->line ($ml - 3, $mt, $ml, $mt, $black);
for ($i = 1; $i < 4; $i++)
{
  $image->line ($ml - 3, $mt + ($ymax - $mt - $mb) * $i / 4,
		$xmax - $mr, $mt + ($ymax - $mt - $mb) * $i / 4, gdStyled);

}
$image->string (gdSmallFont, $ml - length ("$c") * gdSmallFont->width - 5,
		$mt - gdSmallFont->height / 2, "$c", $black);

$rx = ($xmax - $mr - $ml) / ($max_x - $min_x + $prec);
$ry = ($ymax - $mt - $mb) / $max_y;
$i = 0;
$p = 0;
$pp = 1;
foreach $v (sort {$a <=> $b} (keys (%ll)))
{
  my ($t1, $t2);
  if ($v < 60)
  {
    $t1 = log ($v) / log (10);
    $t2 = log ($v + 1) / log (10);
  }
  else
  {
    $t1 = log ($v) / log (10);
    $t2 = log ($v) / log (10) + $prec;
  }
  $p += $ll{$v};
  if ($p / $done * 10 > $pp)
  {
    $image->line ($ml + ($t2 - $min_x) * $rx, $mt,
			$ml + ($t2 - $min_x) * $rx, $ymax - $mb, gdStyled);
    $image->line ($ml + ($t2 - $min_x) * $rx, $mt - 3,
		  $ml + ($t2 - $min_x) * $rx, $mt, $black);
    $pp++;
    my $s = sprintf "%d%%", $p / $done * 100;
    $image->string (gdSmallFont,
	    $ml + ($t2 - $min_x) * $rx - (gdSmallFont->width * length $s) / 2,
	    $mt - gdSmallFont->height - 5, $s, $black);
  }
  $image->filledRectangle ($ml + ($t1 - $min_x) * $rx,
			   $ymax - $mb - $ll{$v} * $ry,
			   $ml + ($t2 - $min_x) * $rx,
			   $ymax - $mb,
			   $blue);
}
my $s = "100%";
$image->string (gdSmallFont,
	    $xmax - $mr - (gdSmallFont->width * length $s) / 2,
	    $mt - gdSmallFont->height - 5, $s, $black);
$image->line ($xmax - $mr, $mt -3, $xmax - $mr , $mt, $black);


# Graduations
@a = (1, 3, 7, 15, 30,		# seconds
      60, 180, 420, 900, 1800,	# minutes
      3600, 10800, 43200,	# hours
      86400, 259200, 864000);	# days

# Labels
@b = ("1s", "3s", "7s", "15s", "30s",
      "1mn", "3mn", "7mn", "15mn", "30mn",
      "1h", "3h", "12h",
      "1day", "3days", "10days");

for ($i = 0; $i <= $#a; $i++)
{
  $v = $a[$i];
  next if (log ($v) / log (10) < $min_x);
  next if (log ($v) / log (10) > $max_x);
  $image->line ($ml + (log ($v) / log (10) - $min_x) * $rx, $ymax - $mb,
		$ml + (log ($v) / log (10) - $min_x) * $rx, $ymax - $mb + 5,
		$black);
  $image->string (gdSmallFont, $ml + (log ($v) / log (10) - $min_x) * $rx
		  - length ("$b[$i]") * gdSmallFont->width / 2,
		  $ymax - $mb + 7, $b[$i], $black);
}
open (IMG, "> $out") || die "can open \"$out\": $!\n";
print IMG $image->gif;
close (IMG);

