-sub add_message {
- my ($self, $mime) = @_; # mime = Email::MIME object
- my $db = $self->{xdb};
-
- my $doc_id;
- my $mid_orig = mid_clean($mime->header_obj->header_raw('Message-ID'));
- my $mid = mid_compressed($mid_orig);
- my $was_ghost = 0;
- my $ct_msg = $mime->header('Content-Type') || 'text/plain';
-
- eval {
- my $smsg = $self->lookup_message($mid);
- my $doc;
-
- if ($smsg) {
- $smsg->ensure_metadata;
- # convert a ghost to a regular message
- # it will also clobber any existing regular message
- $smsg->mime($mime);
- $doc = $smsg->{doc};
-
- my $type = xpfx('type');
- eval {
- $doc->remove_term($type . 'ghost');
- $was_ghost = 1;
- };
-
- # probably does not exist:
- eval { $doc->remove_term($type . 'mail') };
- $doc->add_term($type . 'mail');
- } else {
- $smsg = PublicInbox::SearchMsg->new($mime);
- $doc = $smsg->{doc};
- $doc->add_term(xpfx('mid') . $mid);
- }
-
- my $subj = $smsg->subject;
-
- if (length $subj) {
- $doc->add_term(xpfx('subject') . $subj);
-
- my $path = subject_path($subj);
- $doc->add_term(xpfx('path') . mid_compressed($path));
- }
-
- my $from = $smsg->from_name;
- my $date = $smsg->date;
- my $ts = Search::Xapian::sortable_serialise($smsg->ts);
- $doc->add_value(PublicInbox::Search::TS, $ts);
-
- $doc->set_data($smsg->to_doc_data);
-
- my $tg = $self->term_generator;
-
- $tg->set_document($doc);
- $tg->index_text($subj, 1, 'S') if $subj;
- $tg->increase_termpos;
- $tg->index_text($subj) if $subj;
- $tg->increase_termpos;
-
- $tg->index_text($smsg->from->format);
- $tg->increase_termpos;
-
- $mime->walk_parts(sub {
- my ($part) = @_;
- return if $part->subparts; # walk_parts already recurses
- my $ct = $part->content_type || $ct_msg;
-
- # account for filter bugs...
- $ct =~ m!\btext/plain\b!i or return;
-
- my (@orig, @quot);
- my $body = $part->body;
- $part->body_set('');
- my @lines = split(/\n/, $body);
- while (defined(my $l = shift @lines)) {
- if ($l =~ /^\s*>/) {
- push @quot, $l;
- } else {
- push @orig, $l;
- }
- }
- if (@quot) {
- $tg->index_text(join("\n", @quot), 0);
- @quot = ();
- $tg->increase_termpos;
- }
- if (@orig) {
- $tg->index_text(join("\n", @orig));
- @orig = ();
- $tg->increase_termpos;
- }
- });
-
- if ($was_ghost) {
- $doc_id = $smsg->doc_id;
- $self->link_message($smsg, 0);
- $db->replace_document($doc_id, $doc);
- } else {
- $self->link_message($smsg, 0);
- $doc_id = $db->add_document($doc);
- }
- };
-
- if ($@) {
- warn "failed to index message <$mid_orig>: $@\n";
- return undef;
- }
- $doc_id;
-}
-
-# returns deleted doc_id on success, undef on missing
-sub remove_message {
- my ($self, $mid_orig) = @_;
- my $db = $self->{xdb};
- my $doc_id;
- $mid_orig = mid_clean($mid_orig);
- my $mid = mid_compressed($mid_orig);
-
- eval {
- $doc_id = $self->find_unique_doc_id('mid', $mid);
- $db->delete_document($doc_id) if defined $doc_id;
- };
-
- if ($@) {
- warn "failed to remove message <$mid_orig>: $@\n";
- return undef;
- }
- $doc_id;
-}
-