[BACK]Return to report_time CVS log [TXT][DIR] Up to [local] / RT / Invoicing

File: [local] / RT / Invoicing / report_time (download)

Revision 1.5, Tue Aug 4 01:28:24 2020 UTC (3 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";
}