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

# RT3 ticket counter
#
# This script counts tickets.
#
# T.D.Bishop@kent.ac.uk, May 2004.
# Updated, May 2005.
#   (using changes sent by Jamie L. Penman-Smithson <jamie@silverdream.org>)
# Updated to display sums, June 2005.
#   (using changes sent by Petter Reinholdtsen <pere@hungry.com>)
# Updates to remove warnings with RT 3.8.0, July 2008.
#
# TODO: look at deleted tickets? they affect the counts.
#
# $Id: rt-count,v 1.9 2008/07/17 15:06:54 tdb Exp $

### Configuration

my(@queues); # do not delete this

# Queues to operate on (default is all)
#@queues = qw ( queue1 queue2 );

# Where to store state
my($statedir) = "/var/rt3";

# Where to mail report to (and from)
my($recipient) = "YOU\@YOURDOMAIN";
my($sender) = "YOU\@YOURDOMAIN";

# charset to use in emails
my($charset) = "ISO-8859-15";

# Location of RT3's libs
use lib ("/usr/local/packages/rt/lib", "/usr/local/packages/rt/local/lib");

### Code

use strict;
use Carp;

# Pull in the RT stuff
package RT;
use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);

# Clean our the environment
CleanEnv();

# Load the RT configuration
RT::LoadConfig();

# Initialise RT
RT::Init();

# Drop any setgid permissions we might have
#RT::DropSetGIDPermissions();

use RT::Date;
use RT::Tickets;

# Path to sendmail and flags. Need to set this after RT::Init()
my($sendmail) = RT->Config->Get('SendmailPath') . " " . RT->Config->Get('SendmailArguments');

if (!@queues) {
    my $queues = new RT::Queues($RT::SystemUser);
    $queues->LimitToEnabled();
    foreach my $queue (@{$queues->ItemsArrayRef()}) {
        push @queues, $queue->Name;
    }
}

# Create message
    my($msg) = <<EOF;
Content-Type: text/plain; charset="$charset"
From: $sender
To: $recipient
Subject: RT ticket counts

Queue statistics for RT:

EOF

$msg .= sprintf(
    "        %15s | %8s | %8s | %8s | %8s\n",
    "queue", "new", "resolved", "stalled", "rejected"
);
$msg .= "        ----------------+----------+----------+----------+---------\n";

my($ticketsum) = 0;
my($resolvedsum) = 0;
my($stalledsum) = 0;
my($rejectedsum) = 0;

foreach my $queuename (@queues) {
    # Load in the queue
    my $queue = new RT::Queue($RT::SystemUser);
    $queue->Load($queuename);

    my $now = new RT::Date($RT::SystemUser);
    $now->SetToNow();

    # Get hold of new and open tickets only
    my $tickets = new RT::Tickets($RT::SystemUser);
    $tickets->LimitQueue(VALUE => $queue->Id);

    my($ticketcount) = 0;

    my($resolvedcount) = 0;
    my($stalledcount) = 0;
    my($rejectedcount) = 0;

    # Count number of tickets
    while (my $ticket = $tickets->Next) {
        $ticketcount++;
        if ($ticket->Status eq "resolved" || $ticket->Status eq "autoclose") {
            $resolvedcount++;
            next;
        }
        if ($ticket->Status eq "stalled") {
            $stalledcount++;
            next;
        }
        if ($ticket->Status eq "rejected") {
            $rejectedcount++;
            next;
        }
    }

    # Open old counts
    my($oldticketcount) = 0;
    my($oldresolvedcount) = 0;
    my($oldstalledcount) = 0;
    my($oldrejectedcount) = 0;

    if (-f "$statedir/rt-count_${queuename}_tickets") {
        open(TMP, "$statedir/rt-count_${queuename}_tickets") || die "Error opening rt-count_${queuename}_tickets: $!";
        $oldticketcount = <TMP>;
        close(TMP);
    }
    if (-f "$statedir/rt-count_${queuename}_resolved") {
        open(TMP, "$statedir/rt-count_${queuename}_resolved") || die "Error opening rt-count_${queuename}_resolved: $!";
        $oldresolvedcount = <TMP>;
        close(TMP);
    }
    if (-f "$statedir/rt-count_${queuename}_stalled") {
        open(TMP, "$statedir/rt-count_${queuename}_stalled") || die "Error opening rt-count_${queuename}_stalled: $!";
        $oldstalledcount = <TMP>;
        close(TMP);
    }
    if (-f "$statedir/rt-count_${queuename}_rejected") {
        open(TMP, "$statedir/rt-count_${queuename}_rejected") || die "Error opening rt-count_${queuename}_rejected: $!";
        $oldrejectedcount = <TMP>;
        close(TMP);
    }

    my($newtickets) = $ticketcount - $oldticketcount;
    my($newresolved) = $resolvedcount - $oldresolvedcount;
    my($newstalled) = $stalledcount - $oldstalledcount;
    my($newrejected) = $rejectedcount - $oldrejectedcount;

    $ticketsum += $newtickets;
    $resolvedsum += $newresolved;
    $stalledsum += $newstalled;
    $rejectedsum += $newrejected;

    $msg .= sprintf(
        "        %15s | %8d | %8d | %8d | %8d\n",
        $queuename, $newtickets, $newresolved, $newstalled, $newrejected
    );

    open(TMP, ">$statedir/rt-count_${queuename}_tickets") || die "Error writing rt-count_${queuename}_tickets: $!";
    print TMP $ticketcount;
    close(TMP);
    open(TMP, ">$statedir/rt-count_${queuename}_resolved") || die "Error writing rt-count_${queuename}_resolved: $!";
    print TMP $resolvedcount;
    close(TMP);
    open(TMP, ">$statedir/rt-count_${queuename}_stalled") || die "Error writing rt-count_${queuename}_stalled: $!";
    print TMP $stalledcount;
    close(TMP);
    open(TMP, ">$statedir/rt-count_${queuename}_rejected") || die "Error writing rt-count_${queuename}_rejected: $!";
    print TMP $rejectedcount;
    close(TMP);
}

$msg .= "        ----------------+----------+----------+----------+---------\n";
$msg .= sprintf(
    "        %15s | %8d | %8d | %8d | %8d\n",
    "sum", $ticketsum, $resolvedsum, $stalledsum, $rejectedsum
);

my($lastrun) = "FIRST RUN";

if (-f "$statedir/rt-count_lastrun") {
    open(TMP, "$statedir/rt-count_lastrun") || die "Error opening rt-count_lastrun: $!";
    $lastrun = <TMP>;
    close(TMP);
    $lastrun = localtime($lastrun);
}

my $now = time;
$now = localtime($now);

$msg .= <<EOF;

These statistics are for the period:

        $lastrun -> $now

EOF
$msg .= RT->Config->Get('WebURL') . "\n";

open(TMP, ">$statedir/rt-count_lastrun") || die "Error writing rt-count_lastrun: $!";
print TMP time;
close(TMP);

# Send the message
open(SENDMAIL, "|$sendmail") || die "Error sending mail: $!";
print SENDMAIL $msg;
close(SENDMAIL);

# Disconnect before we finish off
$RT::Handle->Disconnect();
exit 0;
