#!/usr/bin/perl -T use strict; use vars qw($VERSION); $VERSION="1.0"; # AWIndex - HTML Index Generator for AWStats # Written by Nick Levay # # This is free software. You may copy, modify, and distribute this program # under the same terms as perl. # # AWIndex is a CGI script that generates a HTML index for multiple sites # using AWStats. It reads AWStats config files and creates an index page # which can be sorted by site name, current month's visit count, or current # month's unique visitor count. # These two paths must be correct my $awlinkpath = "/cgi-bin/awstats.cgi"; # path to awstats script my $configdir = "/etc/awstats"; # awstats config directory # From here out, changes are optional my $lmode = 'visits'; # default list mode (name/visits/unique) my $showdomains = 1; # show domains column (0 or 1) my $prettyregex = 1; # make most simple regex more human readable (0 or 1) # Header my $header = < Web Site Traffic Stats

Web Site Traffic Stats

END # Footer my $footer = < Generated by AWIndex v$VERSION for AWStats by Nick Levay <nick\@nicklevay.net> END # Text strings my $str = { site => 'Site', # site button/header label visits => 'Visits', # visits button/header label unique => 'Unique', # unique button/header label domains => 'Domains' # domains buttons/header label }; # END OF CONFIGURATION ###################### # sites -> name -> file (string), visits (int), unique (int), domains (array) my $sites = {}; # Check config dir for config files (exclude awstats.model.conf) opendir(DIR, $configdir) || die "Could not scan $configdir: $!"; while (my $file = readdir(DIR)) { if ($file =~ m/awstats\.(.+)\.conf/ && $1 ne 'model') { my $name = $1; $sites->{$name} = { file => $file }; } } close(DIR); # Read files foreach my $name (keys %{ $sites }) { # Read Config File open(CONF, "$configdir/$sites->{$name}->{file}") || die "Could not read $configdir/$sites->{$name}->{file}: $!"; while (my $line = ) { next if $line =~ m/^#.*/; next unless $line =~ m/^(.*)="(.*)"$/; my ($token, $value) = ($1, $2); if ($token eq 'DirData') { $sites->{$name}->{datadir} = $value; } elsif ($token eq 'SiteDomain' && $showdomains) { push(@{ $sites->{$name}->{domains} }, $value); } elsif ($token eq 'HostAliases' && $showdomains) { foreach my $h (split(/ /, $value)) { next if $h eq 'localhost'; next if $h eq '127.0.0.1'; if ($h =~ m/REGEX\[\^\.(.*)\$\]/ && $prettyregex) { my $hostreg = $1; $hostreg =~ s/\\//g; push(@{ $sites->{$name}->{domains} }, $hostreg); } else { push(@{ $sites->{$name}->{domains} }, $h); } } } if ($showdomains) { last if $sites->{$name}->{domains} && $sites->{$name}->{visits} && $sites->{$name}->{unique}; } else { last if $sites->{$name}->{visits} && $sites->{$name}->{unique}; } } close(CONF); # Get current visitor & unique count my $mytime = sprintf("%02d", (localtime)[4] + 1) . ((localtime)[5] + 1900); my $dfname = "awstats$mytime.$name.txt"; my $datadir; if ($sites->{$name}->{datadir} =~ m/^\.\/.*/) { $datadir = $sites->{$name}->{datadir}; $datadir =~ s/^\.//; $datadir = $configdir . $datadir; } elsif ($sites->{$name}->{datadir} =~ m/^\.\.\//) { $datadir = $sites->{$name}->{datadir}; $datadir =~ s/^\.\.//; $datadir = $configdir . $datadir; } elsif ($sites->{$name}->{datadir} =~ m/^\//) { $datadir = $sites->{$name}->{datadir}; } my $datafile = $datadir . "/" . $dfname; if (-r $datafile) { open(DATA, $datafile) || die "Could not read $datafile: $!"; while (my $line = ) { chomp $line; if ($line =~ m/^TotalVisits (\d+)/) { $sites->{$name}->{visits} = $1; } elsif ($line =~ m/^TotalUnique (\d+)/) { $sites->{$name}->{unique} = $1; } last if $sites->{$name}->{visits} && $sites->{$name}->{unique}; } close(DATA); } else { $sites->{$name}->{visits} = 0; $sites->{$name}->{unique} = 0; } } # Figure out mode & URI my $dmode = $lmode; foreach my $mode ('site', 'visits', 'unique') { $lmode = $mode if $ENV{REQUEST_URI} =~ m/\?s=$mode/; } my $ruri = $ENV{REQUEST_URI}; $ruri =~ s/\?.*$//; # Print Page print "Content-Type: text/html\n\n"; print $header; print "\n"; foreach my $mode ('site', 'visits', 'unique') { if ($lmode eq $mode) { print ""; } else { my $uri = $ruri; $uri .= "?s=$mode" unless $dmode eq $mode; print ""; } } print "" if $showdomains; print "\n"; foreach my $name ( sort { if ($lmode eq 'visits') { ($sites->{$b}->{visits} <=> $sites->{$a}->{visits}) or ($a cmp $b) } elsif ($lmode eq 'unique') { ($sites->{$b}->{unique} <=> $sites->{$a}->{unique}) or ($a cmp $b) } else { $a cmp $b } } keys %{ $sites } ) { print ""; print ""; print ""; print "" if $showdomains; print "\n"; } print "
$str->{$mode}$str->{$mode}Domains
$name$sites->{$name}->{visits}$sites->{$name}->{unique}" . join(" ", @{ $sites->{$name}->{domains} }) . "
\n"; print $footer; # EOF