summaryrefslogtreecommitdiffstats
path: root/mail-user-box-stats.pl
blob: 3431ea6d3e396c60760c64ea83c0f97749ab40eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/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 <user>\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);