From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id BE1F51FA00 for ; Wed, 10 Mar 2021 13:23:45 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 2/5] watch: IMAP: ignore \Deleted and \Draft messages Date: Wed, 10 Mar 2021 13:23:42 +0000 Message-Id: <20210310132345.28283-3-e@80x24.org> In-Reply-To: <20210310132345.28283-1-e@80x24.org> References: <20210310132345.28283-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: This matches existing Maildir behavior, as trash and draft messages have little reason to be exposed publicly. --- lib/PublicInbox/NetReader.pm | 2 ++ lib/PublicInbox/Watch.pm | 26 ++++----------------- xt/net_writer-imap.t | 44 ++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/lib/PublicInbox/NetReader.pm b/lib/PublicInbox/NetReader.pm index f5f71005..d3094fc7 100644 --- a/lib/PublicInbox/NetReader.pm +++ b/lib/PublicInbox/NetReader.pm @@ -349,6 +349,8 @@ sub _imap_do_msg ($$$$$) { if (my $k = $IMAPflags2kw{$f}) { push @$kw, $k; } elsif ($f eq "\\Recent") { # not in JMAP + } elsif ($f eq "\\Deleted") { # not in JMAP + return; } elsif ($self->{verbose}) { warn "# unknown IMAP flag $f <$uri;uid=$uid>\n"; } diff --git a/lib/PublicInbox/Watch.pm b/lib/PublicInbox/Watch.pm index dd245935..4fbc9640 100644 --- a/lib/PublicInbox/Watch.pm +++ b/lib/PublicInbox/Watch.pm @@ -287,30 +287,9 @@ sub watch_fs_init ($) { PublicInbox::DirIdle->new([keys %{$self->{mdmap}}], $cb); } -sub imap_import_msg ($$$$$) { - my ($self, $uri, $uid, $raw, $flags) = @_; - # our target audience expects LF-only, save storage - $$raw =~ s/\r\n/\n/sg; - - my $inboxes = $self->{imap}->{$$uri}; - if (ref($inboxes)) { - for my $ibx (@$inboxes) { - my $eml = PublicInbox::Eml->new($$raw); - import_eml($self, $ibx, $eml); - } - } elsif ($inboxes eq 'watchspam') { - return if $flags !~ /\\Seen\b/; # don't remove unseen messages - local $SIG{__WARN__} = PublicInbox::Eml::warn_ignore_cb(); - my $eml = PublicInbox::Eml->new($raw); - $self->{pi_cfg}->each_inbox(\&remove_eml_i, - $self, $eml, "$uri UID:$uid"); - } else { - die "BUG: destination unknown $inboxes"; - } -} - sub net_cb { # NetReader::(nntp|imap)_each callback my ($uri, $art, $kw, $eml, $self, $inboxes) = @_; + return if grep(/\Adraft\z/, @$kw); local $self->{cur_uid} = $art; # IMAP UID or NNTP article if (ref($inboxes)) { my @ibx = @$inboxes; @@ -321,6 +300,9 @@ sub net_cb { # NetReader::(nntp|imap)_each callback } import_eml($self, $last, $eml); } elsif ($inboxes eq 'watchspam') { + if ($uri->scheme =~ /\Aimaps?\z/ && !grep(/\Aseen\z/, @$kw)) { + return; + } $self->{pi_cfg}->each_inbox(\&remove_eml_i, $self, $eml, "$uri #$art"); } else { diff --git a/xt/net_writer-imap.t b/xt/net_writer-imap.t index 3631d932..11a10e74 100644 --- a/xt/net_writer-imap.t +++ b/xt/net_writer-imap.t @@ -7,6 +7,8 @@ use POSIX qw(strftime); use PublicInbox::OnDestroy; use PublicInbox::URIimap; use PublicInbox::Config; +use PublicInbox::DS; +use PublicInbox::InboxIdle; use Fcntl qw(O_EXCL O_WRONLY O_CREAT); my $imap_url = $ENV{TEST_IMAP_WRITE_URL} or plan skip_all => 'TEST_IMAP_WRITE_URL unset'; @@ -170,6 +172,48 @@ test_lei(sub { $res = json_utf8->decode($lei_out)->[0]; is_deeply([@$res{qw(m kw)}], ['testmessage@example.com', ['seen']], 'kw set'); + + $mic = $nwr->mic_for_folder($folder_uri); + for my $kw (qw(Deleted Seen Answered Draft)) { + my $buf = < + +EOM + $mic->append_string($folder_uri->mailbox, $buf, "\\$kw") + or BAIL_OUT "append $kw $@"; + } + # $mic->expunge or BAIL_OUT "expunge: $@"; + $mic->disconnect; + + my $inboxdir = "$ENV{HOME}/wtest"; + my @cmd = (qw(-init -Lbasic wtest), $inboxdir, + qw(https://example.com/wtest wtest@example.com)); + run_script(\@cmd) or BAIL_OUT "init wtest"; + xsys(qw(git config), "--file=$ENV{HOME}/.public-inbox/config", + 'publicinbox.wtest.watch', + $$folder_uri) == 0 or BAIL_OUT "git config $?"; + my $watcherr = "$ENV{HOME}/watch.err"; + open my $err_wr, '>>', $watcherr or BAIL_OUT $!; + my $pub_cfg = PublicInbox::Config->new; + PublicInbox::DS->Reset; + my $ii = PublicInbox::InboxIdle->new($pub_cfg); + my $cb = sub { PublicInbox::DS->SetPostLoopCallback(sub {}) }; + my $obj = bless \$cb, 'PublicInbox::TestCommon::InboxWakeup'; + $pub_cfg->each_inbox(sub { $_[0]->subscribe_unlock('ident', $obj) }); + my $w = start_script(['-watch'], undef, { 2 => $err_wr }); + diag 'waiting for initial fetch...'; + PublicInbox::DS->EventLoop; + my $ibx = $pub_cfg->lookup_name('wtest'); + my $mm = $ibx->mm; + ok(defined($mm->num_for('Seen@test.example.com')), + '-watch takes seen message'); + ok(defined($mm->num_for('Answered@test.example.com')), + '-watch takes answered message'); + ok(!defined($mm->num_for('Deleted@test.example.com')), + '-watch ignored \\Deleted'); + ok(!defined($mm->num_for('Draft@test.example.com')), + '-watch ignored \\Draft'); }); undef $cleanup; # remove temporary folder