пятница, 30 января 2009 г.

Работа с GnuCash. Часть 4. Finance::Quote. Разработка собственных модулей получения котировок.

UPD: Внимание! Последняя самая актуальная и полная версия руководства по GnuCash на русском языке в различных форматах доступна по адресу http://kilork.org/gnucash.html.

В предыдущей части мы вплотную подошли к необходимости автоматизировать процесс получения котировок. И gnucash предоставляет нам для этого отлично средство - Finance::Quote. Finance::Quote - это perl-модуль, и этим очень многое сказано. В комплекте поставки версии 0.15 множество разнообразных подмодулей. Но нужных нам, естественно, все равно нет. Написаны модули на perl. Множество уже в страхе будут бежать без оглядки, так как perl ассоциируется у всех с чем-то сложным и совершенно непонятным. Скажу, так оно и есть. Но в данном случае, модули очень просто написаны, откомментированы. Я убежден, что для того, чтобы написать собственный модуль под Finance::Quote нужны минимальные познания в программировании, не требуется глубокое знание perl, и нужно только желание достичь цели. В состав Finance::Quote входит документация о разработке собственных модулей получения котировок. Используя это руководство мы сделаем простой модуль для получения котировок ОМС Сбербанка. Процесс создания разобьем на шаги. Начнем с того, что у нашего пользователя нет опыта работы с perl. Прекрасно, тогда переходим к созданию нашего модуля для новичков в perl.

Создание модуля.

Мне кажется, очень много для популярности того или иного языка делают вовсе не его качества именно как языка, а какие-то маленькие удобные фенечки, или большие удобные фенечки. В perl главная большая удобная фенечка - это CPAN, гигантский архив готовых модулей, которые ставятся через единый интерфейс, с зависимостями, тестами, и прочим. Очень большая удобная фенечка. Есть фенечки поменьше. Например, утилитки для генерации каркаса модуля. Открываем терминал, идем в папочку проектов (у себя назову ее ~/Desktop/test):

kilork@pantogan:~$ mkdir Desktop/test
kilork@pantogan:~$ cd Desktop/test
kilork@pantogan:~/Desktop/test$ 


Надо определиться с названием. Я обычно весьма много времени трачу на придумывание названия. Как говорил небезизвестный персонаж, как вы яхту назовете, так она и поплывет. Поэтому название надо очень тщательно выбирать. Наш модуль будет жить в пространстве имен Finance::Quote и относится к Сбербанку, назовем его Finance::Quote::Sberbank. Итак, воспользуемся командой h2xs:

kilork@pantogan:~/Desktop/test$ h2xs -AX -n Finance::Quote::Sberbank
Defaulting to backwards compatibility with perl 5.8.8
If you intend this module to be compatible with earlier perl versions, please
specify a minimum perl version with the -b option.

Writing Finance-Quote-Sberbank/lib/Finance/Quote/Sberbank.pm
Writing Finance-Quote-Sberbank/Makefile.PL
Writing Finance-Quote-Sberbank/README
Writing Finance-Quote-Sberbank/t/Finance-Quote-Sberbank.t
Writing Finance-Quote-Sberbank/Changes
Writing Finance-Quote-Sberbank/MANIFEST


Как видно, одна маленькая команда насоздавала нам множество файликов. Один, очевидно, сам каркас модуля. Затем идет генератор Makefile'ов. Файлик с README, файлик тестов. Лог изменений Changes. И MANIFEST. Чудеса, да и только, почти вся работа сделана за нас этой маленькой чудесной командой. Главное - не давать никому знать об этом.

Сгенерируем Makefile. Укажем дополнительный параметр, говорящий о нашем желании ставить модули в локальную директорию пользователя.

kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ perl Makefile.PL PREFIX=~/perl
Checking if your kit is complete...
Looks good
Writing Makefile for Finance::Quote::Sberbank


Отлично, теперь мы можем собирать, тестировать, инсталлировать, и собирать дистрибутив следующими простыми командами:

kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make # собираем
cp lib/Finance/Quote/Sberbank.pm blib/lib/Finance/Quote/Sberbank.pm
Manifying blib/man3/Finance::Quote::Sberbank.3pm

kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make test # тестируем
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/Finance-Quote-Sberbank....ok                                               
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.08 cusr +  0.01 csys =  0.09 CPU)

kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make install # инсталлируем
Installing /home/kilork/perl/share/perl/5.8.8/Finance/Quote/Sberbank.pm
Installing /home/kilork/perl/man/man3/Finance::Quote::Sberbank.3pm
Writing /home/kilork/perl/lib/perl/5.8.8/auto/Finance/Quote/Sberbank/.packlist
Appending installation info to /home/kilork/perl/lib/perl/5.8.8/perllocal.pod

kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make dist # собираем дистрибутив
rm -rf Finance-Quote-Sberbank-0.01
/usr/bin/perl "-MExtUtils::Manifest=manicopy,maniread" \
-e "manicopy(maniread(),'Finance-Quote-Sberbank-0.01', 'best');"
mkdir Finance-Quote-Sberbank-0.01
mkdir Finance-Quote-Sberbank-0.01/lib
mkdir Finance-Quote-Sberbank-0.01/lib/Finance
mkdir Finance-Quote-Sberbank-0.01/lib/Finance/Quote
mkdir Finance-Quote-Sberbank-0.01/t
Generating META.yml
tar cvf Finance-Quote-Sberbank-0.01.tar Finance-Quote-Sberbank-0.01
Finance-Quote-Sberbank-0.01/
Finance-Quote-Sberbank-0.01/MANIFEST
Finance-Quote-Sberbank-0.01/lib/
Finance-Quote-Sberbank-0.01/lib/Finance/
Finance-Quote-Sberbank-0.01/lib/Finance/Quote/
Finance-Quote-Sberbank-0.01/lib/Finance/Quote/Sberbank.pm
Finance-Quote-Sberbank-0.01/t/
Finance-Quote-Sberbank-0.01/t/Finance-Quote-Sberbank.t
Finance-Quote-Sberbank-0.01/Changes
Finance-Quote-Sberbank-0.01/README
Finance-Quote-Sberbank-0.01/Makefile.PL
Finance-Quote-Sberbank-0.01/META.yml
rm -rf Finance-Quote-Sberbank-0.01
gzip --best Finance-Quote-Sberbank-0.01.tar


Команд немного, все очень просто, на текущем этапе нам понадобятся команды make и make test. Затем make install, если надо будет использовать модуль из gnucash или других программ, и наконец - make dist, если нам вдруг захочется все это дело выложить на CPAN (мне захотелось, можно поискать Sberbank на http://search.cpan.org).

Каркас модуля мы создали, подготовили среду к сборке и тестированию, приступаем к реализации модуля для Finance::Quote.

Реализация модуля для Finance::Quote.

Открываем Sberbank.pm в нашем любимом текстовом редакторе. Текст снабжен неплохими комментариями, так что понятно назначение той или иной секции в сгенерированном файле. Нам надо удалить все лишнее, и реализовать методы для Finance::Quote. Самое забавное, что реализуя модуль под Finance::Quote нам вовсе не надо что-то знать о Finance::Quote, не надо даже упоминать ее в нашем модуле. Достаточно поддержать нужный интерфейс и подложить модуль в правильное место.

Находим строку "# Preloaded methods go here.". Отсюда мы и начнем определять наши методы. Первый метод, который нам понадобится, это метод methods. Этот метод будет вызван Finance::Quote для получения списка нестандартных методов, определяемых нашим модулем. Это как раз та строчка, которую мы увидим, когда подключим наш модуль в gnucash. Кроме этого нам понадобится метод, который вернет список поддерживаемых нами атрибутов labels, ну и собственно, главный метод, в котором мы и будем лазить на сайт Sberbank'а, и забивать значения атрибутов. Пока определим только стандартные методы, и пустышку для главного метода. Вот, что у меня получилось:

sub methods { return ( sberbank => \&sberbank ); }

{
my @labels = qw/name last bid ask date isodate currency/;

sub labels { return ( sberbank => \@labels ); }
}

sub sberbank {
my $quoter = shift;
my @stocks = @_;
}


Получился метод sberbank с двумя параметрами, загадочный $quoter, и не менее загадочные @stocks. Метод ничего не возвращает, а вообще говоря - должен. Тем не менее, это уже вполне минимально подходящий для использования модуль Finance::Quote.

Делаем make, make test, make install. Запускаем gnucash командой:
kilork@pantogan:~/Desktop$ FQ_LOAD_QUOTELET="-defaults Sberbank" gnucash


У меня открылся наш последний пример из 3-й части руководства. Есть золото, но котировки надо вбивать руками. Теперь мы попробуем настроить получение котировок с помощью нашего новомодного модуля. Пустышки правда пока.

Идем в редактор ценных бумаг, находим там наше золото, выбираем "Правка", на открывающеся форме настройки ставим галочку "Получить онлайн котировки", устанавливаем радио-переключатель в положение "Неизвестный", в выпадающем списке находим "sberbank" и выбираем. Жмем "Ок".



Рис 4.1. Настройка получения онлайн котировок.

Мы подключили наш модуль к нашему инструменту - золоту. Теперь убедимся, что пока ничего не работает. Идем в редактор цен, жмем "Получить котировки", получаем вполне ожиаемый результат.



Рис 4.2. Получение котировок с новым "пустым" модулем приводит к ошибке.

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

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