File Coverage

bootylicious
Criterion Covered Total %
statement 35 35 100.0
branch n/a
condition n/a
subroutine 11 11 100.0
pod n/a
total 46 46 100.0


line stmt bran cond sub pod time code
1             #!/usr/bin/env perl
2              
3 1     1   350 use FindBin;
  1         2  
  1         41  
4 1     1   12 use Cwd;
  1         2  
  1         52  
5 1     1   402 use lib "$FindBin::Bin/lib";
  1         525  
  1         6  
6 1     1   481 use Mojolicious::Lite;
  1         34727  
  1         7  
7 1     1   10319 use Mojo::Util qw(md5_sum);
  1         2  
  1         38  
8 1     1   6 use Mojo::File qw(path);
  1         3  
  1         47  
9 1     1   4 use Mojo::Home;
  1         2  
  1         27  
10 1     1   5 use Mojo::Loader qw(data_section);
  1         1  
  1         35  
11 1     1   418 use Bootylicious;
  1         5  
  1         27  
12 1     1   320 use Bootylicious::Timestamp;
  1         3  
  1         6  
13              
14             app->home(Mojo::Home->new($ENV{BOOTYLICIOUS_HOME} || getcwd()));
15              
16             unshift @{app->plugins->namespaces}, 'Bootylicious::Plugin';
17              
18             plugin 'booty_config' => {file => app->home->rel_file('bootylicious.conf')};
19             plugin 'markdown_parser';
20             plugin 'model';
21              
22             my $ALIAS_RE = qr/[a-zA-Z0-9-_]+/;
23             my $TAG_RE = qr/[\w\s-]+/;
24              
25             if (@ARGV && $ARGV[0] eq '--create-config') {
26             if (-e 'bootylicious.conf') {
27             die "bootylicious.conf already exists\n";
28             }
29            
30             path('bootylicious.conf')->spurt(data_section(__PACKAGE__, 'bootylicious.conf'));
31             exit;
32             }
33              
34             get '/' => \&index => 'root';
35             get '/index' => \&index => 'index';
36              
37             sub index {
38 3     3   31748 my $self = shift;
39              
40 3         14 my $timestamp = $self->param('timestamp');
41              
42 3         714 my $pager = $self->get_articles(timestamp => $timestamp);
43              
44 3         46 $self->stash(articles => $pager->articles, pager => $pager);
45              
46 3         75 $self->render_smart('index');
47             }
48              
49             get '/articles/:year/:month' => [year => qr/\d+/, month => qr/\d+/] =>
50             {year => undef, month => undef} => sub {
51             my $self = shift;
52              
53             my $year = $self->stash('year');
54             my $month = $self->stash('month');
55             my $archive = $self->get_archive(year => $year, month => $month);
56              
57             $self->stash(archive => $archive);
58              
59             $self->render_smart;
60             } => 'articles';
61              
62             get '/articles/:year/:month/:alias' =>
63             [year => qr/\d+/, month => qr/\d+/, alias => $ALIAS_RE] => sub {
64             my $self = shift;
65              
66             my $article = $self->get_article(@{$self->stash}{qw/year month alias/});
67              
68             return $self->reply->not_found unless $article;
69              
70             $self->stash(article => $article);
71              
72             $self->render_smart;
73             } => 'article';
74              
75             post '/articles/:year/:month/:alias/comment' => sub {
76             my $self = shift;
77              
78             return $self->reply->not_found unless $self->comments_enabled;
79              
80             my $article = $self->get_article(@{$self->stash}{qw/year month alias/});
81              
82             return $self->reply->not_found unless $article && $article->comments_enabled;
83              
84             my $validator = $self->create_validator;
85             my $comment_name = md5_sum($article->created->year, $article->created->month, $article->name);
86            
87             $validator->field('author')->required(1);
88             $validator->field('email')->email(1);
89             $validator->field('content')->length(0); # bot protection
90             $validator->field($comment_name)->required(1);
91              
92             return $self->render('article', article => $article)
93             unless $self->validate($validator);
94            
95             my $comment_params = $validator->values;
96             $comment_params->{content} = delete $comment_params->{$comment_name};
97             my $comment = $article->comment(%$comment_params);
98              
99             return $self->redirect_to($self->href_to_article($article)
100             ->fragment('comment-' . $comment->number));
101             } => 'comment';
102              
103             get '/comments' => sub {
104             my $self = shift;
105              
106             return $self->reply->not_found unless $self->comments_enabled;
107              
108             $self->render_smart;
109             } => 'comments';
110              
111             get '/tags/:tag' => [tag => $TAG_RE] => sub {
112             my $self = shift;
113              
114             my $tag = $self->stash('tag');
115              
116             my $timestamp = $self->param('timestamp');
117              
118             my $pager = $self->get_articles_by_tag($tag, timestamp => $timestamp);
119              
120             return $self->reply->not_found unless $pager->articles->size;
121              
122             $self->stash(articles => $pager->articles, pager => $pager);
123              
124             $self->render_smart;
125             } => 'tag';
126              
127             get '/tags' => sub {
128             my $self = shift;
129              
130             my $cloud = $self->get_tag_cloud;
131              
132             $self->stash(tags => $cloud);
133              
134             $self->render_smart;
135             } => 'tags';
136              
137             get '/pages/:name' => [name => $ALIAS_RE] => sub {
138             my $self = shift;
139              
140             my $name = $self->stash('name');
141              
142             my $page = $self->get_page($name);
143              
144             return $self->reply->not_found unless $page;
145              
146             $self->stash(page => $page);
147              
148             $self->render_smart;
149             } => 'page';
150              
151             get '/drafts/:name' => [name => $ALIAS_RE] => sub {
152             my $self = shift;
153              
154             my $name = $self->stash('name');
155              
156             my $draft = $self->get_draft($name);
157              
158             return $self->reply->not_found unless $draft;
159              
160             $self->stash(draft => $draft);
161              
162             $self->render_smart;
163             } => 'draft';
164              
165             app->start;
166              
167             __DATA__