#!/bin/bash
#
# GoAwstats
# Release 1.0
# Latest version is always available at http://www.ruwenzori.net/code/go_awstats
#
# Automatic Awstats batch apache log reports production
#
# Always updates the reports for the current month and the current year.
# Produces other reports if they do not exist. To force the regeneration
# of a report, simply erase it.
#
#
# Developped and tested on a Debian 'Testing' system with Awstats 6.4-1.1
# Should work anywhere that has Unix-ish paths, Bash or a bash like shell,
# Awstats and the dependancies thereof.
#
#
# Author : Jean-Marc Liotier
#
#
# License
#
# 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.
#
# Changelog
# 0.1 20041119 Initial release.
# 0.2 20050928 Major restructuration. Now only updates the current
# month, current year and missing reports. Niceness.
# 0.2.2 20051104 Minor readability tweaks.
# 1.0 20061021 Corrected a major year calculation error that
# appeared when the logs began to span more than two
# years. I am now confident the whole thing works,
# hence the bump up to revision 1.0
#
# TODO
#
# - Really smart date handling is not yet implemented (see the program
# structure comment below). I have some doubts about its usefulness,
# and I even think that the current way may be too smart. I may revert
# to user-assigned dates for robustness sake and so that start date
# detection does not rely anymore on a merged log file with full
# history being available - and which standard logrotate does not provide.
#
#############################################
#
# User editable parameters
#
# Root directory of the generated reports
reportdir=/home/repository/www/log.grabeuh.com/awstats
# Path to awstats_buildstaticpages.pl
awstats_buildstaticpages=/home/jim/applications/awstats/awstats_buildstaticpages.pl
# Path to the Awstats script proper
awstatsprog=/usr/lib/cgi-bin/awstats.pl
# Path to the Awstats configuration files
etc_awstats=/etc/awstats
# Path to Awstats icons
iconpath=/usr/share/awstats/icon
# Awstats report builder niceness
niceness=15
#
# If a user wishes to control the access to a report for a vhost
# he must create a .htaccess file named $etc_awstats/.htaccess.vhost.name.tld
# This file will be automatically detected and used.
#
# No user editable parameters below this line
#
##############################################
awstats="nice -$niceness $awstats_buildstaticpages"
##############################################
#
# Date variables initialization
today=`date +%Y%m%d`
# Let's find which year and month the oldest line of all log files we have was produced
startdate=`find $etc_awstats -name 'awstats.*.conf' | xargs grep -h LogFile | sed s/LogFile\=\"//g | sed s/\"//g | xargs head -q -n 1 | awk -F" " '{print($4)}' | awk -F"/" '{print($2,$3)}' | awk -F":" '{print($1)}' | awk -F" " '{print($2,$1)}' | sed s/\ //g | sed s/Jan/01/g | sed s/Feb/02/g | sed s/Mar/03/g | sed s/Apr/04/g | sed s/May/05/g | sed s/Jun/06/g | sed s/Jul/07/g | sed s/Aug/08/g | sed s/Sep/09/g | sed s/Oct/10/g | sed s/Nov/11/g | sed s/Dec/12/g | sort | head -q -n 1`
zefirstyear=`echo $startdate | cut -b 1-4`
zefirstmonthinzefirstyear=`echo $startdate | cut -b 5-6`
zecurrentyear=`echo $today | cut -b 1-4`
zecurrentmonthinzecurrentyear=`echo $today | cut -b 5-6`
# End of date variables initialization
#
##############################################
#####################################
# Comments on the program structure #
#####################################
#
# The main body is made of three nested loops :
#
## What they should do and will do in a future version :
#
# - Vhosts loop : loops across all vhosts that have an Awstat configuration file
# - Years loop : for each vhost, loops between $zefirstyear and $zecurrentyear.
# - Months loop : for each year, between (but not including) $zefirstyear and
# $zecurrentyear loop accross all twelve months.
#
# The main months loop only concerns years $zefirstyear and $zecurrentyear
# because $zefirstyear and $zecurrentyear themselves are treated as special
# cases :
# - When the year is $zefirstyear, loops between $zefirstmonthinzefirstyear
# and December
# - When the year is $zecurrentyear, loops between January and
# $zecurrentmonthinzecurrentyear
# - For all other years in between, execture the months loop.
#
## What they actually do :
#
# All three cases are treated the same, except that in the current year the
# whole year report and the current month report are deleted before every run
# so that their regeneration is forced.
#
#
# In each year, there is a whole year report and twelve monthly reports.
#
# In many places you will find unconditional chmods. After too much time
# debugging trivial permission problems I have come to the conclusion that
# I am better safe than sorry, and the processing cost is negligible.
# Outer loop across all vhosts that have an Awstat configuration file
for zevhost in `find $etc_awstats -name 'awstats.*.conf' -printf '%f\n' | sed 's/^awstats\.\(.*\)\.conf/\1/'`
do
# Creates the vhost reports directory if it does not exists
if [ -d "$reportdir/$zevhost" ]
then
sleep 0
else
mkdir $reportdir/$zevhost
fi
chmod 755 $reportdir/$zevhost &
# If $etc_awstats/.htaccess.vhost.name.tld exists then access control is asked for
# and the .htaccess file must put in place
if [ -f "$etc_awstats/.htaccess.$zevhost" ]
then
cp $etc_awstats/.htaccess.$zevhost $reportdir/$zevhost/.htaccess
chmod 644 $reportdir/$zevhost/.htaccess &
else
rm -f $reportdir/$zevhost/.htaccess &
fi
# Update the statistics for this vhost before producing its reports
$awstatsprog -config=$zevhost -update
###########################################
#
# Special case : the first year
#
# Creates the first year directory if it does does not exist
if [ -d "$reportdir/$zevhost/$zefirstyear" ]
then
sleep 0
else
mkdir $reportdir/$zevhost/$zefirstyear
fi
chmod 755 $reportdir/$zevhost/$zefirstyear &
# Creates the whole first year report directory if it does does not exist
if [ -d "$reportdir/$zevhost/$zefirstyear/all" ]
then
sleep 0
else
mkdir $reportdir/$zevhost/$zefirstyear/all
fi
# Produces the full year report for the first year if it does not exist
if [ -f "$reportdir/$zevhost/$zefirstyear/all/awstats.$zevhost.html" ]
then
sleep 0
else
# Make the full year report
rm -rf $reportdir/$zevhost/$zefirstyear/.all.tmp
mkdir $reportdir/$zevhost/$zefirstyear/.all.tmp
$awstats -awstatsprog=$awstatsprog -config=$zevhost -dir=$reportdir/$zevhost/$zefirstyear/.all.tmp -month=all -year=$zefirstyear
mv $reportdir/$zevhost/$zefirstyear/all $reportdir/$zevhost/$zefirstyear/.all.old
mv $reportdir/$zevhost/$zefirstyear/.all.tmp $reportdir/$zevhost/$zefirstyear/all
ln -s $reportdir/$zevhost/$zefirstyear/all/awstats.$zevhost.html $reportdir/$zevhost/$zefirstyear/all/index.html &
chmod 644 $reportdir/$zevhost/$zefirstyear/all/* &
rm -rf $reportdir/$zevhost/$zefirstyear/.all.tmp &
rm -rf $reportdir/$zevhost/$zefirstyear/.all.old &
fi
chmod 755 $reportdir/$zevhost/$zefirstyear/all &
# Months loop for the first year
# Should start at the month of the earliest log
for zemonth in 01 02 03 04 05 06 07 08 09 10 11 12
do
# If the month directory does not exist we create it
if [ -d "$reportdir/$zevhost/$zefirstyear/$zemonth" ]
then
sleep 0
else
mkdir $reportdir/$zevhost/$zefirstyear/$zemonth
fi
# If the monthly report for that month does not already exist we produce it
if [ -f "$reportdir/$zevhost/$zefirstyear/$zemonth/awstats.$zevhost.html" ]
then
sleep 0
else
# Make the monthly report
rm -rf $reportdir/$zevhost/$zefirstyear/.$zemonth.tmp
mkdir $reportdir/$zevhost/$zefirstyear/.$zemonth.tmp
$awstats -awstatsprog=$awstatsprog -config=$zevhost -dir=$reportdir/$zevhost/$zefirstyear/.$zemonth.tmp -month=$zemonth -year=$zefirstyear
mv $reportdir/$zevhost/$zefirstyear/$zemonth $reportdir/$zevhost/$zefirstyear/.$zemonth.old
mv $reportdir/$zevhost/$zefirstyear/.$zemonth.tmp $reportdir/$zevhost/$zefirstyear/$zemonth
ln -s $reportdir/$zevhost/$zefirstyear/$zemonth/awstats.$zevhost.html $reportdir/$zevhost/$zefirstyear/$zemonth/index.html &
rm -rf $reportdir/$zevhost/$zefirstyear/.$zemonth.tmp &
rm -rf $reportdir/$zevhost/$zefirstyear/.$zemonth.old &
chmod 644 $reportdir/$zevhost/$zefirstyear/$zemonth/* &
fi
chmod 755 $reportdir/$zevhost/$zefirstyear/$zemonth &
done # Month of the first year
###########################################
#
# Normal year (not the first, not the last)
#
#
zesecondyear=`expr $zefirstyear + 1`
zeyear=$zesecondyear
# Years loop - for years between (but not including) $zefirstyear and $zecurrentyear
# wich means years between (and including) $zesecondyear and $zeyearbeforezelast
while [ "$zeyear" -ne $zecurrentyear ]
do
# Creates the year directory if it does does not exist
if [ -d "$reportdir/$zevhost/$zeyear" ]
then
sleep 0
else
mkdir $reportdir/$zevhost/$zeyear
fi
chmod 755 $reportdir/$zevhost/$zeyear &
# Creates the whole year report directory for the current if it does does not exist
if [ -d "$reportdir/$zevhost/$zeyear/all" ]
then
sleep 0
else
mkdir $reportdir/$zevhost/$zeyear/all
fi
# Produces the full year report for that year if it does not exist
if [ -f "$reportdir/$zevhost/$zeyear/all/awstats.$zevhost.html" ]
then
sleep 0
else
# Make the full year report
rm -rf $reportdir/$zevhost/$zeyear/.all.tmp
mkdir $reportdir/$zevhost/$zeyear/.all.tmp
$awstats -awstatsprog=$awstatsprog -config=$zevhost -dir=$reportdir/$zevhost/$zeyear/.all.tmp -month=all -year=$zeyear
mv $reportdir/$zevhost/$zeyear/all $reportdir/$zevhost/$zeyear/.all.old
mv $reportdir/$zevhost/$zeyear/.all.tmp $reportdir/$zevhost/$zeyear/all
ln -s $reportdir/$zevhost/$zeyear/all/awstats.$zevhost.html $reportdir/$zevhost/$zeyear/all/index.html &
rm -rf $reportdir/$zevhost/$zeyear/.all.tmp &
rm -rf $reportdir/$zevhost/$zeyear/.all.old &
chmod 644 $reportdir/$zevhost/$zeyear/all/* &
fi
chmod 755 $reportdir/$zevhost/$zeyear/all &
# Months loop for a normal year
for zemonth in 01 02 03 04 05 06 07 08 09 10 11 12
do
# If the month directory does not exist we create it
if [ -d "$reportdir/$zevhost/$zeyear/$zemonth" ]
then
sleep 0
else
mkdir $reportdir/$zevhost/$zeyear/$zemonth
fi
# If the monthly report for that month does not already exist we produce it
if [ -f "$reportdir/$zevhost/$zeyear/$zemonth/awstats.$zevhost.html" ]
then
sleep 0
else
# Make the monthly report
rm -rf $reportdir/$zevhost/$zeyear/.$zemonth.tmp
mkdir $reportdir/$zevhost/$zeyear/.$zemonth.tmp
$awstats -awstatsprog=$awstatsprog -config=$zevhost -dir=$reportdir/$zevhost/$zeyear/.$zemonth.tmp -month=$zemonth -year=$zeyear
mv $reportdir/$zevhost/$zeyear/$zemonth $reportdir/$zevhost/$zeyear/.$zemonth.old
mv $reportdir/$zevhost/$zeyear/.$zemonth.tmp $reportdir/$zevhost/$zeyear/$zemonth
ln -s $reportdir/$zevhost/$zeyear/$zemonth/awstats.$zevhost.html $reportdir/$zevhost/$zeyear/$zemonth/index.html &
rm -rf $reportdir/$zevhost/$zeyear/.$zemonth.tmp &
rm -rf $reportdir/$zevhost/$zeyear/.$zemonth.old &
chmod 644 $reportdir/$zevhost/$zeyear/$zemonth/* &
fi
chmod 755 $reportdir/$zevhost/$zeyear/$zemonth &
done # Month of a normal year
zeyear=`expr $zeyear + 1`
done # Normal year
###########################################
#
# Special case : the current (and therefore last) year
# Creates the current year directory if it does does not exist
if [ -d "$reportdir/$zevhost/$zecurrentyear" ]
then
sleep 0
else
mkdir $reportdir/$zevhost/$zecurrentyear
fi
chmod 755 $reportdir/$zevhost/$zecurrentyear &
# Creates the whole year report directory for the current if it does does not exist
if [ -d "$reportdir/$zevhost/$zecurrentyear/all" ]
then
sleep 0
else
mkdir $reportdir/$zevhost/$zecurrentyear/all
fi
# Make the full year report for the current year and remove the previous version
rm -rf $reportdir/$zevhost/$zecurrentyear/.all.tmp
mkdir $reportdir/$zevhost/$zecurrentyear/.all.tmp
$awstats -awstatsprog=$awstatsprog -config=$zevhost -dir=$reportdir/$zevhost/$zecurrentyear/.all.tmp -month=all -year=$zecurrentyear
mv $reportdir/$zevhost/$zecurrentyear/all $reportdir/$zevhost/$zecurrentyear/.all.old
mv $reportdir/$zevhost/$zecurrentyear/.all.tmp $reportdir/$zevhost/$zecurrentyear/all
chmod 755 $reportdir/$zevhost/$zecurrentyear/all &
ln -s $reportdir/$zevhost/$zecurrentyear/all/awstats.$zevhost.html $reportdir/$zevhost/$zecurrentyear/all/index.html &
rm -rf $reportdir/$zevhost/$zecurrentyear/.all.tmp &
rm -rf $reportdir/$zevhost/$zecurrentyear/.all.old &
chmod 644 $reportdir/$zevhost/$zecurrentyear/all/* &
# Removes the monthly report for the current month in order to force its regeneration.
rm -rf $reportdir/$zevhost/$zecurrentyear/$zecurrentmonthinzecurrentyear
# Months loop for the current year
# Should start at the month of the earliest log
for zemonth in 01 02 03 04 05 06 07 08 09 10 11 12
do
# If the month directory does not exist we create it
if [ -d "$reportdir/$zevhost/$zecurrentyear/$zemonth" ]
then
sleep 0
else
mkdir $reportdir/$zevhost/$zecurrentyear/$zemonth
fi
# If the monthly report for that month does not already exist we produce it
if [ -f "$reportdir/$zevhost/$zecurrentyear/$zemonth/awstats.$zevhost.html" ]
then
sleep 0
else
# Make the monthly report
rm -rf $reportdir/$zevhost/$zecurrentyear/.$zemonth.tmp
mkdir $reportdir/$zevhost/$zecurrentyear/.$zemonth.tmp
$awstats -awstatsprog=$awstatsprog -config=$zevhost -dir=$reportdir/$zevhost/$zecurrentyear/.$zemonth.tmp -month=$zemonth -year=$zecurrentyear
mv $reportdir/$zevhost/$zecurrentyear/$zemonth $reportdir/$zevhost/$zecurrentyear/.$zemonth.old
mv $reportdir/$zevhost/$zecurrentyear/.$zemonth.tmp $reportdir/$zevhost/$zecurrentyear/$zemonth
ln -s $reportdir/$zevhost/$zecurrentyear/$zemonth/awstats.$zevhost.html $reportdir/$zevhost/$zecurrentyear/$zemonth/index.html &
rm -rf $reportdir/$zevhost/$zecurrentyear/.$zemonth.tmp &
rm -rf $reportdir/$zevhost/$zecurrentyear/.$zemonth.old &
chmod 644 $reportdir/$zevhost/$zecurrentyear/$zemonth/* &
fi
chmod 755 $reportdir/$zevhost/$zecurrentyear/$zemonth &
done # Month of the current year
done # Vhost
# Use the latest icons
rm -rf $reportdir/icon
cp -a $iconpath $reportdir
# Better twice safe than soooorry...
find $reportdir -type d | xargs chmod --silent 755 &
find $reportdir -type f | xargs chmod --silent 644 &