line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Finance::Currency::Convert::Yahoo;
|
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
11938
|
use vars qw/$VERSION $DATE $CHAT %currencies/;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
98
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
$VERSION = 0.2;
|
6
|
|
|
|
|
|
|
$DATE = "14 December 2005";
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 NAME
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
Finance::Currency::Convert::Yahoo - convert currencies using Yahoo
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use Finance::Currency::Convert::Yahoo;
|
15
|
|
|
|
|
|
|
$Finance::Currency::Convert::Yahoo::CHAT = 1;
|
16
|
|
|
|
|
|
|
$_ = Finance::Currency::Convert::Yahoo::convert(1,'USD','GBP');
|
17
|
|
|
|
|
|
|
print defined($_)? "Is $_\n" : "Error.";
|
18
|
|
|
|
|
|
|
exit;
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# See the currencies in a dirty way:
|
21
|
|
|
|
|
|
|
use Finance::Currency::Convert::Yahoo;
|
22
|
|
|
|
|
|
|
use Data::Dumper;
|
23
|
|
|
|
|
|
|
warn %Finance::Currency::Convert::Yahoo::currencies;
|
24
|
|
|
|
|
|
|
exit;
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
Using Finance.Yahoo.com, converts a sum between two currencies.
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=cut
|
31
|
|
|
|
|
|
|
|
32
|
1
|
|
|
1
|
|
5
|
use strict;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
40
|
|
33
|
1
|
|
|
1
|
|
6
|
use Carp;
|
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
69
|
|
34
|
1
|
|
|
1
|
|
5
|
use warnings;
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
32
|
|
35
|
1
|
|
|
1
|
|
1181
|
use LWP::UserAgent;
|
|
1
|
|
|
|
|
68809
|
|
|
1
|
|
|
|
|
34
|
|
36
|
1
|
|
|
1
|
|
11
|
use HTTP::Request;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2923
|
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
#
|
39
|
|
|
|
|
|
|
# Glabal variables
|
40
|
|
|
|
|
|
|
#
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
$CHAT = 0; # Set for real-time notes to STDERR
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# Should have been %CURRENCIES but too late now.
|
45
|
|
|
|
|
|
|
our %CURRENCIES = %currencies = (
|
46
|
|
|
|
|
|
|
'AFA'=>'Afghanistan Afghani', 'ALL'=>'Albanian Lek', 'DZD'=>'Algerian Dinar',
|
47
|
|
|
|
|
|
|
'ADF'=>'Andorran Franc', 'ADP'=>'Andorran Peseta', 'ARS'=>'Argentine Peso',
|
48
|
|
|
|
|
|
|
'AWG'=>'Aruba Florin', 'AUD'=>'Australian Dollar', 'ATS'=>'Austrian Schilling',
|
49
|
|
|
|
|
|
|
'BSD'=>'Bahamian Dollar', 'BHD'=>'Bahraini Dinar', 'BDT'=>'Bangladesh Taka',
|
50
|
|
|
|
|
|
|
'BBD'=>'Barbados Dollar', 'BEF'=>'Belgian Franc', 'BZD'=>'Belize Dollar',
|
51
|
|
|
|
|
|
|
'BMD'=>'Bermuda Dollar', 'BTN'=>'Bhutan Ngultrum', 'BOB'=>'Bolivian Boliviano',
|
52
|
|
|
|
|
|
|
'BWP'=>'Botswana Pula', 'BRL'=>'Brazilian Real', 'GBP'=>'British Pound',
|
53
|
|
|
|
|
|
|
'BND'=>'Brunei Dollar', 'BIF'=>'Burundi Franc', 'XOF'=>'CFA Franc (BCEAO)',
|
54
|
|
|
|
|
|
|
'XAF'=>'CFA Franc (BEAC)', 'KHR'=>'Cambodia Riel', 'CAD'=>'Canadian Dollar',
|
55
|
|
|
|
|
|
|
'CVE'=>'Cape Verde Escudo', 'KYD'=>'Cayman Islands Dollar', 'CLP'=>'Chilean Peso',
|
56
|
|
|
|
|
|
|
'CNY'=>'Chinese Yuan', 'COP'=>'Colombian Peso', 'KMF'=>'Comoros Franc',
|
57
|
|
|
|
|
|
|
'CRC'=>'Costa Rica Colon', 'HRK'=>'Croatian Kuna', 'CUP'=>'Cuban Peso',
|
58
|
|
|
|
|
|
|
'CYP'=>'Cyprus Pound', 'CZK'=>'Czech Koruna', 'DKK'=>'Danish Krone',
|
59
|
|
|
|
|
|
|
'DJF'=>'Dijibouti Franc', 'DOP'=>'Dominican Peso', 'NLG'=>'Dutch Guilder',
|
60
|
|
|
|
|
|
|
'XCD'=>'East Caribbean Dollar', 'ECS'=>'Ecuadorian Sucre', 'EGP'=>'Egyptian Pound',
|
61
|
|
|
|
|
|
|
'SVC'=>'El Salvador Colon', 'EEK'=>'Estonian Kroon', 'ETB'=>'Ethiopian Birr',
|
62
|
|
|
|
|
|
|
'EUR'=>'Euro', 'FKP'=>'Falkland Islands Pound', 'FJD'=>'Fiji Dollar',
|
63
|
|
|
|
|
|
|
'FIM'=>'Finnish Mark', 'FRF'=>'French Franc', 'GMD'=>'Gambian Dalasi',
|
64
|
|
|
|
|
|
|
'DEM'=>'German Mark', 'GHC'=>'Ghanian Cedi', 'GIP'=>'Gibraltar Pound',
|
65
|
|
|
|
|
|
|
'XAU'=>'Gold Ounces', 'GRD'=>'Greek Drachma', 'GTQ'=>'Guatemala Quetzal',
|
66
|
|
|
|
|
|
|
'GNF'=>'Guinea Franc', 'GYD'=>'Guyana Dollar', 'HTG'=>'Haiti Gourde',
|
67
|
|
|
|
|
|
|
'HNL'=>'Honduras Lempira', 'HKD'=>'Hong Kong Dollar', 'HUF'=>'Hungarian Forint',
|
68
|
|
|
|
|
|
|
'ISK'=>'Iceland Krona', 'INR'=>'Indian Rupee', 'IDR'=>'Indonesian Rupiah',
|
69
|
|
|
|
|
|
|
'IQD'=>'Iraqi Dinar', 'IEP'=>'Irish Punt', 'ILS'=>'Israeli Shekel',
|
70
|
|
|
|
|
|
|
'ITL'=>'Italian Lira', 'JMD'=>'Jamaican Dollar', 'JPY'=>'Japanese Yen',
|
71
|
|
|
|
|
|
|
'JOD'=>'Jordanian Dinar', 'KZT'=>'Kazakhstan Tenge', 'KES'=>'Kenyan Shilling',
|
72
|
|
|
|
|
|
|
'KRW'=>'Korean Won', 'KWD'=>'Kuwaiti Dinar', 'LAK'=>'Lao Kip', 'LVL'=>'Latvian Lat',
|
73
|
|
|
|
|
|
|
'LBP'=>'Lebanese Pound', 'LSL'=>'Lesotho Loti', 'LRD'=>'Liberian Dollar',
|
74
|
|
|
|
|
|
|
'LYD'=>'Libyan Dinar', 'LTL'=>'Lithuanian Lita', 'LUF'=>'Luxembourg Franc',
|
75
|
|
|
|
|
|
|
'MOP'=>'Macau Pataca', 'MKD'=>'Macedonian Denar', 'MGF'=>'Malagasy Franc',
|
76
|
|
|
|
|
|
|
'MWK'=>'Malawi Kwacha', 'MYR'=>'Malaysian Ringgit', 'MVR'=>'Maldives Rufiyaa',
|
77
|
|
|
|
|
|
|
'MTL'=>'Maltese Lira', 'MRO'=>'Mauritania Ougulya', 'MUR'=>'Mauritius Rupee',
|
78
|
|
|
|
|
|
|
'MXN'=>'Mexican Peso', 'MDL'=>'Moldovan Leu', 'MNT'=>'Mongolian Tugrik',
|
79
|
|
|
|
|
|
|
'MAD'=>'Moroccan Dirham', 'MZM'=>'Mozambique Metical', 'MMK'=>'Myanmar Kyat',
|
80
|
|
|
|
|
|
|
'NAD'=>'Namibian Dollar', 'NPR'=>'Nepalese Rupee', 'ANG'=>'Neth Antilles Guilder',
|
81
|
|
|
|
|
|
|
'NZD'=>'New Zealand Dollar', 'NIO'=>'Nicaragua Cordoba', 'NGN'=>'Nigerian Naira',
|
82
|
|
|
|
|
|
|
'KPW'=>'North Korean Won', 'NOK'=>'Norwegian Krone', 'OMR'=>'Omani Rial',
|
83
|
|
|
|
|
|
|
'XPF'=>'Pacific Franc', 'PKR'=>'Pakistani Rupee', 'XPD'=>'Palladium Ounces',
|
84
|
|
|
|
|
|
|
'PAB'=>'Panama Balboa', 'PGK'=>'Papua New Guinea Kina', 'PYG'=>'Paraguayan Guarani',
|
85
|
|
|
|
|
|
|
'PEN'=>'Peruvian Nuevo Sol', 'PHP'=>'Philippine Peso', 'XPT'=>'Platinum Ounces',
|
86
|
|
|
|
|
|
|
'PLN'=>'Polish Zloty', 'PTE'=>'Portuguese Escudo', 'QAR'=>'Qatar Rial',
|
87
|
|
|
|
|
|
|
'ROL'=>'Romanian Leu', 'RUB'=>'Russian Rouble', 'WST'=>'Samoa Tala',
|
88
|
|
|
|
|
|
|
'STD'=>'Sao Tome Dobra', 'SAR'=>'Saudi Arabian Riyal', 'SCR'=>'Seychelles Rupee',
|
89
|
|
|
|
|
|
|
'SLL'=>'Sierra Leone Leone', 'XAG'=>'Silver Ounces', 'SGD'=>'Singapore Dollar',
|
90
|
|
|
|
|
|
|
'SKK'=>'Slovak Koruna', 'SIT'=>'Slovenian Tolar', 'SBD'=>'Solomon Islands Dollar',
|
91
|
|
|
|
|
|
|
'SOS'=>'Somali Shilling', 'ZAR'=>'South African Rand', 'ESP'=>'Spanish Peseta',
|
92
|
|
|
|
|
|
|
'LKR'=>'Sri Lanka Rupee', 'SHP'=>'St Helena Pound', 'SDD'=>'Sudanese Dinar',
|
93
|
|
|
|
|
|
|
'SRG'=>'Surinam Guilder', 'SZL'=>'Swaziland Lilageni', 'SEK'=>'Swedish Krona',
|
94
|
|
|
|
|
|
|
'CHF'=>'Swiss Franc', 'SYP'=>'Syrian Pound', 'TWD'=>'Taiwan Dollar',
|
95
|
|
|
|
|
|
|
'TZS'=>'Tanzanian Shilling', 'THB'=>'Thai Baht', 'TOP'=>"Tonga Pa'anga",
|
96
|
|
|
|
|
|
|
'TTD'=>'Trinida and Tobago Dollar', 'TND'=>'Tunisian Dinar', 'TRL'=>'Turkish Lira',
|
97
|
|
|
|
|
|
|
'USD'=>'US Dollar', 'AED'=>'UAE Dirham', 'UGX'=>'Ugandan Shilling',
|
98
|
|
|
|
|
|
|
'UAH'=>'Ukraine Hryvnia', 'UYU'=>'Uruguayan New Peso', 'VUV'=>'Vanuatu Vatu',
|
99
|
|
|
|
|
|
|
'VEB'=>'Venezuelan Bolivar', 'VND'=>'Vietnam Dong', 'YER'=>'Yemen Riyal',
|
100
|
|
|
|
|
|
|
'YUM'=>'Yugoslav Dinar', 'ZMK'=>'Zambian Kwacha', 'ZWD'=>'Zimbabwe Dollar'
|
101
|
|
|
|
|
|
|
);
|
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=head1 USE
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Call the module's C<&convert> routine, supplying three arguments:
|
107
|
|
|
|
|
|
|
the amount to convert, and the currencies to convert from and to.
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
Codes are used to identify currencies: you may view them in the
|
110
|
|
|
|
|
|
|
values of the C<%currencies> hash, where keys are descriptions of
|
111
|
|
|
|
|
|
|
the currencies.
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
In the event that attempts to convert fail, you will recieve C
|
114
|
|
|
|
|
|
|
in response, with errors going to STDERR, and notes displayed if
|
115
|
|
|
|
|
|
|
the modules global C<$CHAT> is defined.
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=head2 SUBROUTINE convert
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
$value = &convert( $amount_to_convert, $from, $to);
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
Requires the sum to convert, and two symbols to represent the source
|
122
|
|
|
|
|
|
|
and target currencies.
|
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
In more detail, access L,
|
125
|
|
|
|
|
|
|
where the value of C (in the example, C) is the value of the source
|
126
|
|
|
|
|
|
|
and target currencies, and the rest is stuff I've not looked into....
|
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=cut
|
129
|
|
|
|
|
|
|
|
130
|
0
|
|
|
0
|
1
|
|
sub convert { my ($amount, $from, $to) = (shift,shift,shift);
|
131
|
0
|
0
|
0
|
|
|
|
die "Please call as ...::convert(\$amount,\$from,\$to) " unless (defined $amount and defined $from and defined $to);
|
|
|
|
0
|
|
|
|
|
132
|
0
|
0
|
0
|
|
|
|
carp "No such currency code as <$from>." and return undef if not exists $currencies{$from};
|
133
|
0
|
0
|
0
|
|
|
|
carp "No such currency code as <$to>." and return undef if not exists $currencies{$to};
|
134
|
0
|
0
|
0
|
|
|
|
carp "Please supply a positive sum to convert ." and return undef if $amount<0;
|
135
|
0
|
0
|
|
|
|
|
warn "Converting <$amount> from <$from> to <$to> " if $CHAT;
|
136
|
0
|
|
|
|
|
|
my ($value);
|
137
|
0
|
|
|
|
|
|
for my $attempt (0..3){
|
138
|
0
|
0
|
|
|
|
|
warn "Attempt $attempt ...\n" if $CHAT;
|
139
|
0
|
|
|
|
|
|
$value = _get_document_csv($amount,$from,$to);
|
140
|
|
|
|
|
|
|
# Can't really say "last if defined $doc" as $doc may be a Yahoo 404-like error?
|
141
|
0
|
0
|
|
|
|
|
last if defined $value;
|
142
|
|
|
|
|
|
|
}
|
143
|
0
|
|
|
|
|
|
return $value;
|
144
|
|
|
|
|
|
|
}
|
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=head2 DEPRECATED SUBROUTINE deprecated_convert
|
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
The old C routine: accesses C,
|
149
|
|
|
|
|
|
|
where C is the currency being converted, C is the
|
150
|
|
|
|
|
|
|
target currency, and C is the amount being converted.
|
151
|
|
|
|
|
|
|
The latter is a number; the former two codes defined in our
|
152
|
|
|
|
|
|
|
C<%currencies> hash. (For the date this was last checked, C).
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=cut
|
155
|
|
|
|
|
|
|
|
156
|
0
|
|
|
0
|
1
|
|
sub deprecated_convert { my ($amount, $from, $to) = (shift,shift,shift);
|
157
|
0
|
|
|
|
|
|
require HTML::TokeParser;
|
158
|
0
|
|
|
|
|
|
import HTML::TokeParser;
|
159
|
0
|
0
|
|
|
|
|
die 'You not have HTML::TokeParser...?' unless HTML::TokeParser->VERSION;
|
160
|
0
|
0
|
0
|
|
|
|
die "Please call as ...::convert(\$amount,\$from,\$to) " unless (defined $amount and defined $from and defined $to);
|
|
|
|
0
|
|
|
|
|
161
|
0
|
0
|
0
|
|
|
|
carp "No such currency code as <$from>." and return undef if not exists $currencies{$from};
|
162
|
0
|
0
|
0
|
|
|
|
carp "No such currency code as <$to>." and return undef if not exists $currencies{$to};
|
163
|
0
|
0
|
0
|
|
|
|
carp "Please supply a positive sum to convert ." and return undef if $amount<0;
|
164
|
0
|
0
|
|
|
|
|
warn "Converting <$amount> from <$from> to <$to> " if $CHAT;
|
165
|
0
|
|
|
|
|
|
my ($doc,$result);
|
166
|
0
|
|
|
|
|
|
for my $attempt (0..3){
|
167
|
0
|
0
|
|
|
|
|
warn "Attempt $attempt ...\n" if $CHAT;
|
168
|
0
|
|
|
|
|
|
$doc = _get_document_html($amount,$from,$to);
|
169
|
|
|
|
|
|
|
# Can't really say "last if defined $doc"
|
170
|
|
|
|
|
|
|
# as $doc may be a Yahoo 404-like error?
|
171
|
0
|
0
|
|
|
|
|
last if defined $doc;
|
172
|
|
|
|
|
|
|
}
|
173
|
0
|
0
|
|
|
|
|
if (defined $doc){
|
174
|
0
|
0
|
|
|
|
|
if ($result = _extract_data($doc)){
|
175
|
0
|
0
|
|
|
|
|
warn "Got doc, result is $result" if defined $CHAT;
|
176
|
|
|
|
|
|
|
}
|
177
|
|
|
|
|
|
|
}
|
178
|
0
|
0
|
0
|
|
|
|
if (defined $doc and defined $result){
|
|
|
0
|
0
|
|
|
|
|
179
|
0
|
0
|
0
|
|
|
|
warn "Result:$result\n" if defined $result and defined $CHAT;
|
180
|
0
|
|
|
|
|
|
return $result;
|
181
|
|
|
|
|
|
|
} elsif (defined $doc and not defined $result){
|
182
|
0
|
0
|
|
|
|
|
carp "Connected to Yahoo but could not read the page: sorry" if defined $CHAT;
|
183
|
0
|
|
|
|
|
|
return undef;
|
184
|
|
|
|
|
|
|
} else {
|
185
|
0
|
0
|
|
|
|
|
carp "Could not connect to Yahoo" if defined $CHAT;
|
186
|
0
|
|
|
|
|
|
return undef;
|
187
|
|
|
|
|
|
|
}
|
188
|
|
|
|
|
|
|
}
|
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
#
|
192
|
|
|
|
|
|
|
# PRIVATE SUB get_document_csv
|
193
|
|
|
|
|
|
|
# Accepts: amount, starting currency, target currency
|
194
|
|
|
|
|
|
|
# Returns: HTML content
|
195
|
|
|
|
|
|
|
# URI: http://finance.yahoo.com/d/quotes.csv?s=GBPEUR=X&f=l1
|
196
|
|
|
|
|
|
|
#
|
197
|
0
|
|
|
0
|
|
|
sub _get_document_csv { my ($amount,$from,$to) = (shift,shift,shift);
|
198
|
0
|
0
|
0
|
|
|
|
die "get_document requires a \$amount,\$from_currency,\$target_currency arrity" unless (defined $amount and defined $to and defined $from);
|
|
|
|
0
|
|
|
|
|
199
|
|
|
|
|
|
|
|
200
|
0
|
|
|
|
|
|
my $ua = LWP::UserAgent->new; # Create a new UserAgent
|
201
|
0
|
|
|
|
|
|
$ua->agent('Mozilla/25.'.(localtime)." (PERL ".__PACKAGE__." $VERSION"); # Give it a type name
|
202
|
|
|
|
|
|
|
|
203
|
0
|
|
|
|
|
|
my $url =
|
204
|
|
|
|
|
|
|
'http://finance.yahoo.com/d/quotes.csv?'
|
205
|
|
|
|
|
|
|
. 's='.$from.$to
|
206
|
|
|
|
|
|
|
. '=X&f=l1'
|
207
|
|
|
|
|
|
|
;
|
208
|
0
|
0
|
|
|
|
|
warn "Attempting to access <$url> ...\n" if $CHAT;
|
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# Format URL request
|
211
|
0
|
0
|
0
|
|
|
|
my $req = new HTTP::Request ('GET',$url) or die "...could not GET.\n" and return undef;
|
212
|
0
|
|
|
|
|
|
my $res = $ua->request($req); # $res is the object UA returned
|
213
|
0
|
0
|
|
|
|
|
if (not $res->is_success()) { # If successful
|
214
|
0
|
|
|
|
|
|
warn"...failed to retrieve currency document from Yahoo...\nTried: $url\n";
|
215
|
0
|
|
|
|
|
|
return undef;
|
216
|
|
|
|
|
|
|
}
|
217
|
0
|
0
|
|
|
|
|
warn "...ok.\n" if $CHAT;
|
218
|
|
|
|
|
|
|
|
219
|
0
|
|
|
|
|
|
my $r = $res->content;
|
220
|
0
|
|
|
|
|
|
$r =~ s/^\s*([\d.]+)\s*$/$1/sg;
|
221
|
0
|
0
|
|
|
|
|
if ($r eq ''){
|
222
|
0
|
|
|
|
|
|
warn "...document contained no data/unexpected data\n";
|
223
|
0
|
|
|
|
|
|
return undef;
|
224
|
|
|
|
|
|
|
}
|
225
|
|
|
|
|
|
|
|
226
|
0
|
|
|
|
|
|
return $amount * $r;
|
227
|
|
|
|
|
|
|
}
|
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
#
|
232
|
|
|
|
|
|
|
# PRIVATE SUB get_document_html
|
233
|
|
|
|
|
|
|
# Accepts: amount, starting currency, target currency
|
234
|
|
|
|
|
|
|
# Returns: HTML content
|
235
|
|
|
|
|
|
|
# URI: http://finance.yahoo.com/currency/convert?amt=1&from=GBP&to=HUF&submit=Convert
|
236
|
|
|
|
|
|
|
#
|
237
|
0
|
|
|
0
|
|
|
sub _get_document_html { my ($amount,$from,$to) = (shift,shift,shift);
|
238
|
0
|
0
|
0
|
|
|
|
die "get_document requires a \$amount,\$from_currency,\$target_currency arrity" unless (defined $amount and defined $to and defined $from);
|
|
|
|
0
|
|
|
|
|
239
|
|
|
|
|
|
|
|
240
|
0
|
|
|
|
|
|
my $ua = LWP::UserAgent->new; # Create a new UserAgent
|
241
|
0
|
|
|
|
|
|
$ua->agent('Mozilla/25.'.(localtime)." (PERL ".__PACKAGE__." $VERSION"); # Give it a type name
|
242
|
|
|
|
|
|
|
|
243
|
0
|
|
|
|
|
|
my $url =
|
244
|
|
|
|
|
|
|
'http://finance.yahoo.com/currency/convert?'
|
245
|
|
|
|
|
|
|
. 'amt='.$amount
|
246
|
|
|
|
|
|
|
. '&from='.$from
|
247
|
|
|
|
|
|
|
. '&to='.$to
|
248
|
|
|
|
|
|
|
. '&submit=Convert'
|
249
|
|
|
|
|
|
|
;
|
250
|
0
|
0
|
|
|
|
|
warn "Attempting to access <$url> ...\n" if $CHAT;
|
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
# Format URL request
|
253
|
0
|
0
|
0
|
|
|
|
my $req = new HTTP::Request ('GET',$url) or die "...could not GET.\n" and return undef;
|
254
|
0
|
|
|
|
|
|
my $res = $ua->request($req); # $res is the object UA returned
|
255
|
0
|
0
|
|
|
|
|
if (not $res->is_success()) { # If successful
|
256
|
0
|
0
|
|
|
|
|
warn"...failed to retrieve currency document.\n" if $CHAT;
|
257
|
|
|
|
|
|
|
return undef
|
258
|
0
|
|
|
|
|
|
}
|
259
|
0
|
0
|
|
|
|
|
warn "...ok.\n" if $CHAT;
|
260
|
|
|
|
|
|
|
|
261
|
0
|
|
|
|
|
|
return $res->content;
|
262
|
|
|
|
|
|
|
}
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
#
|
266
|
|
|
|
|
|
|
# PRIVATE SUB _extract_data
|
267
|
|
|
|
|
|
|
# Accept: HTML doc as arg
|
268
|
|
|
|
|
|
|
# Return amount on success, undef on failure
|
269
|
|
|
|
|
|
|
# NOV 2004: Fifth yfnc_tabledata1 class TD, and bold
|
270
|
|
|
|
|
|
|
# MAY 2003: Sloopy errors fixed. Sorry.
|
271
|
|
|
|
|
|
|
# APR 2003: Data is now in SIXTH table, second row, second (non-header) cell, in bold
|
272
|
|
|
|
|
|
|
# JAN 2003: Data is now in SEVENTH table, second row, second (non-header) cell, in bold
|
273
|
|
|
|
|
|
|
# JULY 2001: Data is in fourth table's fourth TD
|
274
|
|
|
|
|
|
|
# DEC 2001: Data is in FIFTH table
|
275
|
|
|
|
|
|
|
#
|
276
|
0
|
|
|
0
|
|
|
sub _extract_data { my $doc = shift;
|
277
|
0
|
|
|
|
|
|
my $token;
|
278
|
0
|
0
|
|
|
|
|
my $p = HTML::TokeParser->new(\$doc) or die "Couldn't create TokePraser: $!";
|
279
|
|
|
|
|
|
|
# Fifth TD and class is 'yfnc_tabledata1'
|
280
|
0
|
|
|
|
|
|
for (1..5){
|
281
|
0
|
|
0
|
|
|
|
while ($token = $p->get_token and not (
|
|
|
|
0
|
|
|
|
|
282
|
|
|
|
|
|
|
@$token[0] eq 'S' and @$token[1] eq 'td'
|
283
|
|
|
|
|
|
|
and @$token[2]->{class}
|
284
|
|
|
|
|
|
|
and @$token[2]->{class} eq 'yfnc_tabledata1'
|
285
|
|
|
|
|
|
|
) ){}
|
286
|
|
|
|
|
|
|
}
|
287
|
0
|
0
|
|
|
|
|
$token = $p->get_token or return undef;
|
288
|
0
|
0
|
0
|
|
|
|
return undef if @$token[0] ne 'S' and @$token[1] ne 'b';
|
289
|
|
|
|
|
|
|
|
290
|
0
|
0
|
|
|
|
|
$token = $p->get_token or return undef;
|
291
|
0
|
0
|
|
|
|
|
return undef if @$token[0] ne 'T';
|
292
|
|
|
|
|
|
|
|
293
|
0
|
0
|
|
|
|
|
return @$token[1] =~ /^[\d.,]+$/ ? @$token[1] : undef;
|
294
|
|
|
|
|
|
|
}
|
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=head1 EXPORTS
|
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
None.
|
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=head1 REVISIONS
|
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
Please see the enclosed file CHANGES.
|
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=head1 PROBLEMS?
|
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
If this doesn't work, Yahoo have probably changed their URI or HTML format.
|
310
|
|
|
|
|
|
|
Let me know and I'll fix the code. Or by all means send a patch.
|
311
|
|
|
|
|
|
|
Please don't just post a bad review on CPAN, I don't get CC'd them.
|
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=head1 SEE ALSO
|
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
L: L;
|
316
|
|
|
|
|
|
|
L;
|
317
|
|
|
|
|
|
|
L.
|
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=head1 AUTHOR
|
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
Lee Goddard, lgoddard -at- cpan -dot- org.
|
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=head1 COPYRIGHT
|
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
Copyright (C) Lee Goddard, 2001, 2005, ff. - All Rights Reserved.
|
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
This library is free software and may be used only under the same terms as Perl itself.
|
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=cut
|
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# $Finance::Currency::Convert::Yahoo::CHAT=1;
|
333
|
|
|
|
|
|
|
# print Finance::Currency::Convert::Yahoo::convert(1,'EUR','GBP');
|
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
1;
|
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
__END__
|