понедельник, 25 мая 2009 г.

GnuCash - лечим получение котировок валют.

С недавних пор (где-то с 12 мая) мой любимый gnucash перестал получать котировки валют. Как всегда программный отказ удачно совпал с сильными колебаниями на валютном рынке, но мои активы вполне себе спокойно поживали, что меня удивило, но с некоторым запозданием.

Все это конечно ужасно, но поправимо. Меня всегда удивляли люди, которые ругали опенсурс за ошибки. Увидел ошибку - докажи, что сам чего-то стоишь: поправь ее. Ну или баг-репорт отправь.

Итак, как вылечить gnucash? Ответ как всегда в модуле Finance::Quote. Надо его немного поправить.

Ищем, куда спрятался Quote.pm в нашей локальной инсталяции (мы же не будем править то, что ставим дистрибутивом):

kilork@phoenix ~ $ find ~/perl -name Quote.pm
/home/kilork/perl/lib64/perl5/site_perl/5.8.8/Finance/Quote.pm


Правим его. Тут особых подробностей не напишу, кроме того, что освоил debug perl под emacs (M+x perldb). Сами авторы дают резервный вариант для получения котировок валют, но почему-то, чтобы им воспользоваться, приходится попрограммировать. Я для вас поставлю свой вариант исправления, который работает у меня. В upstream пока погожу слать, подожду версии 1.17 Finance::Quote. Ну а если вдруг кому пригодится, то смотрите, как я поправил.

Ищем оригинал (каюсь, не сделал бэкапа, поэтому сравниваем с тем, что идет в дистрибутиве):

phoenix kilork # equery f Finance-Quote | grep Quote.pm
/usr/lib64/perl5/vendor_perl/5.8.8/Finance/Quote.pm


Сравниваем:

kilork@phoenix ~ $ diff -u {/usr/lib64/perl5/vendor,/home/kilork/perl/lib64/perl5/site}_perl/5.8.8/Finance/Quote.pm

--- /usr/lib64/perl5/vendor_perl/5.8.8/Finance/Quote.pm 2009-05-23 23:26:49.000000000 +0400
+++ /home/kilork/perl/lib64/perl5/site_perl/5.8.8/Finance/Quote.pm 2009-05-25 00:56:28.000000000 +0400
@@ -42,9 +42,9 @@
$VERSION $TIMEOUT %MODULES %METHODS $AUTOLOAD
$YAHOO_CURRENCY_URL $USE_EXPERIMENTAL_UA/;

-$YAHOO_CURRENCY_URL = "http://uk.finance.yahoo.com/currency/convert?amt=1&submit=Convert&";
+#$YAHOO_CURRENCY_URL = "http://uk.finance.yahoo.com/currency/convert?amt=1&submit=Convert&";
# If the above URL ever fails, try rewriting this module to use the URL below.
-# $YAHOO_CURRENCY_URL = "http://uk.finance.yahoo.com/q?s=USDCAD%3DX";
+$YAHOO_CURRENCY_URL = "http://uk.finance.yahoo.com/q?s=";# USDCAD%3DX";

@ISA = qw/Exporter/;
@EXPORT = ();
@@ -241,16 +241,11 @@

my $ua = $this->user_agent;

- my $data = $ua->request(GET "${YAHOO_CURRENCY_URL}from=$from&to=$to")->content;
- my $te = HTML::TableExtract->new( headers => ['Symbol', 'Bid', 'Ask'] );
- $te->parse(decode_utf8($data)); # The web page returns utf8 content which gives
- # a warning when parsing $data in HTML::Parser
-
- # Make sure there's a table to parse.
- return undef unless ($te->tables);
-
- my $row = ($te->rows())[0];
- my ($exchange_rate) = $$row[1];
+ my $data = $ua->request(GET "${YAHOO_CURRENCY_URL}$from${to}%3DX")->content;
+ if($data !~ /Bid:.+>(\d+.\d+)<.+Ask:/g) {
+ return undef;
+ }
+ my $exchange_rate = $1;
$exchange_rate =~ s/,// ; # solve a bug when conversion rate
# involves thousands. yahoo inserts
# a comma when thousands occur


Данное решение считаю костылем, жду 1.17 с исправлением досадной ошибочки, или 1.16.1. Надеюсь, костыль не будет передаваться из рук в руки, и пригодится только мне :)

Комментариев нет: