воскресенье, 5 апреля 2009 г.

Использование vpnc

Очень долго хотелось избавиться от cisco-vpnclient-3des. Наконец возникла необходимость и дошли руки настроить. Что было плохо в проприетарном клиенте? Практически все. За исключением того, что он работал и делал то, что от него ожидали. Но сеть замыкалась в vpn, поменять роуты не удавалось, что раздражало. Итак, ставим и настраиваем vpnc в gentoo.

Для меня все в основном повторяет шаги из gentoo wiki.

Смотрим на описание пакета и ставим его:
mexidol kilork # emerge -s vpnc
Searching...
[ Results for search key : vpnc ]
[ Applications found : 5 ]

...

* net-misc/vpnc
Latest version available: 0.5.3
Latest version installed: 0.5.3
Size of files: 96 kB
Homepage: http://www.unix-ag.uni-kl.de/~massar/vpnc/
Description: Free client for Cisco VPN routing software
License: GPL-2 BSD

...

mexidol kilork # emerge vpnc


В моем случае, от старого клиента cisco остался настроенный файлик pcf.

Основу для конфигурации получаем как раз из него:
mexidol kilork # pcf2vpnc /etc/opt/cisco-vpnclient/Profiles/hsbk.pcf /etc/vpnc/hsbk.conf


Создаем ссылку для запуска сервиса:
mexidol kilork # ln -s /etc/init.d/vpnc /etc/init.d/vpnc.hsbk


Все настроили, теперь можно запускать:

mexidol kilork # rc-config start vpnc.hsbk


Одна проблема, роуты плохи, мне надо чтобы через vpnc шло только для одной подсети. Чтобы это исправить, создаем файлик /etc/vpnc/scripts.d/hsbk-postup.sh:
#!/bin/sh
route del -net 0.0.0.0 netmask 0.0.0.0 dev tun0
route add -net 172.20.0.0 netmask 255.255.0.0 dev tun0


Некрасиво здесь, что прошито имя tun0. Но поскольку время поджимало, пока так.

пятница, 6 марта 2009 г.

emacs и highlight

Решил сделать два дела, научиться писать вставки на lisp в emacs, а также - пользоваться утилиткой highlight. Идея крайне проста, пишу простой код в emacs, выделяю, вызываю, текст замещается на результат вызова highlight.

Решить оказалось проще, чем сделать, но, вот она функция, и одновременно результат:

(defun kilork-highlight (start end syntax)
"kilork's highlight"
(interactive "r\nssyntax: \n")
(shell-command-on-region start end (concat "highlight --style=vim-dark -f -X --syntax=" syntax) 1))


Я писал текст прямо в emacs. Т.е. по окончании ввода команды я нажал C+x C+e. Затем перешел в начало функции, нажал С+Space. Снова в конец функции и M+x kilork-highlight. Итак, получили приглащение к вводу языка для раскраски, вводим lisp, ввод. Текст заменился на подкрашенный.

Все же, я добился желаемого, и буду и дальше осваивать emacs lisp. Есть ощущение, что я смогу найти много способов сделать свою жизнь более интересной благодаря удивительным свойствам этого языка в применении к этому редактору. Задание на доработку команды для возможности внесения правки в код и повторного переподкрашивания.

суббота, 21 февраля 2009 г.

GNU и Стивен Фрай

Как иногда новости проходят мимо. Только сейчас обнаружил, что GNU с 25-летием поздравляет Стивен Фрай. Посмотреть можно здесь.

Для меня этот актер, это прежде всего Дживс из соответствующего сериала. Так же, как Хью Лаури - не доктор Хаус, а Вустер. Заглянув в википедию обнаружил несколько интересных вещей, есть еще совместные работы у этого актерского дуэта, ну и как водится, выяснилось, что Фрай - гомосексуалист и страдает биполярным расстройством. Да, со временем узнаешь много чего интересного, чего бы и знать совсем не хотелось. А вот другие работы постараюсь посмотреть, если найду.

пятница, 20 февраля 2009 г.

Статистика и скука

Посмотрел свою статистику в svn с начала года. 6 (ШЕСТЬ) коммитов, около одного коммита в неделю. Размеры коммитов не больше 50 строчек, большинство 1-2.

