# stock.ka v1 by conio (sam@conio.net)
# simple stock quote checker.
set stock(line) ""
set stock(value) 0.00
proc tag_strip fix {
while { [set x [string first < $fix]] != -1 && [set y [string first > $fix]] > $x } {
set fix [string range $fix 0 [expr $x - 1]][string range $fix [expr $y + 1] end]
}
while { [set x [string first & $fix]] != -1 && [set y [string first \; $fix]] > $x } {
set fix [string range $fix 0 [expr $x - 1]][string range $fix [expr $y + 1] end]
}
return $fix
}
proc put_stock { sock mode what } {
switch $mode {
0 { puts $sock "GET /q?s=${what}&d=t" }
1 { puts $sock "GET /l?s=$what" }
}
fileevent $sock writable ""
}
proc frac2dec fraction {
catch {set y [expr ([join [string trim [join [split "[string trim $fraction] " " "] ".0 "]] ") + double("])]}
if [info exists y] {return $y} {return $fraction}
}
proc portfolio args {
set symbol [lindex $args 0]
set value [lindex $args 1]
set x [string toupper [get_cookie stock_portfolio "{^DJI 0} {^IXIC 0} {^SPC 0}"]]
if { $symbol != "" } {
if { [set y [lsearch $x "[string toupper $symbol] *"]] != -1 } {
if { $value == "" } {
if [set z [lindex [lindex $x $y] 1]] {return $z} {return -}
} else {
return [format %.2f [expr {[frac2dec $value] * [lindex [lindex $x $y] 1]}]]
}
} else { return - }
} else {
set z ""
foreach y $x { lappend z [lindex $y 0] }
return $z
}
}
proc get_stock { sock mode } {
global stock litehelp darkhelp
if [eof $sock] {
close $sock
echo "[kano] Finished." query .stock.
return
}
if ![window exists query .stock.] {
/query .stock.
window set_title "YAHOO.COM Stock Quotes" query .stock.
echo "[kano] Yahoo! Stock Quotes (http://quote.yahoo.com/)" query .stock.
}
gets $sock x
switch -glob -- $x {
"*Create New View]
*" {
gets $sock x
echo "[kano] $x" query .stock.
echo [format "${litehelp}%-6s %-16s %-16s %-10s %-8s %-10s" "" Name "Last Trade" Change Shares Value] query .stock.
} "
| *" {
lappend stock(line) [string range $x [expr [string first : $x] + 1] [expr [string first ) $x] - 1]]
lappend stock(line) [string trim [string range $x [expr [string first $x] + 3] [expr [string first $x] - 1]]]
} " | Last Trade*" {
gets $sock ; gets $sock x
lappend stock(line) [string trim [string range $x 0 [expr [string first & $x] - 1]]]: [tag_strip [string range $x [expr [string first $x] + 3] end]]
} " | Change*" {
gets $sock ; gets $sock x
set x [tag_strip $x]
lappend stock(line) [string trim [string range $x 0 [string first " (" $x]]]
} " |
| Symbol*" {
gets $sock ; gets $sock x
lappend stock(line) [tag_strip $x]
} "No such ticker symbol.*" {
lappend stock(line) "No such symbol"
} " |
*" {
if { $stock(line) != "" } {
set x [portfolio [lindex $stock(line) 0] [lindex $stock(line) 3]]
if { $x != "-" } { set stock(value) [expr $stock(value) + $x] }
echo [format "${litehelp}%-6s ${darkhelp}%-16s %-16s %-10s %-8s %-10s" [lindex $stock(line) 0] [lindex $stock(line) 1] "[lindex $stock(line) 2] [lindex $stock(line) 3]" [lindex $stock(line) 4] [portfolio [lindex $stock(line) 0] ""] \$$x] query .stock.
set stock(line) ""
}
} "*Quotes delayed 15 minutes*" {
if $stock(value) {
echo [format "${litehelp}%-60s ${darkhelp}\$%.2f" Total $stock(value)] query .stock.
set stock(value) 0.00
}
} "*Symbol search for*" {
echo "[kano] Symbol search for [string range $x [expr [string first $x] + 3] [string first ' $x]]:" query .stock.
echo [format "${litehelp}%-6s %-64s" "" Name] query .stock.
} "* | *" {
gets $sock y
echo [format "${litehelp}%-6s ${darkhelp}%s" [tag_strip $x] [tag_strip $y]] query .stock.
} "*Your search for*no matches*" {
echo "[kano] Search for [string range $x [expr [string first $x] + 3] [string first ' $x]] returned no matches." query .stock.
} "*Your search for*too many*" {
echo "[kano] Search for [string range $x [expr [string first $x] + 3] [string first ' $x]] returned too many matches; the first 200 will be displayed." query .stock.
}
}
}
alias stock {
do_stock [args]
complete
}
alias portfolio {
set il ""
switch -glob -- [lindex [args] 0] {
-rem {set dowhat "Remove Add"}
-err {set perr [join [lrange [args] 1 end]]}
}
set top 5
if ![info exists dowhat] {set dowhat "Add Remove"}
if [info exists perr] {
lappend il [list label pe 5 5 190 20 $perr]
incr top 20
unset perr
}
lappend il [list combo addrem 5 [expr $top + 10] 45 100 $dowhat]
set symbol ""
set value ""
foreach i [get_cookie stock_portfolio "{^DJI 0} {^IXIC 0} {^SPC 0}"] {
lappend symbol [lindex $i 0]
lappend value [lindex $i 1]
}
lappend il [list label l1 55 $top 75 100 "Ticker symbol:"]
lappend il [list label l2 135 $top 135 100 "Shares owned:"]
lappend il [list combo -e chan 55 [expr $top + 10] 75 100 $symbol]
lappend il [list combo -e chanfix 135 [expr $top + 10] 65 100 $value]
set ans [FALC_dialog -t "Stock Portfolio" 205 [expr $top + 30] $il]
set ch [lindex [lindex $ans 1] 1]
set fix [lindex [lindex $ans 2] 1]
if { $ans != "" } {
if { [lindex [lindex $ans 0] 1] == "Add" } {
set x [get_cookie stock_portfolio "{^DJI 0} {^IXIC 0} {^SPC 0}"]
if { [set y [lsearch $x "[string toupper $ch] *"]] != -1 } {
if { [lindex $x $y] == "[string toupper $ch] $fix" } {
echo "[kano] [llength [get_cookie stock_portfolio "{^DJI 0} {^IXIC 0} {^SPC 0}"]] stock(s): [join [get_cookie stock_portfolio "{^DJI 0} {^IXIC 0} {^SPC 0}"] ", "]."
} else {
set_cookie stock_portfolio [lreplace $x $y $y "[string toupper $ch] $fix"]
/portfolio
}
} elseif { [string trim $fix] == "" } {
/portfolio -err Error: You must specify the number of shares you own for each symbol.
} elseif ![isnum $fix] {
/portfolio -err Error: You must specify an integer for 'Shares owned.'
} else {
lappend x [list [string toupper $ch] $fix]
set_cookie stock_portfolio $x
/portfolio
}
} else {
set t ""
foreach i [get_cookie stock_portfolio "{^DJI 0} {^IXIC 0} {^SPC 0}"] {
if { [string toupper [lindex $i 0]] != [string toupper $ch] } {
lappend t $i
}
}
set_cookie stock_portfolio $t
/portfolio -rem
}
} else { echo "[kano] [llength [get_cookie stock_portfolio "{^DJI 0} {^IXIC 0} {^SPC 0}"]] stock(s): [join [get_cookie stock_portfolio "{^DJI 0} {^IXIC 0} {^SPC 0}"] ", "]." }
complete
}
alias privmsg {
if { [string tolower [lindex [args] 0]] == ".stock." && [string tolower [query]] == ".stock." } {
do_stock [lrange [join [args]] 1 end]
}
}
proc do_stock args {
global stock
set args [join $args]
switch -- [lindex $args 0] {
search {
if { [lindex $args 1] != "" } {
if ![catch {socket quote.yahoo.com 80} stock(sock)] {
fconfigure $stock(sock) -buffering line -blocking 0
fileevent $stock(sock) writable "put_stock $stock(sock) 1 [string toupper [rep [lrange [join $args] 1 end] " " "+"]]"
fileevent $stock(sock) readable "get_stock $stock(sock) 1"
} else { echo [rep [rep [t socketfailed] %type Stock] %error $stock(sock)] }
echo "[kano] Searching for ticker symbol..."
} else { echo "[kano] Please enter a symbol to search for." }
} default {
if { [lindex $args 0] == "" || [lindex $args 0] == "portfolio" } { set args [join [portfolio]] }
if ![catch {socket quote.yahoo.com 80} stock(sock)] {
fconfigure $stock(sock) -buffering line -blocking 0
fileevent $stock(sock) writable "put_stock $stock(sock) 0 [string toupper [rep [join $args] " " "+"]]"
fileevent $stock(sock) readable "get_stock $stock(sock) 0"
} else { echo [rep [rep [t socketfailed] %type Stock] %error $stock(sock)] }
echo "[kano] Retrieving stock quotes..."
}
}
}
addecho "[kano] stock.ka v1 by conio (sam@conio.net) loaded"
addname stock.ka
kaddhelp stock "Retrieves stock quotes from quote.yahoo.com. When no arguments are specified, your portfolio is displayed. The \"search\" argument searches for a ticker symbol.\n \n${litehelp}Note: If the stock window is already open, these commands can be issued in the window without typing \"/stock\" first." "/stock \[ ...]\n/stock search " "Retrieve Stock Quotes" "/portfolio"
kaddhelp portfolio "Edits your stock portfolio." "/portfolio" "Edit Stock Portfolio" "/stock"