X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FLeiLcat.pm;h=8d89cb7303f2b081b8005daea1dfdf2875f1747b;hb=refs%2Fheads%2Fmaster;hp=f9d9633acd49033f18adfb51800c67d442b0a7f8;hpb=74b5dc0569db5adb4cc931ce3c3b1b50507eb31d;p=public-inbox.git
diff --git a/lib/PublicInbox/LeiLcat.pm b/lib/PublicInbox/LeiLcat.pm
index f9d9633a..8d89cb73 100644
--- a/lib/PublicInbox/LeiLcat.pm
+++ b/lib/PublicInbox/LeiLcat.pm
@@ -1,4 +1,4 @@
-# Copyright (C) 2021 all contributors
+# Copyright (C) all contributors
# License: AGPL-3.0+
# lcat: local cat, display a local message by Message-ID or blob,
@@ -11,28 +11,64 @@ use PublicInbox::LeiViewText;
use URI::Escape qw(uri_unescape);
use PublicInbox::MID qw($MID_EXTRACT);
-sub lcat_imap_uid_uri ($$) {
- my ($lei, $uid_uri) = @_;
- my $lms = $lei->{lse}->lms or return;
- my $oidhex = $lms->imap_oid($lei, $uid_uri);
- if (ref(my $err = $oidhex)) { # art2folder error
- $lei->qerr(@{$err->{qerr}}) if $err->{qerr};
+sub lcat_folder ($$;$$) {
+ my ($lei, $folder, $beg, $end) = @_;
+ my $lms = $lei->{-lms_rw} //= $lei->lms // return;
+ my $folders = [ $folder ];
+ eval { $lms->arg2folder($lei, $folders) };
+ return $lei->child_error(0, "# unknown folder: $folder") if $@;
+ my %range;
+ if (defined($beg)) { # NNTP article range
+ $range{min} = $beg;
+ $range{max} = $end // $beg;
+ }
+ for my $f (@$folders) {
+ my $fid = $lms->fid_for($f);
+ push @{$lei->{lcat_todo}}, { fid => $fid, %range };
+ }
+}
+
+sub lcat_imap_uri ($$) {
+ my ($lei, $uri) = @_;
+ # cf. LeiXSearch->lcat_dump
+ my $lms = $lei->{-lms_rw} //= $lei->lms // return;
+ if (defined $uri->uid) {
+ push @{$lei->{lcat_todo}}, $lms->imap_oidhex($lei, $uri);
+ } elsif (defined(my $fid = $lms->fid_for($$uri))) {
+ push @{$lei->{lcat_todo}}, { fid => $fid };
+ } else {
+ lcat_folder($lei, $$uri);
}
- push @{$lei->{lcat_blob}}, $oidhex; # cf. LeiToMail->wq_atexit_child
+}
+
+sub lcat_nntp_uri ($$) {
+ my ($lei, $uri) = @_;
+ my $mid = $uri->message; # already unescaped by URI::news
+ return "mid:$mid" if defined($mid);
+ my $lms = $lei->{-lms_rw} //= $lei->lms // return;
+ my ($ng, $beg, $end) = $uri->group;
+ $uri->group($ng);
+ lcat_folder($lei, $$uri, $beg, $end);
+ '""';
}
sub extract_1 ($$) {
my ($lei, $x) = @_;
- if ($x =~ m!\b(imaps?://[^>]+)!i) {
- my $u = $1;
- require PublicInbox::URIimap;
- $u = PublicInbox::URIimap->new($u);
- defined($u->uid) ? lcat_imap_uid_uri($lei, $u) :
- $lei->child_error(1 << 8, "# no UID= in $u");
- '""'; # blank query, using {lcat_blob}
- } elsif ($x =~ m!\b([a-z]+?://\S+)!i) {
- my $u = $1;
+ if ($x =~ m!\b(maildir:.+)!i) {
+ lcat_folder($lei, $1);
+ '""'; # blank query, using {lcat_todo}
+ } elsif ($x =~ m!\b(([a-z]+)://\S+)!i) {
+ my ($u, $scheme) = ($1, $2);
$u =~ s/[\>\]\)\,\.\;]+\z//;
+ if ($scheme =~ m!\A(imaps?)\z!i) {
+ require PublicInbox::URIimap;
+ lcat_imap_uri($lei, PublicInbox::URIimap->new($u));
+ return '""'; # blank query, using {lcat_todo}
+ } elsif ($scheme =~ m!\A(?:nntps?|s?news)\z!i) {
+ require PublicInbox::URInntps;
+ $u = PublicInbox::URInntps->new($u);
+ return lcat_nntp_uri($lei, $u);
+ } # http, or something else:
require URI;
$u = URI->new($u);
my $p = $u->path;
@@ -62,7 +98,7 @@ sub extract_1 ($$) {
} elsif ($x =~ /\bid:(\S+)/) { # notmuch convention
"mid:$1";
} elsif ($x =~ /\bblob:([0-9a-f]{7,})\b/) {
- push @{$lei->{lcat_blob}}, $1; # cf. LeiToMail->wq_atexit_child
+ push @{$lei->{lcat_todo}}, $1; # cf. LeiToMail->wq_atexit_child
'""'; # blank query
} else {
undef;
@@ -74,7 +110,7 @@ sub extract_all {
my $strict = !$lei->{opt}->{stdin};
my @q;
for my $x (@argv) {
- if (my $term = extract_1($lei,$x)) {
+ if (my $term = extract_1($lei, $x)) {
push @q, $term;
} elsif ($strict) {
return $lei->fail(<<"");
@@ -82,35 +118,31 @@ could not extract Message-ID from $x
}
}
+ delete $lei->{-lms_rw};
@q ? join(' OR ', @q) : $lei->fail("no Message-ID in: @argv");
}
sub _stdin { # PublicInbox::InputPipe::consume callback for --stdin
my ($lei) = @_; # $_[1] = $rbuf
- if (defined($_[1])) {
- $_[1] eq '' and return eval {
- $lei->fchdir or return;
- my @argv = split(/\s+/, $lei->{mset_opt}->{qstr});
- $lei->{mset_opt}->{qstr} = extract_all($lei, @argv)
- or return;
- $lei->_start_query;
- };
- $lei->{mset_opt}->{qstr} .= $_[1];
- } else {
- $lei->fail("error reading stdin: $!");
- }
+ $_[1] // return $lei->fail("error reading stdin: $!");
+ return $lei->{mset_opt}->{qstr} .= $_[1] if $_[1] ne '';
+ eval {
+ $lei->fchdir;
+ my @argv = split(/\s+/, $lei->{mset_opt}->{qstr});
+ $lei->{mset_opt}->{qstr} = extract_all($lei, @argv) or return;
+ $lei->_start_query;
+ };
+ $lei->fail($@) if $@;
}
sub lei_lcat {
my ($lei, @argv) = @_;
my $lxs = $lei->lxs_prepare or return;
- $lei->ale->refresh_externals($lxs);
- my $sto = $lei->_lei_store(1);
- $lei->{lse} = $sto->search;
+ $lei->ale->refresh_externals($lxs, $lei);
+ $lei->_lei_store(1);
my $opt = $lei->{opt};
- my %mset_opt = map { $_ => $opt->{$_} } qw(threads limit offset);
+ my %mset_opt;
$mset_opt{asc} = $opt->{'reverse'} ? 1 : 0;
- $mset_opt{limit} //= 10000;
$opt->{sort} //= 'relevance';
$mset_opt{relevance} = 1;
$lei->{mset_opt} = \%mset_opt;
@@ -127,4 +159,10 @@ no args allowed on command-line with --stdin
$lei->_start_query;
}
+sub _complete_lcat {
+ require PublicInbox::LeiRefreshMailSync;
+ PublicInbox::LeiRefreshMailSync::_complete_refresh_mail_sync(@_);
+ # TODO: message-ids?, blobs? could get expensive...
+}
+
1;