File Coverage

blib/lib/Riji/Model/Blog.pm
Criterion Covered Total %
statement 39 96 40.6
branch 0 32 0.0
condition 0 15 0.0
subroutine 13 21 61.9
pod 0 4 0.0
total 52 168 30.9


line stmt bran cond sub pod time code
1             package Riji::Model::Blog;
2 1     1   579 use feature ':5.10';
  1         4  
  1         184  
3 1     1   8 use strict;
  1         3  
  1         19  
4 1     1   13 use warnings;
  1         2  
  1         102  
5              
6 1     1   7 use File::Spec;
  1         2  
  1         34  
7 1     1   1339 use Git::Repository 'FileHistory';
  1         20581  
  1         5  
8 1     1   6254 use List::UtilsBy qw/rev_sort_by rev_nsort_by sort_by/;
  1         2047  
  1         84  
9 1     1   9 use Path::Tiny 'path';
  1         2  
  1         82  
10 1     1   7 use IPC::Cmd ();
  1         2  
  1         18  
11              
12 1     1   384 use Riji::Model::Atom;
  1         4  
  1         34  
13 1     1   6 use Riji::Model::Entry;
  1         3  
  1         33  
14 1     1   376 use Riji::Model::Tag;
  1         3  
  1         30  
15              
16 1     1   7 use Mouse;
  1         1  
  1         5  
17              
18             has base_dir => (is => 'ro', required => 1);
19             has author => (is => 'ro', required => 1);
20             has title => (is => 'ro', required => 1);
21             has site_url => (
22             is => 'ro',
23             isa => 'URI',
24             required => 1
25             );
26              
27             has fqdn => (
28             is => 'ro',
29             lazy => 1,
30             default => sub {shift->site_url->host},
31             );
32              
33             has tag_uri_specific_prefix => (
34             is => 'ro',
35             lazy => 1,
36             default => sub {
37             my $pref = shift->site_url->path;
38             $pref =~ s!/$!!;
39             $pref =~ s!^/!!;
40             $pref =~ s!/!-!g;
41             $pref .= ':' if $pref;
42             $pref;
43             },
44             );
45              
46             has article_dir => (
47             is => 'ro',
48             default => 'article',
49             );
50              
51             has entry_dir => (
52             is => 'ro',
53             default => 'article/entry',
54             );
55              
56             has article_path => (
57             is => 'ro',
58             lazy => 1,
59             default => sub {
60             my $self = shift;
61             path($self->base_dir, $self->article_dir);
62             },
63             );
64              
65             has entry_path => (
66             is => 'ro',
67             lazy => 1,
68             default => sub {
69             my $self = shift;
70             path($self->base_dir, $self->entry_dir);
71             },
72             );
73              
74             has repo => (
75             is => 'ro',
76             lazy => 1,
77             default => sub {
78             my $self = shift;
79             Git::Repository->new(work_tree => $self->base_dir);
80             },
81             );
82              
83             has branch => (
84             is => 'ro',
85             default => sub {
86             my $git = IPC::Cmd::can_run('git') or return 'master';
87             my $ret = IPC::Cmd::run_forked(join(' ', $git, 'config', 'init.defaultBranch'));
88             if ($ret->{exit_code} == 0) {
89             chomp($ret->{stdout});
90             return $ret->{stdout};
91             }
92             'master';
93             },
94             );
95              
96             has atom => (
97             is => 'ro',
98             lazy => 1,
99             default => sub {
100             my $self = shift;
101             Riji::Model::Atom->new(
102             blog => $self
103             );
104             },
105             );
106              
107             has tag_map => (
108             is => 'ro',
109             isa => 'HashRef[Riji::Model::Tag]',
110             lazy => 1,
111             default => sub {
112             my $self = shift;
113             my %map;
114             for my $entry (@{ $self->entries }) {
115             for my $tag (@{ $entry->raw_tags }) {
116             $map{$tag} ||= Riji::Model::Tag->new(name => $tag);
117             push @{$map{$tag}->entries}, $entry;
118             }
119             }
120             \%map;
121             },
122             );
123              
124             has tags => (
125             is => 'ro',
126             isa => 'ArrayRef[Riji::Model::Tag]',
127             lazy => 1,
128             default => sub {
129             [rev_nsort_by {$_->count} sort_by {$_->name} values %{ shift->tag_map }]
130             },
131             );
132              
133 1     1   1125 no Mouse;
  1         2  
  1         5  
