File: [local] / RT / Invoicing / report_time (download)
Revision 1.5, Tue Aug 4 01:28:24 2020 UTC (4 years, 9 months ago) by afresh1
Branch: MAIN
Changes since 1.4: +11 -4 lines
Print totals for each day and overall
As comments as we probably won't actually process those.
Plus put back not printing zero hour items.
|
#!/usr/bin/perl
# $AFresh1: report_time,v 1.5 2020/08/04 01:28:24 afresh1 Exp $
use v5.16;
use warnings;
my $dir = "$ENV{HOME}/.time";
my %conversions = (
m => "Misc",
pc => "Phone Call",
);
# You can generate the files expected by this with this helpful script.
#
# #!/bin/sh
# action=$( basename $0 )
# realname=$( basename $( readlink -f $0 ) )
# [ "$action" = "$realname" ] && action=sta
# echo $( date ) $action "$@" >> ~/.time/$( date +%Y-%m-%d )
#
# You will have to mkdir ~/.time yourself.
# Link it to both "sta" and "sto" in your path and then start working with
# `sta some work` then stop working with just `sto`.
# A second `sta something else` will stop working on "some work"
# and switch to "something else".
use Time::Piece;
my @files = do {
opendir my $dh, $dir or die "Unable to opendir $dir: $!";
map { "$dir/$_" } sort grep { /^\d{4}-\d{2}-\d{2}$/ } readdir $dh;
};
my %entries;
foreach my $file (@files) {
my $key = 'm';
open my $fh, '<', $file or die "Unable to open $file: $!";
while (readline $fh) {
my ($dt, $type, $description)
= /^ (.*) \s+ (st[ao])\b \s* (.*) \R$/x;
my %entry = ( dt => $dt, type => $type );
$entry{description} = $description if $description;
$key = descr_to_key($description)
if $type eq 'sta' and $description;
push @{ $entries{$key} }, \%entry;
}
close $fh;
}
my %total;
foreach my $key (sort keys %entries) {
my $start;
foreach my $entry (@{ $entries{$key} }) {
# Sat Jul 11 11:56:06 PDT 2020
$entry->{datetime} = Time::Piece->new->strptime(
$entry->{dt}, "%a %b %e %H:%M:%S %Z %Y");
$total{ $entry->{datetime}->date }{$key}
+= $entry->{datetime} - $start->{datetime}
if $start;
$start = $entry->{type} eq 'sta' ? $entry : '';
}
# If we have a timer running, pretend it stops now.
if ($start) {
my $now = localtime;
$total{ $now->date }{$key} += $now - $start->{datetime}
}
}
my $total = 0;
foreach my $date ( sort keys %total ) {
my $subtotal = 0;
foreach my $key ( sort keys %{ $total{$date} } ) {
my $hours = $total{$date}{$key}->hours;
# round to the quarter hour
$hours = sprintf "%.02f",
25 * sprintf "%.02f", $hours / 25;
say "$date $hours $key" if $hours != 0;
$subtotal += $hours;
$total += $hours;
}
printf "# %s %.02f\n", $date, $subtotal;
}
printf "# Total %.02f\n", $total;
sub descr_to_key {
my ($descr) = @_;
my @key = split /\s+/, $descr;
$key[-1] = $conversions{ lc $key[-1] }
if @key < 3 and $conversions{ lc $key[-1] };
return "@key";
}