- #!/usr/bin/env perl
-
- use warnings;
- use strict;
- use 5.10.0;
-
- use File::HomeDir;
-
- my $rcfile = File::HomeDir->my_home . "/.timelogrc";
- # set an unreasonable default, so it's obvious:
- our $hourly_rate = 10000;
- do $rcfile if -e $rcfile;
-
- my $total_hours = 0;
- my $total_expenses = 0;
-
- # while we've got input from a file/stdin, split it into two datestamps
- # and feed that to date(1)
- while (my $line = <>) {
-
- chomp($line);
-
- if ($line =~ m/
- ^
- \s{2,} # leading whitespace, two or more
-
- expense: # the string "expense"
-
- [ ] # a space
-
- \$ ([\d.]+) # an amount
-
- [ ]
- - # a dash with spaces
- [ ]
-
- (.*?) # any notes
-
- $ # eol
- /ix)
- {
- my $expense_amount = $1;
- $total_expenses += $expense_amount;
- my $expense_notes = $2;
- say "* $line";
- }
-
- # skip things that don't look like a date range - everything else can
- # just be commentary.
- next unless $line =~ m/
- ^
- \s{2,} # leading whitespace of two or more chars
-
- (
- \d{4} - \d{2} - \d{2} # date
- )
-
- [ ] # space
-
- (
- \d{1,2} : \d{2} # start timestamp
- )
-
- [ ] - [ ] # delimiter
-
- (
- \d{1,2} : \d{2} # end timestamp
- )
- $
- /ix;
-
- my $start_timestamp = "$1 $2";
- my $end_timestamp = "$1 $3";
-
- my ($start, $end) = map { get_seconds($_) } ($start_timestamp, $end_timestamp);
- my $interval = $end - $start;
- my $hours = $interval / 3600;
- $total_hours += $hours;
- say sprintf("* $line\t%.3f hours", $hours);
-
- }
-
- my $hourly_total = $total_hours * $hourly_rate;
- my $overall_total = $hourly_total + $total_expenses;
-
- print "\n";
- say sprintf(
- # extra spaces at end for newline in markdown:
- '%.3f total hours at $%.2f/hr = $%.2f ',
- $total_hours,
- $hourly_rate,
- $hourly_total
- );
-
- say sprintf(
- '$%.2f in expenses',
- $total_expenses
- );
-
- print "\n";
- say sprintf('**Total due = $%.2f**', $overall_total);
-
- sub get_seconds {
- my ($stamp) = @_;
- my $seconds = `date --date="$stamp" +%s`;
- chomp($seconds);
- return $seconds;
- }
|