App-Chart

 view release on metacpan or  search on metacpan

lib/App/Chart/Suffix/LJ.pm  view on Meta::CPAN

package App::Chart::Suffix::LJ;
use 5.010;
use strict;
use warnings;
use Locale::TextDomain 'App-Chart';

use App::Chart::Glib::Ex::MoreUtils;
use App::Chart;
use App::Chart::DownloadHandler::IndivChunks;
use App::Chart::LatestHandler;
use App::Chart::Sympred;
use App::Chart::TZ;
use App::Chart::Weblink;


my $timezone_ljubljana = App::Chart::TZ->new
  (name     => __('Ljubljana'),
   choose   => [ 'Europe/Ljubljana' ],
   fallback => 'CET-1');

my $pred = App::Chart::Sympred::Suffix->new ('.LJ');
$timezone_ljubljana->setup_for_symbol ($pred);


# (source-help! ljubljana-symbol?
# 	      __p('manual-node','Ljubljana Stock Exchange'))


#-----------------------------------------------------------------------------
# weblink - company info
#
# eg.
# Slovenian: http://www.ljse.si/cgi-bin/jve.cgi?SecurityID=DRKR&doc=818
# English:   http://www.ljse.si/cgi-bin/jve.cgi?SecurityID=DRKR&doc=3131
#

App::Chart::Weblink->new
  (pred => $pred,
   name => __('LJSE _Company Information'),
   desc => __('Open web browser at the Ljubljana Stock Exchange information page for this company'),
   proc => sub {
     my ($symbol) = @_;
     $symbol = URI::Escape::uri_escape(App::Chart::symbol_sans_suffix($symbol));
     my $lang = App::Chart::Glib::Ex::MoreUtils::lang_select (en => '3131',
                                                  sl => '818');
     return "http://www.ljse.si/cgi-bin/jve.cgi?SecurityID=$symbol&doc=$lang";
   });


#-----------------------------------------------------------------------------
# latest
#
# This uses the text file at
#
#     http://www.ljse.si/cgi-bin/jve.cgi?doc=2111
#
# which is
#
use constant BTS_URL => 'http://www.ljse.si/datoteke/BTStecajEUR.txt';
#
# The charset isn't specified in the http headers nor the file format specs
# but it's codepage 1250.  The server provides ETag and Last-Modified.
#
# The symbols in each file are cached, so it's usually possible to go
# straight to the right one.  If some symbols aren't where expected then
# both are downloaded to recheck.
#

App::Chart::LatestHandler->new
  (pred => $pred,
   available_tdate => \&available_tdate,
   proc => \&latest_download);

# per specs pdf file, available around 16:30 each day
sub available_tdate {
  App::Chart::Download::tdate_today_after (16,30, $timezone_ljubljana);
}

sub latest_download {
  my ($symbol_list) = @_;

  App::Chart::Download::status (__('LJSE price file'));
  my $resp = App::Chart::Download->get (BTS_URL,
                                       url_tags_key => 'LJ-BTStecajEUR');
  if (! $resp->is_success) {
    return; # 304 not modified
  }
  App::Chart::Download::write_latest_group (bts_parse ($resp));
}

my ($L0010, $L0020);

sub bts_parse {
  my ($resp) = @_;

  my @data = ();
  my $h = { source       => __PACKAGE__,
            url_tags_key => 'LJ-BTStecajEUR',
            resp         => $resp,
            currency     => 'EUR',
            date_format  => 'dmy',
            suffix       => '.TSP',
            data         => \@data };
  # charset not specified, but is codepage 1250
  my $content = $resp->decoded_content (raise_error => 1,
                                        default_charset => 'cp1250');
  $content =~ s/\r//g;

  # 0001 file format marker
  #   $content =~ /^ 0001 110 /
  #     or die 'Ljubljana: BTS file missing 0001 id line';

  # my $date = txt_to_date ($content);

  foreach my $line (split /\n+/, $content) {
    my $elem;

    if ($line =~ /^ 0010 /) {
      # index
      $L0010 ||= make_parser (code           => 4,
                              symbol         => 8,
                              name           => 40,
                              close          => '15.',
                              change         => '15.',
                              percent_change => '15.');

      $elem = $L0010->($line);
      $elem->{'symbol'} = '^' . $elem->{'symbol'};

    } elsif ($line =~ /^ 0020 /) {
      # stock
      $L0020 ||= make_parser (code             => 4,
                              tier             => 4,
                              type             => 4,
                              symbol           => 8,
                              isin             => 20,
                              name             => 40,
                              dividend         => '15.',
                              note_num         => 10,
                              average_price    => '15.',
                              change           => '15.',
                              percent_change   => '15.',
                              last_date        => 10,
                              bid              => '15.',
                              offer            => '15.',
                              high             => '15.',
                              low              => '15.',
                              open             => '15.',
                              close            => '15.',
                              volume           => 12,
                              volume_offmarket => 12,
                              turnover         => 12,
                              turnover_bas     => 12,
                              IF_1             => 15,
                              IF_2             => 15,
                              IF_percent       => 15,
                              note             => 10,
                              shares_issued    => 12,
                              dividend_date    => 10,
                              p_e              => 10,
                              principle        => 20,
                              interest         => 20,
                              coupon_num       => 5,
                              market_discount  => 15,
                              name_and_city    => 80,
                              trading_mode     => 5,



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