#!/usr/bin/env perl use warnings; use strict; use Data::Dumper; use List::Util qw(sum); use 5.010; if (0+@ARGV < 1) { print STDERR "usage: $0 \n"; exit 1; } my $user = $ARGV[0]; my %mailboxes = (); sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s }; # from: https://stackoverflow.com/a/4186180 sub longest { my $max = -1; my $max_ref; for (@_) { if (length > $max) { $max = length; $max_ref = \$_; } } $$max_ref } sub format_bytes { my $bytes = shift; my $boundry = 2048; my $format; my $unit; my @suffix = qw(B KiB MiB GiB TiB); for (@suffix) { $unit = $_; last if (abs($bytes) < $boundry); $bytes /= 1024; } if ($unit eq "B") { $format = "%.0f"; } else { $format = "%.2f"; } return sprintf $format." %-3s", $bytes, $unit; } sub add { my $mbox = shift; my $msgcount = shift; my $vsize = shift; if ($mbox) { $mailboxes{$mbox} = { "msgcount" => $msgcount, "vsize" => sprintf('%d', $vsize) }; } } open(my $fh, '-|', "doveadm mailbox status -u '$user' 'vsize messages' mailbox '*'") or die $!; while (my $line=<$fh>) { # print "line: $line"; if($line =~ /^([\w\s\-\_\.]+)\s*messages=(\d+)\s*vsize=(\d+)$/) { # print "mbox: $1 ; msgcount: $2 ; vsize: $3\n"; add trim($1), trim($2), trim($3); } } close $fh; # calculate totals my $sum_msgcount = sum(map { $_->{'msgcount'} } values(%mailboxes)); my $sum_vsize = sum(map { $_->{'vsize'} } values(%mailboxes)); my $fmt_mbox = length(longest(keys(%mailboxes))) + 2; my $fmt_msgc = length($sum_msgcount) + 2; $fmt_msgc = 10 if($fmt_msgc < 10); my $head_fmt = "%${fmt_mbox}s %${fmt_msgc}s %12s\n"; my $out_fmt = "%${fmt_mbox}s %${fmt_msgc}d %12s\n"; # printf "User: %s\n", $user; printf $head_fmt, 'FOLDER', 'MSGCOUNT', 'VSIZE'; # sort by vsize desc and msgcount desc foreach my $box (sort { $mailboxes{$b}->{'vsize'} <=> $mailboxes{$a}->{'vsize'} or \ $mailboxes{$b}->{'msgcount'} <=> $mailboxes{$a}->{'msgcount'} } keys %mailboxes) { printf $out_fmt, $box, $mailboxes{$box}->{'msgcount'}, format_bytes($mailboxes{$box}->{'vsize'}); } my $lw = $fmt_mbox + $fmt_msgc + 12 + 2; my @hrule = ("-") x $lw; print(join("", @hrule)."\n"); printf $out_fmt, 'TOTAL', $sum_msgcount, format_bytes($sum_vsize);