App-Chart

 view release on metacpan or  search on metacpan

unused/Float.pm  view on Meta::CPAN

  App::Chart::Download::tdate_today_after
      (21,15, App::Chart::TZ->sydney);
}

#------------------------------------------------------------------------------

# C<$zipstr> is a string of bytes which are the contents of a ".zip" file.
# Unzip and return the first member as a string of bytes, or return undef if
# no members.
#
sub unzip_one {
  my ($zipstr) = @_;

  require Archive::Zip;
  my $zip = Archive::Zip->new;

  require IO::String;
  my $io = IO::String->new ($zipstr);
  $zip->readFromFileHandle ($io);

  my @members = $zip->members();
  my $first = $members[0];
  return undef if (! defined $first);

  return $first->contents;
}
#
# Even if _isSeekable gets the right answer :scalar is opened as IO::Handle
# not IO::Seekable ...
#
#   require IO::Handle;
#   require IO::Seekable;
#   *Archive::Zip::Archive::_isSeekable = sub { print "yes\n"; 1; };
#   open my $io, '<', \$zipstr or die;


sub yyyymmdd_to_iso {
  my ($str) = @_;
  if (length ($str) != 8) { croak "yyyymmdd_to_iso: bad string length: $str"; }
  return substr ($str, 0,4) . '-' .
         substr ($str, 4,2) . '-' .
         substr ($str, 6,2);
}

sub tdate_to_yyyymmdd {
  my ($tdate) = @_;
  my ($year, $month, $day) = App::Chart::tdate_to_ymd ($tdate);
  return sprintf ('%04d%02d%02d', $year, $month, $day);
}

sub zip_parse {
  my ($url, $resp) = @_;
  my @data = ();
  my $h = { source          => __PACKAGE__,
            currency        => 'AUD',
            prefer_decimals => 2,
            #             cover_pred      => $pred,
            #             cover_date      =>
            data            => \@data };

  my $body = $resp->decoded_content (charset=>'none',raise_error=>1);
  $h->{'cost_value'} = length ($body);

  # unknown symbol or no data for a particular date gives a zip file with no
  # members
  $body = unzip_one ($body);
  if (! $body) { return undef; }

  my $max_date = tdate_to_yyyymmdd (available_tdate());

  foreach my $line (App::Chart::Download::split_lines($body)) {
    my ($symbol, $date, $open, $high, $low, $close, $volume)
      = split (/,/, $line);
    next if ($date gt $max_date);

    $date = yyyymmdd_to_iso ($date);
    $symbol .= '.AX';

    push @data, { symbol => $symbol,
                  date   => $date,
                  open   => $open,
                  high   => $high,
                  low    => $low,
                  close  => $close,
                  volume => $volume };
  }
  return $h;
}


#-----------------------------------------------------------------------------
# download - by each symbol
#
# This uses the download of all data for a symbol like
#
#     http://www.float.com.au/download/BHP.zip
#
# An unknown symbol produces an empty file, or a .zip containing an empty
# file.
#
# Some old data, like 1997 in http://www.float.com.au/download/SGW.zip, is
# not in date order.

sub indiv_download {
  my @symbol_list = @_;

  foreach my $symbol (@symbol_list) {
    my $filename = App::Chart::symbol_sans_suffix($symbol) . '.zip';
    App::Chart::Download::status
        (__x('Float.com.au data {filename}', filename => $filename));

    my $url = 'http://www.float.com.au/download/'
      . URI::Escape::uri_escape($filename);
    my $resp = App::Chart::Download->get ($url);
    my $h = zip_parse ($url, $resp);
    if ($h) {
      $h->{'last_download'} = 1;
      $h->{'cost_key'} = 'float-indiv-zip';
      App::Chart::Download::write_daily_group ($h);
    }
  }



( run in 1.896 second using v1.01-cache-2.11-cpan-39bf76dae61 )