Added colors and proper column alignment

master
Michael Dvorkin 12 years ago
parent cf92c5f858
commit 7cf1d8fba2
  1. 87
      lib/format.go
  2. 186
      lib/google_finance.go
  3. 2
      lib/profile.go
  4. 10
      lib/screen.go
  5. BIN
      mop

@ -4,6 +4,7 @@ package mop
import (
"bytes"
"fmt"
"text/template"
"time"
)
@ -15,11 +16,14 @@ func Format(message []Message) string {
Stocks []Message
}{
time.Now().Format("3:04:05pm PST"),
message,
prettify(message),
}
markup := `Hello<right>{{.Now}}</right>
{{range .Stocks}}<green>{{.Ticker}}</green> ${{.LastTrade}} <red>{{.Change}}</red>
markup :=
`Hello<right>{{.Now}}</right>
Ticker Last trade Change % Change Dividend Yield
{{range .Stocks}}{{.Color}}{{.Ticker}} {{.LastTrade}} {{.Change}} {{.ChangePercent}} {{.Dividend}} {{.Yield}}
{{end}}...`
template, err := template.New("screen").Parse(markup)
@ -35,3 +39,80 @@ func Format(message []Message) string {
return buffer.String()
}
func color(m Message) string {
return "x"
}
func prettify(message []Message) []Message {
pretty := make([]Message, len(message))
for i, m := range message {
pretty[i].Ticker = pad(m.Ticker, -10)
pretty[i].LastTrade = pad(with_currency(m.LastTrade), 10)
pretty[i].CurrentPrice = pad(with_currency(m.CurrentPrice), 10)
pretty[i].Change = pad(with_currency(m.Change), 10)
pretty[i].ChangePercent = pad(with_percent(m.ChangePercent), 10)
// ExLastTrade string `json:"el"`
// ExCurrentPrice string `json:"el_cur"`
// ExLastTradeDateTime string `json:"elt"`
// ExChange string `json:"ec"`
// ExChangePercentage string `json:"ecp"`
pretty[i].Dividend = pad(with_currency(nullify(m.Dividend)), 10)
pretty[i].Yield = pad(with_currency(nullify(m.Yield)), 10)
}
// fmt.Printf("%q", pretty)
return pretty
}
func nullify(str string) string {
if len(str) > 0 {
return str
} else {
return "-"
}
}
func with_currency(str string) string {
if str == "-" {
return str
} else {
switch str[0:1] {
case "+", "-":
return str[0:1] + "$" + str[1:]
default:
return "$" + str
}
}
}
func with_percent(str string) string {
if str == "-" {
return str
} else if str[0:1] != "-" {
return "+" + str + "%"
} else {
return str + "%"
}
}
func colorize(str string) string {
if str == "-" {
return str
} else if str[0:1] == "-" {
return "<red>" + str + "</red>"
} else {
return "<green>" + str + "</green>"
}
}
func ticker(str string, change string) string {
if change[0:1] == "-" {
return "<red>" + str + "</red>"
} else {
return "<green>" + str + "</green>"
}
}
func pad(str string, width int) string {
return fmt.Sprintf("%*s", width, str)
}

@ -5,95 +5,131 @@ package mop
import (
"bytes"
"encoding/json"
// "io/ioutil"
// "net/http"
"io/ioutil"
"net/http"
"strings"
"time"
)
const real_time_url = "http://finance.google.com/finance/info?client=ig&q="
const body = `
// [
{
"id": "665300"
,"t" : "COH"
,"e" : "NYSE"
,"l" : "56.54"
,"l_cur" : "56.54"
,"s": "0"
,"ltt":"4:01PM EDT"
,"lt" : "Jun 21, 4:01PM EDT"
,"c" : "-0.75"
,"cp" : "-1.31"
,"ccol" : "chr"
}
,{
"id": "353353"
,"t" : "ATVI"
,"e" : "NASDAQ"
,"l" : "13.55"
,"l_cur" : "13.55"
,"s": "0"
,"ltt":"3:59PM EDT"
,"lt" : "Jun 21, 3:59PM EDT"
,"c" : "-0.33"
,"cp" : "-2.38"
,"ccol" : "chr"
}
,{
"id": "17154"
,"t" : "HPQ"
,"e" : "NYSE"
,"l" : "24.15"
,"l_cur" : "24.15"
,"s": "0"
,"ltt":"4:01PM EDT"
,"lt" : "Jun 21, 4:01PM EDT"
,"c" : "-0.57"
,"cp" : "-2.31"
,"ccol" : "chr"
}
,{
"id": "18241"
,"t" : "IBM"
,"e" : "NYSE"
,"l" : "195.46"
,"l_cur" : "195.46"
,"s": "0"
,"ltt":"4:02PM EDT"
,"lt" : "Jun 21, 4:02PM EDT"
,"c" : "-1.89"
,"cp" : "-0.96"
,"ccol" : "chr"
}
]`
// const body = `
// // [
// {
// "id": "22144"
// ,"t" : "AAPL"
// ,"e" : "NASDAQ"
// ,"l" : "393.78"
// ,"l_cur" : "393.78"
// ,"s": "2"
// ,"ltt":"4:00PM EDT"
// ,"lt" : "Jun 27, 4:00PM EDT"
// ,"c" : "-4.29"
// ,"cp" : "-1.08"
// ,"ccol" : "chr"
// ,"el": "393.40"
// ,"el_cur": "393.40"
// ,"elt" : "Jun 27, 5:04PM EDT"
// ,"ec" : "-0.38"
// ,"ecp" : "-0.10"
// ,"eccol" : "chr"
// ,"div" : "3.05"
// ,"yld" : "3.10"
// }
// ,{
// "id": "353353"
// ,"t" : "ATVI"
// ,"e" : "NASDAQ"
// ,"l" : "13.55"
// ,"l_cur" : "13.55"
// ,"s": "0"
// ,"ltt":"3:59PM EDT"
// ,"lt" : "Jun 21, 3:59PM EDT"
// ,"c" : "-0.33"
// ,"cp" : "-2.38"
// ,"ccol" : "chr"
// }
// ,{
// "id": "17154"
// ,"t" : "HPQ"
// ,"e" : "NYSE"
// ,"l" : "24.15"
// ,"l_cur" : "24.15"
// ,"s": "0"
// ,"ltt":"4:01PM EDT"
// ,"lt" : "Jun 21, 4:01PM EDT"
// ,"c" : "0.57"
// ,"cp" : "2.31"
// ,"ccol" : "chr"
// }
// ,{
// "id": "18241"
// ,"t" : "IBM"
// ,"e" : "NYSE"
// ,"l" : "195.46"
// ,"l_cur" : "195.46"
// ,"s": "0"
// ,"ltt":"4:02PM EDT"
// ,"lt" : "Jun 21, 4:02PM EDT"
// ,"c" : "-1.89"
// ,"cp" : "-0.96"
// ,"ccol" : "chr"
// }
// ]`
type Message struct {
Ticker string `json:"t"`
LastTrade string `json:"l"`
Change string `json:"c"`
Ticker string `json:"t"`
Exchange string `json:"e"`
LastTrade string `json:"l"`
CurrentPrice string `json:"l_cur"`
LastTradeTime string `json:"ltt"`
LastTradeDateTime string `json:"lt"`
Change string `json:"c"`
ChangePercent string `json:"cp"`
ExLastTrade string `json:"el"`
ExCurrentPrice string `json:"el_cur"`
ExLastTradeDateTime string `json:"elt"`
ExChange string `json:"ec"`
ExChangePercent string `json:"ecp"`
Dividend string `json:"div"`
Yield string `json:"yld"`
}
var message []Message
func (m *Message) Color() string {
if strings.Index(m.Change, "-") == -1 {
return "</green><green>"
} else {
return "</red><red>"
}
}
//-----------------------------------------------------------------------------
func Quote(ticker string) []Message {
// // Send the request.
// response, err := http.Get(real_time_url + ticker)
// if err != nil {
// panic(err)
// }
//
// // Fetch response and get its body.
// defer response.Body.Close()
// body, err := ioutil.ReadAll(response.Body)
//
// // Parse JSON.
// var message []Message
// err = json.Unmarshal(sanitize(body), &message)
if len(message) > 0 && time.Now().Second()%5 != 0 { // Fetch quotes every 5 seconds.
return message
}
// Send the request.
response, err := http.Get(real_time_url + ticker)
if err != nil {
panic(err)
}
// Fetch response and get its body.
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
// Parse JSON.
var message []Message
err := json.Unmarshal(sanitize([]byte(body)), &message)
err = json.Unmarshal(sanitize(body), &message)
// Parse JSON.
// err := json.Unmarshal(sanitize([]byte(body)), &message)
if err != nil {
panic(err)
}
return message
}

