This file is indexed.

/usr/share/perl5/Finance/Quote/HU.pm is in libfinance-quote-perl 1.38-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#!/usr/bin/perl -w
#
# HU.pm
#
# Version 0.3 - Fixed BAMOSZ website scraping and download stocks
# directly from www.BET.hu
# This version based on ZA.pm module
#
# Zoltan Levardy <zoltan at levardy dot org> 2008, 2009
# Kristof Marussy <kris7topher at gmail dot com> 2014

package Finance::Quote::HU;
require 5.005;

use strict;

use LWP::UserAgent;
use HTTP::Request::Common;
use HTML::TableExtract;
use Encode;

our $VERSION = '1.38'; # VERSION

my $BAMOSZ_MAINURL = "http://www.bamosz.hu/";
my $BAMOSZ_URL = $BAMOSZ_MAINURL . "alapoldal?isin=";

my $BSE_MAINURL = "http://www.bet.hu/";
my $BSE_URL = $BSE_MAINURL . "topmenu/kereskedesi_adatok/product_search?isinquery=";

sub methods {
    return ( hufund  => \&bamosz,
             bamosz  => \&bamosz,
             hustock => \&bse,
             bse     => \&bse,
             bet     => \&bse,
             hu      => \&hu,
             hungary => \&hu
    );
}

sub labels {
    my @fundlabels =
        qw/symbol method source name currency isin date isodate price last/;
    my @stocklabels =
        qw/symbol method source currency isin date isodate price open close
           high low p_change last/;
    my @alllabels = ( @stocklabels, "name" );
    return ( hufund  => \@fundlabels,
             bamosz  => \@fundlabels,
             hustock => \@stocklabels,
             bse     => \@stocklabels,
             bet     => \@stocklabels,
             hu      => \@alllabels,
             hungary => \@alllabels
    );
}

sub hu {
    my $quoter  = shift;
    my @symbols = @_;
    my %info;

    for my $symbol (@symbols) {
        my %bse_info = bse( $quoter, $symbol );
        if ( $bse_info{ $symbol, "success" } ) {
            %info = ( %info, %bse_info );
            next;
        }

        my %bamosz_info = bamosz( $quoter, $symbol );
        if ( $bamosz_info{ $symbol, "success" } ) {
            %info = ( %info, %bamosz_info );
            next;
        }

        $info{ $symbol, "success" }  = 0;
        $info{ $symbol, "errormsg" } = "Fetch from bse or bamosz failed";
    }

    return wantarray() ? %info : \%info;
}

sub bse {
    my $quoter  = shift;
    my @symbols = @_;
    my %info;

    my $ua = $quoter->user_agent;

    for my $symbol (@symbols) {
        $info{ $symbol, "method" }  = "bse";
        $info{ $symbol, "source" }  = $BSE_MAINURL;
        $info{ $symbol, "success" } = 0;

        my $url      = $BSE_URL . $symbol;
        my $response = $ua->request( GET $url);
        unless ( $response->is_success ) {
            $info{ $symbol, "errormsg" } = "Request error";
            next;
        }

        my $te =
            HTML::TableExtract->new( attribs => { class => "InsAdat_table" } );
        $te->parse( decode_utf8( $response->content ) );
        unless ( $te->first_table_found ) {
            $info{ $symbol, "errormsg" } = "No InsAdat_table found";
            next;
        }

        my @found;
    TABLE_LOOP: for my $ts ( $te->tables ) {
            for my $row ( $ts->rows ) {
                my @trimmed_row = map { trim($_) } @$row;
                if ( $symbol eq $trimmed_row[1] || $symbol eq $trimmed_row[2] )
                {
                    @found = @trimmed_row;
                    last TABLE_LOOP;
                }
            }
        }
        unless (@found) {
            $info{ $symbol, "errormsg" } = "No ticker or ISIN found";
            next;
        }

        # I don't trade stocks, so I am unsure whether the data
        # extracted here is sensible. Please do improve this if
        # needed!
        $info{ $symbol, "symbol" }   = $found[1];
        $info{ $symbol, "isin" }     = $found[2];
        $info{ $symbol, "price" }    = hu_decimal( $found[3] );
        $info{ $symbol, "open" }     = hu_decimal( $found[8] );
        $info{ $symbol, "close" }    = hu_decimal( $found[9] );
        $info{ $symbol, "currency" } = $found[10];
        $info{ $symbol, "low" }      = hu_decimal( $found[13] );
        $info{ $symbol, "high" }     = hu_decimal( $found[14] );
        $info{ $symbol, "p_change" } = hu_decimal( $found[16] );
        $info{ $symbol, "last" }     = hu_decimal( $found[17] );
        $quoter->store_date( \%info, $symbol, { isodate => $found[18] } );

        $info{ $symbol, "success" } = 1;
    }

    return wantarray() ? %info : \%info;
}

sub bamosz {
    my $quoter  = shift;
    my @symbols = @_;
    my %info;

    my $ua = $quoter->user_agent;

    for my $symbol (@symbols) {
        $info{ $symbol, "method" }  = "bamosz";
        $info{ $symbol, "source" }  = $BAMOSZ_MAINURL;
        $info{ $symbol, "success" } = 0;

        my $url      = $BAMOSZ_URL . $symbol;
        my $response = $ua->request( GET $url);
        unless ( $response->is_success ) {
            $info{ $symbol, "errormsg" } = "Request error";
            next;
        }

        my $te = HTML::TableExtract->new( attribs => { class => "dataTable" } );
        $te->parse( decode_utf8( $response->content ) );
        unless ( $te->first_table_found ) {
            $info{ $symbol, "errormsg" } = "No dataTable found";
            next;
        }

        my $ts = $te->table( 0, 0 );
        $info{ $symbol, "name" } = $ts->cell( 0, 1 );
        my $isin = $ts->cell( 2, 1 );
        $info{ $symbol, "symbol" }   = $isin;
        $info{ $symbol, "isin" }     = $isin;
        $info{ $symbol, "currency" } = $ts->cell( 3, 1 );
        my $price = hu_decimal( $ts->cell( 5, 1 ) );
        $info{ $symbol, "price" } = $price;
        $info{ $symbol, "last" }  = $price;
        my $date = $ts->cell( 6, 1 );
        $quoter->store_date( \%info, $symbol, { isodate => $date } );

        $info{ $symbol, "success" } = 1;
    }

    return wantarray() ? %info : \%info;
}

sub trim {
    my $s = shift;
    if ($s) {
        $s =~ s/^\s+//;
        $s =~ s/\s+$//;
        return $s;
    }
    else {
        return '';
    }
}

sub hu_decimal {
    my $s = shift;
    if ($s) {
        $s =~ s/[^\d,-]//g;
        $s =~ s/,/./;
        return $s;
    }
    else {
        return '';
    }
}

1;

=head1 NAME

Finance::Quote::HU - Obtain Hungarian Securities from www.bet.hu
and www.bamosz.hu

=head1 SYNOPSIS

    use Finance::Quote;
    $q = Finance::Quote->new;
    # Don't know anything about failover yet...

=head1 DESCRIPTION

This module obtains information about Hungarian Securities. Share
fetched from www.bet.hu, while mutual funds retrieved from
www.bamosz.hu. Stocks may be searched by either ticker or ISIN, while
mutual funds may only be search be ISIN.

=head1 LABELS RETURNED

Information available may include the following labels:

method source name symbol currency date last price low high open close
p_change

=head1 SEE ALSO

Budapest Stock Exchange (BET) website - http://www.bet.hu
BAMOSZ website - http://www.bamosz.hu/

Finance::Quote

=cut