summaryrefslogtreecommitdiffstats
path: root/mail-user-box-stats.pl
diff options
context:
space:
mode:
Diffstat (limited to 'mail-user-box-stats.pl')
-rwxr-xr-xmail-user-box-stats.pl96
1 files changed, 96 insertions, 0 deletions
diff --git a/mail-user-box-stats.pl b/mail-user-box-stats.pl
new file mode 100755
index 0000000..3431ea6
--- /dev/null
+++ b/mail-user-box-stats.pl
@@ -0,0 +1,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);