die "Unknown order parameter";
}
- my @list = $c->model('Git')->projects;
+ my @list = $c->model('Git')->list_projects;
if (!@list) {
die "No projects found";
}
if (-f $c->config->{home_text}) {
- print "<div class=\"index_include\">\n";
- print slurp($c->config->{home_text});
- print "</div>\n";
+ $c->stash->{home_text_contents} = slurp($c->config->{home_text});
}
- my $cgi;
- print $cgi->startform(-method => "get") .
- "<p class=\"projsearch\">Search:\n" .
- $cgi->textfield(-name => "s", -value => $c->req->param('searchtext')) . "\n" .
- "</p>" .
- $cgi->end_form() . "\n";
+ $c->config->{ENV} = \%ENV;
+ $c->stash->{searchtext} = $c->req->param('searchtext');
+ $c->stash->{projects} = \@list;
+ $c->stash->{action} = 'index';
+}
+
+sub auto : Private {
+ my($self, $c) = @_;
+
+ # Yes, this is hideous.
+ $self->header($c);
+ $self->footer($c);
+}
+
+use Gitalist::Util qw(to_utf8);
+use HTML::Entities qw(encode_entities);
+use URI::Escape qw(uri_escape);
+# Formally git_header_html
+sub header {
+ my($self, $c) = @_;
+
+ my $title = $c->config->{sitename};
+
+ my $project = $c->req->param('project') || $c->req->param('p');
+ my $action = $c->req->param('action') || $c->req->param('a');
+ my $file_name = $c->req->param('filename') || $c->req->param('f');
+ if(defined $project) {
+ $title .= " - " . to_utf8($project);
+ if (defined $action) {
+ $title .= "/$action";
+ if (defined $file_name) {
+ $title .= " - " . encode_entities($file_name);
+ if ($action eq "tree" && $file_name !~ m|/$|) {
+ $title .= "/";
+ }
+ }
+ }
+ }
+
+ $c->stash->{version} = $c->config->{version};
+ $c->stash->{git_version} = $c->model('Git')->run_cmd('--version');
+ $c->stash->{title} = $title;
+
+ #$c->stash->{baseurl} = $ENV{PATH_INFO} && uri_escape($base_url);
+ $c->stash->{stylesheet} = $c->config->{stylesheet} || 'gitweb.css';
+
+ $c->stash->{project} = $project;
+ my @links;
+ if($project) {
+ my %href_params = $self->feed_info($c);
+ $href_params{'-title'} ||= 'log';
+
+ foreach my $format qw(RSS Atom) {
+ my $type = lc($format);
+ push @links, {
+ rel => 'alternate',
+ title => "$project - $href_params{'-title'} - $format feed",
+ # XXX A bit hacky and could do with using gitweb::href() features
+ href => "?a=$type;p=$project",
+ type => "application/$type+xml"
+ }, {
+ rel => 'alternate',
+ # XXX This duplication also feels a bit awkward
+ title => "$project - $href_params{'-title'} - $format feed (no merges)",
+ href => "?a=$type;p=$project;opt=--no-merges",
+ type => "application/$type+xml"
+ };
+ }
+ } else {
+ push @links, {
+ rel => "alternate",
+ title => $c->config->{sitename}." projects list",
+ href => '?a=project_index',
+ type => "text/plain; charset=utf-8"
+ }, {
+ rel => "alternate",
+ title => $c->config->{sitename}." projects feeds",
+ href => '?a=opml',
+ type => "text/plain; charset=utf-8"
+ };
+ }
+
+ $c->stash->{favicon} = $c->config->{favicon};
+
+ # </head><body>
- git_project_list_body(\@list, $order);
+ $c->stash(
+ logo_url => uri_escape($c->config->{logo_url}),
+ logo_label => encode_entities($c->config->{logo_label}),
+ logo_img => $c->config->{logo},
+ home_link => uri_escape($c->config->{home_link}),
+ home_link_str => $c->config->{home_link_str},
+ );
+
+ if(defined $project) {
+ $c->stash(
+ search_text => $c->req->param('s') || $c->req->param('searchtext'),
+ search_hash => $c->req->param('hb') || $c->req->param('hashbase')
+ || $c->req->param('h') || $c->req->param('hash')
+ || 'HEAD'
+ );
+ }
+}
+
+# Formally git_footer_html
+sub footer {
+ my($self, $c) = @_;
+
+ my $feed_class = 'rss_logo';
+
+ my @feeds;
+ my $project = $c->req->param('project') || $c->req->param('p');
+ if(defined $project) {
+ # ... this could be simpler ... # Chop off .git
+ my $descr = $c->model('Git')->project_info(substr($project, 0, -5))->{description};
+ $c->stash->{project_description} = defined $descr
+ ? encode_entities($descr)
+ : '';
+
+ my %href_params = $self->feed_info($c);
+ if (!%href_params) {
+ $feed_class .= ' generic';
+ }
+ $href_params{'-title'} ||= 'log';
+
+ @feeds = [
+ map +{
+ class => $feed_class,
+ title => "$href_params{'-title'} $_ feed",
+ href => "/?p=$project;a=\L$_",
+ name => lc $_,
+ }, qw(RSS Atom)
+ ];
+ } else {
+ @feeds = [
+ map {
+ class => $feed_class,
+ title => '',
+ href => "/?a=$_->[0]",
+ name => $_->[1],
+ }, [opml=>'OPML'],[project_index=>'TXT'],
+ ];
+ }
}
+# XXX This feels wrong here, should probably be refactored.
+# returns hash to be passed to href to generate gitweb URL
+# in -title key it returns description of link
+sub feed_info {
+ my($self, $c) = @_;
+
+ my $format = shift || 'Atom';
+ my %res = (action => lc($format));
+
+ # feed links are possible only for project views
+ return unless $c->req->param('project');
+ # some views should link to OPML, or to generic project feed,
+ # or don't have specific feed yet (so they should use generic)
+ return if $c->req->param('action') =~ /^(?:tags|heads|forks|tag|search)$/x;
+
+ my $branch;
+ my $hash = $c->req->param('h') || $c->req->param('hash');
+ my $hash_base = $c->req->param('hb') || $c->req->param('hashbase');
+ # branches refs uses 'refs/heads/' prefix (fullname) to differentiate
+ # from tag links; this also makes possible to detect branch links
+ if ((defined $hash_base && $hash_base =~ m!^refs/heads/(.*)$!) ||
+ (defined $hash && $hash =~ m!^refs/heads/(.*)$!)) {
+ $branch = $1;
+ }
+ # find log type for feed description (title)
+ my $type = 'log';
+ my $file_name = $c->req->param('f') || $c->req->param('filename');
+ if (defined $file_name) {
+ $type = "history of $file_name";
+ $type .= "/" if $c->req->param('action') eq 'tree';
+ $type .= " on '$branch'" if (defined $branch);
+ } else {
+ $type = "log of $branch" if (defined $branch);
+ }
+
+ $res{-title} = $type;
+ $res{'hash'} = (defined $branch ? "refs/heads/$branch" : undef);
+ $res{'file_name'} = $file_name;
+
+ return %res;
+}
=head2 end
Attempt to render a view, if needed.
use List::MoreUtils qw/any/;
use Scalar::Util qw/blessed/;
-use Gitalist::Util qw(to_utf8);
-
-# from gitweb.pm
-use CGI::Util qw(unescape);
-
-has git => (
- is => 'ro',
- isa => 'Str',
- lazy => 1,
- default => sub {
- my $git;
+{
+ my $git;
+ sub git {
+ return $git
+ if $git;
if (my $config_git = Gitalist->config->{git}) {
$git = $config_git if -x $config_git;
}
return $git;
- },
-);
+ }
+}
sub is_git_repo {
my ($self, $dir) = @_;
#FIXME: Only handles bare repos. Is that enough?
- return -f $dir->file('HEAD');
+ return -f $dir->file('HEAD') or -f $dir->file('.git/HEAD');
}
sub project_info {
chomp $props{description};
};
- if ($props{description} =~ /^Unnamed repository;/) {
+ if ($props{description} && $props{description} =~ /^Unnamed repository;/) {
delete $props{description};
}
+ #Carp::cluck "dir is: $dir";
$props{owner} = (getpwuid $dir->stat->uid)[6];
my $output = $self->run_cmd_in($dir, qw{
sub git_dir_from_project_name {
my ($self, $project) = @_;
+ warn 'er, dir - '.dir(Gitalist->config->{repo_dir});
+ warn 'er, subdir - '.dir(Gitalist->config->{repo_dir})->subdir($project);
return dir(Gitalist->config->{repo_dir})->subdir($project);
}
return $self->run_cmd_in($project, qw/archive --format=tar/, "--prefix=${project}/", $rev);
}
-## from gitweb.pm
-
-# checking HEAD file with -e is fragile if the repository was
-# initialized long time ago (i.e. symlink HEAD) and was pack-ref'ed
-# and then pruned.
-sub check_head_link {
- my ($dir) = @_;
- my $headfile = "$dir/HEAD";
- return ((-e $headfile) ||
- (-l $headfile && readlink($headfile) =~ /^refs\/heads\//));
-}
-
-sub check_export_ok {
- my ($dir) = @_;
- my($export_ok, $export_auth_hook) = @{Gitalist->config}{qw(export_ok export_auth_hook)};
- return (check_head_link($dir) &&
- (!$export_ok || -e "$dir/$export_ok") &&
- (!$export_auth_hook || $export_auth_hook->($dir)));
-}
-
-sub projects {
- my($self, $filter) = @_;
- my @list;
-
- $filter ||= '';
- $filter =~ s/\.git$//;
-
- my $projects_list = Gitalist->config->{projectroot};
- 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 > Gitalist->config->{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("$projects_list/$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;
- }
- }
- if (check_export_ok("$projects_list/$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;
-}
-
1;
__PACKAGE__->meta->make_immutable;
extends 'Catalyst::View::TT';
with 'Catalyst::View::ContentNegotiation::XHTML';
+use Template::Plugin::Cycle;
+
=head1 NAME
Gitalist::View::Default - Catalyst View
__PACKAGE__->config(
TEMPLATE_EXTENSION => '.tt2',
# Set the location for TT files
- INCLUDE_PATH => [ Gitalist->path_to( 'templates' ) ],
-# WRAPPER => 'default.tt2',
+ INCLUDE_PATH => [ Gitalist->path_to( 'templates' ) ],
+ WRAPPER => 'default.tt2',
);
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
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
+ $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
# 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
my $status = shift || "200 OK";
my $expires = shift;
- my $title = "$site_name";
+ my $title = $c->config->{sitename};
if (defined $project) {
$title .= " - " . to_utf8($project);
if (defined $action) {
} else {
$c->stash->{projects_list} = sprintf('<link rel="alternate" title="%s projects list" '.
'href="%s" type="text/plain; charset=utf-8" />'."\n",
- $site_name, href(project=>undef, action=>"project_index"));
+ $c->config->{sitename}, href(project=>undef, action=>"project_index"));
$c->stash->{projects_feed} = sprintf('<link rel="alternate" title="%s projects feeds" '.
'href="%s" type="text/x-opml" />'."\n",
- $site_name, href(project=>undef, action=>"opml"));
+ $c->config->{sitename}, href(project=>undef, action=>"opml"));
}
my $favicon = $c->config->{favicon};
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'";
-charset => 'utf-8',
-content_disposition => 'inline; filename="opml.xml"');
+ my $sitename = $c->config->{sitename};
print <<XML;
<?xml version="1.0" encoding="utf-8"?>
<opml version="1.0">
<head>
- <title>$site_name OPML Export</title>
+ <title>$sitename OPML Export</title>
</head>
<body>
<outline text="git RSS feeds">
<meta name="generator" content="gitweb/[% version %] git/[% git_version %][% mod_perl_version %]"/>
<meta name="robots" content="index, nofollow"/>
<title>[% title %] (Gitalist)</title>
- [% baseurl %]
- [% stylesheets.join("\n") %]
- [% IF project;
- rss_link;
- rss_link_no_merges;
- atom_link;
- atom_link_no_merges;
- ELSE;
- projects_list;
- projects_feed;
- END %]
- [% favicon %]
+ [% IF baseurl %]
+ <base href="[% baseurl %]" />
+ [% END %]
+ <link rel="stylesheet" type="text/css" href="[% stylesheet %]"/>
+ [% FOR link IN links %]
+ <link rel="[% link.rel %]"
+ title="[% link.title %]"
+ href="[% link.href %]"
+ type="[% link.type %]"
+ />
+ [% END %]
+ [% IF favicon %]
+ <link rel="shortcut icon" href="[% favicon %]" type="image/png" />
+ [% END %]
</head>
<body>
[% site_header %]
<div class="page_header">
- [% logo %]
- [% home_link %] / [%
- IF project;
- summary;
- IF action; " / " _ action; END;
+ <a title="[% logo_label %]" href="[% logo_url %]"><img src="[% logo_img %]" alt="git" class="logo"/></a>
+ <a href="/git/gitweb.cgi">Venda Git Repos</a>
+ [%- IF project %]
+ / <a href="/git/gitweb.cgi?p=[% project %];a=summary">[% project %]</a>
+ [% IF action; " / " _ action; END;
END %]
</div>
[% IF project AND have_search %]
<div class="search">
- [% search_form %]
+ <form method="get" action="/" enctype="application/x-www-form-urlencoded">
+ <input name="p" type="hidden" value="[% project %]" />
+ <input name="a" type="hidden" value="search" />
+ <input name="h" type="hidden" value="[% search_hash %]" />
+ <select name="st" >
+ <option value="commit">commit</option>
+ <option value="grep">grep</option>
+ <option value="author">author</option>
+ <option value="committer">committer</option>
+ <option value="pickaxe">pickaxe</option>
+ </select><sup><a href="/?p=[% project %];a=search_help">?</a></sup> search:
+ <input type="text" name="s" value="[% search_text %]"/>
+ <span title="Extended regular expression"><label><input type="checkbox" name="sr" value="1" />re</label></span>
+ </form>
</div>
[% END %]
END;
IF action;
- INCLUDE "$action.tt2";
+ INCLUDE "index.tt2";
ELSE;
# The output of gitweb.cgi is injected at this point.
content;
[%- # git_footer_html
-%]
<div class="page_footer">
-[%
-IF project;
- IF project_description
-%]
+[% IF project AND project_description %]
<div class="page_footer_text">[% project_description %]</div>
-[%
- END;
- rss_feed;
- atom_feed;
-ELSE;
- opml_feed _ " " _ index_feed;
-END %]
+[% END %]
+[% FOR feed IN feeds %]
+ <a class="[% feed.class %]" title="[% feed.title %]" href="[% feed.href %]">[% feed.name %]</a>
+[% END %]
</div>
[% site_footer %]