From b6b86cfd238c170ea3e2c4d4179f06c7af139086 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 24 Apr 2021 09:28:46 +0000 Subject: lei import: keep sync info for Maildir and IMAP folders We aren't using it, yet, but the plan is to be able to use this information to propagate keyword changes back to IMAP and Maildir folders using some to-be-implemented command. "lei inspect" is a half-baked new command to make testing this change easier. It will be updated to support more SQLite+Xapian introspection duties in the future, including public-inbox things independent of lei. --- lib/PublicInbox/LeiInspect.pm | 96 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 lib/PublicInbox/LeiInspect.pm (limited to 'lib/PublicInbox/LeiInspect.pm') diff --git a/lib/PublicInbox/LeiInspect.pm b/lib/PublicInbox/LeiInspect.pm new file mode 100644 index 00000000..6cfc8083 --- /dev/null +++ b/lib/PublicInbox/LeiInspect.pm @@ -0,0 +1,96 @@ +# Copyright (C) 2021 all contributors +# License: AGPL-3.0+ + +# "lei inspect" general purpose inspector for stuff in SQLite and +# Xapian. Will eventually be useful with plain public-inboxes, +# not just lei/store. This is totally half-baked at the moment +# but useful for testing. +package PublicInbox::LeiInspect; +use strict; +use v5.10.1; +use PublicInbox::Config; + +sub inspect_blob ($$) { + my ($lei, $oidhex) = @_; + my $ent = {}; + if (my $lse = $lei->{lse}) { + my @docids = $lse ? $lse->over->blob_exists($oidhex) : (); + $ent->{'lei/store'} = \@docids if @docids; + my $lms = $lse->lms; + if (my $loc = $lms ? $lms->locations_for($oidhex) : undef) { + $ent->{sync} = $loc; + } + } + $ent; +} + +sub inspect_sync_folder ($$) { + my ($lei, $folder) = @_; + my $ent = {}; + my $lse = $lei->{lse} or return $ent; + my $lms = $lse->lms or return $ent; + my @folders; + if ($folder =~ m!\Aimaps?://!i) { + require PublicInbox::URIimap; + my $uri = PublicInbox::URIimap->new($folder)->canonical; + if (defined($uri->uidvalidity)) { + $folders[0] = $$uri; + } else { + my @maybe = $lms->folders($$uri); + @folders = grep { + my $u = PublicInbox::URIimap->new($_); + $uri->uidvalidity($u->uidvalidity); + $$uri eq $$u; + } @maybe; + } + } elsif ($folder =~ m!\A(maildir|mh):(.+)!i) { + my $type = $1; + $folders[0] = "$type:".$lei->abs_path($2); + } elsif (-d $folder) { + $folders[0] = 'maildir:'.$lei->abs_path($folder); + } else { + $lei->fail("$folder not understood"); + } + $lei->qerr("# no folders match $folder (non-fatal)") if !@folders; + for my $f (@folders) { + $ent->{$f} = $lms->location_stats($f); # may be undef + } + $ent +} + +sub inspect1 ($$$) { + my ($lei, $item, $more) = @_; + my $ent; + if ($item =~ /\Ablob:(.+)/) { + $ent = inspect_blob($lei, $1); + } elsif ($item =~ m!\Aimaps?://!i || + $item =~ m!\A(?:maildir|mh):!i || -d $item) { + $ent = inspect_sync_folder($lei, $item); + } else { # TODO: more things + return $lei->fail("$item not understood"); + } + $lei->out($lei->{json}->encode($ent)); + $lei->out(',') if $more; + 1; +} + +sub lei_inspect { + my ($lei, @argv) = @_; + $lei->{1}->autoflush(0); + my $multi = scalar(@argv) > 1; + $lei->out('[') if $multi; + $lei->{json} = ref(PublicInbox::Config::json())->new->utf8->canonical; + $lei->{lse} = ($lei->{opt}->{external} // 1) ? do { + my $sto = $lei->_lei_store; + $sto ? $sto->search : undef; + } : undef; + if ($lei->{opt}->{pretty} || -t $lei->{1}) { + $lei->{json}->pretty(1)->indent(2); + } + while (defined(my $x = shift @argv)) { + inspect1($lei, $x, scalar(@argv)) or return; + } + $lei->out(']') if $multi; +} + +1; -- cgit v1.2.3-24-ge0c7