Skip to content

Commit 2f7198e

Browse files
committed
Completed the weather example using LWP and MOJO
1 parent 7350746 commit 2f7198e

File tree

3 files changed

+179
-1
lines changed

3 files changed

+179
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,5 +136,5 @@ Hopefully will work on older version too (as old as 5.10) and across diferent OS
136136
| Mojolicious |
137137
| Web Crawling |
138138
| Currency Converter | Completed |
139-
| Weather |
139+
| Weather | Completed |
140140
| Stock Price |
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env perl
2+
# We are using https://openweathermap.org/api for our purpose.
3+
4+
use strict;
5+
use warnings;
6+
use LWP::UserAgent;
7+
use IO::Socket::SSL;
8+
use JSON;
9+
use Carp;
10+
use Readonly;
11+
12+
Readonly my $BASE_URL => "https://api.openweathermap.org/data/2.5/";
13+
14+
# Add your APP ID here or in your shell environment and remove this line
15+
local $ENV{"APP_ID"} = "";
16+
17+
# This will return the fingerprint of the given hostname
18+
sub get_fingerprint {
19+
my ($dst) = @_;
20+
my $client = IO::Socket::SSL->new(
21+
PeerAddr => $dst,
22+
PeerPort => 443,
23+
24+
# certificate cannot be validated the normal way, so we need to
25+
# disable validation this one time in the hope that there is
26+
# currently no man in the middle attack
27+
SSL_verify_mode => 0,
28+
) or croak "connect failed";
29+
my $fp = $client->get_fingerprint;
30+
return $fp;
31+
}
32+
33+
sub get_data {
34+
my ($ua, $url) = @_;
35+
my $response = $ua->get($url);
36+
if ($response->is_success) {
37+
my $message = $response->decoded_content;
38+
my $json_response = JSON->new->ascii->pretty->encode(decode_json join '', $message);
39+
return $json_response;
40+
}
41+
else {
42+
croak $response->status_line;
43+
}
44+
}
45+
46+
sub get_current_weather_data {
47+
my ($ua, $parameters) = @_;
48+
my $url = URI->new($BASE_URL . "weather");
49+
$url->query_form(%{$parameters});
50+
print get_data($ua, $url);
51+
}
52+
53+
sub get_five_days_per_three_hour_forecast {
54+
my ($ua, $parameters) = @_;
55+
my $url = URI->new($BASE_URL . "forecast");
56+
$url->query_form(%{$parameters});
57+
print get_data($ua, $url);
58+
}
59+
60+
sub get_weather_by_one_call {
61+
my ($ua, $parameters) = @_;
62+
my $url = URI->new($BASE_URL . "onecall");
63+
$url->query_form(%{$parameters});
64+
print get_data($ua, $url);
65+
}
66+
67+
sub main {
68+
my $fp = get_fingerprint("api.openweathermap.org");
69+
my $ua = LWP::UserAgent->new(ssl_opts => {SSL_fingerprint => $fp});
70+
$ua->show_progress(1);
71+
72+
print "\n-->> Getting current weather data...\n";
73+
get_current_weather_data($ua,
74+
{"q" => "New Delhi", "units" => "metric", "appid" => $ENV{"APP_ID"}});
75+
76+
print "\n-->> Getting 5 days/3 hr forecast...\n";
77+
get_five_days_per_three_hour_forecast($ua, {"q" => "New Delhi", "appid" => $ENV{"APP_ID"}});
78+
79+
print "\n-->> Getting all weather data by one call api...\n";
80+
get_weather_by_one_call(
81+
$ua,
82+
{
83+
"lat" => "28.6139",
84+
"lon" => "77.2090",
85+
"exclude" => "hourly,daily",
86+
"appid" => $ENV{"APP_ID"}
87+
}
88+
);
89+
}
90+
91+
main;
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env perl
2+
# We are using https://openweathermap.org/api for our purpose.
3+
4+
use strict;
5+
use warnings;
6+
use Mojo::UserAgent;
7+
use Carp;
8+
use Readonly;
9+
10+
Readonly my $BASE_URL => "https://api.openweathermap.org/data/2.5/";
11+
12+
# Add your APP ID here or in your shell environment and remove this line
13+
local $ENV{"APP_ID"} = "";
14+
15+
# This will return the fingerprint of the given hostname
16+
sub get_fingerprint {
17+
my ($dst) = @_;
18+
my $client = IO::Socket::SSL->new(
19+
PeerAddr => $dst,
20+
PeerPort => 443,
21+
22+
# certificate cannot be validated the normal way, so we need to
23+
# disable validation this one time in the hope that there is
24+
# currently no man in the middle attack
25+
SSL_verify_mode => 0,
26+
) or croak "connect failed";
27+
my $fp = $client->get_fingerprint;
28+
return $fp;
29+
}
30+
31+
sub get_data {
32+
my ($ua, $url, $parameters) = @_;
33+
my $response = $ua->get($url => form => $parameters)->result;
34+
if ($response->is_success) {
35+
return $response->body;
36+
}
37+
else {
38+
croak $response->status_line;
39+
}
40+
}
41+
42+
sub get_current_weather_data {
43+
my ($ua, $parameters) = @_;
44+
my $url = $BASE_URL . "weather";
45+
print get_data($ua, $url, $parameters);
46+
}
47+
48+
sub get_five_days_per_three_hour_forecast {
49+
my ($ua, $parameters) = @_;
50+
my $url = $BASE_URL . "forecast";
51+
print get_data($ua, $url, $parameters);
52+
}
53+
54+
sub get_weather_by_one_call {
55+
my ($ua, $parameters) = @_;
56+
my $url = $BASE_URL . "onecall";
57+
print get_data($ua, $url, $parameters);
58+
}
59+
60+
sub main {
61+
my $ua = Mojo::UserAgent->new();
62+
63+
# This server certificate cannot be properly validated by normal means hence,
64+
# we are disabling TLS certificate verification.
65+
# There are other ways also like this - https://stackoverflow.com/a/35208289/2001559
66+
$ua->insecure(1);
67+
68+
print "\n-->> Getting current weather data...\n";
69+
get_current_weather_data($ua,
70+
{"q" => "New Delhi", "units" => "metric", "appid" => $ENV{"APP_ID"}});
71+
72+
print "\n-->> Getting 5 days/3 hr forecast...\n";
73+
get_five_days_per_three_hour_forecast($ua, {"q" => "New Delhi", "appid" => $ENV{"APP_ID"}});
74+
75+
print "\n-->> Getting all weather data by one call api...\n";
76+
get_weather_by_one_call(
77+
$ua,
78+
{
79+
"lat" => "28.6139",
80+
"lon" => "77.2090",
81+
"exclude" => "hourly,daily",
82+
"appid" => $ENV{"APP_ID"}
83+
}
84+
);
85+
}
86+
87+
main;

0 commit comments

Comments
 (0)