Skip to content

Commit

Permalink
Enabled re-request on Unauthorized response
Browse files Browse the repository at this point in the history
  • Loading branch information
robin13 committed Sep 26, 2011
1 parent 7590483 commit a6a1b3f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Makefile.PL
Expand Up @@ -22,7 +22,7 @@ WriteMakefile(
'YAML' => 0,
'Carp' => 0,
'Text::CSV' => 0,
'Net::OAuth2::Client' => 0.09,
'Net::OAuth2::Client' => 0.10,
'File::HomeDir' => 0,
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
Expand Down
21 changes: 14 additions & 7 deletions bin/pfusion
Expand Up @@ -100,7 +100,7 @@ sub print_result {
my $result = shift;

my $output = '';

# A Text::Table separator
my $sep = {
is_sep => 1,
Expand Down Expand Up @@ -143,11 +143,15 @@ sub print_result {

# Somehow the Text::Table breaks the encoding again... :-/
$output = encode( 'utf8', $output );

if( $result->error ){
$output .= sprintf "Error: %s\n", $result->error;
}

# Add some information about the time taken
$output .= sprintf "%s line%s in %0.4fs (auth: %0.4fs)\n",
$result->num_rows,
( $result->num_rows > 1 ? 's' : '' ),
( $result->num_rows != 1 ? 's' : '' ),
$result->total_time,
$result->auth_time;
print $output;
Expand All @@ -164,6 +168,8 @@ sub local_command {
foreach my $result( @{ local_source( $1 ) } ){
printf "Success: %s\n", $result->query;
}
}elsif( $command =~ m/^refresh_token$/i ){
$fusion->get_fresh_access_token();
}else{
print "I don't know how to do that...\n";
}
Expand All @@ -173,14 +179,15 @@ sub local_command {
# The user called the local help command... give them some help baby!
sub print_local_help {
my %commands = (
help => 'show the internal commands',
quit => 'exit the application',
source => 'read in a source file',
'exit' => 'exit the application',
help => 'show the internal commands',
quit => 'exit the application',
source => 'read in a source file',
refresh_token => 'refresh access token',
'exit' => 'exit the application',
);
# All local commands start with a '.'
foreach( sort keys %commands ){
printf ".%-10s %s\n", $_, $commands{$_};
printf ".%-14s %s\n", $_, $commands{$_};
}
}

Expand Down
67 changes: 43 additions & 24 deletions lib/Google/Fusion.pm
Expand Up @@ -7,7 +7,7 @@ use HTTP::Request;
use URL::Encode qw/url_encode/;
use YAML qw/LoadFile DumpFile Dump/;
use Carp;
use Net::OAuth2::Client 0.09;
use Net::OAuth2::Client 0.10;
use Google::Fusion::Result;
use Text::CSV;
use Time::HiRes qw/time/;
Expand Down Expand Up @@ -114,6 +114,27 @@ has 'auth_client' => ( is => 'ro', required => 1, lazy => 1,
builder => '_build_auth_client',
);

# Local method to build the auth_client if it wasn't passed
sub _build_auth_client {
my $self = shift;

my %client_params = (
site_url_base => 'https://accounts.google.com/o/oauth2/auth',
access_token_url_base => 'https://accounts.google.com/o/oauth2/token',
authorize_url_base => 'https://accounts.google.com/o/oauth2/auth',
scope => 'https://www.google.com/fusiontables/api/query',
);
foreach( qw/refresh_token access_code access_token keep_alive token_store/ ){
$client_params{$_} = $self->$_ if defined $self->$_;
}
$client_params{id} = $self->client_id if $self->client_id;
$client_params{secret} = $self->client_secret if $self->client_secret;

# $self->logger->debug( "Initialising Client with:\n". Dump( \%client_params ) );
my $client = Net::OAuth2::Client->new( %client_params );
return $client;
}

=head1 SUBROUTINES/METHODS
=head2 query
Expand All @@ -126,6 +147,11 @@ Example:
my $text = $fusion->query( 'SELECT * FROM 123456' );
=cut
sub get_fresh_access_token {
my $self = shift;
$self->auth_client->get_fresh_access_token();
}

sub query {
my $self = shift;
my $sql = shift;
Expand All @@ -152,7 +178,10 @@ sub query {
total_time => $query_time + $auth_time,
);

if( $response->is_success ){
if( not $response->is_success ){
$result->error( sprintf "%s (%u)", $response->message, $response->code );
}else{
# Response was a success
# TODO: RCL 2011-09-08 Parse the actual error message from the response
# TODO: RCL 2011-09-08 Refresh access_key if it was invalid, or move that
# action to the Client?
Expand Down Expand Up @@ -195,27 +224,6 @@ sub query {
return $result;
}

# Local method to build the auth_client if it wasn't passed
sub _build_auth_client {
my $self = shift;

my %client_params = (
site_url_base => 'https://accounts.google.com/o/oauth2/auth',
access_token_url_base => 'https://accounts.google.com/o/oauth2/token',
authorize_url_base => 'https://accounts.google.com/o/oauth2/auth',
scope => 'https://www.google.com/fusiontables/api/query',
);
foreach( qw/refresh_token access_code access_token keep_alive token_store/ ){
$client_params{$_} = $self->$_ if defined $self->$_;
}
$client_params{id} = $self->client_id if $self->client_id;
$client_params{secret} = $self->client_secret if $self->client_secret;

# $self->logger->debug( "Initialising Client with:\n". Dump( \%client_params ) );
my $client = Net::OAuth2::Client->new( %client_params );
return $client;
}

sub query_or_cache {
my $self = shift;
my $sql = shift;
Expand All @@ -230,13 +238,24 @@ sub query_or_cache {
}
}
if( not $response ){
$response = $self->auth_client->post( 'https://www.google.com/fusiontables/api/query',
my @post_args = ( 'https://www.google.com/fusiontables/api/query',
HTTP::Headers->new( Content_Type => 'application/x-www-form-urlencoded' ),
sprintf( 'sql=%s&hdrs=%s',
url_encode( $sql ),
( $self->headers ? 'true' : 'false' ),
),
);


$response = $self->auth_client->post( @post_args );
# If the response was not Unauthorized, most likely is that the token is invalid
# Invalidate the current token, and try again
if( $response->code == 401 and $response->message eq 'Unauthorized' ){
# Make the token expire, so a new one is requested
$self->auth_client->get_fresh_access_token();
$response = $self->auth_client->post( @post_args );
}

if( $self->query_cache ){
DumpFile( $cache_file, $response );
}
Expand Down
1 change: 1 addition & 0 deletions lib/Google/Fusion/Result.pm
Expand Up @@ -57,6 +57,7 @@ Number of rows this result has (excluding headers)

has 'query' => ( is => 'ro', isa => 'Str', required => 1 );
has 'response' => ( is => 'ro', isa => 'HTTP::Response', required => 1 );
has 'error' => ( is => 'rw', isa => 'Str', );
has 'num_columns' => ( is => 'rw', isa => 'Int', required => 1, default => 0 );
has 'num_rows' => ( is => 'rw', isa => 'Int', required => 1, default => 0 );
has 'max_lengths' => ( is => 'rw', isa => 'ArrayRef', required => 1, default => sub{ [] } );
Expand Down

0 comments on commit a6a1b3f

Please sign in to comment.