use PublicInbox::Git;
use PublicInbox::MID qw(mid2path);
use Devel::Peek qw(SvREFCNT);
+use PublicInbox::MIME;
+use POSIX qw(strftime);
my $cleanup_timer;
eval {
sub _cleanup_later ($) {
my ($self) = @_;
- return unless $PublicInbox::EvCleanup::ENABLED;
+ return unless PublicInbox::EvCleanup::enabled();
$cleanup_timer ||= PublicInbox::EvCleanup::later(*cleanup_task);
$CLEANUP->{"$self"} = $self;
}
bless $opts, $class;
}
+sub git_part {
+ my ($self, $part) = @_;
+ ($self->{version} || 1) == 2 or return;
+ $self->{"$part.git"} ||= eval {
+ my $git_dir = "$self->{mainrepo}/git/$part.git";
+ my $g = PublicInbox::Git->new($git_dir);
+ $g->{-httpbackend_limiter} = $self->{-httpbackend_limiter};
+ # no cleanup needed, we never cat-file off this, only clone
+ $g;
+ };
+}
+
sub git {
my ($self) = @_;
$self->{git} ||= eval {
};
}
+sub max_git_part {
+ my ($self) = @_;
+ my $v = $self->{version};
+ return unless defined($v) && $v == 2;
+ my $part = $self->{-max_git_part};
+ my $changed = git($self)->alternates_changed;
+ if (!defined($part) || $changed) {
+ $self->git->cleanup if $changed;
+ my $gits = "$self->{mainrepo}/git";
+ if (opendir my $dh, $gits) {
+ my $max = -1;
+ while (defined(my $git_dir = readdir($dh))) {
+ $git_dir =~ m!\A(\d+)\.git\z! or next;
+ $max = $1 if $1 > $max;
+ }
+ $part = $self->{-max_git_part} = $max if $max >= 0;
+ } else {
+ warn "opendir $gits failed: $!\n";
+ }
+ }
+ $part;
+}
+
sub mm {
my ($self) = @_;
$self->{mm} ||= eval {
+ require PublicInbox::Msgmap;
_cleanup_later($self);
my $dir = $self->{mainrepo};
if (($self->{version} || 1) >= 2) {
local $/ = "\n";
chomp $desc;
$desc =~ s/\s+/ /smg;
- $desc = '($GIT_DIR/description missing)' if $desc eq '';
+ $desc = '($REPO_DIR/description missing)' if $desc eq '';
$self->{description} = $desc;
}
sub msg_by_smsg ($$;$) {
my ($self, $smsg, $ref) = @_;
- return unless defined $smsg; # ghost
-
- # backwards compat to fallback to msg_by_mid
- # TODO: remove if we bump SCHEMA_VERSION in Search.pm:
- defined(my $blob = $smsg->{blob}) or
- return msg_by_path($self, mid2path($smsg->mid), $ref);
+ # ghosts may have undef smsg (from SearchThread.node) or
+ # no {blob} field
+ return unless defined $smsg;
+ defined(my $blob = $smsg->{blob}) or return;
my $str = git($self)->cat_file($blob, $ref);
$$str =~ s/\A[\r\n]*From [^\r\n]*\r?\n//s if $str;
$str;
}
+sub smsg_mime {
+ my ($self, $smsg, $ref) = @_;
+ if (my $s = msg_by_smsg($self, $smsg, $ref)) {
+ $smsg->{mime} = PublicInbox::MIME->new($s);
+ return $smsg;
+ }
+}
+
sub path_check {
my ($self, $path) = @_;
git($self)->check('HEAD:'.$path);
}
+sub mid2num($$) {
+ my ($self, $mid) = @_;
+ my $mm = mm($self) or return;
+ $mm->num_for($mid);
+}
+
+sub smsg_by_mid ($$) {
+ my ($self, $mid) = @_;
+ my $srch = search($self) or return;
+ # favor the Message-ID we used for the NNTP article number:
+ my $num = mid2num($self, $mid);
+ defined $num ? $srch->lookup_article($num) : undef;
+}
+
sub msg_by_mid ($$;$) {
my ($self, $mid, $ref) = @_;
my $srch = search($self) or
- return msg_by_path($self, mid2path($mid), $ref);
- my $smsg;
- $srch->retry_reopen(sub {
- $smsg = $srch->lookup_skeleton($mid) and $smsg->load_expand;
- });
+ return msg_by_path($self, mid2path($mid), $ref);
+ my $smsg = smsg_by_mid($self, $mid);
$smsg ? msg_by_smsg($self, $smsg, $ref) : undef;
}
+sub recent {
+ my ($self, $opts, $after, $before) = @_;
+ search($self)->{over_ro}->recent($opts, $after, $before);
+}
+
1;