[mythtv-users] mythstocks.pl - a stock ticker for mythtvosd
Greg Newton
greg.newton at exemail.com.au
Wed Apr 9 07:29:27 UTC 2008
G'day all
Below is a little script I'm using to display stock prices using
mythtvosd. It can optionally calculate the value and change in your
portfolio, and display that at the end of the stock list.
To set up your portfolio, run mythstocks.pl with the -a option once
per stock, e.g.
./mythstocks.pl -a csco
will add Cisco (without any quantity held).
./mythstocks.pl -a msft:100000
will add 100000 shares of Mickeysoft. Alternatively you could edit
~/.mythtv/mythstocks.xml directly, which may prove less cumbersome.
You only need to define a holding quantity if you also enable display
of your portfolio totals, by
./mythstocks.pl -o showtotal:1
If your shares are not held in a major US stock market, you'll need to
determine the suffix used by Yahoo to indicate your market, and define
that with
./mythstocks.pl -o suffix:.AX
(the example is for the ASX). Alternatively you could just specify the
stocks with their suffix included (i.e. ADA.AX for Adacel on the
Australian Stock Exchange).
You can make this fire up with a remote button by doing something like
this in your .licrc file (note the backquotes):
begin
prog = irexec
button = 16.9-4.3
config = mythtvosd --template="scroller"
--scroll_text="`/home/greg/mythstocks.pl`"
end
I hope someone can find this useful :-)
---- snip ----
#!/usr/bin/perl
#-----------------------------------------------------------------------------
# FILENAME: mythstocks.pl
# PROJECT:
# PURPOSE: Read stock prices from Yahoo and print a string suitable for
# use by mythtvosd --template="scroller"
--scroll_text="`mythstocks.pl`"
#
#-----------------------------------------------------------------------------
# REVISION HISTORY
#-----------------------------------------------------------------------------
# Rev | Created by | Date | Changes made
#-------+----------------------------+------------+---------------------------
# 0.0.1 | greg.lazybastard at gmail.com | 17/03/2008 | First test
# 0.0.2 | greg.lazybastard at gmail.com | 08/04/2008 | Move to XML portfolio
#-----------------------------------------------------------------------------
my $ver = '0.0.2';
################################################################
# Use modules
################################################################
# Be strict about the perl
use strict ;
# be lazy about getting cmdline options
use Getopt::Std ;
# for talking http
use LWP::Simple;
# For storage of portfolio
use XML::Simple;
# For pretty timestamps
use POSIX qw(strftime);
# For easy parsing of csv
use Text::CSV;
################################################################
# 'Global' constants
################################################################
my $configfile = $ENV{'HOME'}.'/.mythtv/mythstocks.xml' ;
my $config;
our ($opt_p, $opt_a, $opt_r, $opt_o);
################################################################
# Read the config file if it exists, create it if not
################################################################
read_config(\$config);
# shortcuts to sections of the config file
my $opt = \$config->{'section'}->{'options'};
my $port = \$config->{'section'}->{'portfolio'};
################################################################
# Get command line options
# -p print all options
# -a symbol[:holding] add / update a symbol
# -r symbol remove a symbol
# -o option:value , where option is one of
# showtotal (0,1)
# source (string)
# suffix (string, . must be used to represent no suffix)
# format (string)
################################################################
getopts('pa:r:o:');
# p = print current settings / portfolio
if( defined($opt_p) ) {
printf "mythstocks v$ver\n";
printf "\nCurrent settings (stored in %s):\n",$configfile;
foreach( keys %{$$opt} ) {
printf "\t%12s: %20s\n", $_, ${$opt}->{$_}[0];
}
printf "\nCurrent portfolio:\n";
foreach( keys %{$$port} ) {
printf "\t%12s: %20s\n", $_, ${$port}->{$_}[0];
}
exit 0;
}
# a = add (or modify) a symbol and optionally holding size
if( defined($opt_a) ) {
my ($symbol,$holding) = split /:/, $opt_a ;
$symbol = uc($symbol);
if( !defined($holding) ) {
$holding = '0';
}
${$port}->{$symbol}[0] = $holding;
write_config($config);
printf "Symbol `%s' (holding %s)\nExiting.\n", $symbol, $holding;
exit 0;
}
# r = remove symbol
if( defined($opt_r) ) {
$opt_r = uc($opt_r);
if( defined( ${$port}->{$opt_r}[0] ) ) {
delete ${$port}->{$opt_r}[0];
write_config($config);
printf "Removing %s from portfolio\nExiting.\n", $opt_r;
} else {
printf "Symbol %s not found in the portolio\nExiting.\n", $opt_r;
}
exit 0;
}
# o = set an option - no checking for validity
if( defined($opt_o) ) {
my ($key,$value) = split /:/, $opt_o ;
${$opt}->{$key}[0] = $value;
write_config($config);
printf "Set option `%s' to `%s'\nExiting.\n", $key, $value;
exit 0;
}
# No command line options, default action is to read from yahoo
# Nothing to do unless portfolio contains symbols
my @syms = keys %{$$port};
if( $#syms lt 0 ) {
print "Use 'mythstocks.pl -a symbol[:holding]' to add symbols
to your portfolio";
exit 0;
}
# Jiggery pokey to 'fake' a null suffix. Otherwise XML:Simple returns a hash
my $suffix = ${$opt}->{'suffix'}[0];
if( $suffix eq '.' ) {
$suffix = '';
}
# build url
my $fetchit = "http://".${$opt}->{'source'}[0]."/d/quotes.csv?s=".
join( $suffix.',', @syms ).
$suffix."&f=".${$opt}->{'format'}[0]."&e=.csv";
my $response = get $fetchit;
if( defined($response) ) {
my $scroll_text = '';
my $csv = Text::CSV->new();
my @stocklines = split(/\n/,$response);
my $portfolio = 0.0;
my $portchange = 0.0;
foreach (@stocklines) {
if ($csv->parse($_."\n")) {
my @columns = $csv->fields();
my $sym = substr($columns[0],0,length($columns[0]) -
length($suffix));
$scroll_text .= $sym.' $'.$columns[2].' ('.$columns[5].') ';
if( ${$port}->{uc($sym)}[0] > 0.0 ) {
$portfolio += ( ${$port}->{uc($sym)}[0] * $columns[2] );
$portchange += ( ${$port}->{uc($sym)}[0] * $columns[5] );
}
} else {
my $err = $csv->error_input;
print "Failed to parse line '$_': $err";
}
}
if( ${$opt}->{'showtotal'}[0] ne '0' && $portfolio > 0 ) {
$scroll_text .= sprintf " [\$%0.2f \$%+0.2f %+0.2f%%]",
$portfolio, $portchange, ($portchange*100)/($portfolio-$portchange);
}
print $scroll_text;
} else {
print 'MythStocks regrets that it is unable to fetch stock
prices at this time ';
die $response->status_line;
}
sub read_config
{
my $config_ref = shift;
# No config file exists, create a default one.
if( ! -e $configfile ) {
${$config_ref} = {
'section' => {
'portfolio' => {
'symbol' => [
]
},
'options' => {
'source' => [
'finance.yahoo.com'
],
'showtotal' => [
'0'
],
'format' => [
'snl1d1t1c1ohgvw'
],
'suffix' => [
'.'
]
}
}
};
write_config(${$config_ref});
}
${$config_ref} = XMLin($configfile,KeyAttr => {section => 'name'},
ForceArray => 1);
}
sub write_config
{
my $config = shift;
open CONFIG, '>'.$ENV{'HOME'}.'/.mythtv/mythstocks.xml' or die $!;
print CONFIG XMLout($config,KeyAttr => {section => 'name'});
close CONFIG ;
}
---- snip ----
More information about the mythtv-users
mailing list