#!/usr/bin/perl -w
use
Encode
qw(decode encode_utf8)
;
use
JSON
qw( decode_json )
;
use
if
DEBUG,
'Smart::Comments'
,
'###'
;
our
$VERSION
=
'1.64_02'
;
our
$DISPLAY
=
'OnVista - Germany'
;
our
@LABELS
=
qw/symbol name open high low last date volume currency exchange method/
;
our
$METHODHASH
= {
subroutine
=> \
&onvista
,
display
=>
$DISPLAY
,
labels
=> \
@LABELS
};
sub
methodinfo {
return
(
onvista
=>
$METHODHASH
,
);
}
sub
labels {
my
%m
= methodinfo();
return
map
{
$_
=> [@{
$m
{
$_
}{labels}}] }
keys
%m
; }
sub
methods {
my
%m
= methodinfo();
return
map
{
$_
=>
$m
{
$_
}{subroutine} }
keys
%m
;
}
sub
onvista {
my
$quoter
=
shift
;
my
@stocks
=
@_
;
my
(
%info
,
$tree
,
$url
,
$reply
,
$json
,
$json_decoded
);
my
$ua
=
$quoter
->user_agent();
foreach
my
$stock
(
@stocks
) {
$url
=
$ONVISTA_URL
.
$stock
;
$reply
=
$ua
->request( GET
$url
);
my
$code
=
$reply
->code;
my
$desc
= HTTP::Status::status_message(
$code
);
my
$headers
=
$reply
->headers_as_string;
my
$body
=
$reply
->decoded_content;
my
(
$name
,
$bid
,
$ask
,
$last
,
$open
,
$high
,
$low
,
$date
);
$info
{
$stock
,
"symbol"
} =
$stock
;
if
(
$code
== 200 ) {
$tree
= HTML::TreeBuilder->new;
if
(
$tree
->parse(
$body
)) {
$tree
->
eof
;
unless
(
$json
= encode_utf8 ((
$tree
->look_down(
_tag
=>
'script'
,
id
=>
'__NEXT_DATA__'
,
type
=>
'application/json'
)->content_list())[0]) ) {
$info
{
$stock
,
"success"
} = 0;
$info
{
$stock
,
"errormsg"
} =
"Error retrieving quote for $stock. No data returned"
;
next
;
}
$json_decoded
= decode_json
$json
;
my
$result_array
=
$json_decoded
->{
'props'
}{
'pageProps'
}{
'facets'
}[0]{
'results'
};
$url
=
$json_decoded
->{
'props'
}{
'pageProps'
}{
'facets'
}[0]{
'results'
}[0]{
'urls'
}{
'WEBSITE'
};
foreach
my
$item
(
@$result_array
) {
if
(
$item
->{
'symbol'
} &&
$item
->{
'symbol'
} eq
$stock
) {
$url
=
$item
->{
'urls'
}{
'WEBSITE'
};
last
;
}
}
unless
(
$url
) {
$info
{
$stock
,
"success"
} = 0;
$info
{
$stock
,
"errormsg"
} =
"No data found for $stock."
;
next
;
}
$reply
=
$ua
->request( GET
$url
);
$code
=
$reply
->code;
$desc
= HTTP::Status::status_message(
$code
);
$headers
=
$reply
->headers_as_string;
$body
=
$reply
->decoded_content;
unless
(
$code
== 200 ) {
$info
{
$stock
,
"success"
} = 0;
$info
{
$stock
,
"errormsg"
} =
"Error accessing $url ($desc)."
;
next
;
}
$tree
= HTML::TreeBuilder->new;
unless
(
$tree
->parse(
$body
)) {
$info
{
$stock
,
"success"
} = 0;
$info
{
$stock
,
"errormsg"
} =
"Error parsing HTML from $url."
;
next
;
}
$tree
->
eof
;
unless
(
$json
= encode_utf8 ((
$tree
->look_down(
_tag
=>
'script'
,
id
=>
'__NEXT_DATA__'
,
type
=>
'application/json'
)->content_list())[0]) ) {
$info
{
$stock
,
"success"
} = 0;
$info
{
$stock
,
"errormsg"
} =
"Error retrieving quote for $stock. No data returned"
;
next
;
}
eval
{
$json_decoded
= decode_json
$json
};
if
($@) {
$info
{
$stock
,
'success'
} = 0;
$info
{
$stock
,
'errormsg'
} = $@;
next
;
}
$info
{
$stock
,
"success"
} = 1;
$info
{
$stock
,
'method'
} =
'onvista'
;
$info
{
$stock
,
'name'
} =
$json_decoded
->{
'props'
}{
'pageProps'
}{
'data'
}{
'snapshot'
}{
'instrument'
}{
'name'
};
my
$json_quote
=
$json_decoded
->{
'props'
}{
'pageProps'
}{
'data'
}{
'snapshot'
}{
'quote'
};
$info
{
$stock
,
'open'
} =
$json_quote
->{
'open'
};
$info
{
$stock
,
'high'
} =
$json_quote
->{
'high'
};
$info
{
$stock
,
'low'
} =
$json_quote
->{
'low'
};
$info
{
$stock
,
'last'
} =
$json_quote
->{
'last'
};
$info
{
$stock
,
'price'
} =
$json_quote
->{
'last'
};
$info
{
$stock
,
'currency'
} =
$json_quote
->{
'isoCurrency'
};
$info
{
$stock
,
'volume'
} =
$json_quote
->{
'volume'
};
$info
{
$stock
,
'exchange'
} =
$json_quote
->{
'market'
}{
'nameExchange'
};
$date
=
$json_quote
->{
'datetimeLast'
};
$quoter
->store_date(\
%info
,
$stock
, {
isodate
=>
substr
$date
, 0, 10});
}
else
{
$tree
->
eof
;
$info
{
$stock
,
"success"
} = 0;
$info
{
$stock
,
"errormsg"
} =
"Error retrieving quote for $stock. Could not parse HTML returned from $url."
;
}
}
else
{
$info
{
$stock
,
"success"
} = 0;
$info
{
$stock
,
"errormsg"
} =
"Error retrieving quote for $stock. Attempt to fetch the URL $url resulted in HTTP response $code ($desc)"
;
}
}
return
wantarray
() ?
%info
: \
%info
;
return
\
%info
;
}
1;