Если пересчитать в у.е. за коммит, получится очень круто, хотя - у.е. за строчку будет тоже немало. Ну а что вы хотели, класс то растет, скоро даже мой взгляд на репозиторий будет стоить как текущая месячная зарплата.

При этом работы на самом деле сделано очень много. Но чужими руками, или результаты не попадают в svn (например, старые клиенты, для которых все еще используется PVCS).

В последнее время убеждаюсь, как хорошо быть хорошим программистом, и как плохо быть хорошим программистом и руководить людьми, с целью получить программный продукт. Если бы я был плохим программистом, меня бы так не трясло от всей ереси, которую приходится фильтровать. Поэтому наверно, менеджеры не должны уметь программировать, не чтобы получать более качественный продукт в заданные сроки, а совсем с другой целью, чтобы в мире не прибавлялось вселенского зла. Люди, утверждающие, что управление людьми интересное занятие - не искрени до безобразия. Это все равно, что шахтеры будут утверждать, что их работа легка и полезна для здоровья. Ну или уборщица, с радостью стирающая блевотину в подъезде. Утешение находится в том, что хоть какие-то вещи можно делать интересными и на такой позиции. И их немало, так что скуку удается побороть.

пятница, 13 февраля 2009 г.

Работа с GnuCash. Часть 5. Finance::Quote. Придание модулю Sberbank полезных функций.

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

Для разнообразия решил писать этот пост в emacs. Несколько странно, поскольку делаю это уже где-то в 4-й раз, привыкаю к emacs, потом начинаешь пользоваться "классическим редактором", и emacs забывается. А зря. На eee есть правда существенный недостаток - справа нет ctrl, что делает пользование несколько осложненным. В четвертый раз вместо забоя пользуюсь backspace, что свидетельствует о наличии застарелых рудиментарных атавизмов, а ведь одна из главных идей emacs - отказ от лишних и утомительных движений, а тянуться к backspace между прочим очень утомительно. Все, хватит о emacs, вернемся к нашим баранчикам.

Чтобы сделать что-то полезное, зайдем на сайт Сбербанка на страничку с котировками ОМС. Текст странички сохраняем на диск. Файл с котировками в формате xls аналогично. Начнем разбираться с последним. Для работы с excel файлами используется модуль Spreadsheet::Read. Все тонкости работы с excel нам не нужны, достаточно с первой странички получить значение из ячейки с известным адресом. Делается это следующим образом:

#!/usr/bin/perl
use Spreadsheet::Read;

my $xls = ReadData("dm1002.xls");

print "$xls->[1]{'A1'}\n";


Этот код выведет первую ячейку, с первой страницы.

Нам надо существенно больше. Найти котировки счетов и вытащить цену покупки/продажи. Но простота обращения с модулем облегчит нам задачу. Теперь надо разобраться со страничкой. Если взглянуть на реализации других модулей для Finance::Quote, то можно понять, что люди предпочитают HTML::TableExtract. Нам же только вытащить ссылку с первой строчкой, так что сойдут и более простые методы. Котировки в Сбербанке идут по месяцам. Страница для января 2009 года это:

http://sbrf.ru/ru/valkprev/archive_1/index.php?year114=2009&month114=01


Получаемая страница содержит котировки с датами, идут они в обратном порядке. Пример HTML кода с котировками:

<li class="xls"><a href="/common/img/uploaded/c_list/sdmet/download/2009/01/dm0131.xls" target="_blank">31 января 2009 года</a><!-- --> (с 00 часов 00 мин.)</li>


Для отбора нам понадобится регулярное выражение. Наверно это самый сложный для понимания кусок, но к счастью, писать регулярные выражения существенно проще, чем читать. Итак, на основе предыдущего текста:

