Annotation of RT/Invoicing/report_time, Revision 1.6
1.1 afresh1 1: #!/usr/bin/perl
1.6 ! afresh1 2: # $AFresh1: report_time,v 1.5 2020/08/04 01:28:24 afresh1 Exp $
1.1 afresh1 3: use v5.16;
4: use warnings;
5:
1.6 ! afresh1 6: my $dir = "$ENV{HOME}/rt_invoicing/time";
1.1 afresh1 7:
8: my %conversions = (
9: m => "Misc",
10: pc => "Phone Call",
11: );
12:
13: # You can generate the files expected by this with this helpful script.
14: #
15: # #!/bin/sh
16: # action=$( basename $0 )
17: # realname=$( basename $( readlink -f $0 ) )
18: # [ "$action" = "$realname" ] && action=sta
19: # echo $( date ) $action "$@" >> ~/.time/$( date +%Y-%m-%d )
20: #
21: # You will have to mkdir ~/.time yourself.
22: # Link it to both "sta" and "sto" in your path and then start working with
23: # `sta some work` then stop working with just `sto`.
24: # A second `sta something else` will stop working on "some work"
25: # and switch to "something else".
26:
27: use Time::Piece;
28:
29: my @files = do {
30: opendir my $dh, $dir or die "Unable to opendir $dir: $!";
31: map { "$dir/$_" } sort grep { /^\d{4}-\d{2}-\d{2}$/ } readdir $dh;
32: };
33:
1.6 ! afresh1 34: my @entries;
1.1 afresh1 35: foreach my $file (@files) {
36: open my $fh, '<', $file or die "Unable to open $file: $!";
37: while (readline $fh) {
38: my ($dt, $type, $description)
39: = /^ (.*) \s+ (st[ao])\b \s* (.*) \R$/x;
40:
41: my %entry = ( dt => $dt, type => $type );
42: $entry{description} = $description if $description;
43:
1.6 ! afresh1 44: push @entries, \%entry;
1.1 afresh1 45: }
46: close $fh;
47: }
48:
1.2 afresh1 49: my %total;
1.6 ! afresh1 50: {
1.1 afresh1 51: my $start;
1.6 ! afresh1 52: my $key = 'm';
! 53: foreach my $entry (@entries) {
1.1 afresh1 54:
55: # Sat Jul 11 11:56:06 PDT 2020
56: $entry->{datetime} = Time::Piece->new->strptime(
57: $entry->{dt}, "%a %b %e %H:%M:%S %Z %Y");
58:
1.6 ! afresh1 59: if ($start) {
! 60: $key = descr_to_key($start->{description})
! 61: if $start->{description};
! 62: $total{ $entry->{datetime}->date }{$key}
! 63: += $entry->{datetime} - $start->{datetime};
! 64: }
1.1 afresh1 65:
66: $start = $entry->{type} eq 'sta' ? $entry : '';
67: }
68:
69: # If we have a timer running, pretend it stops now.
70: if ($start) {
1.6 ! afresh1 71: $key = descr_to_key($start->{description})
! 72: if $start->{description};
1.1 afresh1 73: my $now = localtime;
1.2 afresh1 74: $total{ $now->date }{$key} += $now - $start->{datetime}
1.1 afresh1 75: }
1.2 afresh1 76: }
1.1 afresh1 77:
1.5 afresh1 78: my $total = 0;
1.2 afresh1 79: foreach my $date ( sort keys %total ) {
1.5 afresh1 80: my $subtotal = 0;
1.2 afresh1 81: foreach my $key ( sort keys %{ $total{$date} } ) {
1.3 afresh1 82: my $hours = $total{$date}{$key}->hours;
83:
1.1 afresh1 84: # round to the quarter hour
1.5 afresh1 85: $hours = sprintf "%.02f",
86: 25 * sprintf "%.02f", $hours / 25;
1.3 afresh1 87:
1.5 afresh1 88: say "$date $hours $key" if $hours != 0;
89:
90: $subtotal += $hours;
91: $total += $hours;
1.1 afresh1 92: }
1.5 afresh1 93: printf "# %s %.02f\n", $date, $subtotal;
1.1 afresh1 94: }
1.5 afresh1 95: printf "# Total %.02f\n", $total;
1.1 afresh1 96:
97: sub descr_to_key {
98: my ($descr) = @_;
99:
100: my @key = split /\s+/, $descr;
101:
1.4 afresh1 102: $key[-1] = $conversions{ lc $key[-1] }
103: if @key < 3 and $conversions{ lc $key[-1] };
1.1 afresh1 104:
105: return "@key";
106: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>