3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-13 23:49:31 +01:00
pbot/lib/PBot/Plugin/Weather.pm

129 lines
3.6 KiB
Perl
Raw Normal View History

# File: Weather.pm
#
2021-07-11 00:00:22 +02:00
# Purpose: Weather command. See Wttr.pm for a more featureful command.
2021-07-11 00:00:22 +02:00
# SPDX-FileCopyrightText: 2021 Pragmatic Software <pragma78@gmail.com>
# SPDX-License-Identifier: MIT
2021-07-14 04:45:56 +02:00
package PBot::Plugin::Weather;
use parent 'PBot::Plugin::Base';
2021-06-19 06:23:34 +02:00
use PBot::Imports;
2021-07-24 04:22:25 +02:00
use PBot::Core::Utils::LWPUserAgentCached;
use XML::LibXML;
sub initialize {
2020-02-15 23:38:32 +01:00
my ($self, %conf) = @_;
$self->{pbot}->{commands}->add(
name => 'weather',
help => 'Provides weather service via AccuWeather',
subref => sub { $self->cmd_weather(@_) },
);
}
sub unload {
2020-02-15 23:38:32 +01:00
my $self = shift;
$self->{pbot}->{commands}->remove('weather');
}
sub cmd_weather {
my ($self, $context) = @_;
2021-07-31 00:01:38 +02:00
2020-05-20 23:19:10 +02:00
my $usage = "Usage: weather (<location> | -u <user account>)";
2020-02-15 23:38:32 +01:00
my $arguments = $context->{arguments};
2021-07-31 00:01:38 +02:00
my %opts;
2020-02-15 23:38:32 +01:00
2021-07-31 00:01:38 +02:00
my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
$arguments,
\%opts,
['bundling'],
'u=s',
'h',
2020-02-15 23:38:32 +01:00
);
2021-07-31 00:01:38 +02:00
return $usage if $opts{h};
return "/say $opt_error -- $usage" if defined $opt_error;
$arguments = "@$opt_args";
my $user_override = $opts{u};
2020-02-15 23:38:32 +01:00
if (defined $user_override) {
my $userdata = $self->{pbot}->{users}->{storage}->get_data($user_override);
return "No such user account $user_override." if not defined $userdata;
return "User account does not have `location` set." if not exists $userdata->{location};
$arguments = $userdata->{location};
} else {
if (not length $arguments) {
$arguments = $self->{pbot}->{users}->get_user_metadata($context->{from}, $context->{hostmask}, 'location') // '';
}
}
2020-02-15 23:38:32 +01:00
if (not length $arguments) { return $usage; }
return $self->get_weather($arguments);
}
sub get_weather {
2020-02-15 23:38:32 +01:00
my ($self, $location) = @_;
2020-02-15 23:38:32 +01:00
my %cache_opt = (
'namespace' => 'accuweather',
'default_expires_in' => 3600
);
2021-07-24 04:22:25 +02:00
my $ua = PBot::Core::Utils::LWPUserAgentCached->new(\%cache_opt, timeout => 10);
2020-02-15 23:38:32 +01:00
my $response = $ua->get("http://rss.accuweather.com/rss/liveweather_rss.asp?metric=0&locCode=$location");
2020-02-15 23:38:32 +01:00
my $xml;
2020-02-15 23:38:32 +01:00
if ($response->is_success) { $xml = $response->decoded_content; }
else { return "Failed to fetch weather data: " . $response->status_line; }
2020-02-15 23:38:32 +01:00
my $dom = XML::LibXML->load_xml(string => $xml);
2020-02-15 23:38:32 +01:00
my $result = '';
2020-02-15 23:38:32 +01:00
foreach my $channel ($dom->findnodes('//channel')) {
my $title = $channel->findvalue('./title');
my $description = $channel->findvalue('./description');
2020-02-15 23:38:32 +01:00
if ($description eq 'Invalid Location') {
return
"Location $location not found. Use \"<city>, <country abbrev>\" (e.g. \"paris, fr\") or a US Zip Code or \"<city>, <state abbrev>, US\" (e.g., \"austin, tx, us\").";
}
2020-02-15 23:38:32 +01:00
$title =~ s/ - AccuW.*$//;
$result .= "Weather for $title: ";
}
2020-02-15 23:38:32 +01:00
foreach my $item ($dom->findnodes('//item')) {
my $title = $item->findvalue('./title');
my $description = $item->findvalue('./description');
if ($title =~ m/^Currently:/) {
$title = $self->fix_temps($title);
$result .= "$title; ";
}
if ($title =~ m/Forecast$/) {
$description =~ s/ <img.*$//;
$description = $self->fix_temps($description);
$result .= "Forecast: $description";
last;
}
}
2020-02-15 23:38:32 +01:00
return $result;
}
sub fix_temps {
2020-02-15 23:38:32 +01:00
my ($self, $text) = @_;
$text =~ s|(-?\d+)\s*F|my $f = $1; my $c = ($f - 32 ) * 5 / 9; $c = sprintf("%.1d", $c); "${c}C/${f}F"|eg;
2020-02-15 23:38:32 +01:00
return $text;
}
1;