——package
Weather::OpenWeatherMap::Request;
$Weather::OpenWeatherMap::Request::VERSION
=
'0.001004'
;
# TRIAL
use
v5.10;
use
strictures 1;
use
Carp;
use
Types::Standard -all;
use
Types::DateTime -all;
use
HTTP::Request;
sub
new_for {
my
(
$class
,
$type
) =
splice
@_
, 0, 2;
confess
"Expected a subclass type"
unless
$type
;
my
$subclass
=
$class
.
'::'
.
ucfirst
(
$type
);
use_module(
$subclass
)->new(
@_
)
}
=pod
=for Pod::Coverage has_\w+
=cut
has
api_key
=> (
lazy
=> 1,
is
=>
'ro'
,
isa
=> Str,
predicate
=> 1,
builder
=>
sub
{
''
},
);
has
tag
=> (
lazy
=> 1,
is
=>
'ro'
,
predicate
=> 1,
builder
=>
sub
{
''
},
);
has
location
=> (
required
=> 1,
is
=>
'ro'
,
isa
=> Str,
);
has
ts
=> (
is
=>
'ro'
,
isa
=> StrictNum,
builder
=>
sub
{
time
},
);
has
url
=> (
init_arg
=>
undef
,
lazy
=> 1,
is
=>
'ro'
,
isa
=> Str,
builder
=>
sub
{
shift
->_parse_location_str },
);
has
http_request
=> (
lazy
=> 1,
is
=>
'ro'
,
isa
=> InstanceOf[
'HTTP::Request'
],
builder
=>
sub
{
my
(
$self
) =
@_
;
my
$req
= HTTP::Request->new(
GET
=>
$self
->url );
$req
->header(
'x-api-key'
=>
$self
->api_key )
if
$self
->has_api_key and
length
$self
->api_key;
$req
},
);
has
_units
=> (
required
=> 1,
is
=>
'ro'
,
isa
=> Str,
builder
=>
sub
{
'imperial'
},
);
sub
_url_bycode {
my
(
$self
,
$code
) =
@_
;
. uri_escape_utf8(
$code
)
.
'&units='
.
$self
->_units
}
sub
_url_bycoord {
my
$self
=
shift
;
my
(
$lat
,
$long
) =
map
{; uri_escape_utf8(
$_
) }
@_
;
"http://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$long"
.
'&units='
.
$self
->_units
}
sub
_url_byname {
my
(
$self
,
@parts
) =
@_
;
.
join
(
','
,
map
{; uri_escape_utf8(
$_
) }
@parts
)
.
'&units='
.
$self
->_units
}
sub
_parse_location_str {
my
(
$self
) =
@_
;
state
$latlong
=
qr{\Alat(?:itude)?\s+?(-?[0-9.]+),?\s+?long?(?:itude)?\s+?(-?[0-9.]+)}
;
my
$str
=
$self
->location;
my
$url
;
URL: {
if
(is_StrictNum
$str
) {
$url
=
$self
->_url_bycode(
$str
);
last
URL
}
if
(
my
(
$lat
,
$lon
) =
$str
=~
$latlong
) {
$url
=
$self
->_url_bycoord(
$lat
,
$lon
);
last
URL
}
my
@parts
=
split
/,\s+?/,
$str
;
$url
=
$self
->_url_byname(
@parts
);
}
$url
}
1;
=pod
=head1 NAME
Weather::OpenWeatherMap::Request - Weather lookup request superclass
=head1 SYNOPSIS
# Normally generated via Weather::OpenWeatherMap
# (when a request is made)
=head1 DESCRIPTION
This is the parent class for request objects generated by
L<Weather::OpenWeatherMap>.
See also:
L<Weather::OpenWeatherMap::Request::Current>
L<Weather::OpenWeatherMap::Request::Forecast>
=head2 ATTRIBUTES
=head3 api_key
The L<OpenWeatherMap API key|http://www.weathermap.org/api> attached to this
request.
=head3 location
B<Required:>
The location string, used to (lazily) generate the L</http_request> and L</url>
attributes.
Locations can be specified in various ways.
Strings such as 'City, State' or 'City, Country' will be parsed appropriately.
A numeric location is taken to be an
L<OpenWeatherMap|http://www.openweathermap.org> city code.
A string in the form of 'lat X, long Y' or 'latitude X, longitude Y' is also
accepted.
=head3 tag
An (optional) arbitrary scalar attached to the request object at construction
time.
=head3 http_request
The (generated) L<HTTP::Request> object used to request the weather data.
=head3 ts
The C<time()> the request object was created.
=head3 url
The (generated) L<OpenWeatherMap|http://www.openweathermap.org/> URL.
=head2 METHODS
=head3 new_for
Factory method; returns a new object belonging to the appropriate subclass:
my $request = Weather::OpenWeatherMap::Request->new_for(
Current =>
api_key => $api_key,
location => $location,
tag => $tag,
);
=head1 AUTHOR
Jon Portnoy <avenj@cobaltirc.org>
=cut