--lrZ03NoBR/3+SXJZ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable ----- Forwarded message from Collin Starkweather <collin.starkweather@colorado.edu> ----- --=20 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Collin Starkweather http://www.collinstarkweather.com Consulting Software Architect collin.starkweather@colorado.edu Ph.D. Candidate University of Colorado Department of Economics ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #!/usr/bin/perl =3Dhead1 NAME ticker - A stock monitoring client written for Peep: The Network Auralizer. Peep takes virtual events and turns them into unobtrusive sounds like birds chirping, rain falling, crickets doing whatever crickets do, etc. It is mostly used for network and systems monitoring because it is well suited for that task, but I recently added an API to Net::Peep that allows customized clients to be built with very little code. Since there are some stocks I follow I decided to make my first custom client a stock ticker. Thanks to Finance::Quote, it took me about a half-hour to write :-) A rooster crow or doorbell chime tells me that something is happening with my stocks. And at the end of the day, it e-mails me a report on any questionable activity. =3Dhead1 USAGE ./ticker --help ./ticker --noautodiscovery --server=3Dlocalhost --port=3D2001 --nodaemon If you have any problems, try turning on debugging output with something like --debug=3D9. =3Dhead1 CONFIGURATION To use this client, include a section like the following in peep.conf: client ticker class home port 1999 config # Stock symbol Stock exchange Event Max Min RHAT nasdaq red-hat 4.0 3.6 SUNW nasdaq sun-microsystems 9.0 8.0 end config notification notification-hosts localhost notification-recipients bogus.user@bogusdomain.com notification-level warn end notification end client ticker and another section in the events block with something like events #Event Type | Path to Sound File | # of sounds to load ... red-hat /usr/local/share/peep/sounds/misc/events/rooster.* 1 sun-microsystems /usr/local/share/peep/sounds/misc/events/doorbell.* 1 end events =3Dhead1 AUTHOR Collin Starkweather <collin.starkweather@colorado.edu> Copyright (C) 2001 =3Dhead1 SEE ALSO perl(1), peepd(1), Net::Peep, Net::Peep::Client, Net::Peep::BC, Net::Peep::Notifier, Net::Peep::Notification, Finance::Quote http://peep.sourceforge.net =3Dcut # Always use strict :-) use strict; use Net::Peep::BC; use Net::Peep::Log; use Net::Peep::Client; use Net::Peep::Notifier; use Net::Peep::Notification; use Finance::Quote; use vars qw{ %config $logger $client $quoter $conf }; # The Net::Peep::Log object will allow us to print out some things in # a nicely formatted way so we can tell ourselves what we're doing ... $logger =3D new Net::Peep::Log; # Instantiate a Peep client object. The client object handles most of # the dirty work for us so we don't have to worry about things such as # forking in daemon mode or parsing the command-line options or the # Peep configuration file. For more information, perldoc # Net::Peep::Client $client =3D new Net::Peep::Client; $quoter =3D new Finance::Quote; # First we have to give the client a name $client->name('ticker'); # Now we initialize the client. If the initialization returns a false # value, we display documentation for the script. $client->initialize() || $client->pods(); # Now we assign a parser that will parse the 'ticker' section of the # Peep configuration file $client->parser( \&parse ); # Now we tell the client to get the information from the configuration # file. It returns a Net::Peep::Conf, the Peep configuration object, # which contains information from the configuration file. $conf =3D $client->configure(); # Register a callback which will be executed every 60 seconds. The # callback is simply a function which checks the price of the stock # and peeps every time it exceeds the maximum or minimum price that # has been set. $client->callback( \&loop ); # Start looping. The callback will be executed every 60 seconds ... $client->MainLoop(60); sub parse { # Parse the config section for the ticker client in the Peep # configuration file # We'll use a regular expression to extract the ticker information # and stuff it into a data structure (the global variable %config) # This subroutine will be used to parse lines from peep.conf such # as the following and store the information in %config: # RHAT nasdaq red-hat 4.0 3.6 # SUNW nasdaq sun-microsystems 9.0 8.0 for my $line (@_) { if ($line =3D~ /^\s*([A-Z]+)\s+(\w+)\s+([\w\-]+)\s+([\d\.]+)\s+([\d\.]+)/) { my ($symbol,$exchange,$event,$max,$min) =3D ($1,$2,$3,$4,$5,$6); $config{$symbol} =3D { event=3D>$event, exchange=3D>$exchange, max=3D>$max, min=3D>$min }; } } } # end sub parse sub loop { for my $key (sort keys %config) { $logger->log("Checking the price of [$key] ..."); # Fetch some information about the stock including the price my %results =3D $quoter->fetch($config{$key}->{'exchange'},$key); my $price =3D $results{$key,'price'}; $logger->log("\tThe price of [$key] is [$price]."); if ($price > $config{$key}->{'max'} or $price < $config{$key}->{'min'}) { $logger->log("\tThe price is out of bounds! Sending notification ...."); # The price is out of bounds! We'll start peeping ... my $broadcast =3D Net::Peep::BC->new('ticker',$conf); $broadcast->send('ticker', type=3D>0, sound=3D>$config{$key}->{'event'}, location=3D>128, priority=3D>0, volume=3D>255); # In case we're away from our desk, we'll also send out an # e-mail notification. Don't want to miss the action! my $notifier =3D new Net::Peep::Notifier; my $notification =3D new Net::Peep::Notification; $notification->client('ticker'); $notification->status('crit'); $notification->datetime(time()); $notification->message("The price of $key is $price!"); $notifier->notify($notification); } } } # end sub loop __END__ ----- End forwarded message ----- --=20 pub 1024D/01045933 2001-02-01 Linas Vepstas (Labas!) <linas@linas.org> Key fingerprint =3D 8305 2521 6000 0B5E 8984 3F54 64A9 9A82 0104 5933 --lrZ03NoBR/3+SXJZ Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQE7vHhhZKmaggEEWTMRAlZUAJ0SH50zzbJD2fWt8NY0wTY/BtzC+QCeKTvT 2GDMiBJSV4JMR0YdDp4ewVY=TM+A -----END PGP SIGNATURE----- --lrZ03NoBR/3+SXJZ--