about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-08-19 09:49:34 +0000
committerEric Wong <e@80x24.org>2021-08-21 20:52:46 +0000
commit6b8a044462073a15f7746c597f4fd2d4bddf5e7a (patch)
tree928d54493df2ed01380b65397b8696671d676850 /lib/PublicInbox
parentd99020ac3612308d04e3760bd780417218748168 (diff)
downloadpublic-inbox-6b8a044462073a15f7746c597f4fd2d4bddf5e7a.tar.gz
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".
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/LEI.pm42
-rw-r--r--lib/PublicInbox/LeiMailSync.pm10
-rw-r--r--lib/PublicInbox/LeiNoteEvent.pm2
-rw-r--r--lib/PublicInbox/LeiStore.pm5
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(<<EOM, undef, $new, $fid);
+UPDATE folders SET loc = ? WHERE fid = ?
+EOM
+}
+
 sub imap_oidbin ($$$) {
         my ($self, $url, $uid) = @_; # $url MUST have UIDVALIDITY
         my $fid = $self->{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);