X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FLeiLcat.pm;h=8d89cb7303f2b081b8005daea1dfdf2875f1747b;hb=HEAD;hp=8f8e83bce12fec916b371c87baa5ddc8c5111e86;hpb=8eaa877179910dce156179e9025d1e0df34089d8;p=public-inbox.git diff --git a/lib/PublicInbox/LeiLcat.pm b/lib/PublicInbox/LeiLcat.pm index 8f8e83bc..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,49 +11,64 @@ use PublicInbox::LeiViewText; use URI::Escape qw(uri_unescape); use PublicInbox::MID qw($MID_EXTRACT); -sub lcat_folder ($$$) { - my ($lei, $lms, $folder) = @_; - $lms //= $lei->lms or return; - my $folders = [ $folder]; - my $err = $lms->arg2folder($lei, $folders); - $lei->qerr(@{$err->{qerr}}) if $err && $err->{qerr}; - if ($err && $err->{fail}) { - $lei->child_error(0, "# unknown folder: $folder"); - } else { - for my $f (@$folders) { - my $fid = $lms->fid_for($f); - push @{$lei->{lcat_fid}}, $fid; - } +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) = @_; - my $lms = $lei->lms or return; - # cf. LeiXsearch->lcat_dump + # cf. LeiXSearch->lcat_dump + my $lms = $lei->{-lms_rw} //= $lei->lms // return; if (defined $uri->uid) { - my @oidhex = $lms->imap_oidhex($lei, $uri); - push @{$lei->{lcat_blob}}, @oidhex; + push @{$lei->{lcat_todo}}, $lms->imap_oidhex($lei, $uri); } elsif (defined(my $fid = $lms->fid_for($$uri))) { - push @{$lei->{lcat_fid}}, $fid; + push @{$lei->{lcat_todo}}, { fid => $fid }; } else { - lcat_folder($lei, $lms, $$uri); + lcat_folder($lei, $$uri); } } +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; - lcat_imap_uri($lei, PublicInbox::URIimap->new($u)); - '""'; # blank query, using {lcat_blob} or {lcat_fid} - } elsif ($x =~ m!\b(maildir:.+)!i) { - lcat_folder($lei, undef, $1); - '""'; # blank query, using {lcat_blob} or {lcat_fid} - } 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; @@ -83,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; @@ -95,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(<<""); @@ -103,23 +118,21 @@ 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 { @@ -128,9 +141,8 @@ sub lei_lcat { $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; @@ -148,10 +160,9 @@ no args allowed on command-line with --stdin } sub _complete_lcat { - my ($lei, @argv) = @_; - my $lms = $lei->lms or return; - my $match_cb = $lei->complete_url_prepare(\@argv); - map { $match_cb->($_) } $lms->folders; + require PublicInbox::LeiRefreshMailSync; + PublicInbox::LeiRefreshMailSync::_complete_refresh_mail_sync(@_); + # TODO: message-ids?, blobs? could get expensive... } 1;