#!/usr/bin/perl 
#
# copyright 2000 by Gottfried Szing e9625460@stud3.tuwien.ac.at
#
# version 0.01

eval("require '$ARGV[0]'") || die ("please specify a config file to use! $!\nUsage: $0 <config>\n");

my $config = shift;

use Time::ParseDate;
use MIME::Entity;

sub printx
{
	print @_ unless ($config::quiet);
}


# ============== CONFIGURATION START =========================
my $version 	= "0.01";	    	# dont touch this ;-)
# =============== CONFIGURATION END ==========================

$| = 1;

use strict;
use DBI;		# db-connection
use DBI::DBD;

# get the date wanted
# by default it is the current day
my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime;

$year 	+= 1900;
$month++;

$day 	= shift if ($#ARGV >= 0);
$month 	= shift if ($#ARGV >= 0);
$year	= shift if ($#ARGV >= 0);
$hour 	= shift if ($#ARGV >= 0);
$min	= shift if ($#ARGV >= 0);

# prepend leading zero
$day 	= sprintf "%02d", $day;
$month 	= sprintf "%02d", $month;

# printx header
printx <<EOF;
Generate reports from the MySQL Database

Database:  $config::serverDb\@$config::serverName:$config::serverPort


EOF

# open DB
my $dbh 	= DBI->connect("DBI:mysql:database=$config::serverDb;host=$config::serverName;port=$config::serverPort",
				$config::serverUser,$config::serverPass);

# generate informational header
my $startdate	= scalar localtime;
my $mail	= <<EOF;

Access report for $config::WEBSERVER

Generated for the day $year/$month/$day

Generated at $startdate

EOF

printx "Previous month...";
$mail .= &AllMonth();

printx "done\n";
printx "Totals of this month...";
$mail .= &CurrentMonth_Totals();

printx "done\n";
printx "Responses...";
$mail .= &CurrentMonth_Responses()		if ($config::SHOW_RESPONSES);

printx "done\n";
printx "Daily/Hourly usage...";
$mail .= &CurrentMonth_Daily()			if ($config::DAILY_USAGE);
$mail .= &CurrentMonth_Hourly()			if ($config::HOURLY_USAGE);

printx "done\n";
printx "Requests by Hits and Size...";
$mail .= &CurrentMonth_URLSbyHitsAndSize() 	if ($config::SHOW_REQUESTS);

printx "done\n";
printx "Exit Pages...";
$mail .= &CurrentMonth_ExitPages()		if ($config::SHOW_EXITPAGES);

printx "done\n";
printx "Domain usage....";
$mail .= &CurrentMonth_DomainsByHitsAndSize()	if ($config::SHOW_DOMAINS);

printx "done\n";
printx "Usage by hosts...";
$mail .= &CurrentMonth_HostsByHits()		if ($config::SHOW_HOSTS);
$mail .= &CurrentMonth_HostsBySize()		if ($config::SHOW_HOSTS);

printx "done\n";

$dbh->disconnect();


# and now some general generating statistics
my $stopdate = localtime;

printx <<EOF;

Start Time:     $startdate
Stop Time:      $stopdate

EOF

printx save_report($mail);
printx send_mail($mail);

exit 0;

# save report as file
sub save_report()
{
	my $report = shift;

	my $FILE_NAME = "${config::ARCHIVE_DIR}/report_${year}_${month}_${day}.csv";

	if ($config::OUTPUT_FILE)
	{
		open(REPORT, ">$FILE_NAME") || return "couldnt open file $FILE_NAME: $!";
		print REPORT $mail;
		close(REPORT);

		return "\nReport saved to file $FILE_NAME\n";
	}
}

# save report as file
sub send_mail()
{
	my $report = shift;
	my $retval = "";
	my $mail_text = <<EOF;

Daily Statistics of $config::WEBSERVER. The file attached is a CSV
(Comma Separated Values). 

EOF

	my $lt = "${year}_${month}_${day}";

	if ($config::OUTPUT_MAIL)
	{
		foreach my $MAIL (@config::RECIPIENTS)
		{
			my $top = build MIME::Entity    From     => $config::MAILFROM,
			                                To       => $MAIL,
                       				        Subject  => "Statistics for ${year}/${month}/${day}",
                                			Data     => $mail_text;

			# Attach stuff to it:
			$top->attach(   Type        => "application/vnd.ms-excel",
					Encoding    => "base64",
					Description => "Statistics for ${year}/${month}/${day}",
					Filename    => "report_$lt.csv",
					Data        => $report);

			open(SEND, "|/usr/lib/sendmail -t -oi -oem") || return "Couldn't open sendmail to send: $!";
				$top->print(\*SEND);
			close (SEND);
			
			$retval .= "Sent to $MAIL\n";
		}

		return $retval."\nReport sent to mailing list\n";
	}
}


# generate stats for the previous month and returns 
# a formated report
# 
# all values are in monthly total and in daily average
# - hits
# - hosts
# - kbytes
sub AllMonth()
{
	my %trans 	= ();
	my %hits	= ();
	my $retval 	= "";

	my $EXCLUDEHOST = &generateExclude("h.host");

	$retval = "COMPLETE MONTHLY STATISTICS\n";
	$retval .= "Month;Hits;Size (in Bytes)\n";
	$retval .= "------------------;----------;----------\n";


	# calculate hits and transfered size
	my $sql_statement = "select date_format(time, '%M %Y') as month, sum(size) as trans, count(*) as cnt
				from transfer t, host h
				where t.hostid = h.id 
				and t.time <= '$year/$month/$day $hour:$min'
				$EXCLUDEHOST
				group by month order by time";

	my $cur = $dbh->prepare($sql_statement);

	$cur->execute;
	
	while (my @req = $cur->fetchrow_array() )
	{
		$trans{$req[0]}	= $req[1];
		$hits{$req[0]}	= $req[2];
	}

	$cur->finish;

	# generate return data
	foreach my $month (sort { parsedate($a) <=> parsedate($b) } keys %trans)
	{
		$retval .= "$month;$hits{$month};$trans{$month}";

		$retval .= "\n";
	}

	$retval .= "\n\n\n";

	return $retval;
}

# generate total stats for this month
# 
# - total hits
# - total kbytes
# 
# - hits per hour avg/max
#
# - hits per day avg/max
sub CurrentMonth_Totals()
{
	my $retval = "";

	$retval = "MONTHLY TOTALS\n\n";

	$retval .= CurrentMonth_Totals_HitsSize();

	$retval .= "\n;Average;Maximum\n";
	$retval .= CurrentMonth_Totals_HourlyUsage();
	$retval .= CurrentMonth_Totals_DailyUsage();

	$retval .= "\n\n\n";

	return $retval;
}

sub CurrentMonth_Totals_HitsSize()
{
	my $retval = "";
	
	my $total_hits		= 0;
	my $total_hosts		= 0;
	my $total_size		= 0;

	# title
	#$retval = "Monthly Statistics\n\n";

	my $EXCLUDEHOST = &generateExclude("h.host");

	# get total hits
		my $sql_statement = "select count(*)
					from transfer t, host h
					where t.hostid = h.id and
					t.time <= '$year/$month/$day $hour:$min'
					and t.time >= '$year/$month/01 00:00'
					$EXCLUDEHOST";
					
		my $cur = $dbh->prepare($sql_statement);

		$cur->execute;

		($total_hits) = $cur->fetchrow_array();

		$cur->finish;

	# get total size
		$sql_statement = "select sum(t.size)
					from transfer t, host h
					where t.hostid = h.id and
					t.time <= '$year/$month/$day $hour:$min'
					and t.time >= '$year/$month/01 00:00'
					$EXCLUDEHOST";
					
		$cur = $dbh->prepare($sql_statement);

		$cur->execute;

		($total_size) = $cur->fetchrow_array();

		$cur->finish;

	# get total size
		$sql_statement = "select distinct t.hostid
					from transfer t, host h
					where t.hostid = h.id and
					t.time <= '$year/$month/$day $hour:$min'
					and t.time >= '$year/$month/01 00:00'
					$EXCLUDEHOST";
					
		$cur = $dbh->prepare($sql_statement);

		$cur->execute;

		($total_hosts) = $cur->rows;

		$cur->finish;

	# generate report
	$retval .= "Total hits;$total_hits\n";
	$retval .= "Total hosts;$total_hosts\n";
	$retval .= "Total transfer (in bytes);$total_size\n";

	#$retval .= "\n";
	return $retval;
}

sub CurrentMonth_Totals_HourlyUsage()
{
	my $retval = "";

	my $hits_total		= 0;
	my $hits_max		= 0;
	my $transfer_total	= 0;
	my $transfer_max	= 0;

	my $EXCLUDEHOST = &generateExclude("h.host");
	# get current days in this month
		my $sql_statement = "select distinct(to_days(time))
					from transfer t
					where 
					t.time <= '$year/$month/$day $hour:$min'
					and t.time >= '$year/$month/01 00:00'";

		my $cur = $dbh->prepare($sql_statement);

		$cur->execute;

		my $total_days	= $cur->rows;

		$cur->finish;

	# calculate hits and transfered size
		$cur = $dbh->prepare("set SQL_BIG_TABLES = 1");
		$cur->execute();

		$sql_statement = "select date_format(t.time, '%d %H') as hour, 
					sum(t.size) as trans, count(*) as cnt
					from transfer t, host h, cgi c
					where t.hostid = h.id and
					t.cgiid = c.id and
					t.time <= '$year/$month/$day $hour:$min'
					and t.time >= '$year/$month/01 00:00'
					$EXCLUDEHOST
					group by hour";

		$cur = $dbh->prepare($sql_statement);

		$cur->execute;

	my $oldhour 	= "";
	my $cur_hits	= 0;
	my $cur_size	= 0;

	while (my @req = $cur->fetchrow_array() )
	{
		my ($hour, $size, $count) = @req;

		if ($oldhour ne $hour)
		{
			$hits_max	= $cur_hits	if($hits_max < $cur_hits);
			$transfer_max	= $cur_size	if($transfer_max < $cur_size);

			$cur_size	= 0;
			$cur_hits	= 0;
		}

		$oldhour	= $hour;
		$cur_hits 	+= $count;
		$cur_size	+= $size;

		$hits_total 	+= $count;
		$transfer_total	+= $size;
	}

	$retval .= "Hits per hour;" . $hits_total/($total_days*24) . ";$hits_max\n";
	$retval .= "Transfer per hour (in bytes);" . $transfer_total/($total_days*24) . ";$transfer_max\n";

	#$retval .= "\n";
	return $retval;
}

sub CurrentMonth_Totals_DailyUsage()
{
	my $retval = "";

	my $hits_total		= 0;
	my $hits_max		= 0;
	my $transfer_total	= 0;
	my $transfer_max	= 0;

	my $EXCLUDEHOST = &generateExclude("h.host");

	# get current days in this month
		my $sql_statement = "select distinct(to_days(time))
					from transfer t
					where 
					t.time <= '$year/$month/$day $hour:$min'
					and t.time >= '$year/$month/01 00:00'";

		my $cur = $dbh->prepare($sql_statement);

		$cur->execute;

		my $total_days	= $cur->rows;

		$cur->finish;

	# calculate hits and transfered size
		$cur = $dbh->prepare("set SQL_BIG_TABLES = 1");
		$cur->execute();

		$sql_statement = "select date_format(t.time, '%m/%d/%Y') as day,
					sum(t.size) as trans, count(*) as cnt
					from transfer t, host h, cgi c
					where t.hostid = h.id
					and t.cgiid = c.id and
					t.time <= '$year/$month/$day $hour:$min'
					and t.time >= '$year/$month/01 00:00'
					$EXCLUDEHOST
					group by day";

		my $cur = $dbh->prepare($sql_statement);

		$cur->execute;

	my $oldday 	= "";
	my $cur_hits	= 0;
	my $cur_size	= 0;

	while (my @req = $cur->fetchrow_array() )
	{
		my ($day, $size, $count) = @req;

		if ($oldday ne $day)
		{
			$hits_max	= $cur_hits	if($hits_max < $cur_hits);
			$transfer_max	= $cur_size	if($transfer_max < $cur_size);

			$cur_size	= 0;
			$cur_hits	= 0;
		}

		$oldday		= $day;
		$cur_hits 	+= $count;
		$cur_size	+= $size;

		$hits_total 	+= $count;
		$transfer_total	+= $size;
	}

	$retval .= "Hits per day;" . $hits_total/$total_days . ";$hits_max\n";
	$retval .= "Transfer per day(in bytes);" . $transfer_total/$total_days . ";$transfer_max\n";

	#$retval .= "\n";
	return $retval;
}

# returns a listing of the response codes produced
#
# - code, shrot description and count
sub CurrentMonth_Responses()
{
	my $retval = "";

	$retval = "SERVER RESPONSES\n\n";
	$retval .= "Response Code;Count;Description\n";
	$retval .= "------------------;----------;----------\n";

	my $EXCLUDEHOST = &generateExclude("h.host");

	my $sql_statement = "select t.response as code, count(*)
				from transfer t, host h
				where t.hostid = h.id and
				t.time <= '$year/$month/$day $hour:$min'
				and t.time >= '$year/$month/01 00:00'
				$EXCLUDEHOST
				group by code order by code";

	my $cur = $dbh->prepare($sql_statement);

	$cur->execute;
	
	while (my @req = $cur->fetchrow_array() )
	{
		# get short description of code
		my $cur_short = $dbh->prepare("select short from httpresponses where code = $req[0]");
		$cur_short->execute;
		my @short = $cur_short->fetchrow_array();
		$cur_short->finish;

		$short[0] = "unknown response" unless (defined($short[0]));
		$retval .= "$req[0];$req[1];$short[0]\n";
	}

	$cur->finish();

	$retval .= "\n\n\n";

	return $retval;
}

# daily stats listed by day
#
# - hits
# - hosts
sub CurrentMonth_Daily()
{
	my %trans 	= ();
	my %hits	= ();

	my $oldday		= "";
	my $maxhits		= 0;
	my $maxhits_day		= "";
	my $maxtrans		= 0;
	my $maxtrans_day	= "";

	my $EXCLUDEHOST = &generateExclude("h.host");

	my $retval 	= "";

	$retval = "NUMBER OF REQUESTS GROUPED BY DAY\n";
	$retval .= "Day;Hits;Size (in Bytes)\n";
	$retval .= "------------------;----------;----------\n";


	# calculate hits and transfered size
	my $sql_statement = "select date_format(time, '%m/%d/%Y') as day, sum(size) as trans, count(*) as cnt
				from transfer t, host h
				where t.hostid = h.id and
				t.time <= '$year/$month/$day $hour:$min'
				and t.time >= '$year/$month/01 00:00'
				$EXCLUDEHOST
				group by day order by day";

	my $cur = $dbh->prepare($sql_statement);

	$cur->execute;

	
	while (my @req = $cur->fetchrow_array() )
	{
		$trans{$req[0]}	= $req[1];
		$hits{$req[0]}	= $req[2];
		
		if($maxhits < $req[2])
		{
			$maxhits 	= $req[2];
			$maxhits_day	= $req[0];
		}
		if($maxtrans < $req[1])
		{
			$maxtrans 	= $req[1];
			$maxtrans_day	= $req[0];
		}
	}

	$cur->finish;

	# generate return data
	foreach my $day (sort keys %trans)
	{
		$retval .= "$day;$hits{$day};$trans{$day}";

		$retval .= ";Max Hits"		if ($day eq $maxhits_day);
		$retval .= ";Max Transfer"	if ($day eq $maxtrans_day);

		$retval .= "\n";
	}

	$retval .= "\n\n\n";

	return $retval;
}

# hourly stats listed by day
#
# - hits
# - hosts
sub CurrentMonth_Hourly()
{
	my %trans 	= ();
	my %hits	= ();

	my $oldhour		= "";
	my $maxhits		= 0;
	my $maxhits_hour	= "";
	my $maxtrans		= 0;
	my $maxtrans_hour	= "";

	my $EXCLUDEHOST = &generateExclude("h.host");

	my $retval 	= "";

	$retval = "NUMBER OF REQUESTS GROUPED BY HOUR.\n";
	$retval .= "Hour;Hits;Size (in Bytes)\n";
	$retval .= "------------------;----------;----------\n";


	# calculate hits and transfered size
	my $sql_statement = "select date_format(time, '%H:00') as hour, sum(size) as trans, count(*) as cnt
				from transfer t, host h
				where t.hostid = h.id and
				t.time <= '$year/$month/$day $hour:$min'
				and t.time >= '$year/$month/01 00:00'
				$EXCLUDEHOST
				group by hour order by hour";

	my $cur = $dbh->prepare($sql_statement);

	$cur->execute;

	
	while (my @req = $cur->fetchrow_array() )
	{
		$trans{$req[0]}	= $req[1];
		$hits{$req[0]}	= $req[2];
		
		if($maxhits < $req[2])
		{
			$maxhits 	= $req[2];
			$maxhits_hour	= $req[0];
		}
		if($maxtrans < $req[1])
		{
			$maxtrans 	= $req[1];
			$maxtrans_hour	= $req[0];
		}
	}

	$cur->finish;

	# generate return data
	foreach my $hour (sort keys %trans)
	{
		$retval .= "$hour;$hits{$hour};$trans{$hour}";

		$retval .= ";Max Hits"		if ($hour eq $maxhits_hour);
		$retval .= ";Max Transfer"	if ($hour eq $maxtrans_hour);

		$retval .= "\n";
	}

	$retval .= "\n\n\n";

	return $retval;
}

# show top $config::MAX_URLS after grouping for this month
# sorted by hits produced and the size 
#
# sorted by hits perl url
# grouped by pattern
sub CurrentMonth_URLSbyHitsAndSize()
{
	my $retval = "";

	my $EXCLUDEHOST = &generateExclude("h.host");

	my $sql_statement = "select r.request, t.size
				from transfer t, host h, request r
				where t.hostid = h.id and
				t.time <= '$year/$month/$day $hour:$min'
				and t.time >= '$year/$month/01 00:00' and
				t.requestid = r.id
				$EXCLUDEHOST";

	my $cur = $dbh->prepare($sql_statement);

	$cur->execute;

	my %trans 	= ("$config::URL_GROUPING{rest}" => 0);
	my %hits	= ("$config::URL_GROUPING{rest}" => 0);
	
	ROW: while (my @req = $cur->fetchrow_array() )
	{
		if ($req[0] =~ /^\d+$/)
		{
			$hits{"$config::URL_GROUPING{rest}"} 	++;
			$trans{"$config::URL_GROUPING{rest}"} 	+= $req[1];

			next ROW;
		}

		$req[0] = groupURL($req[0]);
		$hits{"$req[0]"}++;
		$trans{"$req[0]"}	+= $req[1];
	}

	$cur->finish();

	$retval = "PAGES REQUESTED SORTED BY NUMBER OF HITS\n";
	$retval .= "Only top $config::MAX_URLS\n\n";
	$retval .= "Request;Hits;Size (in Bytes)\n";
	$retval .= "------------------;----------;----------\n";

	my $count = $config::MAX_URLS;
	foreach my $URL (sort { $hits{$b} <=> $hits{$a} } keys %hits)
	{
		$retval .= "$URL;$hits{$URL};$trans{$URL}\n";
		last if ($count-- == 0);
	}

	$retval .= "\n\n\n";

	$retval .= "PAGES REQUESTED SORTED BY NUMBER OF BYTES TRANSFERED\n";
	$retval .= "Only top $config::MAX_URLS\n\n";
	$retval .= "Request;Hits;Size (in Bytes)\n";
	$retval .= "------------------;----------;----------\n";

	$count = $config::MAX_URLS;
	foreach my $URL (sort { $trans{$b} <=> $trans{$a} } keys %hits)
	{
		$retval .= "$URL;$hits{$URL};$trans{$URL}\n";
		last if ($count-- == 0);
	}

	$retval .= "\n\n\n";

	return $retval;
}

# returns the hits produced by a host
# sorted by kbytes
sub CurrentMonth_HostsBySize()
{
	my $retval = "";

	$retval = "Requests by hosts sorted by number of bytes transfered.\n";
	$retval .= "Only top $config::MAX_HOSTS\n\n";
	$retval .= "Host;Hits;Size (in Bytes)\n";
	$retval .= "------------------;----------;----------\n";

	my $EXCLUDEHOST = &generateExclude("h.host");

	my $sql_statement = "select h.host as hh, sum(t.size) as trans, count(*) as cnt
				from transfer t, host h
				where t.hostid = h.id and
				t.time <= '$year/$month/$day $hour:$min'
				and t.time >= '$year/$month/01 00:00'
				$EXCLUDEHOST
				group by hh order by trans desc LIMIT 0, $config::MAX_HOSTS";

	my $cur = $dbh->prepare($sql_statement);

	$cur->execute;
	
	while (my @req = $cur->fetchrow_array() )
	{
		#printx "$req[0];$req[1];$req[2]\n";
		$retval .= "$req[0];$req[2];$req[1]\n";
	}

	$cur->finish();

	$retval .= "\n\n\n";

	return $retval;
}

# returns the hits produced by a host
# sorted by hits
sub CurrentMonth_HostsByHits()
{
	my $retval = "";

	$retval = "Requests by hosts sorted by number of hits.\n";
	$retval .= "Only top $config::MAX_HOSTS\n\n";
	$retval .= "Host;Hits;Size (in Bytes)\n";
	$retval .= "------------------;----------;----------\n";

	my $EXCLUDEHOST = &generateExclude("h.host");

	my $sql_statement = "select h.host as hh, sum(t.size) as trans, count(*) as cnt
				from transfer t, host h
				where t.hostid = h.id
				and t.time <= '$year/$month/$day $hour:$min'
				and t.time >= '$year/$month/01 00:00'
				$EXCLUDEHOST
				group by hh order by cnt desc LIMIT 0, $config::MAX_HOSTS";

	my $cur = $dbh->prepare($sql_statement);

	$cur->execute;
	
	while (my @req = $cur->fetchrow_array() )
	{
		#printx "$req[0];$req[1];$req[2]\n";
		$retval .= "$req[0];$req[2];$req[1]\n";
	}

	$cur->finish();

	$retval .= "\n\n\n";

	return $retval;
}

# returns the hits produced by a host
# sorted by hits
sub CurrentMonth_DomainsByHitsAndSize()
{
	my $retval = "";


	my $EXCLUDEHOST = &generateExclude("substring_index(h.host, '.', -1)");

	my $sql_statement = "select substring_index(h.host, '.', -1) as hh, sum(t.size) as trans, count(*) as cnt
				from transfer t, host h
				where t.hostid = h.id 
				and t.time <= '$year/$month/$day $hour:$min'
				and t.time >= '$year/$month/01 00:00'
				$EXCLUDEHOST
				group by hh order by cnt desc";

	my $cur = $dbh->prepare($sql_statement);

	$cur->execute;

	my %trans 	= ("$config::URL_GROUPING{rest}" => 0);
	my %hits	= ("$config::URL_GROUPING{rest}" => 0);
	
	ROW: while (my @req = $cur->fetchrow_array() )
	{
		#printx "$req[0];$req[1];$req[2]
		if ($req[0] =~ /^\d+$/)
		{
			$hits{$config::URL_GROUPING{"rest"}} += $req[2];
			$trans{$config::URL_GROUPING{"rest"}} += $req[1];

			next ROW;
		}

		$hits{$req[0]}	= $req[2];
		$trans{$req[0]}	= $req[1];
	}

	$cur->finish();

	$retval = "REQUESTS GROUPED BY DOMAINS SORTED BY NUMBER OF HITS\n\n";
	$retval .= "Domain;Hits;Size (in Bytes)\n";
	$retval .= "------------------;----------;----------\n";
	foreach my $domain (sort { $hits{$b} <=> $hits{$a} } keys %hits)
	{
		$retval .= "$domain;$hits{$domain};$trans{$domain}\n";

	}
	$retval .= "\n\n\n";

	$retval .= "REQUESTS GROUPED BY DOMAINS SORTED BY NUMBER OF BYTES TRANSFERED\n\n";
	$retval .= "Domain;Hits;Size (in Bytes)\n";
	$retval .= "------------------;----------;----------\n";
	foreach my $domain (sort { $trans{$b} <=> $trans{$a} } keys %hits)
	{
		$retval .= "$domain;$hits{$domain};$trans{$domain}\n";

	}
	$retval .= "\n\n\n";

	return $retval;
}


# generates a valid SQL clause to exlude special hosts
# like localhost and the alias names for the server
sub generateExclude($$)
{
	return "" if ($#config::IGNORE_HOSTS == 0);

	my $fieldname = shift;
	my $retval = " and not (";

	foreach my $HOST (@config::IGNORE_HOSTS)
	{
		$retval .= " $fieldname like '\%$HOST\%' or ";
	}

	return $retval. " 0)";
}

# returns the group of the URL supplied
# groups are stored in the global config::URL_GROUPING hash
#
# if no group found the rest group is used
sub groupURL($$)
{
	my $url = shift || return $config::URL_GROUPING{"rest"};

	foreach my $group (keys %config::URL_GROUPING)
	{
		#printx "$url ==> $group\n";
		return $config::URL_GROUPING{$group} if ($url =~ /$group/);
	}

	return $config::URL_GROUPING{"rest"} if ($config::GROUPUNKNOWN == 1);

	return $url;
}


