diff options
author | Eric Wong <e@yhbt.net> | 2020-06-10 07:04:07 +0000 |
---|---|---|
committer | Eric Wong <e@yhbt.net> | 2020-06-13 07:55:45 +0000 |
commit | 0735aef9bffc4779628a069aefc438e5371b40cc (patch) | |
tree | 1947d8ba211ebc37e27f2fff179c5fa553752aea /lib | |
parent | a62624ba8aa07f4d38d6d99623f6a2e679193896 (diff) | |
download | public-inbox-0735aef9bffc4779628a069aefc438e5371b40cc.tar.gz |
We'll optimize for the common case of: $TAG LIST "" * and rely on the grep perlfunc to handle trickier cases.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/PublicInbox/IMAP.pm | 14 | ||||
-rw-r--r-- | lib/PublicInbox/IMAPD.pm | 25 |
2 files changed, 39 insertions, 0 deletions
diff --git a/lib/PublicInbox/IMAP.pm b/lib/PublicInbox/IMAP.pm index 7745d9f9..ca9a0ea7 100644 --- a/lib/PublicInbox/IMAP.pm +++ b/lib/PublicInbox/IMAP.pm @@ -336,6 +336,20 @@ sub cmd_status ($$$;@) { "$tag OK Status complete\r\n"; } +my %patmap = ('*' => '.*', '%' => '[^\.]*'); +sub cmd_list ($$$$) { + my ($self, $tag, $refname, $wildcard) = @_; + my $l = $self->{imapd}->{inboxlist}; + if ($refname eq '' && $wildcard eq '') { + # request for hierarchy delimiter + $l = [ qq[* LIST (\\Noselect) "." ""\r\n] ]; + } elsif ($refname ne '' || $wildcard ne '*') { + $wildcard =~ s!([^a-z0-9_])!$patmap{$1} // "\Q$1"!eig; + $l = [ grep(/ \Q$refname\E$wildcard\r\n\z/s, @$l) ]; + } + \(join('', @$l, "$tag OK List complete\r\n")); +} + sub cmd_uid_fetch ($$$;@) { my ($self, $tag, $range, @want) = @_; my $ibx = $self->{ibx} or return "$tag BAD No mailbox selected\r\n"; diff --git a/lib/PublicInbox/IMAPD.pm b/lib/PublicInbox/IMAPD.pm index 05aa30e4..a3a25986 100644 --- a/lib/PublicInbox/IMAPD.pm +++ b/lib/PublicInbox/IMAPD.pm @@ -21,10 +21,35 @@ sub new { }, $class; } +sub refresh_inboxlist ($) { + my ($self) = @_; + my @names = map { $_->{newsgroup} } @{delete $self->{grouplist}}; + my %ns; # "\Noselect \HasChildren" + for (@names) { + my $up = $_; + while ($up =~ s/\.[^\.]+\z//) { + $ns{$up} = '\\Noselect \\HasChildren'; + } + } + @names = map {; + my $at = delete($ns{$_}) ? '\\HasChildren' : '\\HasNoChildren'; + qq[* LIST ($at) "." $_\r\n] + } @names; + push(@names, map { qq[* LIST ($ns{$_}) "." $_\r\n] } keys %ns); + @names = sort { + my ($xa) = ($a =~ / (\S+)\r\n/g); + my ($xb) = ($b =~ / (\S+)\r\n/g); + length($xa) <=> length($xb); + } @names; + $self->{inboxlist} = \@names; +} + sub refresh_groups { my ($self) = @_; my $pi_config = $self->{pi_config} = PublicInbox::Config->new; $self->SUPER::refresh_groups($pi_config); + refresh_inboxlist($self); + if (my $idler = $self->{idler}) { $idler->refresh($pi_config); } |