#! /usr/bin/perl use strict; use warnings; use LWP::Simple qw(); use XML::Twig; use Date::Parse; use Data::Dumper; use Term::ANSIColor qw(:constants); use DBI; use FindBin; my $user = shift or die "Need to pass in user name!"; my @convert = ( [ 1, '%02d', 'sec' ], [ 60, '%02d:', 'min' ], [ 60, '%2d:', 'hr' ], [ 24, '%d ', 'd' ], ); sub convert_seconds { my $sec = shift; my @c = @convert; my @vals = ($sec); my $output = ' %s'; while (my $c = shift @c) { if ($vals[0] > $c->[0]) { $output = $c->[1] . $output; unshift @vals, int($vals[0] / $c->[0]); $vals[1] %= $c->[0]; $vals[-1] = $c->[2]; } else { last; } } sprintf $output, @vals; } my $xml = #do { use IO::File;local $/; my $f = IO::File->new('i.xml'); <$f> }; LWP::Simple::get('http://www.perlmonks.org/index.pl?displaytype=xml;node=' . $user); if ($xml) { my %data; my $twig = XML::Twig->new(); $twig->parse($xml); my $rootnode = $twig->root(); $data{created} = $rootnode->att('created'); for my $want (qw(experience numwriteups)) { ($data{$want} = ($rootnode->descendants("field[\@name=\"$want\"]"))[0]->text()) =~ s/\s+//g; } my $table_file = File::Spec->catfile($FindBin::Bin,'stats.' . $user); my $eol = -e $table_file ? "\n" : ', '; my $since = $data{created}; #$since =~ s/\s\S*$//; #$since =~ s/at //; my $tbegin = str2time($since, 'GMT'); my $tdiff = time - $tbegin; my $duration = $tdiff / (60 * 60 * 24); if ($eol =~ /^\s*$/) { print $user,$/; print '-' x (length $user), $/; } else { print "[$user] stats: "; } printf "Member for: %.3f days%s", $duration, $eol; println('Experience: ', $data{experience}, $duration); print $eol; println('Writeups: ', $data{numwriteups}, $duration); print $eol; printf("Which makes it %s%.3f%s XP per writeup!\n", BOLD.RED, ($data{experience} / $data{numwriteups}, RESET)); #/)); if (-e $table_file) { my $dbh = DBI->connect('dbi:CSV:f_dir=' . $FindBin::Bin . ";csv_eol=\n") or warn "Can't connect to DBI"; $dbh->{csv_tables}->{stats} = { file => $table_file, }; my $total = $dbh->selectall_arrayref('select sum(xp) from stats')->[0][0]; if ($total != $data{experience}) { require Time::localtime; my $lt = Time::localtime::localtime(time() + (2 * 60 * 60)); my $date = sprintf("%04d-%02d-%02d", $lt->year + 1900, $lt->mon + 1, $lt->mday); #print "Today is $date\n"; my $count = $dbh->selectall_arrayref('select count(*) from stats where date = ?', {}, $date)->[0][0]; my $cur = $dbh->selectall_arrayref('select xp from stats where date = ?', {}, $date); $cur = $cur->[0] while $cur and ref $cur; my $gained = $data{experience} - $total; printf "%s %s%d%s XP!\n", $gained > 0 ? "Gained" : "Lost", RED.BOLD, abs($gained), RESET; if ($count) { $cur += $gained; print "Updating today ($date) to be XP = $cur\n"; $dbh->do('update stats set xp = ? where date = ?', undef, $cur, $date); } else { $cur = $gained; print "Inserting into today to be XP = $cur\n"; $dbh->do('insert into stats (date,xp) values(?,?)', {}, $date,$cur); } } } } else { print "Can't get node for $user\n"; } sub println { my ($type, $data, $duration) = @_; my $rate = $data / $duration; my $per = 24 * 60 * 60 / $rate; printf("%s %d (%s%.3f%s per day, or 1 per %s%s%s)", $type, $data, BLUE.BOLD, $rate, RESET, BOLD.BLUE, convert_seconds($per), RESET); }