WebService-MODIS

 view release on metacpan or  search on metacpan

lib/WebService/MODIS.pm  view on Meta::CPAN

### method for download

sub download {
    my $self = shift;
    my $arg  = shift;
    $self->{targetDir} = $arg if ($arg);
    $arg = shift;
    $self->{forceReload} = $arg if ($arg);

    my $nUrl = @{$self->{url}};

    $self->createUrl if ($nUrl == 0);
    $nUrl = @{$self->{url}};

    if (! -d $self->{targetDir}) {
        make_path($self->targetDir) or croak "Cannot create directory '$self->{targetDir}': $!\n";
    }

    # adjusted from http://stackoverflow.com/questions/6813726/continue-getting-a-partially-downloaded-file
    my $ua = LWP::UserAgent->new(cookie_jar => HTTP::Cookies->new());

    for (my $i=0; $i < $nUrl; $i++) {
        my $file = $self->{targetDir}."/".basename(@{$self->{url}}[$i]);
        unlink($file) if ($self->{forceReload} && -f $file);
        open(my $fh, '>>:raw', $file) or croak "Cannot open '$file': $!\n";
        my $bytes = -s $file;
        my $res;
        if ( $bytes && ! $self->{forceReload}) {
            #print "resume ${$self->{url}}[$i] -> $file ($bytes) " if ($verbose);
            $res = $ua->get(
                ${$self->{url}}[$i],
                'Range' => "bytes=$bytes-",
                ':content_cb' => sub { my ( $chunk ) = @_; print $fh $chunk; }
                );
        } else {
            #print "$URL[$i] -> $destination[$i] " if ($verbose);
            $res = $ua->get(
                ${$self->{url}}[$i],
                ':content_cb' => sub { my ( $chunk ) = @_; print $fh $chunk; }
                );
        }
        close $fh;

        my $status = $res->status_line;
        if ( $status =~ /^(200|206|416)/ ) {
            #print "OK\n" if ($verbose && $status =~ /^20[06]/);
            #print "already complete\n" if ($verbose && $status =~ /^416/);
        } else {
            print "Unknown STATUS: '$status'!\n";
        }
    }
}

###################################################
###################################################
### Internal functions 

### retrieve a list of available MODIS Products
### and return a hash with the name of the first subdirectory 
sub getAvailProducts () {
    my $caller = (caller)[0];
    carp "This is an internal WebService::MODIS function. You should know what you are doing." if ($caller ne "WebService::MODIS");

    my %lookupTable = ();
    my $ua = new LWP::UserAgent;
    foreach my $subdir (@DATA_DIR) {
        my $response = $ua->get("${BASE_URL}/${subdir}");

        unless ($response->is_success) {
            die $response->status_line;
        }

        my $content = $response->decoded_content();
        my @content = split("\n", $content);
        foreach (@content) {
            next if (!/href="M/);
            s/.*href="//;
            s/\/.*//;

            print "Key already exists\n" if exists $lookupTable{$_};
            print "Key already defined\n" if defined $lookupTable{$_};
            print "True\n" if $lookupTable{$_};

            $lookupTable{$_} = $subdir;
        }
    }
    return %lookupTable;
}

### get the available second level directories, named by date
### (YYYY.MM.DD) under which the hdf files reside. This does
### not ensure that the files are really there.
sub getAvailDates() {
    my $caller = (caller)[0];
    carp "This is an internal WebService::MODIS function. You should know what you are doing." if ($caller ne "WebService::MODIS");

    my %lookupTable = ();

    my $ua = new LWP::UserAgent;
    foreach my $key (keys %modisProducts) {
        my @dates=();
        my $response = $ua->get("${BASE_URL}/$modisProducts{$key}/$key");

        unless ($response->is_success) {
            die $response->status_line;
        }

        my $content = $response->decoded_content();
        my @content = split("\n", $content);
        foreach (@content) {
            next if (!/href="20[0-9]{2}\.[0-9]{2}\.[0-9]{2}/);
            s/.*href="//;
            s/\/.*//;
            push(@dates, $_);
        }
        my $datesString = "['".join("', '", @dates)."']";
        $lookupTable{$key} = eval $datesString;
    }
    return %lookupTable;
}

### return a file list for one product and date on the server
sub getDateFullURLs($$) {
    my $caller = (caller)[0];
    carp "This is an internal WebService::MODIS function. You should know what you are doing." if ($caller ne "WebService::MODIS");

    my $product = shift;
    my $date = shift;

    my @flist = ();

    my $ua = new LWP::UserAgent;

    my $response = $ua->get("${BASE_URL}/$modisProducts{$product}/$product/$date");
  
    unless ($response->is_success) {
        die $response->status_line;
    }

    my $content = $response->decoded_content();
    my @content = split("\n", $content);
    foreach (@content) {
        next if (!/href="M/);
        next if (/hdf.xml/);
        s/.*href="//;
        s/".*//;
        push(@flist, "${BASE_URL}/$modisProducts{$product}/$product/$date/$_");
    }
    return(@flist);
}

1;

__END__

=head1 NAME

WebService::MODIS - Perl extension for downloading MODIS satellite data

=head1 SYNOPSIS
  use WebService::MODIS;

  ### to initalize or reload the cached server side directory structure
  initCache;
  ### write the cache to configuration files.
  ### A different directory can be passed as parameter.
  writeCache;
  ### load the cache from a previous writeCache.
  ### A different directory can be passed as parameter.
  readCache;

  ### Only available with use WebService::MODIS qw(:all);
  # my %ret = getModisProducts;
  # print "$_ : $ret{$_}\n" foreach (keys %ret);
  # %ret = getModisGlobal;
  # print "$_ : $ret{$_}\n" foreach (keys %ret);

  ### print available versions of a certain product
  print "Versions of MCD12Q1:";
  print " $_" foreach (getVersions("MCD12Q1"));
  print "\n";

  ### new object of land cover type in Rondonia, Brazil for 2001 and 2010
  my $lct = WebService::MODIS->new(product => "MCD12Q1", 



( run in 1.203 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )