diff --git a/lib/format.go b/lib/format.go
index 44a48d6..0a72da2 100644
--- a/lib/format.go
+++ b/lib/format.go
@@ -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{{.Now}}
-{{range .Stocks}}{{.Ticker}} ${{.LastTrade}} {{.Change}}
+ markup :=
+ `Hello{{.Now}}
+
+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 "" + str + ""
+ } else {
+ return "" + str + ""
+ }
+}
+
+func ticker(str string, change string) string {
+ if change[0:1] == "-" {
+ return "" + str + ""
+ } else {
+ return "" + str + ""
+ }
+}
+
+func pad(str string, width int) string {
+ return fmt.Sprintf("%*s", width, str)
+}
diff --git a/lib/google_finance.go b/lib/google_finance.go
index 9d6cc77..948fddf 100644
--- a/lib/google_finance.go
+++ b/lib/google_finance.go
@@ -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 ""
+ } else {
+ return ""
+ }
}
//-----------------------------------------------------------------------------
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
}
diff --git a/lib/profile.go b/lib/profile.go
index b418aab..73a9bca 100644
--- a/lib/profile.go
+++ b/lib/profile.go
@@ -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"
}
diff --git a/lib/screen.go b/lib/screen.go
index dc3c32b..97d8d8f 100644
--- a/lib/screen.go
+++ b/lib/screen.go
@@ -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"
//-----------------------------------------------------------------------------
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]
diff --git a/mop b/mop
new file mode 100755
index 0000000..144fd25
Binary files /dev/null and b/mop differ