134              
135             sub entries {
136 0     0 0   my ($self, @args) = @_;
137              
138             $self->{entries} ||= [
139 0     0     rev_sort_by { $_->published_at->datetime . $_->file }
140 0 0         grep { $_ && !$_->is_draft }
141 0           map { $self->entry($_->relative($self->entry_path) .'') }
142 0   0       do {
143 0           my $itr = $self->entry_path->iterator({recurse => 1});
144 0           my @files;
145 0           while (my $file = $itr->()) {
146 0 0         next unless -f -r $file;
147 0           push @files, $file;
148             }
149 0           @files;
150             }
151             ];
152 0 0         return $self->{entries} unless @args;
153              
154 0           $self->_search_entries(@args);
155             }
156              
157             sub entry {
158 0     0 0   my ($self, $file) = @_;
159              
160 0           my $entry = Riji::Model::Entry->new(
161             file => File::Spec->catfile('entry', $file),
162             blog => $self,
163             );
164 0 0         return () unless -f -r $entry->file_path;
165              
166 0           $entry;
167             }
168              
169             sub article {
170 0     0 0   my ($self, $file, $opt) = @_;
171              
172 0           my $article = Riji::Model::Article->new(
173             file => $file,
174             blog => $self,
175             %$opt,
176             );
177 0 0         return () unless -f -r $article->file_path;
178 0 0 0       return () if !$article->paginate && $article->page;
179              
180 0           $article;
181             }
182              
183             sub tag {
184 0     0 0   my ($self, $tag) = @_;
185              
186 0           $tag = Riji::Model::Tag->normalize_tag($tag);
187 0           $self->tag_map->{$tag};
188             }
189              
190             # _search_entries(tag => 'hoge', sort_by => 'last_updated_at', sort_order => 'desc', limit => 10);
191             sub _search_entries {
192 0     0     my $self = shift;
193 0 0         my %opt = @_ == 1 ? %{$_[0]} : @_;
  0            
194 0           my @entries = @{ $self->entries };
  0            
195              
196 0 0         if (my $tag = $opt{tag}) {
197 0           @entries = grep { grep {$_ eq $tag} @{ $_->raw_tags } } @entries;
  0            
  0            
  0            
198             }
199              
200 0 0         if (my $sort_by = $opt{sort_by}) {
201 0           my @enable_fields = qw/published_at last_modified_at title/;
202 0 0         if (grep {$sort_by eq $_} @enable_fields) {
  0            
203 0 0         if ($sort_by eq 'last_modified_at') {
    0          
204 0     0     @entries = rev_sort_by {$_->last_modified_at->datetime . $_->title} @entries;
  0            
205             }
206             elsif ($sort_by ne 'published_at') {
207 0     0     @entries = rev_sort_by {$_->title} @entries;
  0            
208             }
209             }
210             else {
211 0           warn "$sort_by is unknown sort item";
212             }
213             }
214              
215 0   0       my $sort_order = lc($opt{sort_order} || '');
216 0 0 0       if ($sort_order && ! grep {$sort_order eq $_} qw/asc desc/) {
  0            
217 0           warn "$sort_order is unknown sort_order";
218 0           $sort_order = undef;
219             }
220 0 0 0       if ($opt{sort_by} && !$sort_order) {
221             $sort_order = {
222             last_modified_at => 'desc',
223             published_at => 'desc',
224             title => 'asc',
225 0           }->{$opt{sort_by}};
226             }
227 0   0       $sort_order ||= 'desc';
228 0 0         @entries = reverse @entries if $sort_order eq 'asc';
229              
230 0 0         if (my $limit = $opt{limit}) {
231 0           @entries = splice @entries, 0, $limit;
232             }
233 0           [@entries];
234             }
235              
236             1;