File Coverage

blib/lib/WWW/OPG/Scraper.pm
Criterion Covered Total %
statement 15 53 28.3
branch 0 28 0.0
condition 0 3 0.0
subroutine 5 9 55.5
pod 4 4 100.0
total 24 97 24.7


line stmt bran cond sub pod time code
1             # WWW::OPG::Scraper
2             # Perl interface to Ontario Power Generation's site
3             #
4             # $Id: Scraper.pm 10925 2010-01-10 20:27:32Z FREQUENCY@cpan.org $
5              
6             package WWW::OPG::Scraper;
7              
8 1     1   57543 use strict;
  1         3  
  1         41  
9 1     1   7 use warnings;
  1         2  
  1         32  
10 1     1   7 use Carp ();
  1         2  
  1         15  
11              
12 1     1   3475 use LWP::UserAgent;
  1         90532  
  1         33  
13 1     1   1445 use DateTime;
  1         177981  
  1         675  
14              
15             =head1 NAME
16              
17             WWW::OPG::Scraper - Drop-in module using web page scraping
18              
19             =head1 VERSION
20              
21             Version 1.004 ($Id: Scraper.pm 10925 2010-01-10 20:27:32Z FREQUENCY@cpan.org $)
22              
23             =cut
24              
25             our $VERSION = '1.004';
26             $VERSION = eval $VERSION;
27              
28             =head1 SYNOPSIS
29              
30             use WWW::OPG::Scraper;
31              
32             my $opg = WWW::OPG::Scraper->new();
33             eval {
34             $opg->poll();
35             };
36             print "Currently generating ", $opg->power, "MW of electricity\n";
37              
38             =head1 DESCRIPTION
39              
40             This module was formerly the main interface provided in L. It
41             provides a Perl interface to information published on Ontario Power
42             Generation's web site at L by scraping the main page.
43              
44             =head1 METHODS
45              
46             =head2 new
47              
48             WWW::OPG::Scraper->new( \%params )
49              
50             Implements the interface as specified in C
51              
52             =cut
53              
54             sub new {
55 0     0 1   my ($class, $params) = @_;
56              
57 0 0         Carp::croak('You must call this as a class method') if ref($class);
58              
59 0           my $self = {
60             };
61              
62 0 0         if (exists $params->{useragent}) {
63 0           $self->{useragent} = $params->{useragent};
64             }
65             else {
66 0           my $ua = LWP::UserAgent->new;
67 0           $ua->agent(__PACKAGE__ . '/' . $VERSION . ' ' . $ua->_agent);
68 0           $self->{useragent} = $ua;
69             }
70              
71 0           bless($self, $class);
72 0           return $self;
73             }
74              
75             =head2 poll
76              
77             $opg->poll()
78              
79             Implements the interface as specified in C
80              
81             =cut
82              
83             sub poll {
84 0     0 1   my ($self) = @_;
85              
86 0 0         Carp::croak('You must call this method as an object') unless ref($self);
87              
88 0           my $ua = $self->{useragent};
89 0           my $r = $ua->get('http://www.opg.com/');
90              
91 0 0         Carp::croak('Error reading response: ' . $r->status_line)
92             unless $r->is_success;
93              
94 0 0         if ($r->content =~ m{
95             ([0-9]+),?([0-9]+)\ MW
96             }x)
97             {
98 0           $self->{power} = $1 . $2;
99              
100 0 0         if ($r->content =~ m{
101             Last\ updated:\ (\d+)/(\d+)/(\d+)\ (\d+):(\d+):(\d+)\ (AM|PM)
102             }x)
103             {
104 0           my $hour = $4;
105             # 12:00 noon and midnight are a special case
106 0 0         if ($hour == 12) {
    0          
107             # 12am is midnight
108 0 0         if ($7 eq 'AM') {
109 0           $hour = 0;
110             }
111             }
112             elsif ($7 eq 'PM') {
113 0           $hour += 12;
114             }
115              
116 0           my $dt = DateTime->new(
117             month => $1,
118             day => $2,
119             year => $3,
120             hour => $hour, # derived from $4
121             minute => $5,
122             second => $6,
123             time_zone => 'America/Toronto',
124             );
125              
126 0 0 0       if (!exists $self->{updated} || $self->{updated} != $dt)
127             {
128 0           $self->{updated} = $dt;
129 0           return 1;
130             }
131 0           return 0;
132             }
133             }
134              
135 0           die 'Error parsing response, perhaps the format has changed?';
136 0           return;
137             }
138              
139             =head2 power
140              
141             $opg->power()
142              
143             Implements the interface as specified in C
144              
145             =cut
146              
147             sub power {
148 0     0 1   my ($self) = @_;
149              
150 0 0         Carp::croak('You must call this method as an object') unless ref($self);
151              
152 0 0         return unless exists $self->{power};
153 0           return $self->{power};
154             }
155              
156             =head2 last_updated
157              
158             $opg->last_updated()
159              
160             Implements the interface as specified in C
161              
162             =cut
163              
164             sub last_updated {
165 0     0 1   my ($self) = @_;
166              
167 0 0         Carp::croak('You must call this method as an object') unless ref($self);
168              
169 0 0         return unless exists $self->{updated};
170 0           return $self->{updated};
171             }
172              
173             =head1 AUTHOR
174              
175             Jonathan Yu Ejawnsy@cpan.orgE
176              
177             =head1 SEE ALSO
178              
179             L
180              
181             =head1 SUPPORT
182              
183             Please file bugs for this module under the C distribution. For
184             more information, see L's perldoc.
185              
186             =head1 LICENSE
187              
188             This has the same copyright and licensing terms as L.
189              
190             =head1 DISCLAIMER OF WARRANTY
191              
192             The software is provided "AS IS", without warranty of any kind, express or
193             implied, including but not limited to the warranties of merchantability,
194             fitness for a particular purpose and noninfringement. In no event shall the
195             authors or copyright holders be liable for any claim, damages or other
196             liability, whether in an action of contract, tort or otherwise, arising from,
197             out of or in connection with the software or the use or other dealings in
198             the software.
199              
200             =cut
201              
202             1;