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

Annotation of RT/Invoicing/report_time, Revision 1.5

1.1       afresh1     1: #!/usr/bin/perl
1.5     ! afresh1     2: # $AFresh1: report_time,v 1.4 2020/08/04 01:24:44 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.5     ! afresh1    77: my $total = 0;
1.2       afresh1    78: foreach my $date ( sort keys %total ) {
1.5     ! afresh1    79:        my $subtotal = 0;
1.2       afresh1    80:        foreach my $key ( sort keys %{ $total{$date} } ) {
1.3       afresh1    81:                my $hours = $total{$date}{$key}->hours;
                     82:
1.1       afresh1    83:                # round to the quarter hour
1.5     ! afresh1    84:                $hours = sprintf "%.02f",
        !            85:                    25 * sprintf "%.02f", $hours / 25;
1.3       afresh1    86:
1.5     ! afresh1    87:                say "$date $hours $key" if $hours != 0;
        !            88:
        !            89:                $subtotal += $hours;
        !            90:                $total    += $hours;
1.1       afresh1    91:        }
1.5     ! afresh1    92:        printf "# %s %.02f\n", $date, $subtotal;
1.1       afresh1    93: }
1.5     ! afresh1    94: printf "# Total %.02f\n", $total;
1.1       afresh1    95:
                     96: sub descr_to_key {
                     97:        my ($descr) = @_;
                     98:
                     99:        my @key = split /\s+/, $descr;
                    100:
1.4       afresh1   101:        $key[-1] = $conversions{ lc $key[-1] }
                    102:            if @key < 3 and $conversions{ lc $key[-1] };
1.1       afresh1   103:
                    104:        return "@key";
                    105: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>