" . esc_html($line) . "
\n";
- }
- }
- close $fd;
-
- if (defined $from) {
- unlink($from_tmp);
- }
- if (defined $to) {
- unlink($to_tmp);
+ print "\n" .
- "\n";
- if (!defined($order) || (defined($order) && ($order eq "project"))) {
- @projects = sort {$a->{'path'} cmp $b->{'path'}} @projects;
- print "| Project | \n";
- } else {
- print "" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=project")}, "Project") . " | \n";
- }
- if (defined($order) && ($order eq "descr")) {
- @projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects;
- print "Description | \n";
- } else {
- print "" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=descr")}, "Description") . " | \n";
- }
- if (defined($order) && ($order eq "owner")) {
- @projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects;
- print "Owner | \n";
- } else {
- print "" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=owner")}, "Owner") . " | \n";
- }
- if (defined($order) && ($order eq "age")) {
- @projects = sort {$a->{'commit'}{'age'} <=> $b->{'commit'}{'age'}} @projects;
- print "Last Change | \n";
- } else {
- print "" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=age")}, "Last Change") . " | \n";
- }
- print " | \n" .
- "
\n";
- my $alternate = 0;
- foreach my $pr (@projects) {
- if ($alternate) {
- print "\n";
- } else {
- print "
\n";
- }
- $alternate ^= 1;
- print "| " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"), -class => "list"}, esc_html($pr->{'path'})) . " | \n" .
- "" . esc_html($pr->{'descr'}) . " | \n" .
- "" . chop_str($pr->{'owner'}, 15) . " | \n";
- print "{'commit'}{'age'}) . "\">" . $pr->{'commit'}{'age_string'} . " | \n" .
- "" .
- $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary") .
- " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") .
- " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") .
- " | \n" .
- "
\n";
- }
- print "
\n";
- git_footer_html();
-}
-
-sub read_info_ref {
- my $type = shift || "";
- my %refs;
- # 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c refs/tags/v2.6.11
- # c39ae07f393806ccf406ef966e9a15afc43cc36a refs/tags/v2.6.11^{}
- open my $fd, "$projectroot/$project/info/refs" or return;
- while (my $line = <$fd>) {
- chomp $line;
- # attention: for $type == "" it saves only last path part of ref name
- # e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb'
- if ($line =~ m/^([0-9a-fA-F]{40})\t.*$type\/([^\^]+)/) {
- if (defined $refs{$1}) {
- $refs{$1} .= " / $2";
- } else {
- $refs{$1} = $2;
- }
- }
- }
- close $fd or return;
- return \%refs;
-}
-
-sub git_get_referencing {
- my ($refs, $id) = @_;
-
- if (defined $refs->{$id}) {
- return ' " . esc_html($line) . "
\n";
+ }
+ }
+ close $fd;
+
+ if (defined $from) {
+ unlink($from_tmp);
+ }
+ if (defined $to) {
+ unlink($to_tmp);
+ }
+}
+
+
+## ======================================================================
+## ======================================================================
+## actions
+
+# git-logo (cached in browser for one day)
+sub git_logo {
+ binmode STDOUT, ':raw';
+ print $cgi->header(-type => 'image/png', -expires => '+1d');
+ # cat git-logo.png | hexdump -e '16/1 " %02x" "\n"' | sed 's/ /\\x/g'
+ print "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" .
+ "\x00\x00\x00\x48\x00\x00\x00\x1b\x04\x03\x00\x00\x00\x2d\xd9\xd4" .
+ "\x2d\x00\x00\x00\x18\x50\x4c\x54\x45\xff\xff\xff\x60\x60\x5d\xb0" .
+ "\xaf\xaa\x00\x80\x00\xce\xcd\xc7\xc0\x00\x00\xe8\xe8\xe6\xf7\xf7" .
+ "\xf6\x95\x0c\xa7\x47\x00\x00\x00\x73\x49\x44\x41\x54\x28\xcf\x63" .
+ "\x48\x67\x20\x04\x4a\x5c\x18\x0a\x08\x2a\x62\x53\x61\x20\x02\x08" .
+ "\x0d\x69\x45\xac\xa1\xa1\x01\x30\x0c\x93\x60\x36\x26\x52\x91\xb1" .
+ "\x01\x11\xd6\xe1\x55\x64\x6c\x6c\xcc\x6c\x6c\x0c\xa2\x0c\x70\x2a" .
+ "\x62\x06\x2a\xc1\x62\x1d\xb3\x01\x02\x53\xa4\x08\xe8\x00\x03\x18" .
+ "\x26\x56\x11\xd4\xe1\x20\x97\x1b\xe0\xb4\x0e\x35\x24\x71\x29\x82" .
+ "\x99\x30\xb8\x93\x0a\x11\xb9\x45\x88\xc1\x8d\xa0\xa2\x44\x21\x06" .
+ "\x27\x41\x82\x40\x85\xc1\x45\x89\x20\x70\x01\x00\xa4\x3d\x21\xc5" .
+ "\x12\x1c\x9a\xfe\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82";
+}
+
+sub git_project_list {
+ my $order = $cgi->param('o');
+ if (defined $order && $order !~ m/project|descr|owner|age/) {
+ die_error(undef, "Invalid order parameter '$order'.");
+ }
+
+ my @list = git_read_projects();
+ my @projects;
+ if (!@list) {
+ die_error(undef, "No projects found.");
+ }
+ foreach my $pr (@list) {
+ my $head = git_read_head($pr->{'path'});
+ if (!defined $head) {
+ next;
+ }
+ $ENV{'GIT_DIR'} = "$projectroot/$pr->{'path'}";
+ my %co = git_read_commit($head);
+ if (!%co) {
+ next;
+ }
+ $pr->{'commit'} = \%co;
+ if (!defined $pr->{'descr'}) {
+ my $descr = git_read_description($pr->{'path'}) || "";
+ $pr->{'descr'} = chop_str($descr, 25, 5);
+ }
+ if (!defined $pr->{'owner'}) {
+ $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || "";
+ }
+ push @projects, $pr;
+ }
+
+ git_header_html();
+ if (-f $home_text) {
+ print "\n" .
+ "\n";
+ $order ||= "project";
+ if ($order eq "project") {
+ @projects = sort {$a->{'path'} cmp $b->{'path'}} @projects;
+ print "| Project | \n";
+ } else {
+ print "" .
+ $cgi->a({-href => "$my_uri?" . esc_param("o=project"),
+ -class => "header"}, "Project") .
+ " | \n";
+ }
+ if ($order eq "descr") {
+ @projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects;
+ print "Description | \n";
+ } else {
+ print "" .
+ $cgi->a({-href => "$my_uri?" . esc_param("o=descr"),
+ -class => "header"}, "Description") .
+ " | \n";
+ }
+ if ($order eq "owner") {
+ @projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects;
+ print "Owner | \n";
+ } else {
+ print "" .
+ $cgi->a({-href => "$my_uri?" . esc_param("o=owner"),
+ -class => "header"}, "Owner") .
+ " | \n";
+ }
+ if ($order eq "age") {
+ @projects = sort {$a->{'commit'}{'age'} <=> $b->{'commit'}{'age'}} @projects;
+ print "Last Change | \n";
+ } else {
+ print "" .
+ $cgi->a({-href => "$my_uri?" . esc_param("o=age"),
+ -class => "header"}, "Last Change") .
+ " | \n";
+ }
+ print " | \n" .
+ "
\n";
+ my $alternate = 0;
+ foreach my $pr (@projects) {
+ if ($alternate) {
+ print "\n";
+ } else {
+ print "
\n";
+ }
+ $alternate ^= 1;
+ print "| " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"),
+ -class => "list"}, esc_html($pr->{'path'})) . " | \n" .
+ "" . esc_html($pr->{'descr'}) . " | \n" .
+ "" . chop_str($pr->{'owner'}, 15) . " | \n";
+ print "{'commit'}{'age'}) . "\">" .
+ $pr->{'commit'}{'age_string'} . " | \n" .
+ "" .
+ $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary") . " | " .
+ $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") . " | " .
+ $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") .
+ " | \n" .
+ "
\n";
+ }
+ print "
\n";
+ git_footer_html();
+}
+
sub git_summary {
my $descr = git_read_description($project) || "none";
my $head = git_read_head($project);
@@ -1319,27 +1448,13 @@ sub git_summary {
my $headlist = git_read_refs("refs/heads");
if (defined @$headlist) {
git_header_div('heads');
- git_heads_body($taglist, $head, 0, 15,
+ git_heads_body($headlist, $head, 0, 15,
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=heads")}, "..."));
}
git_footer_html();
}
-sub git_print_page_path {
- my $name = shift;
- my $type = shift;
-
- if (!defined $name) {
- print "\n";
print <
@@ -1546,84 +1661,6 @@ sub git_heads {
git_footer_html();
}
-sub git_get_hash_by_path {
- my $base = shift;
- my $path = shift || return undef;
-
- my $tree = $base;
-
- open my $fd, "-|", $GIT, "ls-tree", $base, "--", $path
- or die_error(undef, "Open git-ls-tree failed.");
- my $line = <$fd>;
- close $fd or return undef;
-
- #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c'
- $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/;
- return $3;
-}
-
-sub mimetype_guess_file {
- my $filename = shift;
- my $mimemap = shift;
- -r $mimemap or return undef;
-
- my %mimemap;
- open(MIME, $mimemap) or return undef;
- while (
) {
- my ($mime, $exts) = split(/\t+/);
- my @exts = split(/\s+/, $exts);
- foreach my $ext (@exts) {
- $mimemap{$ext} = $mime;
- }
- }
- close(MIME);
-
- $filename =~ /\.(.*?)$/;
- return $mimemap{$1};
-}
-
-sub mimetype_guess {
- my $filename = shift;
- my $mime;
- $filename =~ /\./ or return undef;
-
- if ($mimetypes_file) {
- my $file = $mimetypes_file;
- #$file =~ m#^/# or $file = "$projectroot/$path/$file";
- $mime = mimetype_guess_file($filename, $file);
- }
- $mime ||= mimetype_guess_file($filename, '/etc/mime.types');
- return $mime;
-}
-
-sub git_blob_plain_mimetype {
- my $fd = shift;
- my $filename = shift;
-
- if ($filename) {
- my $mime = mimetype_guess($filename);
- $mime and return $mime;
- }
-
- # just in case
- return $default_blob_plain_mimetype unless $fd;
-
- if (-T $fd) {
- return 'text/plain' .
- ($default_text_plain_charset ? '; charset='.$default_text_plain_charset : '');
- } elsif (! $filename) {
- return 'application/octet-stream';
- } elsif ($filename =~ m/\.png$/i) {
- return 'image/png';
- } elsif ($filename =~ m/\.gif$/i) {
- return 'image/gif';
- } elsif ($filename =~ m/\.jpe?g$/i) {
- return 'image/jpeg';
- } else {
- return 'application/octet-stream';
- }
-}
-
sub git_blob_plain {
if (!defined $hash) {
if (defined $file_name) {
@@ -1749,7 +1786,7 @@ sub git_tree {
if (defined $file_name) {
$base = esc_html("$file_name/");
}
- git_print_page_path($file_name);
+ git_print_page_path($file_name, 'tree');
print "\n";
print "
\n";
my $alternate = 0;
@@ -1793,98 +1830,6 @@ sub git_tree {
git_footer_html();
}
-sub git_rss {
- # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ
- open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project)
- or die_error(undef, "Open git-rev-list failed.");
- my @revlist = map { chomp; $_ } <$fd>;
- close $fd or die_error(undef, "Reading rev-list failed.");
- print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
- print "\n".
- "\n";
- print "\n";
- print "$project\n".
- "" . esc_html("$my_url?p=$project;a=summary") . "\n".
- "$project log\n".
- "en\n";
-
- for (my $i = 0; $i <= $#revlist; $i++) {
- my $commit = $revlist[$i];
- my %co = git_read_commit($commit);
- # we read 150, we always show 30 and the ones more recent than 48 hours
- if (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) {
- last;
- }
- my %cd = date_str($co{'committer_epoch'});
- open $fd, "-|", $GIT, "diff-tree", '-r', $co{'parent'}, $co{'id'} or next;
- my @difftree = map { chomp; $_ } <$fd>;
- close $fd or next;
- print "- \n" .
- "" .
- sprintf("%d %s %02d:%02d", $cd{'mday'}, $cd{'month'}, $cd{'hour'}, $cd{'minute'}) . " - " . esc_html($co{'title'}) .
- "\n" .
- "" . esc_html($co{'author'}) . "\n" .
- "$cd{'rfc2822'}\n" .
- "" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "\n" .
- "" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "\n" .
- "" . esc_html($co{'title'}) . "\n" .
- "" .
- "\n";
- }
- print "
\n";
- foreach my $line (@difftree) {
- if (!($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/)) {
- next;
- }
- my $file = validate_input(unquote($7));
- $file = decode("utf8", $file, Encode::FB_DEFAULT);
- print "$file
\n";
- }
- print "]]>\n" .
- "\n" .
- " \n";
- }
- print "";
-}
-
-sub git_opml {
- my @list = git_read_projects();
-
- print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
- print "\n".
- "\n".
- "".
- " $site_name Git OPML Export\n".
- "\n".
- "\n".
- "\n";
-
- foreach my $pr (@list) {
- my %proj = %$pr;
- my $head = git_read_head($proj{'path'});
- if (!defined $head) {
- next;
- }
- $ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}";
- my %co = git_read_commit($head);
- if (!%co) {
- next;
- }
-
- my $path = esc_html(chop_str($proj{'path'}, 25, 5));
- my $rss = "$my_url?p=$proj{'path'};a=rss";
- my $html = "$my_url?p=$proj{'path'};a=summary";
- print "\n";
- }
- print "\n".
- "\n".
- "\n";
-}
-
sub git_log {
my $head = git_read_head($project);
if (!defined $hash) {
@@ -2347,7 +2292,7 @@ sub git_history {
git_print_page_path($file_name, $ftype);
open my $fd, "-|",
- $GIT, "rev-list", "--full-history", $hash_base, "--", "\'$file_name\'";
+ $GIT, "rev-list", "--full-history", $hash_base, "--", $file_name;
print "\n";
my $alternate = 0;
while (my $line = <$fd>) {
@@ -2371,7 +2316,7 @@ sub git_history {
"" .
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") .
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") .
- " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=$commit;f=$file_name")}, "blob");
+ " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$ftype;hb=$commit;f=$file_name")}, $ftype);
my $blob = git_get_hash_by_path($hash_base, $file_name);
my $blob_parent = git_get_hash_by_path($commit, $file_name);
if (defined $blob && defined $blob_parent && $blob ne $blob_parent) {
@@ -2556,3 +2501,98 @@ sub git_shortlog {
git_footer_html();
}
+
+## ......................................................................
+## feeds (RSS, OPML)
+
+sub git_rss {
+ # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ
+ open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project)
+ or die_error(undef, "Open git-rev-list failed.");
+ my @revlist = map { chomp; $_ } <$fd>;
+ close $fd or die_error(undef, "Reading rev-list failed.");
+ print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
+ print "\n".
+ "\n";
+ print "\n";
+ print "$project\n".
+ "" . esc_html("$my_url?p=$project;a=summary") . "\n".
+ "$project log\n".
+ "en\n";
+
+ for (my $i = 0; $i <= $#revlist; $i++) {
+ my $commit = $revlist[$i];
+ my %co = git_read_commit($commit);
+ # we read 150, we always show 30 and the ones more recent than 48 hours
+ if (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) {
+ last;
+ }
+ my %cd = date_str($co{'committer_epoch'});
+ open $fd, "-|", $GIT, "diff-tree", '-r', $co{'parent'}, $co{'id'} or next;
+ my @difftree = map { chomp; $_ } <$fd>;
+ close $fd or next;
+ print "- \n" .
+ "" .
+ sprintf("%d %s %02d:%02d", $cd{'mday'}, $cd{'month'}, $cd{'hour'}, $cd{'minute'}) . " - " . esc_html($co{'title'}) .
+ "\n" .
+ "" . esc_html($co{'author'}) . "\n" .
+ "$cd{'rfc2822'}\n" .
+ "" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "\n" .
+ "" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "\n" .
+ "" . esc_html($co{'title'}) . "\n" .
+ "" .
+ "\n";
+ }
+ print "
\n";
+ foreach my $line (@difftree) {
+ if (!($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/)) {
+ next;
+ }
+ my $file = validate_input(unquote($7));
+ $file = decode("utf8", $file, Encode::FB_DEFAULT);
+ print "$file \n";
+ }
+ print "]]>\n" .
+ "\n" .
+ " \n";
+ }
+ print "";
+}
+
+sub git_opml {
+ my @list = git_read_projects();
+
+ print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
+ print "\n".
+ "\n".
+ "".
+ " $site_name Git OPML Export\n".
+ "\n".
+ "\n".
+ "\n";
+
+ foreach my $pr (@list) {
+ my %proj = %$pr;
+ my $head = git_read_head($proj{'path'});
+ if (!defined $head) {
+ next;
+ }
+ $ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}";
+ my %co = git_read_commit($head);
+ if (!%co) {
+ next;
+ }
+
+ my $path = esc_html(chop_str($proj{'path'}, 25, 5));
+ my $rss = "$my_url?p=$proj{'path'};a=rss";
+ my $html = "$my_url?p=$proj{'path'};a=summary";
+ print "\n";
+ }
+ print "\n".
+ "\n".
+ "\n";
+}
|