-# normalize subjects so they are suitable as pathnames for URLs
-sub subject_path {
- my $subj = pop;
- $subj = subject_normalized($subj);
- $subj =~ s![^a-zA-Z0-9_\.~/\-]+!_!g;
- lc($subj);
-}
-
-sub subject_normalized {
- my $subj = pop;
- $subj =~ s/\A\s+//s; # no leading space
- $subj =~ s/\s+\z//s; # no trailing space
- $subj =~ s/\s+/ /gs; # no redundant spaces
- $subj =~ s/\.+\z//; # no trailing '.'
- $subj =~ s/$REPLY_RE//igo; # remove reply prefix
- $subj;
-}
-
-sub do_cat_mail {
- my ($git, $blob) = @_;
- my $mime = eval {
- my $str = $git->cat_file($blob);
- Email::MIME->new($str);
- };
- $@ ? undef : $mime;
-}
-
-sub index_blob {
- my ($self, $git, $blob) = @_;
- my $mime = do_cat_mail($git, $blob) or return;
- eval { $self->add_message($mime) };
- warn "W: index_blob $blob: $@\n" if $@;
-}
-
-sub unindex_blob {
- my ($self, $git, $blob) = @_;
- my $mime = do_cat_mail($git, $blob) or return;
- my $mid = $mime->header_obj->header('Message-ID');
- eval { $self->remove_message($mid) } if defined $mid;
- warn "W: unindex_blob $blob: $@\n" if $@;
-}
-
-sub enquire {
- my ($self) = @_;
- $self->{enquire} ||= Search::Xapian::Enquire->new($self->{xdb});
-}
-
-# indexes all unindexed messages
-sub index_sync {
- my ($self, $head) = @_;
- require PublicInbox::GitCatFile;
- my $db = $self->{xdb};
- my $hex = '[a-f0-9]';
- my $h40 = $hex .'{40}';
- my $addmsg = qr!^:000000 100644 \S+ ($h40) A\t${hex}{2}/${hex}{38}$!;
- my $delmsg = qr!^:100644 000000 ($h40) \S+ D\t${hex}{2}/${hex}{38}$!;
- $head ||= 'HEAD';
-
- $db->begin_transaction;
- eval {
- my $git = PublicInbox::GitCatFile->new($self->{git_dir});
-
- my $latest = $db->get_metadata('last_commit');
- my $range = length $latest ? "$latest..$head" : $head;
- $latest = undef;
-
- # get indexed messages
- my @cmd = ('git', "--git-dir=$self->{git_dir}", "log",
- qw/--reverse --no-notes --no-color --raw -r
- --no-abbrev/, $range);
- my $pid = open(my $log, '-|', @cmd) or
- die('open` '.join(' ', @cmd) . " pipe failed: $!\n");
-
- while (my $line = <$log>) {
- if ($line =~ /$addmsg/o) {
- $self->index_blob($git, $1);
- } elsif ($line =~ /$delmsg/o) {
- $self->unindex_blob($git, $1);
- } elsif ($line =~ /^commit ($h40)/o) {
- $latest = $1;
- }
- }
- close $log;
- $db->set_metadata('last_commit', $latest) if defined $latest;
- };
- if ($@) {
- warn "indexing failed: $@\n";
- $db->cancel_transaction;
- } else {
- $db->commit_transaction;
- }