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-ASN: 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 94A881F8C6 for ; Thu, 19 Aug 2021 09:49:34 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH] lei: implicitly watch all Maildirs it knows about Date: Thu, 19 Aug 2021 09:49:34 +0000 Message-Id: <20210819094934.13341-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: This allows MUA-made flag changes to Maildirs to be instantly read and acknowledged for future search results. In the future, it may be used to speed up --augment and --import-before (the default) with with "lei q". --- lib/PublicInbox/LEI.pm | 42 +++++++++++++++++++++++++++------ lib/PublicInbox/LeiMailSync.pm | 10 ++++++++ lib/PublicInbox/LeiNoteEvent.pm | 2 +- lib/PublicInbox/LeiStore.pm | 5 ++++ 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 79dc9bf9..4d5c61fe 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -1370,6 +1370,14 @@ sub cancel_maildir_watch ($$) { for my $x (@{$w // []}) { $x->cancel } } +sub add_maildir_watch ($$) { + my ($d, $cfg_f) = @_; + if (!exists($MDIR2CFGPATH->{$d}->{$cfg_f})) { + my @w = $dir_idle->add_watches(["$d/cur", "$d/new"], 1); + push @{$MDIR2CFGPATH->{$d}->{$cfg_f}}, @w if @w; + } +} + sub refresh_watches { my ($lei) = @_; my $cfg = _lei_cfg($lei) or return; @@ -1380,7 +1388,7 @@ sub refresh_watches { for my $w (grep(/\Awatch\..+\.state\z/, keys %$cfg)) { my $url = substr($w, length('watch.'), -length('.state')); require PublicInbox::LeiWatch; - my $lw = $watches->{$url} //= PublicInbox::LeiWatch->new($url); + $watches->{$url} //= PublicInbox::LeiWatch->new($url); $seen{$url} = undef; my $state = $cfg->get_1("watch.$url", 'state'); if (!watch_state_ok($state)) { @@ -1391,16 +1399,36 @@ sub refresh_watches { my $d = canonpath_harder($1); if ($state eq 'pause') { cancel_maildir_watch($d, $cfg_f); - } elsif (!exists($MDIR2CFGPATH->{$d}->{$cfg_f})) { - my @w = $dir_idle->add_watches( - ["$d/cur", "$d/new"], 1); - push @{$MDIR2CFGPATH->{$d}->{$cfg_f}}, @w if @w; + } else { + add_maildir_watch($d, $cfg_f); } } else { # TODO: imap/nntp/jmap - $lei->child_error(1, - "E: watch $url not supported, yet"); + $lei->child_error(1, "E: watch $url not supported, yet") + } + } + + # add all known Maildir folders as implicit watches + my $sto = $lei->_lei_store; + my $renames = 0; + if (my $lms = $sto ? $sto->search->lms : undef) { + for my $d ($lms->folders('maildir:')) { + substr($d, 0, length('maildir:')) = ''; + my $cd = canonpath_harder($d); + my $f = "maildir:$cd"; + + # fixup old bugs while we're iterating: + if ($d ne $cd) { + $sto->ipc_do('lms_rename_folder', + "maildir:$d", $f); + ++$renames; + } + next if $watches->{$f}; # may be set to pause + $watches->{$f} = PublicInbox::LeiWatch->new($f); + $seen{$f} = undef; + add_maildir_watch($cd, $cfg_f); } } + my $wait = $renames ? $sto->ipc_do('done') : undef; if ($old) { # cull old non-existent entries for my $url (keys %$old) { next if exists $seen{$url}; diff --git a/lib/PublicInbox/LeiMailSync.pm b/lib/PublicInbox/LeiMailSync.pm index 6dfa03be..80e1bb9d 100644 --- a/lib/PublicInbox/LeiMailSync.pm +++ b/lib/PublicInbox/LeiMailSync.pm @@ -412,6 +412,16 @@ sub forget_folder { $dbh->do('DELETE FROM folders WHERE fid = ?', undef, $fid); } +# only used for changing canonicalization errors +sub rename_folder { + my ($self, $old, $new) = @_; + my $fid = delete($self->{fmap}->{$old}) // + fid_for($self, $old) // return; + $self->{dbh}->do(<{fmap}->{$url} //= fid_for($self, $url) // return; diff --git a/lib/PublicInbox/LeiNoteEvent.pm b/lib/PublicInbox/LeiNoteEvent.pm index d6511cf6..1cd15296 100644 --- a/lib/PublicInbox/LeiNoteEvent.pm +++ b/lib/PublicInbox/LeiNoteEvent.pm @@ -74,7 +74,7 @@ sub lei_note_event { my $err = $lms->arg2folder($lei, [ $folder ]); return if $err->{fail}; undef $lms; - my $state = $cfg->get_1("watch.$folder", 'state') // 'pause'; + my $state = $cfg->get_1("watch.$folder", 'state') // 'tag-rw'; return if $state eq 'pause'; $lei->ale; # prepare $sto->write_prepare($lei); diff --git a/lib/PublicInbox/LeiStore.pm b/lib/PublicInbox/LeiStore.pm index e8334187..bbd853e5 100644 --- a/lib/PublicInbox/LeiStore.pm +++ b/lib/PublicInbox/LeiStore.pm @@ -222,6 +222,11 @@ sub lms_forget_folders { for my $f (@folders) { $lms->forget_folder($f) } } +sub lms_rename_folder { + my ($self, $old, $new) = @_; + _lms_rw($self)->rename_folder($old, $new); +} + sub set_sync_info { my ($self, $oidhex, $folder, $id) = @_; _lms_rw($self)->set_src($oidhex, $folder, $id);