diff options
Diffstat (limited to '')
-rw-r--r-- | scripts/xetra.pl | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/scripts/xetra.pl b/scripts/xetra.pl new file mode 100644 index 0000000..ae28266 --- /dev/null +++ b/scripts/xetra.pl @@ -0,0 +1,209 @@ +# by Stefan 'tommie' Tomanek <stefan@pico.ruhr.de> +use strict; + +use vars qw($VERSION %IRSSI); +$VERSION = "20030208"; +%IRSSI = ( + authors => "Stefan 'tommie' Tomanek", + contact => "stefan\@pico.ruhr.de", + name => "Xetra", + description => "brings the stock exchanges of the world to your irssi", + license => "GPLv2", + changed => "$VERSION", + sbitems => "xetra", + commands => "xetra" +); + + +use Irssi 20020324; +use Irssi::TextUI; +use LWP::Simple; +use vars qw($forked @ticker $shift $timer); + +sub draw_box ($$$$) { + my ($title, $text, $footer, $colour) = @_; + my $box = ''; + $box .= '%R,--[%n%9%U'.$title.'%U%9%R]%n'."\n"; + foreach (split(/\n/, $text)) { + $box .= '%R|%n '.$_."\n"; + } + $box .= '%R`--<%n'.$footer.'%R>->%n'; + $box =~ s/%.//g unless $colour; + return $box; +} + +sub show_help() { + my $help=$IRSSI{name}." ".$VERSION." +/xetra update + Retrieve new stock information for ticker +/xetra get WKN/EXC + Retrieve data for stock <WKN> at stock exchange <EXC> +"; + my $text = ''; + foreach (split(/\n/, $help)) { + $_ =~ s/^\/(.*)$/%9\/$1%9/; + $text .= $_."\n"; + } + print CLIENTCRAP draw_box($IRSSI{name}." help", $text, "help", 1) ; +} + +sub stock ($) { + if ($_[0] =~ /^(.*?)\/(.*?)$/) { + return $_[0]; + } elsif ($_[0] =~ /^(.*?)\.(.*?)$/) { + return $_[0].'/'.$2; + } else { + my $exchange = Irssi::settings_get_str('xetra_default_stock_exchange'); + return $_[0].'/'.$exchange if ($_[0] =~ /^\d+$/); + return $_[0].'.'.$exchange.'/'.$exchange; + } +} + +sub get_stock ($$) { + my ($wkn, $exchange) = @_; + #my $data = get('http://informer2.comdirect.de/de/default/_pages/fokus/main.html?sSymbol='.$symbol); + my $data = get('http://informer2.comdirect.de/de/suche/main.html?nop=0&searchButton=Exakt&searchfor='.$wkn.'&XsearchBoersen='.$exchange); + my $stock; + if ($data =~ / WKN: (.*?) /) { + $stock->{wkn} = $1; + } + if ($data =~ /<th class="right">( |<img src="\/_common\/images\/pfeil_.*?\.gif" width=11 height=10 alt="">) (.*?)<\/th>/) { + $stock->{current} = $2; + } + if ($data =~ /<td align="right"><b><div class="color.*?"><nobr> (.*?) <\/nobr><\/div><\/b><\/td>/) { + $stock->{change} = $1; + } + if ($data =~ /Symbol: (.*?)</) { + $stock->{symbol} = $1; + } + if ($data =~ /Börse: (.*?) /) { + $stock->{exchange} = $1; + } + if ($data =~ /<nobr> ([0-9,+-]+\%) <\/nobr>/) { + $stock->{percent} = $1; + } + if ($data =~ /<td align="right">(\d+)\.(\d+)\. <\/td><td align="right">(\d+):(\d+) <\/td>/) { + $stock->{date} = $1.'.'.$2.'.'; + $stock->{time} = $3.':'.$4; + } + return $stock; +} + +sub bg_fetch ($$) { + my ($symbols, $job) = @_; + my ($rh, $wh); + pipe($rh, $wh); + return if $forked > 3; + $forked++; + my $pid = fork(); + if ($pid > 0) { + close $wh; + Irssi::pidwait_add($pid); + my ($pipetag); + my @args = ($rh, \$pipetag, $job); + $pipetag = Irssi::input_add(fileno($rh), INPUT_READ, \&pipe_input, \@args); + } else { + my $result; + foreach (@$symbols) { + $_ = stock($_); + my ($wkn, $exchange) = split('/', $_); + my $item = get_stock($wkn, $exchange); + push @$result, $item; + } + my $dumper = Data::Dumper->new([$result]); + $dumper->Purity(1)->Deepcopy(1); + my $data = $dumper->Dump; + print($wh $data); + close($wh); + POSIX::_exit(1); + } +} + +sub pipe_input ($$$) { + my ($rh, $pipetag, $job) = @{$_[0]}; + $forked--; + my $text; + $text .= $_ foreach (<$rh>); + close($rh); + Irssi::input_remove($$pipetag); + return unless($text); + no strict; + my $result = eval "$text"; + return unless ref $result; + if ($job eq 'ticker') { + @ticker = @$result; + Irssi::statusbar_items_redraw('xetra'); + } elsif ($job eq 'get') { + foreach (@$result) { + show_stock($_); + } + } +} + +sub show_stock ($) { + my ($stock) = @_; + my $text; + $text .= '%9WKN:%9 '.$stock->{wkn}." (".$stock->{exchange}.")\n"; + $text .= '%9Current:%9 '.$stock->{current}."\n"; + $text .= '%9Change:%9 '.$stock->{change}.' ('.$stock->{percent}.")\n\n"; + $text .= $stock->{date}.", ".$stock->{time}."\n"; + print CLIENTCRAP &draw_box('Xetra stockinfo', $text, $stock->{symbol}, 1); +} + +sub update_ticker { + my @stocks = split(/ /, Irssi::settings_get_str('xetra_ticker_stocks')); + bg_fetch(\@stocks, 'ticker'); +} + +sub show_ticker ($$) { + my ($item, $get_size_only) = @_; + $shift = 0 if $shift+1 > scalar(@ticker); + return unless defined $ticker[$shift]; + my $tape; + $_ = $ticker[$shift]; + $tape .= $_->{symbol}.': '; + $tape .= $_->{current}.' '; + if ($_->{change} =~ /^\+/) { + $tape .= '%g'; + } elsif ($_->{change} =~ /^\-/) { + $tape .= '%r'; + } + $tape .= $_->{change}.'%n'; + + $shift++ unless $get_size_only; + my $format = "{sb ".$tape."}"; + $item->{min_size} = $item->{max_size} = length($tape); + $item->default_handler($get_size_only, $format, 0, 1); + Irssi::timeout_remove($timer); + $timer = Irssi::timeout_add(Irssi::settings_get_int('xetra_ticker_interval')*1000, 'update_ticker', undef); +} + +sub cmd_xetra ($$$) { + my ($args, $server, $witem) = @_; + my @arg = split(/ /, $args); + return unless defined $arg[0]; + if ($arg[0] eq 'get' && defined $arg[1]) { + shift(@arg); + bg_fetch(\@arg, 'get'); + } elsif ($arg[0] eq 'update') { + update_ticker(); + } elsif ($arg[0] eq 'help') { + show_help(); + } +} + +Irssi::statusbar_item_register('xetra', 0, 'show_ticker'); + +Irssi::settings_add_str($IRSSI{name}, 'xetra_default_stock_exchange', 'ETR'); +Irssi::settings_add_str($IRSSI{name}, 'xetra_ticker_stocks', ''); +Irssi::settings_add_int($IRSSI{name}, 'xetra_ticker_interval', 3); + +Irssi::command_bind('xetra' => \&cmd_xetra); +foreach my $cmd ('get', 'update', 'help') { + Irssi::command_bind('xetra '.$cmd => sub { cmd_xetra("$cmd ".$_[0], $_[1], $_[2]);}); +} + +$timer = Irssi::timeout_add(Irssi::settings_get_int('xetra_ticker_interval')*1000, 'update_ticker', undef); +update_ticker(); + +print CLIENTCRAP '%B>>%n '.$IRSSI{name}.' '.$VERSION.' loaded: /xetra help for help'; |