about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-01-16 22:22:42 +0000
committerEric Wong <e@80x24.org>2016-04-05 18:58:27 +0000
commit9114c0649e4f675afae1128e73b4d1b94d8929e5 (patch)
tree05ff2e0482b3c78f41feed25842481bd300012ee
parent940a4d5f32ae0bed0e39da852dacf44798d7c623 (diff)
downloadpublic-inbox-9114c0649e4f675afae1128e73b4d1b94d8929e5.tar.gz
Sometimes; people like to advertise projects and group them.
Of course, "-hidden" is a valid group for projects which do
not want to be advertised.
-rw-r--r--lib/PublicInbox/Repobrowse.pm23
-rw-r--r--lib/PublicInbox/RepobrowseConfig.pm15
-rw-r--r--lib/PublicInbox/RepobrowseGitLog.pm2
-rw-r--r--lib/PublicInbox/RepobrowseGitSummary.pm2
-rw-r--r--lib/PublicInbox/RepobrowseGitTag.pm4
-rw-r--r--lib/PublicInbox/RepobrowseRoot.pm71
6 files changed, 100 insertions, 17 deletions
diff --git a/lib/PublicInbox/Repobrowse.pm b/lib/PublicInbox/Repobrowse.pm
index f344e0f8..cc18255d 100644
--- a/lib/PublicInbox/Repobrowse.pm
+++ b/lib/PublicInbox/Repobrowse.pm
@@ -61,6 +61,12 @@ sub no_tslash {
           [ "Redirecting to $url\n" ] ]
 }
 