@ -4,5 +4,5 @@ package mop
//-----------------------------------------------------------------------------
func LoadProfile() string {
return "coh,atvi,hpq,ibm"
return "aapl,atvi,c,coh,goog,hpq,ibm,ma,tsla,v,yhoo,inin,crm,saas"
}

@ -30,9 +30,11 @@ var tags = map[string]termbox.Attribute{
//-----------------------------------------------------------------------------
func Draw(stocks string) {
message := Quote(stocks)
// for _, m := range message {
// fmt.Printf("%s, %s, %s\n", m.Ticker, m.LastTrade, m.Change)
// fmt.Printf("%s, %s, %s\n", m.Ticker, m.LastTrade, m.Change)
// }
// fmt.Printf("%s\n", Format(message))
drawScreen(Format(message))
}
@ -55,7 +57,7 @@ func tagsRegexp() *regexp.Regexp {
// Return true if a string looks like a tag.
//-----------------------------------------------------------------------------
func isTag(str string) (is bool, open bool) {
is = (str[0:1] == "<" && str[len(str)-1:] == ">")
is = (len(str) > 3 && str[0:1] == "<" && str[len(str)-1:] == ">")
open = (is && str[1:2] != "/")
return
}
@ -64,7 +66,9 @@ func isTag(str string) (is bool, open bool) {
// Extract tag name from the given tag, i.e. "<hello>" => "hello"
//-----------------------------------------------------------------------------
func tagName(str string) string {
if str[1:2] != "/" {
if len(str) < 3 {
return ""
} else if str[1:2] != "/" {
return str[1 : len(str)-1]
} else {
return str[2 : len(str)-1]

BIN
mop

Binary file not shown.
Loading…
Cancel
Save