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 )