Skip to content

Instantly share code, notes, and snippets.

@jacoby
Last active October 27, 2018 20:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacoby/38c52feba770d71951b6aeef292ea72f to your computer and use it in GitHub Desktop.
Save jacoby/38c52feba770d71951b6aeef292ea72f to your computer and use it in GitHub Desktop.
My Google API-interfacing code
package GoogleGeo;
# interfaces with Google Geolcation API
# https://developers.google.com/maps/documentation/geolocation/intro
use strict;
use warnings;
use utf8;
use feature qw{ postderef say signatures state };
no warnings qw{ experimental::postderef experimental::signatures };
use Carp;
use Data::Dumper;
use Exporter qw(import);
use Getopt::Long;
use JSON::XS;
use LWP::Protocol::https;
use LWP::UserAgent;
our @EXPORT = qw{
geocode
geolocate
timezone
};
my $json = JSON::XS->new->pretty;
my $agent = LWP::UserAgent->new;
sub timezone ( $Google_API_key, $obj ) {
croak unless defined $Google_API_key;
my $url = 'https://maps.googleapis.com/maps/api/timezone/json?key='
. $Google_API_key;
my $latlng = join ',', $obj->{lat}, $obj->{lng};
$url .= '&location=' . $latlng;
$url .= '&timestamp=' . $obj->{time};
my $r = $agent->post($url);
if ( $r->is_success ) {
my $j = $r->content;
my $o = $json->decode($j);
return $o;
}
return {};
}
sub geocode ( $Google_API_key, $obj ) {
croak unless defined $Google_API_key;
my $url = 'https://maps.googleapis.com/maps/api/geocode/json?key='
. $Google_API_key;
my $latlng = join ',', $obj->{lat}, $obj->{lng};
$url .= '&latlng=' . $latlng;
my $object = { latlng => $latlng };
my $r = $agent->post($url);
if ( $r->is_success ) {
my $j = $r->content;
my $o = $json->decode($j);
return $o;
}
return {};
}
sub geolocate ($Google_API_key) {
my $url = 'https://www.googleapis.com/geolocation/v1/geolocate?key='
. $Google_API_key;
my $object = {};
my $r = $agent->post( $url, $object );
if ( $r->is_success ) {
my $j = $r->content;
my $o = $json->decode($j);
return {
lat => $o->{location}{lat},
lng => $o->{location}{lng},
acc => $o->{accuracy},
};
}
return {};
}
'here';
#!/usr/bin/env perl
# Determines current location based on IP address using Google
# Geolocation, finds current temperature via the DarkSky API
# and stores it into a YAML file, so that get_temp.pl can be
# in the bash prompt to display current local temperature.
use strict ;
use warnings ;
use utf8 ;
use feature qw{ postderef say signatures state } ;
no warnings qw{ experimental::postderef experimental::signatures } ;
use Carp ;
use Data::Dumper ;
use DateTime ;
use IO::Interactive qw{ interactive } ;
use JSON::XS ;
use YAML::XS qw{ DumpFile LoadFile } ;
use lib $ENV{ HOME } . '/lib' ;
use GoogleGeo ;
my $json = JSON::XS->new->pretty->canonical ;
my $config = config() ;
my $location = geolocate( $config->{ geolocate } ) ;
croak 'No Location Data' unless $location->{ lat } ;
my $forecast = get_forecast( $config, $location ) ;
croak 'No Location Data' unless $forecast->{ currently } ;
my $current = $forecast->{ currently } ;
say { interactive } $json->encode( $location ) ;
say { interactive } $json->encode( $current ) ;
my $now = DateTime->now()->set_time_zone( 'America/New_York' )->datetime() ;
my $temp_f = int $current->{ temperature } ;
my $icon = $current->{ icon } ;
my $summary = $current->{ summary } ;
store( $now, $temp_f, $icon, $summary ) ;
exit ;
# ======================================================================
# Reads configuration data from YAML files. Dies if no valid config files
sub config {
my $geofile = $ENV{ HOME } . '/.googlegeo.yaml' ;
croak 'no Geolocation config' unless -f $geofile ;
my $keys = LoadFile( $geofile ) ;
my $forecastfile = $ENV{ HOME } . '/.forecast.yaml' ;
croak 'no forecast config' unless -f $forecastfile ;
my $fkeys = LoadFile( $forecastfile ) ;
$keys->{ forecast } = $fkeys->{ apikey } ;
croak 'No forecast key' unless $keys->{ forecast } ;
croak 'No forecast key' unless $keys->{ geolocate } ;
return $keys ;
}
# ======================================================================
# Takes the config for the API keys and the location, giving us lat and lng
# returns the forecast object or an empty hash if failing
sub get_forecast {
my ( $config, $location ) = @_ ;
my $url =
'https://api.darksky.net/forecast/'
. $config->{ forecast } . '/'
. ( join ',', map { $location->{ $_ } } qw{ lat lng } ) ;
my $agent = LWP::UserAgent->new( ssl_opts => { verify_hostname => 0 } ) ;
my $response = $agent->get( $url ) ;
if ( $response->is_success ) {
my $content = $response->content ;
my $forecast = decode_json $content ;
return $forecast ;
}
return {} ;
}
sub store ( $time, $temp, $icon, $summary ) {
say { interactive } qq{Current Time: $time} ;
say { interactive } qq{Current Temperature: $temp} ;
say { interactive } qq{Current Icon: $icon} ;
say { interactive } qq{Current Summary: $summary} ;
my $data_file = $ENV{ HOME } . '/.temp.yaml' ;
my $obj = {
curr_time => $time,
curr_temp => $temp,
curr_icon => $icon,
curr_summ => $summary,
} ;
DumpFile( $data_file, $obj ) ;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment