From fa77e6c1b2eb526ab79a708ed8d04824c28f7445 Mon Sep 17 00:00:00 2001 From: dakkar Date: Thu, 16 May 2013 21:01:28 +0100 Subject: modularise forceast client --- forecast.pl | 27 +++++--------- lib/WebService/ForecastIo.pm | 85 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 lib/WebService/ForecastIo.pm diff --git a/forecast.pl b/forecast.pl index a3dd7d6..5d78906 100644 --- a/forecast.pl +++ b/forecast.pl @@ -2,30 +2,21 @@ use strict; use warnings; use 5.014; -use LWP::Simple; -use URI; +use WebService::ForecastIo; use JSON; use Data::Printer; my $key=$ARGV[0]; -my $base = URI->new('https://api.forecast.io/forecast'); - -sub URI::path_segments_push { - my ($uri,@segments) = @_; - $uri->path_segments($uri->path_segments,@segments); -} - -# home -$base->path_segments_push( - $key,"51.54,-0.37", -); -$base->query_form({ - units => 'si', - exclude => 'minutely,flags', +my $fio = WebService::ForecastIo->new({ + api_key => $key, }); -my $content = get($base); +my $response = $fio->request({ + latitude => 51.54, + longitude => -0.37, + exclude => ['minutely','flags'], +}); -my $output = decode_json($content); +my $output = decode_json($response); p $output; diff --git a/lib/WebService/ForecastIo.pm b/lib/WebService/ForecastIo.pm new file mode 100644 index 0000000..fd6bcb8 --- /dev/null +++ b/lib/WebService/ForecastIo.pm @@ -0,0 +1,85 @@ +package WebService::ForecastIo; +use Moose; +use MooseX::Types::URI 'Uri'; +use MooseX::Params::Validate; +use Moose::Util::TypeConstraints; + +has base_uri => ( + is => 'ro', + isa => Uri, + coerce => 1, + default => 'https://api.forecast.io/forecast', +); + +has api_key => ( + is => 'ro', + isa => 'Str', + required => 1, +); + +has user_agent => ( + is => 'ro', + isa => duck_type(['get']), + lazy_build => 1, +); +sub _build_user_agent { + require LWP::UserAgent; + my $agent = LWP::UserAgent->new( + agent => __PACKAGE__ . ' version ' . ($WebService::ForecastIo::VERSION // 'devel' ), + env_proxy => 1, + keep_alive => 1, + ); + $agent->default_header( 'Accept-Encoding' => 'gzip' ); + return $agent; +} + +sub _make_request_uri { + my ($self,%opts) = @_; + + my ($lat,$lon,$time) = delete @opts{qw(latitude longitude time)}; + + my $req_uri = $self->base_uri->clone; + $req_uri->path_segments( + grep { length($_)>0 } + $req_uri->path_segments, + $self->api_key, + "$lat,$lon", + ( defined $time ? $time : () ), + ); + + if ($opts{exclude}) { + $opts{exclude} = join ',',@{$opts{exclude}}; + } + + $req_uri->query_form(\%opts); + + return $req_uri; +} + +enum my $units_type=__PACKAGE__.'::units', + [qw(us si ca uk auto)]; +enum my $block_type=__PACKAGE__.'::block', + [qw(currently minutely hourly daily alerts flags)]; + +sub request { + my ($self,%opts) = validated_hash( + \@_, + latitude => { isa => 'Num' }, + longitude => { isa => 'Num' }, + time => { isa => 'Num|Str', optional => 1 }, + units => { isa => $units_type, default => 'si' }, + exclude => { isa => "ArrayRef[$block_type]", default => sub { [] } }, + ); + + my $uri = $self->_make_request_uri(%opts); + + my $response = $self->user_agent->get($uri); + if ($response->is_success) { + return $response->decoded_content; + } + else { + die $response->status_line + } +} + +1; -- cgit v1.2.3