package weather; =begin https://metacpan.org/pod/Dancer2::Cookbook#An-example:-Writing-API-interfaces usage: plackup -p 5000 -L Shotgun https://volvox.uk:5000/[/ or direct url: https://weather.volvox.uk/[/] =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 /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/[/', 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;