Annotation of RT/Invoicing/report_time, Revision 1.4
1.1 afresh1 1: #!/usr/bin/perl
1.4 ! afresh1 2: # $AFresh1: report_time,v 1.3 2020/08/04 01:23:48 afresh1 Exp $
1.1 afresh1 3: use v5.16;
4: use warnings;
5:
6: my $dir = "$ENV{HOME}/.time";
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:
34: my %entries;
35: foreach my $file (@files) {
36: my $key = 'm';
37:
38: open my $fh, '<', $file or die "Unable to open $file: $!";
39: while (readline $fh) {
40: my ($dt, $type, $description)
41: = /^ (.*) \s+ (st[ao])\b \s* (.*) \R$/x;
42:
43: my %entry = ( dt => $dt, type => $type );
44: $entry{description} = $description if $description;
45:
46: $key = descr_to_key($description)
47: if $type eq 'sta' and $description;
48:
49: push @{ $entries{$key} }, \%entry;
50: }
51: close $fh;
52: }
53:
1.2 afresh1 54: my %total;
1.1 afresh1 55: foreach my $key (sort keys %entries) {
56: my $start;
57: foreach my $entry (@{ $entries{$key} }) {
58:
59: # Sat Jul 11 11:56:06 PDT 2020
60: $entry->{datetime} = Time::Piece->new->strptime(
61: $entry->{dt}, "%a %b %e %H:%M:%S %Z %Y");
62:
1.2 afresh1 63: $total{ $entry->{datetime}->date }{$key}
1.1 afresh1 64: += $entry->{datetime} - $start->{datetime}
65: if $start;
66:
67: $start = $entry->{type} eq 'sta' ? $entry : '';
68: }
69:
70: # If we have a timer running, pretend it stops now.
71: if ($start) {
72: my $now = localtime;
1.2 afresh1 73: $total{ $now->date }{$key} += $now - $start->{datetime}
1.1 afresh1 74: }
1.2 afresh1 75: }
1.1 afresh1 76:
1.2 afresh1 77: foreach my $date ( sort keys %total ) {
78: foreach my $key ( sort keys %{ $total{$date} } ) {
1.3 afresh1 79: my $hours = $total{$date}{$key}->hours;
80:
1.1 afresh1 81: # round to the quarter hour
1.3 afresh1 82: $hours = sprintf "%.2f",
83: 25 * sprintf "%.2f", $hours / 25;
84:
1.2 afresh1 85: say "$date $hours $key";# if $hours != 0;
1.1 afresh1 86: }
87: }
88:
89: sub descr_to_key {
90: my ($descr) = @_;
91:
92: my @key = split /\s+/, $descr;
93:
1.4 ! afresh1 94: $key[-1] = $conversions{ lc $key[-1] }
! 95: if @key < 3 and $conversions{ lc $key[-1] };
1.1 afresh1 96:
97: return "@key";
98: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>