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   57355 use strict;
  3         15  
  3         111  
4             our $VERSION = '0.02';
5              
6 3     3   393 use Catmandu::Sane;
  3         165664  
  3         16  
7 3     3   562 use Catmandu::Util qw(:is);
  3         5  
  3         646  
8 3     3   17 use Moo;
  3         5  
  3         14  
9 3     3   1444 use POSIX qw(strftime);
  3         5  
  3         23  
10              
11             sub parse_sfx_threshold {
12 6     6 0 4410 my ($self,$str) = @_;
13            
14 6         26 my $res = { raw => $str , start => {} , end => {} , limit => {} , years => [] };
15              
16             # Parse the Available from part...
17 6 100       24 if ($str =~ m{^Available\s+(.*)\.}) {
18 4         9 my $from = $1;
19              
20 4 50 33     39 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         11 $res->{start}->{year} = $2;
29 4 100       12 $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     17 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       29 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         10 $res->{limit}->{num} = $1;
65 4         9 $res->{limit}->{type} = $2;
66 4 100       11 $res->{limit}->{available} = $3 ? 0 : 1;
67             }
68              
69 6 100 66     25 if (exists $res->{end}->{year} || exists $res->{limit}->{num}) {
70 4         8 $res->{is_running} = 0;
71             }
72             else {
73 2         4 $res->{is_running} = 1;
74             }
75              
76 6         14 $res->{years} = $self->parse_year_ranges($res);
77              
78 6         15 $res->{human} = $self->parse_human_ranges($res);
79              
80 6         119 $res;
81             }
82              
83             sub parse_human_ranges {
84 6     6 0 8 my ($self,$parsed) = @_;
85 6         11 my $years = $parsed->{years};
86              
87 6         8 my @human = ();
88              
89 6 50 33     24 if (is_array_ref($years) && @$years > 0) {
90 6         10 push @human , $years->[0];
91 6 100       13 push @human , $years->[-1] if @$years > 1;
92             }
93              
94 6 100       17 if ($parsed->{is_running} == 0) {
95 4         18 return join(' - ', @human);
96             }
97             else {
98 2         9 return shift(@human) . " - ";
99             }
100             }
101              
102             sub parse_year_ranges {
103 6     6 0 8 my ($self,$parsed) = @_;
104              
105             # Calculate which years are available for users...
106 6         331 my $this_year = strftime("%Y", localtime);
107              
108 6         19 my ($start_year,$end_year);
109            
110 6 100       19 $start_year = $parsed->{start}->{year} if exists $parsed->{start}->{year};
111 6   66     18 $start_year //= $this_year;
112              
113 6 50       13 $end_year = $parsed->{end}->{year} if exists $parsed->{end}->{year};
114 6   33     22 $end_year //= $this_year;
115              
116             # If most recent X years(s) are not available
117 6 100 66     35 if (exists $parsed->{limit} &&
      100        
      100        
118             $parsed->{limit}->{num} &&
119             $parsed->{limit}->{type} eq 'year' &&
120             $parsed->{limit}->{available} == 0) {
121 2         5 $end_year -= $parsed->{limit}->{num} + 1;
122             }
123              
124 6 100       17 if ($start_year < $end_year) {
125 4         18 return [ ($start_year .. $end_year) ];
126             }
127             else {
128 2         7 return [ ($end_year .. $start_year) ];
129             }
130             }
131              
132             sub parse_sfx_year_range {
133 1     1 0 2327 my ($self, $years) = @_;
134              
135 1 50 33     13 return "" unless is_array_ref($years) && @$years > 0;
136              
137 1         56 my $curryear = [localtime time]->[5] + 1900;
138 1         17 my %h;
139              
140 1         4 foreach (@$years) {
141 6         13 $h{$_} = 1;
142             }
143              
144 1         1 my $start = undef;
145 1         2 my $prev = undef;
146 1         7 my $human = '';
147              
148 1         7 foreach (sort { $a <=> $b } keys %h) {
  9         14  
149 6 100       14 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         2 $start = $_;
156             }
157             else {
158 1         4 $human .= "$start - $prev ; ";
159 1         2 $start = $_;
160             }
161 6         9 $prev = $_;
162             }
163              
164 1         3 $human .= "$start - $prev";
165              
166 1         22 return $human;
167             }
168              
169             1;
170              
171             __END__
172              
173             =encoding utf-8
174              
175             =head1 NAME
176              
177             Catmandu::SFX - Catmandu modules for parsing SFX data
178              
179             =head1 DESCRIPTION
180              
181             Catmandu::SFX provides methods to work with SFX input within the L<Catmandu>
182             framework. See L<Catmandu::Introduction> and L<http://librecat.org/> for an
183             introduction into Catmandu.
184              
185             =head1 CATMANDU MODULES
186              
187             =over
188              
189             =item * L<Catmandu::Fix::sfx_threshold>
190              
191             =item * L<Catmandu::Fix::sfx_year_range>
192              
193             =back
194              
195             =head1 AUTHOR
196              
197             Patrick Hochstenbach <Patrick.Hochstenbach@UGent.be>
198              
199             =head1 COPYRIGHT AND LICENSE
200              
201             This software is copyright (c) 2015 by Patrick Hochstenbach.
202              
203             This is free software; you can redistribute it and/or modify it under
204             the same terms as the Perl 5 programming language system itself.
205              
206             =cut