Data-OFAC
view release on metacpan or search on metacpan
lib/Data/OFAC/SDN.pm view on Meta::CPAN
use Data::OFAC::SDN::Schema;
use constant { SDNURL => 'http://www.treasury.gov/ofac/downloads/sdall.zip' };
sub new {
my $class = shift;
my %args = @_;
my $self = bless {}, $class;
while ( my ( $key, $value ) = each %args ) {
$self->{$key} = $value;
}
# This logic is probably convoluted.
my $databaseupdated;
$databaseupdated = -1 unless ( -f $self->{p}->{database_file} );
$self->{db}
= Data::OFAC::SDN::Schema->connect(
"dbi:SQLite:" . $self->{p}->{database_file} )
unless defined $self->{db};
if ( defined $databaseupdated && $databaseupdated == -1 ) {
# Force database update if no file is present.
$self->updateDatabase;
$databaseupdated = 1;
}
$self->{_lastupdate} = (stat($self->{p}->{database_file}))[9];
unless ( defined $databaseupdated || $self->{p}->{auto_update} eq '0' ) {
my $lupdate = $self->{db}->resultset('Lastupdate')
->search( {}, { order_by => 'LASTUPDATEDATETIME' } );
my $lastupdate = $lupdate->single;
if ( defined $lastupdate
&& ( time() - $lastupdate->lastupdatedatetime )
>= ( $self->{p}->{auto_update_frequency} * 3600 ) )
{
$self->updateDatabase();
}
return $self;
}
unless ( $self->{_status} && $self->{_status} eq 'dirty') {
$self->{_status} = 'clean';
}
return $self;
}
sub updateDatabase {
my $self = shift;
my $lwp = LWP::UserAgent->new();
$lwp->timeout(10);
$lwp->env_proxy;
my $rsp = $lwp->get(SDNURL);
if ( $rsp->is_success ) {
$self->buildDatabase( $rsp->decoded_content );
}
else {
$self->{_status} = 'dirty';
}
return 1;
}
sub buildDatabase {
my $self = shift;
my $zip = shift;
if ( $^O eq 'MSWin32' ) {
$self->{tempdir} = $ENV{TEMP} . '/';
}
else {
# Seriously? WTF People?
$self->{tempdir} = ($ENV{TMPDIR} || '/tmp') . '/';
}
my $sdnzip = ( $self->{tempdir} || '/tmp/' ) . "sdn.zip";
open( my $fh, ">", $sdnzip )
or die "Could not open file: " . $!;
binmode $fh;
print $fh $zip;
close $fh;
my $sdnfiles = ( $self->{tempdir} || '/tmp/' );
my $ae = Archive::Extract->new( archive => $sdnzip );
$ae->extract( to => $sdnfiles );
# Files are not always cased properly, determine the actual files here
map { $self->{_z}->{lc($_)} = $_ } @{$ae->files};
map { $self->{_f}->{$_} = $self->{_z}->{$_} } qw{ sdn.csv sdn_comments.csv add.csv alt.csv};
unless ( scalar keys %{$self->{_f}} == 4 ) { # Exactly four needed
$self->{_status} = 'dirty';
return; # Abort
}
# Changed to set up a temporary database to make the swap out quick.
$self->{dbh}
= DBI->connect( 'dbi:SQLite:' . ( $self->{p}->{database_file} ) . '_temp',
( run in 0.627 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )