Current version of commandline utility
authorJoey Schulze <joey@infodrom.org>
Tue, 12 Aug 2008 16:19:01 +0000 (16:19 +0000)
committerJoey Schulze <joey@infodrom.org>
Tue, 12 Aug 2008 16:19:01 +0000 (16:19 +0000)
src/InfoCon/stempel/stempel [new file with mode: 0755]

diff --git a/src/InfoCon/stempel/stempel b/src/InfoCon/stempel/stempel
new file mode 100755 (executable)
index 0000000..31acc97
--- /dev/null
@@ -0,0 +1,209 @@
+#! /usr/bin/perl
+
+#  Time Tracker
+#
+#  Copyright (c) 2007  Martin Schulze <joey@infodrom.org>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+
+use strict;
+use warnings;
+
+use DBI;
+use Getopt::Long;
+use Term::ReadLine;
+
+my $table = "stempel";
+my $engine = "dbi:Pg:dbname=infocon";
+
+my $dbh = DBI->connect($engine);
+if (!$dbh) {
+    print "Access to database denied!\n";
+    return 1;
+}
+$dbh->do("SET DateStyle = 'ISO'");
+
+sub min2hour
+{
+    my $minutes = shift;
+
+    return sprintf('%02d:%02d', $minutes/60, $minutes%60);
+}
+
+sub is_open
+{
+    my $query = q{SELECT count(*) AS count FROM stempel WHERE stop IS NULL};
+    my $sth = $dbh->prepare ($query);
+    if ($sth && $sth->execute > 0) {
+       my $row = $sth->fetchrow_hashref;
+       return $row->{count} > 0 ? 1 : 0;
+    }
+    return 0;
+}
+
+sub customerlist
+{
+    my @res;
+
+    my $query = q{SELECT DISTINCT customer FROM stempel ORDER BY customer};
+    my $sth = $dbh->prepare ($query);
+    if ($sth && $sth->execute > 0) {
+       while ((my $row = $sth->fetchrow_hashref)) {
+           push @res, $row->{customer};
+       }
+    }
+    return @res;
+}
+
+sub open_task
+{
+    my $term = new Term::ReadLine '';
+    my @customers = customerlist;
+
+    $term->addhistory($_) foreach (@customers);
+
+    my $attribs = $term->Attribs;
+    $attribs->{completion_entry_function} = $attribs->{list_completion_function};
+    $attribs->{completion_word} = \@customers;
+
+    printf "[%s]\n", join (', ', @customers);
+
+    my $customer = $term->readline ('Kunde: ');
+
+    if (defined $customer && length($customer) > 0) {
+       $customer =~ s/\s*$//;
+       $attribs->{completion_word} = undef;
+       my $task = $term->readline ('Aufgabe: ');
+       if (length($task) > 0) {
+           my $query = q{INSERT INTO stempel (start,customer,task) VALUES('now()',?,?)};
+           my $sth = $dbh->prepare($query);
+           $sth->execute($customer, $task);
+       }
+    }
+}
+
+sub quarter
+{
+    my $min = shift;
+
+    return 15 if $min < 15;
+
+    return $min - $min%15 if ($min%15 < 3);
+
+    return $min + 15-$min%15;
+}
+
+sub hdiff
+{
+    my ($sh, $sm, $eh, $em) = @_;
+
+    if ($em >= $sm) {
+       return ($eh-$sh)*60 + $em-$sm;
+    } else {
+       return ($eh-$sh)*60 - ($sm-$em);
+    }
+}
+
+sub close_task
+{
+    my ($d_sec,$d_min,$d_hour,$d_mday,$d_mon,$d_year,$d_wday,$d_isdst) = localtime();
+
+    my $query = q{SELECT oid,start FROM stempel WHERE stop IS NULL};
+    my $sth = $dbh->prepare ($query);
+    if ($sth && $sth->execute > 0) {
+       while ((my $row = $sth->fetchrow_hashref)) {
+           my @arr = split(/ /, $row->{start});
+           my @d = split(/-/, $arr[0]);
+
+           if ($d[0] != $d_year+1900 || $d[1] != $d_mon+1 || $d[2] != $d_mday) {
+               printf "Task not started today, aborting.\n";
+               next;
+           }
+
+           my @t = split(/:/, $arr[1]);
+           my $int = quarter(hdiff($t[0], $t[1], $d_hour, $d_min));
+
+           $query = sprintf('UPDATE stempel SET stop=now(),time=%d WHERE oid = %d',
+                            $int, $row->{oid});
+           $dbh->do ($query);
+           printf "Wrote %s.\n", min2hour($int);
+       }
+    }
+    exit(0);
+}
+
+sub list_open
+{
+    my ($d_sec,$d_min,$d_hour,$d_mday,$d_mon,$d_year,$d_wday,$d_isdst) = localtime();
+    my $query = q{SELECT customer,start,task FROM stempel WHERE time IS NULL ORDER BY start,customer};
+
+    my $sth = $dbh->prepare ($query);
+    if ($sth && $sth->execute > 0) {
+       while ((my $row = $sth->fetchrow_hashref)) {
+           my @arr = split(/ /, $row->{start});
+           my $day = $arr[0];
+           my @d = split(/-/, $day);
+
+           if ($d[0] != $d_year+1900 || $d[1] != $d_mon+1 || $d[2] != $d_mday) {
+               printf "Task not started today, aborting.\n";
+               next;
+           }
+
+           my @t = split(/:/, $arr[1]);
+           my $time = sprintf('%02d:%02d', $t[0], $t[1]);
+           my $int = quarter(hdiff($t[0], $t[1], $d_hour, $d_min));
+
+           printf "%-15s  %s %s (%s)  %s\n", $row->{customer}, $day, $time, min2hour($int), $row->{task};
+       }
+    }
+    exit 0;
+}
+
+sub list_all
+{
+    # my $query = q{SELECT customer,sum(time) FROM stempel GROUP BY customer ORDER BY customer};
+    my $query = q{SELECT start,customer,time,task FROM stempel WHERE time IS NOT NULL ORDER BY customer,start};
+
+    my $sth = $dbh->prepare ($query);
+
+    if ($sth && $sth->execute > 0) {
+       while ((my $row = $sth->fetchrow_hashref)) {
+           if (defined $row->{time}) {
+               my $day = (split(/ /, $row->{start}))[0];
+               my $time = min2hour $row->{time};
+               printf "%-15s  %s  %s  %s\n", $row->{customer}, $day, $time, $row->{task};
+           }
+       }
+    }
+    exit 0;
+}
+
+sub toggle_task
+{
+    if (is_open) {
+       list_open;
+    } else {
+       open_task;
+    }
+}
+
+
+my %options = ('list' => \&list_all,
+              'open' => \&list_open,
+              'terminate|end|d' => \&close_task,
+              );
+GetOptions %options;
+
+toggle_task;