File Coverage

blib/lib/Catmandu/SFX.pm
Criterion Covered Total %
statement 76 79 96.2
branch 33 44 75.0
condition 17 30 56.6
subroutine 9 9 100.0
pod 0 4 0.0
total 135 166 81.3


line stmt bran cond sub pod time code
1             package Catmandu::SFX;
2              
3 3     3   15193 use strict;
  3         4  
  3         150  
4             our $VERSION = '0.01';
5              
6 3     3   450 use Catmandu::Sane;
  3         72380  
  3         20  
7 3     3   1083 use Catmandu::Util qw(:is);
  3         36699  
  3         735  
8 3     3   16 use Moo;
  3         5  
  3         16  
9 3     3   2273 use POSIX qw(strftime);
  3         13425  
  3         15  
10              
11             sub parse_sfx_threshold {
12 6     6 0 6418 my ($self,$str) = @_;
13            
14 6         31 my $res = { raw => $str , start => {} , end => {} , limit => {} , years => [] };
15              
16             # Parse the Available from part...
17 6 100       26 if ($str =~ m{^Available\s+(.*)\.}) {
18 4         9 my $from = $1;
19              
20 4 50 33     48 if (defined $from && $from =~ m{
21             (in|from)
22             \s+
23             (\d+)
24             (\s+volume:\s+(\S+))?
25             (\s+issue:\s+(\S+))?
26             (.*)
27             }x) {
28 4         16 $res->{start}->{year} = $2;
29 4 100       13 $res->{start}->{volume} = $4 if $3;
30 4 100       12 $res->{start}->{issue} = $6 if $5;
31             }
32              
33 4         8 my $until = $7;
34              
35 4 50 33     23 if (defined $until && $until =~ m{
36             until
37             \s+
38             (\d+)
39             (\s+volume:\s+(\S+))?
40             (\s+issue:\s+(\S+))?
41             }x) {
42 0 0       0 $res->{end}->{year} = $1 if $1;
43 0 0       0 $res->{end}->{volume} = $3 if $3;
44 0 0       0 $res->{end}->{issue} = $5 if $5;
45             }
46             }
47            
48             # Parse the Most recent part...
49 6 100       37 if ($str =~ m{
50             Most
51             \s+
52             recent
53             \s+
54             (\d+)
55             \s+
56             (year|month)
57             \(s\)
58             \s+
59             (not\s+)?
60             available
61             \.
62            
63             }x) {
64 4         26 $res->{limit}->{num} = $1;
65 4         19 $res->{limit}->{type} = $2;
66 4 100       18 $res->{limit}->{available} = $3 ? 0 : 1;
67             }
68              
69 6 100 66     35 if (exists $res->{end}->{year} || exists $res->{limit}->{num}) {
70 4         7 $res->{is_running} = 0;
71             }
72             else {
73 2         4 $res->{is_running} = 1;
74             }
75              
76 6         34 $res->{years} = $self->parse_year_ranges($res);
77              
78 6         16 $res->{human} = $self->parse_human_ranges($res);
79              
80 6         167 $res;
81             }
82              
83             sub parse_human_ranges {
84 6     6 0 8 my ($self,$parsed) = @_;
85 6         7 my $years = $parsed->{years};
86              
87 6         10 my @human = ();
88              
89 6 50 33     33 if (is_array_ref($years) && @$years > 0) {
90 6         9 push @human , $years->[0];
91 6 100       21 push @human , $years->[-1] if @$years > 1;
92             }
93              
94 6 100       11 if ($parsed->{is_running} == 0) {
95 4         15 return join(' - ', @human);
96             }
97             else {
98 2         10 return shift(@human) . " - ";
99             }
100             }
101              
102             sub parse_year_ranges {
103 6     6 0 7 my ($self,$parsed) = @_;
104              
105             # Calculate which years are available for users...
106 6         307 my $this_year = strftime("%Y", localtime);
107              
108 6         12 my ($start_year,$end_year);
109            
110 6 100       23 $start_year = $parsed->{start}->{year} if exists $parsed->{start}->{year};
111 6   66     16 $start_year //= $this_year;
112              
113 6 50       14 $end_year = $parsed->{end}->{year} if exists $parsed->{end}->{year};
114 6   33     20 $end_year //= $this_year;
115              
116             # If most recent X years(s) are not available
117 6 100 66     49 if (exists $parsed->{limit} &&
      100        
      100        
118             $parsed->{limit}->{num} &&
119             $parsed->{limit}->{type} eq 'year' &&
120             $parsed->{limit}->{available} == 0) {
121 2         7 $end_year -= $parsed->{limit}->{num} + 1;
122             }
123              
124 6 100       16 if ($start_year < $end_year) {
125 4         17 return [ ($start_year .. $end_year) ];
126             }
127             else {
128 2         8 return [ ($end_year .. $start_year) ];
129             }
130             }
131              
132             sub parse_sfx_year_range {
133 1     1 0 4725 my ($self, $years) = @_;
134              
135 1 50 33     12 return "" unless is_array_ref($years) && @$years > 0;
136              
137 1         126 my $curryear = [localtime time]->[5] + 1900;
138 1         3 my %h;
139              
140 1         3 foreach (@$years) {
141 6         11 $h{$_} = 1;
142             }
143              
144 1         2 my $start = undef;
145 1         2 my $prev = undef;
146 1         2 my $human = '';
147              
148 1         7 foreach (sort { $a <=> $b } keys %h) {
  10         11  
149 6 100       15 if (! defined $start) {
    100          
    100          
150 1         2 $start = $_;
151             }
152             elsif ($_ == $prev + 1) { }
153             elsif ($start == $prev) {
154 1         3 $human .= "$start ; ";
155 1         1 $start = $_;
156             }
157             else {
158 1         4 $human .= "$start - $prev ; ";
159 1         2 $start = $_;
160             }
161 6         7 $prev = $_;
162             }
163              
164 1         2 $human .= "$start - $prev";
165              
166 1         30 return $human;
167             }
168              
169             1;
170              
171             __END__