about summary refs log tree commit homepage
path: root/lib/PublicInbox/SearchMsg.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-08-13 02:32:22 +0000
committerEric Wong <e@80x24.org>2015-08-13 03:30:40 +0000
commit675494c58ef7a39a92c79cbf02975b9da3991c0b (patch)
tree5ab166b191b8bec3e112977b86ae7806ef1952d6 /lib/PublicInbox/SearchMsg.pm
parent2981d6929f400630e575bcc8fc1851bc531e73e9 (diff)
downloadpublic-inbox-675494c58ef7a39a92c79cbf02975b9da3991c0b.tar.gz
This shall allow us to search for replies/threads more easily.
Diffstat (limited to 'lib/PublicInbox/SearchMsg.pm')
-rw-r--r--lib/PublicInbox/SearchMsg.pm105
1 files changed, 105 insertions, 0 deletions
diff --git a/lib/PublicInbox/SearchMsg.pm b/lib/PublicInbox/SearchMsg.pm
new file mode 100644
index 00000000..920804ac
--- /dev/null
+++ b/lib/PublicInbox/SearchMsg.pm
@@ -0,0 +1,105 @@
+# Copyright (C) 2015, all contributors <meta@public-inbox.org>
+# License: GPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+# based on notmuch, but with no concept of folders, files or flags
+package PublicInbox::SearchMsg;
+use strict;
+use warnings;
+use Search::Xapian;
+our $PFX2TERM_RE = undef;
+
+sub new {
+        my ($class, $mime) = @_;
+        my $doc = Search::Xapian::Document->new;
+        $doc->add_term(PublicInbox::Search::xpfx('type') . 'mail');
+
+        bless { type => 'mail', doc => $doc, mime => $mime }, $class;
+}
+
+sub wrap {
+        my ($class, $doc, $mid) = @_;
+        bless { doc => $doc, mime => undef, mid => $mid }, $class;
+}
+
+sub ensure_metadata {
+        my ($self) = @_;
+        my $doc = $self->{doc};
+        my $i = $doc->termlist_begin;
+        my $end = $doc->termlist_end;
+
+        unless (defined $PFX2TERM_RE) {
+                my $or = join('|', keys %PublicInbox::Search::PFX2TERM_RMAP);
+                $PFX2TERM_RE = qr/\A($or)/;
+        }
+
+        for (; $i != $end; $i->inc) {
+                my $val = $i->get_termname;
+
+                if ($val =~ s/$PFX2TERM_RE//o) {
+                        my $field = $PublicInbox::Search::PFX2TERM_RMAP{$1};
+                        if ($field eq 'references') {
+                                my $refs = $self->{references} ||= [];
+                                push @$refs, $val;
+                        } else {
+                                $self->{$field} = $val;
+                        }
+                }
+        }
+}
+
+sub mid {
+        my ($self, $mid) = @_;
+
+        if (defined $mid) {
+            $self->{mid} = $mid;
+        } else {
+            $self->{mid} ||= $self->_extract_mid;
+        }
+}
+
+sub _extract_mid {
+        my ($self) = @_;
+
+        my $mid = $self->mime->header('Message-ID');
+        if ($mid && $mid =~ /<([^>]+)>/) {
+                return $1;
+        }
+        return $mid;
+}
+
+sub mime {
+        my ($self, $mime) = @_;
+        if (defined $mime) {
+                $self->{mime} = $mime;
+        } else {
+                # TODO load from git
+                $self->{mime};
+        }
+}
+
+sub doc_id {
+        my ($self, $doc_id) = @_;
+        if (defined $doc_id) {
+                $self->{doc_id} = $doc_id;
+        } else {
+                # TODO load from xapian
+                $self->{doc_id};
+        }
+}
+
+sub thread_id {
+        my ($self) = @_;
+        my $tid = $self->{thread};
+        return $tid if defined $tid;
+        $self->ensure_metadata;
+        $self->{thread};
+}
+
+sub path {
+        my ($self) = @_;
+        my $path = $self->{path};
+        return $path if defined $path;
+        $self->ensure_metadata;
+        $self->{path};
+}
+
+1;