timetracker/timetracker-sections.pl
2024-06-25 14:55:05 -04:00

174 lines
5.0 KiB
Perl
Executable File

#!/usr/bin/perl -w
use strict;
use warnings;
use Date::Manip;
use Math::Round;
my $datetime; # Stores date and time pulled from log
my $entry; # Stores the log entry for processing
my $action; # Stores the action for processing (this will be the key to the
# hash).
my $time; # the $datetime converted to UNIX timestamp
my %begin; # Data structure for storing the beginning of a time frame
my %end; # Data structure for storing the end of a time frame
my %ind; # Data structure for storing individual timecards
my %misc; # Data structure for storing miscellaneous (<0.25hrs) timecards
my ($bc,$ec); # variables for determining if we have a complete set.
while(<>) {
if(/^\s*$/) { # If current line is an empty string, skip to next line
next;
}
chomp;
($datetime,$entry) = split /:\s{1,2}/;
#print STDERR "$datetime: $entry\n";
$time = UnixDate($datetime, "%s");
#print STDERR "$time: $entry\n";
if($entry =~ /^Begin/) {
#print STDERR "DEBUG: Writing an BEGIN action\n";
#print STDERR "$time: ";
$action = $entry;
$action =~ s/^Begin\s+(.+)\s*/$1/;
$action =~ s/\s+$//; # trim off any whitespace at the end
#print STDERR "$action\n";
push(@{$begin{$action}},$time);
}
if($entry =~ /^End/) {
#print STDERR "DEBUG: Writing an END action\n";
#print STDERR "$time: ";
$action = $entry;
$action =~ s/^End\s+(.+)\s*/$1/;
$action =~ s/\s+$//; # trim off any whitespace at the end
#print STDERR "$action\n";
push(@{$end{$action}},$time);
}
}
# We're here, begin processing
my $act;
my $gtot = 0;
foreach $act (sort keys %begin) { # For every activity we started.
# error checking
$bc = 0;
$ec = 0;
$bc = @{$begin{$act}}; # or die "Activity \"$act\" is incomplete. Missing Begin.\n";
#print STDERR "$act\n";
$ec = @{$end{$act}}; # or die "Activity \"$act\" is incomplete. Missing End.\n";
#print STDERR "DEBUG: \"$act\" bc=$bc,ec=$ec\n";
if(($bc - $ec) > 1) {
# haven't logged more than one closing time
# print STDERR "Activity \"$act\" is incomplete. Missing multiple Ends.\n";
exit 2;
} elsif($bc > $ec) { # should be exactly one greater
# print STDERR "Activity \"$act\" is incomplete. Missing one End. Removing last from array.\n";
pop(@{$begin{$act}});
# GRATUITOUS USE OF GOTO HERE!
goto THERE;
# END GRATUITOUS USE OF GOTO HERE!
} elsif($ec > $bc) {
# have missed a begin time
# print STDERR "Activity \"$act\" is incomplete. Missing Begin.\n";
exit 1;
} else {
THERE:
my $sum = 0;
# DOIT
while(@{$begin{$act}} && @{$end{$act}}) {
my $beg = shift @{$begin{$act}};
my $en = shift @{$end{$act}};
$sum += $en - $beg;
}
#printf ("\"$act\": %10ds %3.2fhr\n", $sum, ($sum / 3600 >= 0.25)?nearest(0.25, $sum / 3600):$sum / 3600);
#printf ("\"$act\":\t\t%10ds\t%3.2fhrs\n", $sum, $sum / 3600);
# If sum is greater than fifteen minutes, put it individual list
# otherwise, put it in
# 2014-10-02: Remove miscellaneous, since we will no longer be reporting in
# fifteen minute increments
#$sum > 900?$ind{$act}=$sum:$misc{$act}=$sum;
$ind{$act}=$sum;
$gtot += $sum;
}
}
#my $spr;
my $sec;
my $hrs;
my $min;
my $fhrs;
my $ctot = 0;
my $utot = 0;
# DEBUGGING
#foreach $act (sort keys %ind) {
# print STDERR "Activity: " . $act . " ";
# print STDERR "$ind{$act}s " . $ind{$act}/3600 . "hrs ";
# print STDERR $ind{$act}%3600/60 . "min\n";
#}
format STDOUT =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>>> @>>>>>>>>>> @>>>>>>>>>> @>>>>>>>>>>
$act, $sec, $hrs, $min, $fhrs
.
foreach $act (sort keys %ind) {
#$spr = sprintf("%3.2fhrs",nearest(0.25, $ind{$act}/3600));
$min = sprintf("%dmin",nearest(1, $ind{$act}%3600/60));
$hrs = sprintf("%dhrs",$ind{$act}/3600);
$fhrs = sprintf("%.2fhrs",$ind{$act}/3600);
$sec = "$ind{$act}s";
write;
if($act =~ /^\d{8}/) {
#print STDERR "Got a case\n";
$ctot += $ind{$act};
} else {
#print STDERR "Got a non-case\n";
$utot += $ind{$act};
}
# } elsif($changed == 0) {
# print "\n";
# printf ("Case total: %10ds, %3.2fhrs, %3.2fhrs (rounded)\n", $ctot, $ctot / 3600, nearest(0.25, $ctot / 3600));
# print "\n";
# $changed = 1;
#}
# else {
# $min = sprintf("%dmin",nearest(1, $ind{$act}%3600/60));
# $hrs = sprintf("%dhrs",$ind{$act}/3600);
# $fhrs = sprintf("%.2fhrs",$ind{$act}/3600);
# $sec = "$ind{$act}s";
# write;
# $utot += $ind{$act};
# }
}
print "\n";
printf ("Case total: %10ds, %3.2fhrs, %3.2fhrs (rounded)\n", $ctot, $ctot / 3600, nearest(0.25, $ctot / 3600));
print "\n";
print "\n";
printf ("Unnumbered total: %10ds, %3.2fhrs, %3.2fhrs (rounded)\n", $utot, $utot / 3600, nearest(0.25, $utot / 3600));
print "\n";
# REMOVED 2014-10-02
#$tot = 0;
#foreach $act (sort keys %misc) {
# $spr = sprintf("%3.2fhrs", $misc{$act}/3600);
# $sec = "$misc{$act}s";
# write;
# $tot += $misc{$act};
#}
#print "\n";
#printf ("Miscellaneous total: %10ds, %3.2fhrs, %3.2fhrs (rounded)\n", $tot,$tot / 3600, nearest(0.25, $tot / 3600));
#print "\n";
$gtot = $ctot + $utot;
print "\n";
printf "Grand Total: %10ds, %.02fhrs\n", $gtot, $gtot / 3600;
#my &section_post {
#
#};