Skip to content

Instantly share code, notes, and snippets.

@mlampret
Last active December 18, 2015 07:38
Show Gist options
  • Save mlampret/5747755 to your computer and use it in GitHub Desktop.
Save mlampret/5747755 to your computer and use it in GitHub Desktop.
Mojolicious::Plugin::GoogleCalc - currency converter with cache
package Mojolicious::Plugin::GoogleCalc;
use Mojo::Base 'Mojolicious::Plugin';
use Mojo::ByteStream;
use Mojo::Loader;
use Mojo::JSON 'j';
use Mojo::ByteStream 'b';
use Mojo::UserAgent;
use strict;
my $app=undef;
my $c=undef;
my $conf=undef;
sub register {
my ($self, $app_param, $args) = @_;
$app=$app_param;
$conf=$args;
$app->helper(
'google_calc' => sub {
my $self = shift;
my $class_name = shift;
$class_name ||= 'Mojolicious::Plugin::GoogleCalc';
unless ($class_name =~ m/[A-Z]/) {
my $namespace = ref($self->app) . '::';
$namespace = '' if $namespace =~ m/^Mojolicious::Lite/;
$class_name = join '' => $namespace, Mojo::ByteStream->new($class_name)->camelize;
}
my $e = Mojo::Loader->new->load($class_name);
Carp::croak qq/Can't load validator '$class_name': / . $e->message if ref $e;
Carp::croak qq/Can't find validator '$class_name'/ if $e;
Carp::croak qq/Wrong validator '$class_name' isa/ unless $class_name->isa($class_name);
return $class_name->new(%$conf, @_);
}
);
}
sub convert_currency {
my $self = shift;
my ($params)=@_;
$params={} unless (ref $params eq 'HASH');
my $response_json=undef;
my $cache=undef;
$self->{conf}=$conf;
if ($self->{conf}->{cache_file}) {
unless (-f $self->{conf}->{cache_file}) {
warn "Creating cache file: $self->{conf}->{cache_file}" if ($params->{debug});
open(CACHE_FILE,">$self->{conf}->{cache_file}");
close(CACHE_FILE);
}
use Cache::FastMmap;
$cache = Cache::FastMmap->new(
share_file => $self->{conf}->{cache_file},
expire_time => $self->{conf}->{cache_expire_time} || 3600 * 6,
);
$response_json=$cache->get('convert_curency:response:'.$params->{from}.":".$params->{to});
warn "Cache content:" if ($params->{debug});
warn $app->dumper( $response_json ) if ($params->{debug});
}
unless ($response_json) {
warn "Will retrieve data from Google" if ($params->{debug});
my $calc_url='http://www.google.com/ig/calculator'
."?q=1".$params->{from}."=?".$params->{to};
my $ua = Mojo::UserAgent->new;
$ua->max_redirects(5);
my $google_response = $ua->get($calc_url)->res->body;
my $google_response_fixed = $google_response;
$google_response_fixed =~s!([,{]{1})(\S+?)\:!$1"$2":!isg;
$response_json=j($google_response_fixed);
$response_json->{ratio}=$response_json->{rhs};
$response_json->{ratio}=~s!\s.+$!!;
if ($cache) {
$cache->set('convert_curency:response:'.$params->{from}.":".$params->{to}, $response_json);
warn "Data cached" if ($params->{debug});
}
}
$response_json->{amount}=$response_json->{ratio}*$params->{amount};
warn "Full data: " if ($params->{debug});
warn $app->dumper( $response_json ) if ($params->{debug});
return $response_json->{amount};
}
1;
=comment
$self->plugin('GoogleCalc', {
cache_file => '/tmp/razdalje_google_calc.shm', # optional, requires Cache::FastMmap;
expire_time => 3600 * 6, # optional
});
$self->google_calc->convert_currency({ from=>'USD', to=>'EUR', amount=>123, debug=>1 });
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment