File Coverage

blib/lib/WWW/MelbourneBikeShare.pm
Criterion Covered Total %
statement 15 81 18.5
branch 0 14 0.0
condition 0 8 0.0
subroutine 5 25 20.0
pod 11 11 100.0
total 31 139 22.3


line stmt bran cond sub pod time code
1             package WWW::MelbourneBikeShare;
2              
3 1     1   13248 use strict;
  1         2  
  1         22  
4 1     1   3 use warnings;
  1         1  
  1         18  
5              
6 1     1   514 use LWP;
  1         31516  
  1         23  
7 1     1   651 use JSON;
  1         8191  
  1         3  
8 1     1   515 use WWW::MelbourneBikeShare::Terminal;
  1         1  
  1         607  
9              
10             our $VERSION = 0.01;
11              
12             sub new {
13 0     0 1   my ( $class, %args ) = @_;
14              
15 0           my $self = bless {}, $class;
16              
17 0           $self->__init( %args );
18              
19 0           return $self
20             }
21              
22             sub __init {
23 0     0     my ( $self, %args ) = @_;
24              
25 0           $self->{ __ua } = LWP::UserAgent->new();
26 0           $self->{ __uri } = 'https://data.melbourne.vic.gov.au/resource/qnjw-wgaj.json';
27 0   0       $self->{ __cache }->{ timeout } = $args{ cache } ||= 900;
28 0           $self->{ __cache }->{ present } = 0;
29 0           $self->{ __cache }->{ last_update } = 0;
30              
31 0           $self->__get_service_data;
32             }
33              
34             sub __cache_is_valid {
35 0     0     my $self = shift;
36              
37 0 0         $self->{ __cache }->{ present } or return 0;
38              
39             ( ( time - $self->{ __cache }->{ last_update } ) < $self->{ __cache }->{ timeout } )
40 0 0         or return 0
41             }
42              
43             sub __get_service_data {
44 0     0     my $self = shift;
45              
46 0 0         return if $self->__cache_is_valid;
47              
48 0           $self->__process_service_data(
49             $self->__get(
50             $self->__get_service_uri
51             )
52             );
53             }
54              
55             sub __process_service_data {
56 0     0     my ( $self, $d ) = @_;
57              
58 0           @{ $self->{ __cache }->{ data } } =
59 0           map { WWW::MelbourneBikeShare::Terminal->new( $_ ) } @{ $d };
  0            
  0            
60              
61 0           $self->{ __cache }->{ present } = 1;
62 0           $self->{ __cache }->{ last_update } = time;
63             }
64              
65             sub __get {
66 0     0     my ( $self, $url ) = @_;
67              
68 0           my $r = $self->{ __ua }->get( $url );
69              
70 0 0         if ( $r->is_success ) {
71 0           $self->{ error } = '';
72 0           return from_json( $r->content );
73             }
74             else {
75 0           $self->{ error } = "Unable to retrieve $url: "
76             . $r->status_line . "\n";
77 0           return 0
78             }
79             }
80              
81             sub __get_service_uri {
82 0     0     my $self = shift;
83              
84 0           return 'https://data.melbourne.vic.gov.au/resource/qnjw-wgaj.json';
85             }
86              
87             sub __data {
88 0     0     my $self = shift;
89              
90 0           $self->__get_service_data;
91              
92 0           return @{ $self->{ __cache }->{ data } }
  0            
93             }
94              
95             sub __sort_by {
96 0     0     my ( $self, $attr, @args ) = @_;
97              
98 0           my @t = map { $_->[0] }
99 0           sort { $a->[1] <=> $b->[1] }
100 0           map { [ $_, $_->$attr( @args ) ] }
  0            
101             $self->terminals;
102              
103             return @t
104 0           }
105              
106             sub __grep {
107 0     0     my ( $self, $var, $val ) = @_;
108              
109 0 0 0       $val and $var or return;
110              
111 0           for ( $self->terminals ) {
112 0 0         return $_ if $_->$var eq $val
113             }
114             }
115              
116             sub refresh {
117 0     0 1   $_->{ cache }->{ present } = 0
118             }
119              
120             sub terminals {
121 0     0 1   return $_[0]->__data
122             }
123              
124             sub id {
125 0     0 1   my ( $self, $id ) = @_;
126              
127 0           return $self->__grep( 'id', $id )
128             }
129              
130             sub terminal {
131 0     0 1   my ( $self, $terminal ) = @_;
132              
133 0           return $self->__grep( 'terminal', $terminal )
134             }
135              
136             sub by_distance {
137 0     0 1   my ( $self, $lat, $lon ) = @_;
138              
139 0 0 0       return unless $lat and $lon;
140              
141 0           return $self->__sort_by( 'distance', $lat, $lon );
142             }
143              
144             sub by_id {
145 0     0 1   my $self = shift;
146              
147 0           return $self->__sort_by( 'id' )
148             }
149              
150             sub by_terminal {
151 0     0 1   my $self = shift;
152              
153 0           return $self->__sort_by( 'terminal' )
154             }
155              
156             sub by_available_bikes {
157 0     0 1   my $self = shift;
158              
159 0           return reverse $self->__sort_by( 'bikes' )
160             }
161              
162             sub by_available_docks {
163 0     0 1   my $self = shift;
164              
165 0           return reverse $self->__sort_by( 'empty' )
166             }
167              
168             sub closest {
169 0     0 1   my ( $self, $lat, $lon ) = @_;
170              
171 0           return ( $self->by_distance( $lat, $lon ) )[0]
172             }
173              
174             1;
175              
176             __END__