From 74bdccb25e66298c3f9c81af0f611ad3adfc5a01 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 29 Jan 2016 03:23:39 +0000 Subject: repobrowse: implement Atom feed Mostly following cgit, except we do not serve redundant text-only output which wastes bandwidth and doesn't preserve pre-formatting layout which is critical to some messages. --- lib/PublicInbox/Repobrowse.pm | 2 +- lib/PublicInbox/RepobrowseGitAtom.pm | 117 +++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 lib/PublicInbox/RepobrowseGitAtom.pm (limited to 'lib') diff --git a/lib/PublicInbox/Repobrowse.pm b/lib/PublicInbox/Repobrowse.pm index 91d0ab20..82d38f90 100644 --- a/lib/PublicInbox/Repobrowse.pm +++ b/lib/PublicInbox/Repobrowse.pm @@ -23,7 +23,7 @@ use warnings; use URI::Escape qw(uri_escape_utf8 uri_unescape); use PublicInbox::RepobrowseConfig; -my %CMD = map { lc($_) => $_ } qw(Log Commit Tree Patch Blob Plain Tag); +my %CMD = map { lc($_) => $_ } qw(Log Commit Tree Patch Blob Plain Tag Atom); my %VCS = (git => 'Git'); my %LOADED; diff --git a/lib/PublicInbox/RepobrowseGitAtom.pm b/lib/PublicInbox/RepobrowseGitAtom.pm new file mode 100644 index 00000000..9326841d --- /dev/null +++ b/lib/PublicInbox/RepobrowseGitAtom.pm @@ -0,0 +1,117 @@ +# Copyright (C) 2016 all contributors +# License: AGPL-3.0+ + +# show log as an Atom feed +package PublicInbox::RepobrowseGitAtom; +use strict; +use warnings; +use PublicInbox::Hval qw(utf8_html); +use base qw(PublicInbox::RepobrowseBase); +my $ATOM_FMT = '--pretty=tformat:'. + join('%x00', qw(%s %ct %an %ae %at %h %H %b), '', ''); + +use constant DATEFMT => '%Y-%m-%dT%H:%M:%SZ'; +use POSIX qw(strftime); + +sub call_git_atom { + my ($self, $req) = @_; + my $repo_info = $req->{repo_info}; + my $max = $repo_info->{max_commit_count} || 10; + $max = int($max); + $max = 50 if $max == 0; + + my $git = $repo_info->{git}; + my $q = PublicInbox::RepobrowseGitQuery->new($req->{cgi}); + my $h = $q->{h}; + $h eq '' and chomp($h = $git->qx(qw(symbolic-ref --short HEAD))); + + my @cmd = (qw(log --no-notes --no-color --abbrev-commit), + $git->abbrev, $ATOM_FMT, "-$max", $h, '--'); + push @cmd, $req->{expath} if length($req->{expath}); + my $log = $git->popen(@cmd); + + sub { + my ($res) = @_; # Plack callback + my @h = ( 'Content-Type' => 'application/atom+xml' ); + my $fh = $res->([200, \@h]); + $self->git_atom_stream($req, $q, $log, $fh, $h); + $fh->close; + } +} + +sub repo_root_url { + my ($self, $req) = @_; + my $cgi = $req->{cgi}; + my $uri = $cgi->request_uri; + $uri =~ s/\?.+\z//; # no query string + my @uri = split(m!/+!, $uri); + shift @uri; # leading slash + my @extra = @{$req->{extra}}; + while (@uri && @extra && $uri[-1] eq $extra[-1]) { + pop @uri; + pop @extra; + } + pop @uri if $uri[-1] eq 'atom'; # warn if not equal? + $cgi->base . join('/', @uri); +} + +sub git_atom_stream { + my ($self, $req, $q, $log, $fh, $h) = @_; + my $repo_info = $req->{repo_info}; + my $title = join('/', $repo_info->{repo}, @{$req->{extra}}); + $title = utf8_html("$title, branch $h"); + + my $url = $self->repo_root_url($req); + $fh->write(qq(\n) . + qq() . + qq($title) . + qq($repo_info->{desc_html}) . + qq()); + my $rel = $req->{relcmd}; + my %acache; + local $/ = "\0"; + while (defined(my $s = <$log>)) { + chomp $s; + my $entry = ''; + $entry .= utf8_html($s); # commit subject + $entry .= ''; + + chomp($s = <$log>); # commit time + $entry .= strftime(DATEFMT, gmtime($s)); + $entry .= ''; + + chomp($s = <$log>); # author name + $entry .= $acache{$s} ||= utf8_html($s); + $entry .= ''; + + chomp($s = <$log>); # author email + $entry .= $acache{$s} ||= utf8_html($s); + $entry .= ''; + + chomp($s = <$log>); # author time + $entry .= strftime(DATEFMT, gmtime($s)); + $entry .= ''; + + $entry .= qq(); + chomp($s = <$log>); # unabbreviated commit hash + $entry .= $s; + $entry .= qq(); + + $entry .= qq(); + $entry .= qq(\n); + chomp($s = <$log>); + $entry .= utf8_html($s); # body + $fh->write($entry .= qq()); + eval { + local $/ = "\0\n"; + $s = <$log>; + }; + } + $fh->write(''); +} + +1; -- cgit v1.2.3-24-ge0c7