#!/usr/bin/perl # mdc3-parse.pl # June 2007 # Yoran Heling # License: MIT use strict; use warnings; use Storable 'store', 'retrieve'; use POSIX; use POSIX::strptime; my $log = 'log'; # the microdc2 log file my $result = 'transferred.html'; # the resulting html file my $cache = 'logparse.pl_cache'; # file for the Storable cache my %ts = -s $cache ? ( %{retrieve($cache)} ) : (); my $totalsent = 0; # using STDIN/OUT -> lazy and ugly :-) open(STDIN, '<', $log) || die $!; open(STDOUT, '>', $result) || die $!; while(<>) { s/\r?\n//; # 28.04.2007 20:15:25 next if !s/^([0-9]{2}\.[0-9]{2}\.[0-9]{4}\s+[0-9]{2}:[0-9]{2}:[0-9]{2})\s//; my $date = $1; # plesnivec: Upload of `Ghost in the Shell - Stand Alone Complex - 25.avi' succeeded (transfer complete). 1.5MiB transferred in 53s (29KiB/s). # [Anime]Spank: Upload of `Rozen Maiden - Traumend - 07.avi' succeeded (transfer complete). 177MiB transferred in 2h46m35s (19KiB/s). # [izms]Inkognito: Upload of `Ultra Maniac TV - 16.avi' failed (communication error). 1.7MiB transferred in 3m4s (9KiB/s). if(/^(.+): Upload of `(.+)' (succeeded|failed) \(([^)]+)\)\. ([0-9\.]+[GMK]?i?B) transferred in ([0-9dhms]+) \(([0-9]+)KiB\/s\)/) { my($nick, $file, $sf, $msg, $sent, $time, $speed) = ($1, $2, $3, $4, $5, $6); $file =~ s/\\'/'/g; my $epoch = POSIX::mktime(POSIX::strptime($date, '%d.%m.%Y %T')); $sent = calcsize($sent); $time = calctime($time); $totalsent += $sent; my $k = $nick.$file; next if $ts{$k} && grep { +$_ == $epoch } @{$ts{$k}{epoch}}; if($ts{$k}) { $ts{$k}{sent} += $sent; $ts{$k}{time} += $time; $ts{$k}{chunks}++; $ts{$k}{failed}++ if $sf eq 'failed'; $ts{$k}{succeeded}++ if $sf eq 'succeeded'; push(@{$ts{$k}{epoch}}, $epoch); } else { $ts{$k} = { file => $file, nick => $nick, sent => $sent, time => $time, date => $date, epoch => [ $epoch ], # only used for identification and sorting # msg => $msg, # unused chunks => 1, failed => $sf eq 'failed' ? 1 : 0, succeeded => $sf eq 'succeeded' ? 1 : 0, }; } } } store \%ts, $cache; printf "\nSent %d files and %s\n", scalar keys %ts, calcsize($totalsent); print qq| \n|; printf(qq|\n|, $ts{$_}{date}, calcsize($ts{$_}{sent}), calctime($ts{$_}{time}), $ts{$_}{sent}/($ts{$_}{time}||1), $ts{$_}{chunks}, $ts{$_}{succeeded}, $ts{$_}{failed}, $ts{$_}{nick}, $ts{$_}{file}, ) for (sort { $ts{$b}{epoch}[0] <=> $ts{$a}{epoch}[0] } keys %ts); print qq|
Date/time Transfered Time Speed Chunks User Filename
%s %s %s %.2f KiB/s %d/%d/%d %s %s
|; sub calcsize { # in KBytes by default, to avoid a 32bit int overflow if($_[0] =~ /^([0-9\.]+)(GiB|MiB|KiB|B)$/) { return $2 eq 'B' ? $1/1024 : $2 eq 'KiB' ? $1 : $2 eq 'MiB' ? $1*1024 : $1*1024*1024; } else { my $r = $_[0]; my $x = 'KiB'; if($r > 1024) { $r/=1024; $x='MiB' } if($r > 1024) { $r/=1024; $x='GiB' } return sprintf "%.1f %s", $r, $x; } } sub calctime { if($_[0] =~ /[dhms]/) { my @t = reverse split(/[dhms]/, $_[0]); return ($t[3]||0)*86400 + ($t[2]||0)*3600 + ($t[1]||0)*60 + $t[0]; } else { my $r = $_[0]; my $x = ''; if($r > 24*3600) { $x .= int($r/(24*3600)).' d '; $r%=24*3600; } $x .= sprintf '%d:%02d:%02d', int($r/3600), int(($r%3600)/60), ($r%3600) % 60; return $x; } }