X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Fgitweb.pm;h=d110b7647690287269fc0c02c8d81b32f015736a;hb=74af77a336a18f3f46d0ebe723e1495d12faacd1;hp=1a6a551802aba7a021a57854a54da2e0bb9bc7e1;hpb=49595228a08bccfe841064138d6b06919cc78fb7;p=catagits%2FGitalist.git diff --git a/lib/gitweb.pm b/lib/gitweb.pm index 1a6a551..d110b76 100755 --- a/lib/gitweb.pm +++ b/lib/gitweb.pm @@ -20,14 +20,16 @@ use File::Basename qw(basename); use FindBin; binmode STDOUT, ':utf8'; +use Gitalist::Util qw(to_utf8); + BEGIN { CGI->compile(); } use vars qw( $cgi $version $my_url $my_uri $base_url $path_info $GIT $projectroot - $project_maxdepth $home_link $home_link_str $site_name $site_header - $home_text $site_footer @stylesheets $stylesheet $logo $favicon + $project_maxdepth $home_link $home_link_str $site_header + $home_text $site_footer @stylesheets $logo_url $logo_label $logo_url $logo_label $projects_list $projects_list_description_width $default_projects_order $export_ok $export_auth_hook $strict_export @git_base_url_list @@ -79,14 +81,11 @@ sub main { # core git executable to use # this can just be "git" if your webserver has a sensible PATH - our $GIT = "/usr/bin/git"; + our $GIT = `which git`; + chomp($GIT); # absolute fs-path which will be prepended to the project path - our $projectroot = "/pub/scm"; - - # fs traversing limit for getting project list - # the number is relative to the projectroot - our $project_maxdepth = 2007; + #our $projectroot = "/pub/scm"; # target of the home link on top of all pages our $home_link = $my_uri || "/"; @@ -94,11 +93,6 @@ sub main { # string of the home link on top of all pages our $home_link_str = "Project Gitalist"; - # name of your site or organization to appear in page titles - # replace this with something more descriptive for clearer bookmarks - our $site_name = "" - || ($ENV{'SERVER_NAME'} || "Untitled") . " Git"; - # filename of html text to include at top of each page our $site_header = ""; # html text to include at home page @@ -108,19 +102,13 @@ sub main { # URI of stylesheets our @stylesheets = ("gitweb.css"); - # URI of a single stylesheet, which can be overridden in GITWEB_CONFIG. - our $stylesheet = undef; - # URI of GIT logo (72x27 size) - our $logo = "git-logo.png"; - # URI of GIT favicon, assumed to be image/png type - our $favicon = "git-favicon.png"; # URI and label (title) of GIT logo link our $logo_url = "http://www.kernel.org/pub/software/scm/git/docs/"; our $logo_label = "git documentation"; # source of projects list - our $projects_list = ""; + our $projectroot = our $projects_list = $c->config->{projectroot}; # the width (in characters) of the projects list "Description" column our $projects_list_description_width = 25; @@ -436,8 +424,6 @@ sub main { # version of the core git binary our $git_version = qx("$GIT" --version) =~ m/git version (.*)$/ ? $1 : "unknown"; - $projects_list ||= $projectroot; - # ====================================================================== # input validation and dispatch @@ -1031,19 +1017,6 @@ sub validate_refname { return $input; } -# decode sequences of octets in utf8 into Perl's internal form, -# which is utf-8 with utf8 flag set if needed. gitweb writes out -# in utf-8 thanks to "binmode STDOUT, ':utf8'" at beginning -sub to_utf8 { - my $str = shift; - if (utf8::valid($str)) { - utf8::decode($str); - return $str; - } else { - return decode($fallback_encoding, $str, Encode::FB_DEFAULT); - } -} - # quote unsafe chars, but keep the slash, even when it's not # correct, but quoted slashes look too horrible in bookmarks sub esc_param { @@ -2167,106 +2140,6 @@ sub git_get_project_url_list { return wantarray ? @git_project_url_list : \@git_project_url_list; } -sub git_get_projects_list { - my ($filter) = @_; - my @list; - - $filter ||= ''; - $filter =~ s/\.git$//; - - my $check_forks = gitweb_check_feature('forks'); - - if (-d $projects_list) { - # search in directory - my $dir = $projects_list . ($filter ? "/$filter" : ''); - # remove the trailing "/" - $dir =~ s!/+$!!; - my $pfxlen = length("$dir"); - my $pfxdepth = ($dir =~ tr!/!!); - - File::Find::find({ - follow_fast => 1, # follow symbolic links - follow_skip => 2, # ignore duplicates - dangling_symlinks => 0, # ignore dangling symlinks, silently - wanted => sub { - # skip project-list toplevel, if we get it. - return if (m!^[/.]$!); - # only directories can be git repositories - return unless (-d $_); - # don't traverse too deep (Find is super slow on os x) - if (($File::Find::name =~ tr!/!!) - $pfxdepth > $project_maxdepth) { - $File::Find::prune = 1; - return; - } - - my $subdir = substr($File::Find::name, $pfxlen + 1); - # we check related file in $projectroot - my $path = ($filter ? "$filter/" : '') . $subdir; - if (check_export_ok("$projectroot/$path")) { - push @list, { path => $path }; - $File::Find::prune = 1; - } - }, - }, "$dir"); - - } elsif (-f $projects_list) { - # read from file(url-encoded): - # 'git%2Fgit.git Linus+Torvalds' - # 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin' - # 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman' - my %paths; - open my ($fd), $projects_list or return; - PROJECT: - while (my $line = <$fd>) { - chomp $line; - my ($path, $owner) = split ' ', $line; - $path = unescape($path); - $owner = unescape($owner); - if (!defined $path) { - next; - } - if ($filter ne '') { - # looking for forks; - my $pfx = substr($path, 0, length($filter)); - if ($pfx ne $filter) { - next PROJECT; - } - my $sfx = substr($path, length($filter)); - if ($sfx !~ /^\/.*\.git$/) { - next PROJECT; - } - } elsif ($check_forks) { - PATH: - foreach my $filter (keys %paths) { - # looking for forks; - my $pfx = substr($path, 0, length($filter)); - if ($pfx ne $filter) { - next PATH; - } - my $sfx = substr($path, length($filter)); - if ($sfx !~ /^\/.*\.git$/) { - next PATH; - } - # is a fork, don't include it in - # the list - next PROJECT; - } - } - if (check_export_ok("$projectroot/$path")) { - my $pr = { - path => $path, - owner => to_utf8($owner), - }; - push @list, $pr; - (my $forks_path = $path) =~ s/\.git$//; - $paths{$forks_path}++; - } - } - close $fd; - } - return @list; -} - our $gitweb_project_owner = undef; sub git_get_project_list_from_file { @@ -2903,182 +2776,6 @@ sub blob_contenttype { return $type; } -## ====================================================================== -## functions printing HTML: header, footer, error page - -sub git_header_html { - # XXX These aren't used, how odd. - my $status = shift || "200 OK"; - my $expires = shift; - - my $title = "$site_name"; - if (defined $project) { - $title .= " - " . to_utf8($project); - if (defined $action) { - $title .= "/$action"; - if (defined $file_name) { - $title .= " - " . esc_path($file_name); - if ($action eq "tree" && $file_name !~ m|/$|) { - $title .= "/"; - } - } - } - } - - $c->stash->{version} = $version; - $c->stash->{git_version} = $git_version; - $c->stash->{title} = $title; - - # the stylesheet, favicon etc urls won't work correctly with path_info - # unless we set the appropriate base URL - $c->stash->{baseurl} = $ENV{PATH_INFO} - ? q[] - : ''; - - # print out each stylesheet that exist, providing backwards capability - # for those people who defined $stylesheet in a config file - my $ssfmt = q[]; - $c->stash->{stylesheets} = [defined $stylesheet - ? sprintf($ssfmt, $stylesheet) - : map(sprintf($ssfmt, $_), grep $_, @stylesheets) - ]; - - $c->stash->{project} = defined $project; - if (defined $project) { - my %href_params = get_feed_info(); - if (!exists $href_params{'-title'}) { - $href_params{'-title'} = 'log'; - } - - foreach my $format qw(RSS Atom) { - my $type = lc($format); - my %link_attr = ( - '-rel' => 'alternate', - '-title' => "$project - $href_params{'-title'} - $format feed", - '-type' => "application/$type+xml" - ); - - $href_params{'action'} = $type; - $link_attr{'-href'} = href(%href_params); - $c->stash->{lc $format.'_link'} = "\n"; - - $href_params{'extra_options'} = '--no-merges'; - $link_attr{'-href'} = href(%href_params); - $link_attr{'-title'} .= ' (no merges)'; - $c->stash->{lc $format.'_link_no_merges'} = "\n"; - } - - } else { - $c->stash->{projects_list} = sprintf(''."\n", - $site_name, href(project=>undef, action=>"project_index")); - $c->stash->{projects_feed} = sprintf(''."\n", - $site_name, href(project=>undef, action=>"opml")); - } - - $c->stash->{favicon} = defined $favicon - ? qq() - : ''; - - # - - $c->stash->{site_header} = -f $site_header - ? insert_file($site_header) - : ''; - - $c->stash->{logo} - = $cgi->a({-href => esc_url($logo_url), - -title => $logo_label}, - qq()); - $c->stash->{home_link} = $cgi->a({-href => esc_url($home_link)}, $home_link_str); - - if(defined $project) { - $c->stash->{summary} = $cgi->a({-href => href(action=>"summary")}, esc_html($project)); - $c->stash->{action} = $action; - } - - my $have_search = $c->stash->{have_search} = gitweb_check_feature('search'); - if (defined $project && $have_search) { - if (!defined $searchtext) { - $searchtext = ""; - } - my $search_hash; - if (defined $hash_base) { - $search_hash = $hash_base; - } elsif (defined $hash) { - $search_hash = $hash; - } else { - $search_hash = "HEAD"; - } - my $action = $my_uri; - my $use_pathinfo = gitweb_check_feature('pathinfo'); - if ($use_pathinfo) { - $action .= "/".esc_url($project); - } - # This could be done better, but meh. - $c->stash->{search_form} = $cgi->startform(-method => "get", -action => $action) . - (!$use_pathinfo && - $cgi->input({-name=>"p", -value=>$project, -type=>"hidden"}) . "\n") . - $cgi->input({-name=>"a", -value=>"search", -type=>"hidden"}) . "\n" . - $cgi->input({-name=>"h", -value=>$search_hash, -type=>"hidden"}) . "\n" . - $cgi->popup_menu(-name => 'st', -default => 'commit', - -values => ['commit', 'grep', 'author', 'committer', 'pickaxe']) . - $cgi->sup($cgi->a({-href => href(action=>"search_help")}, "?")) . - " search:\n". - $cgi->textfield(-name => "s", -value => $searchtext) . "\n" . - "" . - $cgi->checkbox(-name => 'sr', -value => 1, -label => 're', - -checked => $search_use_regexp) . - "" . - $cgi->end_form() . "\n"; - } -} - -sub git_footer_html { - my $feed_class = 'rss_logo'; - - if (defined $project) { - my $descr = git_get_project_description($project); - $c->stash->{project_description} = defined $descr - ? esc_html($descr) - : ''; - - my %href_params = get_feed_info(); - if (!%href_params) { - $feed_class .= ' generic'; - } - $href_params{'-title'} ||= 'log'; - - foreach my $format qw(RSS Atom) { - $href_params{'action'} = lc($format); - $c->stash->{lc $format.'_feed'} = $cgi->a({-href => href(%href_params), - -title => "$href_params{'-title'} $format feed", - -class => $feed_class}, $format); - } - - } else { - $c->stash->{opml_feed} = $cgi->a({-href => href(project=>undef, action=>"opml"), - -class => $feed_class}, "OPML"); - $c->stash->{index_feed} = $cgi->a({-href => href(project=>undef, action=>"project_index"), - -class => $feed_class}, "TXT"); - } - - $c->stash->{site_footer} = -f $site_footer - ? insert_file($site_footer) - : ''; -} - # die_error(, ) # Example: die_error(404, 'Hash not found') # By convention, use the following status codes (as defined in RFC 2616): @@ -3107,7 +2804,7 @@ sub die_error {
EOF - die bless {}; + die bless { $status => $http_responses{$status}, err => $error }; } ## ---------------------------------------------------------------------- @@ -6053,7 +5750,7 @@ sub git_feed { return if ($cgi->request_method() eq 'HEAD'); # header variables - my $title = "$site_name - $project/$action"; + my $title = $c->config->{sitename} . " - $project/$action"; my $feed_type = 'log'; if (defined $hash) { $title .= " - '$hash'"; @@ -6099,10 +5796,10 @@ XML "en\n" . # project owner is responsible for 'editorial' content "$owner\n"; - if (defined $logo || defined $favicon) { + if ($c->config->{logo} || $c->config->{favicon}) { # prefer the logo to the favicon, since RSS # doesn't allow both - my $img = esc_url($logo || $favicon); + my $img = esc_url($c->config->{logo} || $c->config->{favicon}); print "\n" . "$img\n" . "$title\n" . @@ -6127,12 +5824,12 @@ XML "" . href(-full=>1) . "\n" . # use project owner for feed author "$owner\n"; - if (defined $favicon) { - print "" . esc_url($favicon) . "\n"; + if ($c->config->{favicon}) { + print "" . esc_url($c->config->{favicon}) . "\n"; } if (defined $logo_url) { # not twice as wide as tall: 72 x 27 pixels - print "" . esc_url($logo) . "\n"; + print "" . esc_url($c->config->{logo}) . "\n"; } if (! %latest_date) { # dummy date to keep the feed valid until commits trickle in: @@ -6267,11 +5964,12 @@ sub git_opml { -charset => 'utf-8', -content_disposition => 'inline; filename="opml.xml"'); + my $sitename = $c->config->{sitename}; print < - $site_name OPML Export + $sitename OPML Export