<li class="xls"><a href="(.*\/(\d{4})\/(\d{2})\/dm(\d{2})(\d{2})(?:\_\d+)?\.xls)"[^\(]*\(.+(\d{2}).+(\d{2})


Еще один кусок кода. Пора объединить все это в единое целое. В модуле Finance::Quote::Sberbank находим метод sberbank. Сейчас он имеет следующий вид:

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


Для получения текста страничек нам понадобится user agent. К счастью, он есть у нас, итак, первая строка:

my $ua = $quoter->user_agent;


Теперь можно и запросить страничку.

my $year = 2009;
my $mon = 1;
my $url = "http://sbrf.ru/ru/valkprev/archive_1/index.php?year114=${year}&month114=${mon}";
my $response = $ua->request(GET $url);


Важно стараться сделать какую-никакую, но обработку ошибок, в случае с запросом странички, стоит проверить успешность операции. А если неуспешно, нам надо правильно выставить статусы ошибок. Статусы ошибок записываются в @stocks следующим образом:
unless ($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock, "success"} = 0;
$info{$stock, "errormsg"} = "HTTP failure";
}
return wantarray() ? %info : \%info;
}


Т.е. для каждого запрашиваемого инструмента ставим статус success = 0 и errormsg = HTTP failure. Какая-то обработка ошибок. Теперь надо разобрать содержимое на предмет интересующих нас ссылок:
my $link = "";
my $content = $response->content;
if($content =~ /<li class="xls"><a href="(.*\/(\d{4})\/(\d{2})\/dm(\d{2})(\d{2})(?:\_\d+)?\.xls)"[^\(]*\(.+(\d{2}).+(\d{2})/g) {
$link = $1;
}


Получили ссылку на файлик xls, теперь надо бы его получить, и наконец уже зачитать наши котировки. Единственное, надо бы определиться как мы их назовем. Например, вот так:
Золото SBRF.AU
Серебро SBRF.AG
Платина SBRF.PT
Палладий SBRF.PD


Итак, ссылка найдена, и мы получаем котировки:

if($link) {
$url = "http://sbrf.ru/".$link;
$response = $ua->request(GET $url);
unless($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock, "success"} = 0;
$info{$stock, "errormsg"} = "HTTP failure";
}
return wantarray() ? %info : \%info;
}
$content = $response->content;


Загружаем его как xls-файл:

my $xls = ReadData($content);


Теперь нам надо найти начало котировок ОМС. Это место начинается со строки, определяемой следующим регулярным выражением:

/\d+\. Котировки продажи и покупки драгоценных металлов в обезличенном виде/


Пробегаем примитивным поиском:

my $start = 1;
while($xls->[1]{"A$start"} !~ /\d+\. Котировки продажи и покупки драгоценных металлов в обезличенном виде/ && $start < 100) {
$start++;
}


Определим хэш значений для поиска, в соответствии с определенными выше кодами для различных ОМС:

my %map = (
'Золото' => 'SBRF.AU',
'Серебро' => 'SBRF.AG',
'Платина' => 'SBRF.PT',
'Палладий' => 'SBRF.PD'
);


Начиная с этого момента нам осталось только пробежать по оставшимся строкам в файле, найти наши котировки и заполнить соответствующие части в info:

while($xls->[1]{"A$start"}) {
$start++;
my $name = $xls->[1]{"A$start"};
if($name) {
my $stock = $map{$name};
next unless($stock);
$info{$stock, "symbol"} = $stock;
$info{$stock, "name"} = $name;
$info{$stock, "currency"} = "RUB";
$info{$stock, "method"} = "sberbank";
$info{$stock, "bid"} = $xls->[1]{"E$start"};
$info{$stock, "ask"} = $xls->[1]{"D$start"};
$info{$stock, "last"} = $info{$stock, "bid"};
$quoter->store_date(\%info, $stock, {today => 1});
$info{$stock, "success"} = 1;
}
}


Теперь осталось только сделать тесты. Здесь на помощь приходит модуль Test::More. Открываем t/Finance-Quote-Sberbank.t и пишем там такое:

use encoding 'utf8';
use Test::More;

plan tests => 5;

use_ok('Finance::Quote');
use_ok('Finance::Quote::Sberbank');

my $quoter = Finance::Quote->new("Sberbank");

ok(defined $quoter, "created");

my %info = $quoter->fetch("sberbank", "SBRF.PD");

ok(%info, "fetched");

ok($info{"SBRF.PD", "name"}, "palladium");



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

kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make test
cp lib/Finance/Quote/Sberbank.pm blib/lib/Finance/Quote/Sberbank.pm
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=5,  1 wallclock secs ( 1.05 cusr +  0.06 csys =  1.11 CPU)


Это хорошо, теперь можно смело делать make install и запускать gnucash с загрузкой нашего свежего модуля:

kilork@pantogan:~/Desktop/test/Finance-Quote-Sberbank$ make install
Manifying blib/man3/Finance::Quote::Sberbank.3pm
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$ FQ_LOAD_QUOTELET="-defaults Sberbank" gnucash
gnc.bin-Message: main: binreloc relocation support was disabled at configure time.

Found Finance::Quote version 1.15


Заходим в редактор цен, жмем "Получить котировки", убеждаемся, что все получилось:



Рис 5.1. Получение котировок новым модулем Sberbank.

В заключение, полный текст модуля и скриншот набора текста в emacs:

package Finance::Quote::Sberbank;

use 5.008008;
use strict;
use warnings;
use encoding 'utf8';

use HTTP::Request::Common;
use Spreadsheet::Read;

require Exporter;

our @ISA = qw(Exporter);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration use Finance::Quote::Sberbank ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(

) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(

);

our $VERSION = '0.01';


# Preloaded methods go here.
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 = @_;
my %info;

my $ua = $quoter->user_agent;
my $year = 2009;
my $mon = 1;
my $url = "http://sbrf.ru/ru/valkprev/archive_1/index.php?year114=${year}&month114=${mon}";
my $response = $ua->request(GET $url);
unless ($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock, "success"} = 0;
$info{$stock, "errormsg"} = "HTTP failure";
}
return wantarray() ? %info : \%info;
}
my $link = "";
my $content = $response->content;
if($content =~ /<li class="xls"><a href="(.*\/(\d{4})\/(\d{2})\/dm(\d{2})(\d{2})(?:\_\d+)?\.xls)"[^\(]*\(.+(\d{2}).+(\d{2})/g) {
$link = $1;
}
if($link) {
$url = "http://sbrf.ru/".$link;
$response = $ua->request(GET $url);
unless($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock, "success"} = 0;
$info{$stock, "errormsg"} = "HTTP failure";
}
return wantarray() ? %info : \%info;
}
$content = $response->content;
my $xls = ReadData($content);
my $start = 1;
while($xls->[1]{"A$start"} !~ /\d+\. Котировки продажи и покупки драгоценных металлов в обезличенном виде/ && $start < 100) {
$start++;
}
my %map = (
'Золото' => 'SBRF.AU',
'Серебро' => 'SBRF.AG',
'Платина' => 'SBRF.PT',
'Палладий' => 'SBRF.PD'
);
while($xls->[1]{"A$start"}) {
$start++;
my $name = $xls->[1]{"A$start"};
if($name) {
my $stock = $map{$name};
next unless($stock);
$info{$stock, "symbol"} = $stock;
$info{$stock, "name"} = $name;
$info{$stock, "currency"} = "RUB";
$info{$stock, "method"} = "sberbank";
$info{$stock, "bid"} = $xls->[1]{"E$start"};
$info{$stock, "ask"} = $xls->[1]{"D$start"};
$info{$stock, "last"} = $info{$stock, "bid"};
$quoter->store_date(\%info, $stock, {today => 1});
$info{$stock, "success"} = 1;
}
}
}
return wantarray() ? %info : \%info;
}
1;
__END__




Рис 5.2. Набор этого поста в emacs.

Очередная часть могучего труда готова. Удачи и успехов в освоении gnucash!

среда, 4 февраля 2009 г.

Reading trends

Давно не смотрел свою статистику в Google.Reader'е. 12,5 тысяч прочитанных новостей, 16 отмеченных звездочками, значит заинтересовало, и либо оставил, либо хотел изучить когда будет время. 2 - расшарил для своих читателей.

Удивило то, что за оверлеем экспериментального гнома кроме меня следит только один человек, на искуственный интеллект подписалось 6 (оно и не удивительно, один спам). Да и вообще, за пакетами в генту через гугл.ридер люди не следят.

Общий вывод - из всего, что меня интересует, стоящим является около 1/10 процента. Меньше десятой части процента. Все остальное - шлак. А остальное меня даже не интересует. Ну или я еще не нашел. Мир ужасно скучный.

пятница, 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, и выдает даже какую-то ошибку при попытке запроса. В следующей части мы постараемся научить его делать более полезные вещи.