From a2a4175a81c9f1696654945078b16e61615859a0 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 15 Jan 2017 02:26:39 +0000 Subject: repobrowse: use qspawn for plain tree views We may eventually handle tree parsing ourselves (since we already git cat-file), but for now we can rely on ls-tree to give good output and qspawn to manage resource allocation. --- lib/PublicInbox/RepobrowseGitPlain.pm | 59 +++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/lib/PublicInbox/RepobrowseGitPlain.pm b/lib/PublicInbox/RepobrowseGitPlain.pm index c985173c..80324498 100644 --- a/lib/PublicInbox/RepobrowseGitPlain.pm +++ b/lib/PublicInbox/RepobrowseGitPlain.pm @@ -6,6 +6,7 @@ use warnings; use base qw(PublicInbox::RepobrowseBase); use PublicInbox::RepobrowseGitBlob; use PublicInbox::Hval qw(utf8_html); +use PublicInbox::Qspawn; sub call_git_plain { my ($self, $req) = @_; @@ -32,6 +33,32 @@ sub call_git_plain { git_blob_stream_response($git, $cat, $size, $type, $buf, $left); } +sub git_tree_sed ($) { + my ($req) = @_; + my $buf = ''; + my $end; + my $pfx = $req->{tpfx}; + sub { # $_[0] = buffer or undef + my $dst = delete $req->{tstart} || ''; + my @files; + if (defined $_[0]) { + @files = split(/\0/, $buf .= $_[0]); + $buf = pop @files if scalar @files; + } else { + @files = split(/\0/, $buf); + $end = ''; + } + foreach my $n (@files) { + $n = PublicInbox::Hval->utf8($n); + my $ref = $n->as_path; + $dst .= qq(
  • ); + $dst .= $n->as_html; + $dst .= '
  • '; + } + $end ? $dst .= $end : $dst; + } +} + # This should follow the cgit DOM structure in case anybody depends on it, # not using
     here as we don't expect people to actually view it much
     sub git_tree_plain {
    @@ -52,25 +79,23 @@ sub git_tree_plain {
     			$pfx = "$last/";
     		}
     	}
    -	my $ls = $git->popen(qw(ls-tree --name-only -z), $git->abbrev, $hex);
    -	sub {
    -		my ($res) = @_;
    -		my $fh = $res->([ 200, ['Content-Type' => 'text/html']]);
    -		$fh->write("$title".
    -				$t);
     
    -		local $/ = "\0";
    -		while (defined(my $n = <$ls>)) {
    -			chomp $n;
    -			$n = PublicInbox::Hval->utf8($n);
    -			my $ref = $n->as_path;
    -			$n = $n->as_html;
    -
    -			$fh->write(qq(
  • $n
  • )) + $req->{tpfx} = $pfx; + $req->{tstart} = "$title".$t; + my $cmd = [ 'git', "--git-dir=$git->{git_dir}", + qw(ls-tree --name-only -z), $git->abbrev, $hex ]; + my $rdr = { 2 => $git->err_begin }; + my $qsp = PublicInbox::Qspawn->new($cmd, undef, $rdr); + my $env = $req->{env}; + $qsp->psgi_return($env, undef, sub { + my ($r) = @_; + if (!defined $r) { + [ 500, [ 'Content-Type', 'text/plain' ], [ $git->err ]]; + } else { + $env->{'qspawn.filter'} = git_tree_sed($req); + [ 200, [ 'Content-Type', 'text/html' ] ]; } - $fh->write(''); - $fh->close; - } + }); } 1; -- cgit v1.2.3-24-ge0c7