1 package Gitalist::Controller::Root;
5 use Sys::Hostname qw/hostname/;
6 use XML::OPML::SimpleGen;
8 use Gitalist::Utils qw/ age_string /;
10 use namespace::autoclean;
12 BEGIN { extends 'Gitalist::Controller' }
14 __PACKAGE__->config->{namespace} = '';
16 sub root : Chained('/') PathPart('') CaptureArgs(0) {}
19 my($self, $c, $haveh) = @_;
21 my $h = $haveh || $c->req->param('h') || '';
22 my $f = $c->req->param('f');
24 my $m = $c->stash->{Repository};
27 # Either use the provided h(ash) parameter, the f(ile) parameter or just use HEAD.
28 my $hash = ($h =~ /[^a-f0-9]/ ? $m->head_hash($h) : $h)
29 || ($f && $m->hash_by_path($f))
31 # XXX This could definitely use more context.
32 || Carp::croak("Couldn't find a hash for the commit object!");
34 my $obj = $m->get_object($hash)
35 or Carp::croak("Couldn't find a object for '$hash' in '$pd'!");
40 sub index : Chained('base') PathPart('') Args(0) {
41 my ( $self, $c ) = @_;
43 $c->detach($c->req->param('a'))
44 if $c->req->param('a');
46 my $search = $c->req->param('s') || '';
49 search_text => $search,
54 my ( $self, $c ) = @_;
55 my $repository = $c->stash->{Repository};
56 my $h = $c->req->param('h')
57 || $repository->hash_by_path($c->req->param('hb'), $c->req->param('f'))
58 || die "No file or sha1 provided.";
59 my $hb = $c->req->param('hb')
60 || $repository->head_hash
61 || die "Couldn't discern the corresponding head.";
63 my $filename = $c->req->param('f') || '';
65 my $blob = $repository->get_object($h);
66 $blob = $repository->get_object(
67 $repository->hash_by_path($h || $hb, $filename)
68 ) if $blob->type ne 'blob';
70 return $blob, $repository->get_object($hb), $filename;
75 The plain text version of blobdiff.
79 sub blobdiff_plain : Chained('base') Args(0) {
82 $c->stash(no_wrapper => 1);
83 $c->response->content_type('text/plain; charset=utf-8');
85 $c->forward('blobdiff');
90 Exposes a given diff of a blob.
94 sub blobdiff : Chained('base') Args(0) {
95 my ( $self, $c ) = @_;
96 my $commit = $self->_get_object($c, $c->req->param('hb'));
97 my $filename = $c->req->param('f')
98 || croak("No file specified!");
99 my($tree, $patch) = $c->stash->{Repository}->diff(
102 parent => $c->req->param('hpb') || undef,
108 filename => $filename,
109 # XXX Hack hack hack, see View::SyntaxHighlight
110 blobs => [$patch->[0]->{diff}],
114 $c->forward('View::SyntaxHighlight')
115 unless $c->stash->{no_wrapper};
118 # For legacy support.
119 sub history : Chained('base') Args(0) {
120 my ( $self, $c ) = @_;
122 my $repository = $c->stash->{Repository};
123 my $file = $repository->get_object(
124 $repository->hash_by_path(
125 $repository->head_hash,
126 $c->stash->{filename}
130 filetype => $file->type,
136 Provides some help for the search form.
140 sub search_help : Chained('base') Args(0) {}
142 sub opml : Chained('base') Args(0) {
145 my $opml = XML::OPML::SimpleGen->new();
147 $opml->head(title => lc(hostname()) . ' - ' . Gitalist->config->{name});
149 my @list = @{ $c->model()->repositories };
150 die 'No repositories found in '. $c->model->repo_dir
153 for my $proj ( @list ) {
154 $opml->insert_outline(
155 text => $proj->name. ' - '. $proj->description,
156 xmlUrl => $c->uri_for(rss => {p => $proj->name}),
160 $c->response->body($opml->as_string);
161 $c->response->content_type('application/rss');
162 $c->response->status(200);
165 sub base : Chained('/root') PathPart('') CaptureArgs(0) {
168 my $git_version = `git --version`;
171 git_version => $git_version,
172 version => $Gitalist::VERSION,
174 # XXX Move these to a plugin!
176 return 'never' unless $_[0];
177 return age_string(time - $_[0]->epoch);
181 my($line) = split /\n/, $cmt;
182 $line =~ s/^(.{70,80}\b).*/$1 \x{2026}/;
185 abridged_description => sub {
186 join(' ', grep { defined } (split / /, shift)[0..10]);
191 sub end : ActionClass('RenderView') {
193 # Give repository views the current HEAD.
194 if ($c->stash->{Repository}) {
195 $c->stash->{HEAD} = $c->stash->{Repository}->head_hash;
199 sub error_404 : Action {
201 $c->response->status(404);
202 $c->response->body('Page not found');
205 __PACKAGE__->meta->make_immutable;
211 Gitalist::Controller::Root - Root controller for the application
215 This controller handles all of the root level paths for the application
221 Root of chained actions
225 Populate the header and footer. Perhaps not the best location.
229 Provides the repository listing.
233 Attempt to render a view, if needed.
243 =head2 repository_index
247 See L<Gitalist> for authors.
251 See L<Gitalist> for the license.