DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Run Analog For Monthly And Yearly Reports

06.02.2007
| 1124 views |
  • submit to reddit
        // Run Analog for monthly and yearly reports

#!/usr/bin/perl

# $Id$

use strict;
use warnings;

## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
our ($VERSION) = '$Revision$' =~ m{ \$Revision: \s+ (\S+) }xms;
## use critic

use English qw( -no_match_vars );
use Getopt::Long;
use POSIX qw( WIFEXITED );

my @ANALOG_CMD = qw(/usr/bin/nice /usr/local/packages/analog/analog -G);

my $config = get_config();

do_months($config);
do_years($config);

exit;

# Run yearly Analog reports
sub do_years {
    my ($config) = @_;
    
    my ($year)         = $config->{ startmonth   } =~ m/ \A (\d{4}) /xms;
    my ($current_year) = $config->{ currentmonth } =~ m/ \A (\d{4}) /xms;
    
    # Run Analog for all years except current year (if not already run)
    while ($year != $current_year) {
        run_cmd($config, $year);
        $year++;
    }
    
    return;
}

# Run monthly Analog reports
sub do_months {
    my ($config) = @_;
    
    my $month = $config->{startmonth};
    
    while ($month != $config->{currentmonth}) {
        # Run Analog for this month if not already run
        if ( ! -e $config->{outputdir} . q{/} . $month . '.html' ) {
            run_cmd($config, $month);
        }
        
        # Get next month
        my ($y, $m) = $month =~ m/ \A (\d{4}) (\d{2}) \z /xms;
        $m++;
        if ($m == 13) {
            $m = 1;
            $y++;
        }
        $month = sprintf '%04d%02d', $y, $m;
    }
    
    run_cmd($config, $month);
    
    return;
}

# Run Analog 
sub run_cmd {
    my ($config, $date) = @_;
    
    my @cmd;
    
    push @cmd, @ANALOG_CMD;
    
    # Config files
    foreach my $configfile ( @{$config->{configfiles}} ) {
        my $file = $config->{configdir} . "/$configfile";
        push @cmd, "+g$file";
    }
    
    # Year or month config file
    push @cmd, '+g' . $config->{configdir} . q{/}
               . ( length $date == 4 ? 'year.cfg' : 'month.cfg' );
    
    # Output options
    my $prefix = $date;
    if ($date == $config->{currentmonth}) {
        $prefix = 'current';
    }
    push @cmd, '+O' . $config->{outputdir} . q{/} . $prefix . '.html';
    push @cmd, "+CCHARTDIR $prefix-";
    push @cmd, '+CLOCALCHARTDIR ' . $config->{outputdir} . "/$prefix-";
    
    # Date range
    my $from;
    my $to;
    if (length $date == 4) {
        # Year
        $from = $date . '0101';
        $to   = $date . '1231';
    }
    elsif (length $date == 6) {
        # Month
        $from = $date . '01';
        $to   = $date . '31';
    }
    # Year needs to be in two digit format
    substr $from, 0, 2, q{};
    substr $to,   0, 2, q{};
    push @cmd, "+F$from";
    push @cmd, "+T$to";
    
    # Get logs
    my $need_prev = 1;
    my $got_log = 0;
    # Iterate over all logs
    LOG:
    for my $i ( 0 .. $#{$config->{logs}} ) {
        if ( $config->{logs}->[$i] =~ m/\D$date/xms ) {
            # Got a matching log
            $got_log = 1;
            if ($need_prev) {
                # Get the previous log(s)
                my $j = $i - 1;
                my $prev_date;
                while ( $j >= 0 ) {
                    if (!defined $prev_date) {
                        # Get previous log
                        push @cmd, $config->{logs}->[$j];
                        ($prev_date) = $config->{logs}->[$j] =~ m/(\d+)/xms;
                    }
                    else {
                        # Get other previous logs with the same date
                        my ($prev_date2) = $config->{logs}->[$j] =~ m/(\d+)/xms;
                        if ($prev_date == $prev_date2) {
                            push @cmd, $config->{logs}->[$j];
                        }
                        else {
                            $need_prev = 0;
                            last;
                        }
                    }
                    $j--;
                }
            }
            push @cmd, $config->{logs}->[$i];
        }
        else {
            if ($got_log) {
                # Get the next log(s)
                push @cmd, $config->{logs}->[$i];
                my ($next_date) = $config->{logs}->[$i] =~ m/(\d+)/xms;
                # Get other next logs with the same date
                my $j = $i + 1;
                while ( $j <= $#{$config->{logs}} ) {
                    my ($next_date2) = $config->{logs}->[$j] =~ m/(\d+)/xms;
                    if ($next_date == $next_date2) {
                        push @cmd, $config->{logs}->[$j];
                    }
                    else {
                        last LOG;
                    }
                    $j++;
                }
            }
        }
    }
    
    WIFEXITED(system @cmd) or die "Couldn't run: @cmd ($OS_ERROR)\n";
    
    return;
}

# Get command line options, check them and get all logs
sub get_config {
    my $config = {};
    
    $config->{ startmonth   } = q{};
    $config->{ currentmonth } = q{};
    $config->{ outputdir    } = q{};
    $config->{ configdir    } = q{};
    $config->{ configfiles  } = [];
    $config->{ logglobs     } = [];
    
    GetOptions(
          'startmonth=s' => \$config->{ startmonth   },
        'currentmonth=s' => \$config->{ currentmonth },
           'outputdir=s' => \$config->{ outputdir    },
           'configdir=s' => \$config->{ configdir    },
          'configfile=s' =>  $config->{ configfiles  },
             'logglob=s' =>  $config->{ logglobs     },
    );
    
    # Check config
    foreach my $configfile ( @{$config->{configfiles}} ) {
        my $file = $config->{configdir} . "/$configfile";
        die "$file does not exist\n" if ! -e $file;
        die "$file cannot be read\n" if ! -r $file;
    }
    if ( ! -w $config->{outputdir} ) {
        die $config->{outputdir} . " cannot be written to\n";
    }
    if ($config->{startmonth}   !~ m/ \A \d{6} \z /xms) {
        die "--startmonth should be YYYYMM\n";
    }
    if ($config->{currentmonth} !~ m/ \A \d{6} \z /xms) {
        die "--currentmonth should be YYYYMM\n";
    }
    
    # Get logs from globs
    $config->{logs} = [];
    foreach my $logglob ( @{$config->{logglobs}} ) {
        my @logs = glob $logglob;
        push @{$config->{logs}}, @logs;
    }
    die "No logs found\n" if !@{$config->{logs}};
    
    # Sort logs by date
    @{$config->{logs}} = sort sort_logs @{$config->{logs}};
    
    return $config;
}

# Sort logs by date then alphabetically
sub sort_logs {
    my ($a_date) = $a =~ m/(\d+)/xms;
    my ($b_date) = $b =~ m/(\d+)/xms;
    return $a_date <=> $b_date || $a cmp $b;
}