File Coverage

blib/lib/Weather/YR/Base.pm
Criterion Covered Total %
statement 48 58 82.7
branch 6 16 37.5
condition 1 2 50.0
subroutine 11 11 100.0
pod 0 1 0.0
total 66 88 75.0


line stmt bran cond sub pod time code
1             package Weather::YR::Base;
2 3     3   2257 use Moose;
  3         10  
  3         22  
3 3     3   21353 use namespace::autoclean;
  3         10  
  3         28  
4              
5 3     3   280 use DateTime::Format::ISO8601;
  3         7  
  3         109  
6 3     3   31 use DateTime::TimeZone;
  3         7  
  3         107  
7 3     3   22 use DateTime;
  3         6  
  3         83  
8 3     3   4402 use LWP::UserAgent;
  3         135815  
  3         142  
9 3     3   36 use Mojo::URL;
  3         7  
  3         50  
10 3     3   2985 use XML::LibXML;
  3         103816  
  3         27  
11 3     3   3592 use XML::Simple;
  3         29497  
  3         37  
12              
13             has 'service_url' => (
14             isa => 'Mojo::URL',
15             is => 'ro',
16             lazy => 1,
17             default => sub { Mojo::URL->new('https://api.met.no') },
18             );
19              
20             has [ 'lat', 'lon', 'msl' ] => (
21             isa => 'Num',
22             is => 'rw',
23             required => 0,
24             default => 0,
25             );
26              
27             has 'xml' => (
28             isa => 'Maybe[Str]',
29             is => 'rw',
30             required => 0,
31             );
32              
33             has 'lang' => (
34             isa => 'Str',
35             is => 'rw',
36             required => 0,
37             default => 'en',
38             );
39              
40             has 'tz' => (
41             isa => 'DateTime::TimeZone',
42             is => 'rw',
43             required => 0,
44             default => sub { DateTime::TimeZone->new( name => 'UTC' ); },
45             );
46              
47             has 'ua' => (
48             isa => 'Object',
49             is => 'rw',
50             required => 0,
51             default => sub { LWP::UserAgent->new; },
52             );
53              
54             has 'xml_ref' => (
55             isa => 'Maybe[HashRef]',
56             is => 'ro',
57             lazy_build => 1,
58             );
59              
60             # Make sure that 'lat' and 'lon' is restricted to four decimals, ref.
61             # https://api.met.no/doc/TermsOfService#traffic
62             around [ 'lat', 'lon' ] => sub {
63             my $orig = shift;
64             my $self = shift;
65             my $value = shift || $self->$orig;
66              
67             $value = sprintf( '%0.4f', $value );
68              
69             return $self->$orig( $value );
70             };
71              
72             sub _build_xml_ref {
73 1     1   7 my $self = shift;
74              
75 1 50       36 unless ( length $self->xml ) {
76 0         0 my $response = $self->ua->get( $self->url->to_string );
77              
78 0 0       0 if ( $self->can('status_code') ) {
79 0         0 $self->status_code( $response->code );
80             }
81              
82 0 0       0 if ( $response->is_success ) {
83 0         0 $self->xml( $response->decoded_content );
84             }
85             else {
86 0         0 warn "Failed to GET data from " . $self->url->to_string;
87             }
88             }
89              
90 1 50       27 if ( length $self->xml ) {
91 1 50       7 if ( $self->can('schema_url') ) {
92 1         3 eval {
93 1         8 my $xml_doc = XML::LibXML->new->load_xml( string => $self->xml );
94 1         8141 my $response = $self->ua->get( $self->schema_url->to_string );
95 1         338907 my $schema = XML::LibXML::Schema->new( string => $response->decoded_content );
96              
97 1         10757 $schema->validate( $xml_doc );
98             };
99              
100 1 50       9 if ( $@ ) {
101 0         0 warn "Failed to validate the XML returned from YR.no using schema URL '" . $self->schema_url . "'; $@";
102             }
103             else {
104 1         4 my $result = undef;
105              
106 1         2 eval {
107 1         44 $result = XML::Simple::XMLin( $self->xml, ForceArray => 0 );
108             };
109              
110 1 50       299473 unless ( $@ ) {
111 1         59 return $result;
112             }
113             }
114             }
115             }
116             else {
117 0         0 warn "No XML to parse!";
118             }
119              
120             # Something failed!
121 0         0 return undef;
122             }
123              
124             sub date_to_datetime {
125 684     684 0 1133 my $self = shift;
126 684   50     1697 my $date = shift // '';
127              
128 684 50       1916 if ( length $date ) {
129 684         2527 $date = DateTime::Format::ISO8601->parse_datetime( $date );
130             }
131             else {
132 0         0 $date = DateTime->now;
133             }
134              
135 684         348086 $date->set_time_zone( $self->tz );
136              
137 684         232382 return $date;
138             }
139              
140             __PACKAGE__->meta->make_immutable;
141              
142             1;