RSS Git Download  Clone
Raw Blame History
package weather;

=begin
https://metacpan.org/pod/Dancer2::Cookbook#An-example:-Writing-API-interfaces

usage: plackup -p 5000 -L Shotgun <app_name>
    https://volvox.uk:5000/<city>[/<country]>
or direct url:
	https://weather.volvox.uk/<city>[/<country>]
=cut

use JSON;
use IO::All;
use Dancer2;
use HTTP::Tiny;
use File::Spec;
use Data::Printer;
use Data::Dumper::Concise;

# warn app->environment;

set template => 'template_toolkit';  # set template engine
set layout   => undef;               # disable layout
# custom error template:
set error_template => 'error.tt';
# env-dependent settings (full path to views):
if ( app->environment eq 'production' ) {
    my $app_dir = File::Spec->rel2abs('..'); # relative to <app-dir>/public
    set logger => 'File';
    set views  => $app_dir;
    set log    => 'warning';
    # set log_dir - override '/tmp' setting in config.yml:
    config->{engines}->{logger}->{File}->{log_dir} = $app_dir;
}
else {
	set log    => 'debug';
    set logger => 'Console::Colored';
    set views  => File::Spec->rel2abs('.'); # same as config->{appdir}
}

hook before => sub { # p my $c = config;
    # io('/home/raj/apps/debug.txt')->append(Dumper \%ENV);
};

get '/' => sub {
    my $location = query_parameters->get('location') || 'leeds'; debug $location;
    # send_error 'usage: http://openweather.mine.nu/<city>[/<country]>', 418;
    forward '/' . $location;
};

# if both city & country passed:
any ['get', 'post'] => '/:city/:country' => sub { # set country var & forward
    var country => route_parameters->get('country'); debug var 'country';
    forward '/' . route_parameters->get('city');
};

any ['get', 'post'] => '/:city' => sub {
    my $city = route_parameters->get('city'); debug $city;
	# use METAR button to force checkwx api:
	my $want_metar = query_parameters->get('.metar'); debug $want_metar;
	
	# if 'city' is 4 digits & submitted with 'METAR' button then use checkwx api 
	# otherwise use openweathermap:
	if ( length($city) == 4 && $want_metar ) { # city is ICDO - use checkwx api:
		my $api = config->{api}->{checkwxapi}; # p $api;
		# warn '#' x 30;
		my $url = sprintf $api->{url}, uc $city, $api->{key};  debug $url;
		my $res = do_api_call($url); # p $res; # HoA
		# returns HoA (keys = data,result), only want array 0 of key 'data'
		template metar => { data => $res->{data}->[0] }; 
	}
	else { # use openweathermap api:
		my $api = config->{api}->{openweathermap}; # p $api;
		# warn '#' x 30;
		my %h;
		for my $status ( qw/weather forecast/ ) {
			# append city, or city & country to uri:
			my $q = ( var 'country' )
				? join ',', $city, var 'country'
				: $city;
			my $url = sprintf $api->{url}, $status, $api->{key}, $q; debug $url;
			# fetch data
			my $data = do_api_call($url);
			$h{$status}{data} = $data;
		}
		# return view:
		template weather => { data => \%h };
	}
};

# default 404 page:
any qr{.*} => sub { 'no content' };

sub do_api_call {
	my $url = shift;
	
	my $res = HTTP::Tiny->new->get($url);   # p $res;
	my $data = decode_json $res->{content}; # p $data;
	return $data;
}

dance;