File Coverage

blib/lib/LBMA/Statistics/GoldFixing/Daily.pm
Criterion Covered Total %
statement 52 90 57.7
branch 11 36 30.5
condition n/a
subroutine 12 15 80.0
pod 6 6 100.0
total 81 147 55.1


line stmt bran cond sub pod time code
1             package LBMA::Statistics::GoldFixing::Daily;
2              
3 15     15   194781 use warnings;
  15         46  
  15         528  
4 15     15   146 use strict;
  15         34  
  15         746  
5              
6             our $VERSION = '0.061';
7              
8 15     15   19446 use WWW::Mechanize;
  15         2984356  
  15         669  
9 15     15   18440 use HTML::TableExtract;
  15         134436  
  15         123  
10 15     15   729 use Encode;
  15         33  
  15         1757  
11 15     15   13476 use Log::Log4perl qw/:easy/;
  15         541431  
  15         152  
12              
13             =head1 NAME
14              
15             LBMA::Statistics::GoldFixing::Daily - Daily Prices Gold Fixings London Bullion Market (Internal only)
16              
17             =head1 DESCRIPTION
18              
19             Does the hard work.
20              
21              
22             =head1 SYNOPSIS
23              
24              
25             This modul is for internal use only. There's no need to use it directly.
26              
27             Everthing is done by LBMA::Statistics (See L).
28              
29              
30             =head2 new - Constructor
31              
32             use strict;
33              
34             use warnings;
35              
36             use LBMA::Statistics::GoldFixing::Daily;
37              
38             my $lbma = LBMA::Statistics::GoldFixing::Daily->new(
39             year => $year,
40             day_pattern => $day_pattern
41             ) or die $!;
42              
43             =cut
44              
45             sub new {
46 9     9 1 3017 my $class = shift;
47 9         42 my $self = {};
48 9         32 bless $self, $class;
49 9         45 $self->_init(@_);
50 6         19 return $self;
51             }
52              
53             =head2 _init
54              
55             private method to initialize the object
56              
57             =cut
58              
59             sub _init {
60 9     9   22 my $self = shift;
61 9         47 my %args = @_;
62 9         52 $self->{year} = $args{year};
63 9         27 $self->{day_pattern} = $args{day_pattern};
64 9 100       46 LOGDIE "Missing mandantory parameter year" unless $self->{year};
65 7 100       44 LOGDIE "Missing mandantory parameter day_pattern"
66             unless $self->{day_pattern};
67              
68             }
69              
70             =head2 year
71              
72             returns the year to look for
73              
74             =cut
75              
76             sub year {
77 1     1 1 6 my $self = shift;
78 1         9 return $self->{year};
79             }
80              
81             =head2 day_pattern
82              
83             returns the day_pattern to look for
84              
85             =cut
86              
87             sub day_pattern {
88 3     3 1 13 my $self = shift;
89 3         17 return $self->{day_pattern};
90             }
91              
92             =head2 dailystatsurl
93              
94             determines url for daily goldstats
95              
96              
97             =cut
98              
99             sub dailystatsurl {
100 0     0 1 0 my $self = shift;
101 0         0 my $url = 'http://lbma.oblive.co.uk/table?metal=gold&year=';
102 0         0 $url .= $self->year();
103 0         0 $url .= '&type=daily';
104 0         0 DEBUG("url: $url");
105 0         0 return $url;
106             }
107              
108             =head2 retrieve_row_am
109              
110             Just the A.M. Gold Fixing Data
111              
112             =cut
113              
114             sub retrieve_row_am {
115 0     0 1 0 my $self = shift;
116 0         0 my $fixings = $self->retrieve_row();
117 0         0 my $year = $self->year();
118 0         0 my @am_fixings = ();
119              
120             # Step by step
121 0 0       0 $am_fixings[0] = @$fixings[0] if defined @$fixings[0]; # Date
122 0 0       0 $am_fixings[1] = @$fixings[1] if defined @$fixings[1]; # USD
123 0 0       0 $am_fixings[2] = @$fixings[2] if defined @$fixings[2]; # GBP
124 0 0       0 if ( $year >= 1999 ) {
125              
126             # EUR
127 0 0       0 $am_fixings[3] = @$fixings[3] if defined @$fixings[3];
128             }
129             else {
130              
131             # No EUR before 1999 - do nothing
132             }
133 0 0       0 return wantarray ? @am_fixings : \@am_fixings;
134             }
135              
136             =head2 retrieve_row
137              
138             Returns an array of fixings.
139              
140             The number and order of elements varies depending on the year data is retrieved.
141             There is no EUR befor 1999.
142              
143              
144             # @fixings 1999 --
145             # 0 date (DD-MMM-YY)
146             # 1 GOLD A.M. USD
147             # 2 GOLD A.M. GBP
148             # 3 GOLD A.M. EUR
149             # 4 GOLD P.M. USD
150             # 5 GOLD P.M. GBP
151             # 6 GOLD P.M. EUR
152             # @fixings 1968 -- 1998
153             # 0 date (DD-MMM-YY)
154             # 1 GOLD A.M. USD
155             # 2 GOLD A.M. GBP
156             # 3 GOLD P.M. USD
157             # 4 GOLD P.M. GBP
158            
159             In scalar context a reference to an array is returned.
160              
161             Returns undef or empty list if data can't be retrieved e.g. dates without fixing like holydays.
162              
163             =cut
164              
165             sub retrieve_row {
166 0     0 1 0 my $self = shift;
167 0         0 my $url = $self->dailystatsurl();
168              
169 0 0       0 my $browser = WWW::Mechanize->new(
170             stack_depth => 10,
171             autocheck => 1,
172             ) or LOGDIE $!;
173              
174 0         0 $browser->agent_alias('Windows IE 6'); # Hide crawler
175              
176 0 0       0 $browser->get($url) or LOGDIE $!;
177              
178 0         0 my $fixings = $self->_parse( $browser->content() );
179 0         0 my @clean = ();
180             # Order of columns changed - we need to rearrange manually
181              
182 0         0 my $year = $self->year();
183              
184             # Got values
185 0 0       0 if ( scalar @$fixings ) {
186 0         0 $clean[0] = $fixings->[0]; # Date
187 0 0       0 if ( $year >= 1999 ) {
188 0         0 $clean[1] = $fixings->[1]; # GOLD A.M. USD
189 0         0 $clean[2] = $fixings->[3]; # GOLD A.M. GBP
190 0         0 $clean[3] = $fixings->[5]; # GOLD A.M. EUR
191 0         0 $clean[4] = $fixings->[2]; # GOLD P.M. USD
192 0         0 $clean[5] = $fixings->[4]; # GOLD P.M. GBP
193 0         0 $clean[6] = $fixings->[6]; # GOLD P.M. EUR
194             } else {
195             # No EURO before 1999
196 0         0 $clean[1] = $fixings->[1]; # GOLD A.M. USD
197 0         0 $clean[2] = $fixings->[3]; # GOLD A.M. GBP
198 0         0 $clean[3] = $fixings->[2]; # GOLD P.M. USD
199 0         0 $clean[4] = $fixings->[4]; # GOLD P.M. GBP
200             }
201             }
202              
203 0 0       0 return wantarray ? @clean : \@clean;
204             }
205              
206             =head2 _parse
207              
208             parses the content of the retrieved HTML page
209              
210             =cut
211              
212             sub _parse {
213 2     2   680 my $self = shift;
214 2         39 my $content = shift @_;
215 2         15 $content = decode_utf8($content);
216 2         3628 my $day_pattern = $self->day_pattern();
217 2         7 my @fixings = ();
218 2 50       22 my $te = HTML::TableExtract->new() or LOGDIE $!;
219 2 50       363 $te->parse($content) or LOGDIE $!;
220 2         514588 TABLE: foreach my $ts ( $te->tables ) {
221 2         30 ROW: foreach my $row ( $ts->rows ) {
222 235 100       51416 next ROW unless defined @$row[0];
223             {
224 15     15   28499 no warnings;
  15         38  
  15         2210  
  233         258  
225 233         879 TRACE( "Current Row: ", join( "|", @$row ) );
226             }
227 233 100       2108 next ROW unless @$row[0] =~ m/$day_pattern/;
228 2         8 @fixings = @$row;
229 2         11 last TABLE;
230             }
231             }
232 2 50       1490 return wantarray ? @fixings : \@fixings;
233             }
234              
235             1;
236             __END__