+sub root_index {
+        my ($self) = @_;
+        my $mod = load_once('PublicInbox::RepobrowseRoot');
+        $mod->new->call($self->{rconfig}); # RepobrowseRoot::call
+}
+
 sub run {
         my ($self, $cgi, $method) = @_;
         return r(405, 'Method Not Allowed') if ($method !~ /\AGET|HEAD\z/);
@@ -68,11 +74,12 @@ sub run {
         # URL syntax: / repo [ / cmd [ / path ] ]
         # cmd: log | commit | diff | tree | view | blob | snapshot
         # repo and path (@extra) may both contain '/'
-        my $rconfig = $self->{rconfig};
         my $path_info = uri_unescape($cgi->path_info);
         my (undef, $repo_path, @extra) = split(m{/+}, $path_info, -1);
 
-        return r404() unless $repo_path;
+        return $self->root_index($self) unless length($repo_path);
+
+        my $rconfig = $self->{rconfig}; # RepobrowseConfig
         my $repo_info;
         until ($repo_info = $rconfig->lookup($repo_path)) {
                 my $p = shift @extra or last;
@@ -104,12 +111,8 @@ sub run {
                 if ($path_info =~ m!/\z!) {
                         $tslash = $path_info =~ tr!/!!;
                 } else {
-                        my @repo = split('/', $repo_path);
-                        if (@repo > 1) {
-                                $req->{relcmd} = "./$repo[-1]/";
-                        } else {
-                                $req->{relcmd} = "/$repo[-1]/";
-                        }
+                        my @x = split('/', $repo_path);
+                        $req->{relcmd} = @x > 1 ? "./$x[-1]/" : "/$x[-1]/";
                 }
         }
         while (@extra && $extra[-1] eq '') {
@@ -117,9 +120,7 @@ sub run {
                 ++$tslash;
         }
 
-        if ($tslash && $path_info ne '/' && $NO_TSLASH{$mod}) {
-                return no_tslash($cgi);
-        }
+        return no_tslash($cgi) if ($tslash && $NO_TSLASH{$mod});
 
         $req->{tslash} = $tslash;
         $mod = load_once("PublicInbox::Repobrowse$vcs$mod");
diff --git a/lib/PublicInbox/RepobrowseConfig.pm b/lib/PublicInbox/RepobrowseConfig.pm
index 800db05d..5752beed 100644
--- a/lib/PublicInbox/RepobrowseConfig.pm
+++ b/lib/PublicInbox/RepobrowseConfig.pm
@@ -11,6 +11,8 @@ sub new {
         $file = default_file() unless defined($file);
         my $self = bless PublicInbox::Config::git_config_dump($file), $class;
         $self->{-cache} = {};
+        # for root
+        $self->{-groups} = { -hidden => [], -none => [] };
         $self;
 }
 
@@ -36,8 +38,9 @@ sub lookup {
         my $path = $self->{"repo.$repo_path.path"};
         (defined $path && -d $path) or return;
         $rv->{path} = $path;
-        $rv->{path_info} = $repo_path;
+        $rv->{repo} = $repo_path;
 
+        # gitweb compatibility
         foreach my $key (qw(description cloneurl)) {
                 $rv->{$key} = try_cat("$path/$key");
         }
@@ -45,10 +48,18 @@ sub lookup {
         $rv->{desc_html} =
                 PublicInbox::Hval->new_oneline($rv->{description})->as_html;
 
-        foreach my $key (qw(publicinbox vcs readme)) {
+        foreach my $key (qw(publicinbox vcs readme group)) {
                 $rv->{$key} = $self->{"repo.$repo_path.$key"};
         }
 
+        my $g = $rv->{group};
+        defined $g or $g = '-none';
+        if (ref($g) eq 'ARRAY') {
+                push @{$self->{-groups}->{$_} ||= []}, $repo_path foreach @$g;
+        } else {
+                push @{$self->{-groups}->{$g} ||= []}, $repo_path;
+        }
+
         # of course git is the default VCS
         $rv->{vcs} ||= 'git';
         $self->{-cache}->{$repo_path} = $rv;
diff --git a/lib/PublicInbox/RepobrowseGitLog.pm b/lib/PublicInbox/RepobrowseGitLog.pm
index 197d2cb1..0c360e73 100644
--- a/lib/PublicInbox/RepobrowseGitLog.pm
+++ b/lib/PublicInbox/RepobrowseGitLog.pm
@@ -29,7 +29,7 @@ sub call_git_log {
         sub {
                 my ($res) = @_; # Plack callback
                 my $fh = $res->([200, ['Content-Type'=>'text/html']]);
-                my $title = utf8_html("log: $repo_info->{path_info} ($h)");
+                my $title = "log: $repo_info->{repo} ".utf8_html("($h)");
                 $fh->write($self->html_start($req, $title));
                 git_log_stream($req, $q, $log, $fh, $git);
                 $fh->close;
diff --git a/lib/PublicInbox/RepobrowseGitSummary.pm b/lib/PublicInbox/RepobrowseGitSummary.pm
index 65e32b6a..db601ad9 100644
--- a/lib/PublicInbox/RepobrowseGitSummary.pm
+++ b/lib/PublicInbox/RepobrowseGitSummary.pm
@@ -37,7 +37,7 @@ sub emit_summary {
         $fh = $res->([200, ['Content-Type'=>'text/html; charset=UTF-8']]);
         # ref names are unpredictable in length and requires tables :<
         $fh->write($self->html_start($req,
-                                "$repo_info->{path_info}: overview") .
+                                "$repo_info->{repo}: overview") .
                         '</pre><table>');
 
         my $rel = $req->{relcmd};
diff --git a/lib/PublicInbox/RepobrowseGitTag.pm b/lib/PublicInbox/RepobrowseGitTag.pm
index ebda729e..229d5ff0 100644
--- a/lib/PublicInbox/RepobrowseGitTag.pm
+++ b/lib/PublicInbox/RepobrowseGitTag.pm
@@ -133,7 +133,7 @@ sub git_tag_list {
 
         # tag names are unpredictable in length and requires tables :<
         $fh->write($self->html_start($req,
-                                "$repo_info->{path_info}: tag list") .
+                                "$repo_info->{repo}: tag list") .
                 '</pre><table><tr>' .
                 join('', map { "<th><tt>$_</tt></th>" } qw(tag subject date)).
                 '</tr>');
@@ -166,7 +166,7 @@ sub unknown_tag_type {
         my $obj_link = qq(<a\nhref="$rel$cmd?id=$hex">$label</a>\n);
 
         $fh->write($self->html_start($req,
-                                "$repo_info->{path_info}: ref: $h") .
+                                "$repo_info->{repo}: ref: $h") .
                 "\n\n       <b>$h</b> (lightweight tag)\nobject $obj_link\n");
 }
 
diff --git a/lib/PublicInbox/RepobrowseRoot.pm b/lib/PublicInbox/RepobrowseRoot.pm
new file mode 100644
index 00000000..fda96437
--- /dev/null
+++ b/lib/PublicInbox/RepobrowseRoot.pm
@@ -0,0 +1,71 @@
+# Copyright (C) 2016 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+
+# displays the root '/' where all the projects lie
+package PublicInbox::RepobrowseRoot;
+use strict;
+use warnings;
+use base qw(PublicInbox::RepobrowseBase);
+use PublicInbox::Hval qw(utf8_html);
+
+sub call {
+        my ($self, $rconfig) = @_;
+        sub {
+                my ($res) = @_; # PSGI callback
+                my @h = ('Content-Type', 'text/html; charset=UTF-8');
+                my $fh = $res->([200, \@h]);
+                repobrowse_index($fh, $rconfig);
+                $fh->close;
+        }
+}
+
+sub repobrowse_index {
+        my ($fh, $rconfig) = @_;
+        my $title = 'repobrowse index';
+        $fh->write("<html><head><title>$title</title>" .
+                        PublicInbox::Hval::STYLE .
+                        "</head><body><pre><b>$title</b>");
+
+        # preload all groups
+        foreach my $k (sort keys %$rconfig) {
+                $k =~ /\Arepo\.(.+)\.path\z/ or next;
+                my $repo_path = $1;
+                $rconfig->lookup($repo_path); # insert into groups
+        }
+
+        my $groups = $rconfig->{-groups};
+        if (scalar(keys %$groups) > 2) { # default has '-none' + '-hidden'
+                $fh->write("\n\n<b>uncategorized</b></pre>".
+                        "<table\nsummary=repoindex>");
+        } else {
+                $fh->write("</pre><table\nsummary=repoindex>");
+        }
+        foreach my $repo_path (sort @{$groups->{-none}}) {
+                my $r = $rconfig->lookup($repo_path);
+                my $p = PublicInbox::Hval->utf8($r->{repo});
+                my $l = $p->as_html;
+                $p = $p->as_path;
+                $fh->write(qq(<tr><td><tt><a\nhref="$p">$l</a></tt></td>) .
+                        "<td><tt> $r->{desc_html}</tt></td></tr>");
+        }
+
+        foreach my $group (keys %$groups) {
+                next if $group =~ /\A-(?:none|hidden)\z/;
+                my $g = utf8_html($group);
+                $fh->write("<tr><td><pre> </pre></td></tr>".
+                        "<tr><td><pre><b>$g</b></pre></tr>");
+                foreach my $repo_path (sort @{$groups->{$group}}) {
+                        my $r = $rconfig->lookup($repo_path);
+                        my $p = PublicInbox::Hval->utf8($r->{repo});
+                        my $l = $p->as_html;
+                        $p = $p->as_path;
+                        $fh->write('<tr><td><tt> ' .
+                                qq(<a\nhref="$p">$l</a></tt></td>) .
+                                "<td><tt> $r->{desc_html}</tt></td></tr>");
+                }
+        }
+
+        $fh->write('</table></body></html>');
+}
+
+1;