diff --git a/lib/google.go b/lib/google.go new file mode 100644 index 0000000..14168f5 --- /dev/null +++ b/lib/google.go @@ -0,0 +1,83 @@ +// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved. +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +package mop + +import ( + // "fmt" + "bytes" + "encoding/json" + "io/ioutil" + "net/http" + // "strings" +) + +const real_time_url = "http://finance.google.com/finance/info?client=ig&q=" + +// body := ` +// // [ +// { +// "id": "22144" +// ,"t" : "AAPL" +// ,"e" : "NASDAQ" +// ,"l" : "416.84" +// ,"l_cur" : "416.84" +// ,"s": "2" +// ,"ltt":"4:00PM EDT" +// ,"lt" : "Jun 20, 4:00PM EDT" +// ,"c" : "-6.16" +// ,"cp" : "-1.46" +// ,"ccol" : "chr" +// ,"el": "416.74" +// ,"el_cur": "416.74" +// ,"elt" : "Jun 20, 7:16PM EDT" +// ,"ec" : "-0.10" +// ,"ecp" : "-0.02" +// ,"eccol" : "chr" +// ,"div" : "3.05" +// ,"yld" : "2.93" +// } +// ]` + +type Message struct { + Ticker string `json:"t"` + LastTrade string `json:"l"` + Change string `json:"c"` +} + +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 err != nil { + panic(err) + } + return message +} + +func sanitize(ascii []byte) []byte { + return bytes.Replace(ascii, []byte{'/'}, []byte{}, -1) +} + +// func sanitize(str string) string { +// r := strings.NewReplacer("//", "", "[", "", "]", "") +// fmt.Printf("%s\n", []byte(r.Replace(str))) +// return r.Replace(str) +// } +// +// func main() { +// +// message := Quote("coh,atvi,hpq,ibm,xxx") +// for _,m := range message { +// fmt.Printf("%s, %s, %s\n", m.Ticker, m.LastTrade, m.Change) +// } +// } diff --git a/mop.go b/mop.go index e69de29..cf6a126 100644 --- a/mop.go +++ b/mop.go @@ -0,0 +1,139 @@ +// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved. +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +package main + +import ( + "bytes" + "fmt" + "github.com/michaeldv/just" + "github.com/michaeldv/mop/lib" + "github.com/nsf/termbox-go" + "regexp" + "strings" + "text/template" +) + +// Can combine attributes and a single color using bitwise OR. +// +// AttrBold Attribute = 1 << (iota + 4) +// AttrUnderline +// AttrReverse +// +var colors = map[string]termbox.Attribute{ + "black": termbox.ColorBlack, + "red": termbox.ColorRed, + "green": termbox.ColorGreen, + "yellow": termbox.ColorYellow, + "blue": termbox.ColorBlue, + "magenta": termbox.ColorMagenta, + "cyan": termbox.ColorCyan, + "white": termbox.ColorWhite, +} + +// +// Return regular expression that matches all possible color tags, i.e. +// || ... | +// +func color_tags() *regexp.Regexp { + tags := []string{} + + for color, _ := range colors { + tags = append(tags, "") + } + + return regexp.MustCompile(strings.Join(tags, "|")) +} + +// +// Return true if a string looks like a tag. +// +func is_tag(str string) (is bool, open bool) { + is = (str[0:1] == "<" && str[len(str)-1:] == ">") + open = (is && str[1:2] != "/") + return +} + +// +// Extract tag name from the given tag, i.e. "" => "hello" +// +func tag_name(str string) string { + if str[1:2] != "/" { + return str[1 : len(str)-1] + } else { + return str[2 : len(str)-1] + } +} + +func draw_color_line(x int, y int, str string) { + column := 0 + foreground, background := termbox.ColorDefault, termbox.ColorDefault + + for _, token := range just.Split(color_tags(), str) { + if tag, open := is_tag(token); tag { + if color, ok := colors[tag_name(token)]; ok { + token = "" + if open { + foreground = color + } else { + foreground = termbox.ColorDefault + } + } + } + + for _, char := range token { + termbox.SetCell(x+column, y, char, foreground, background) + column += 1 + } + } +} + +func draw_screen(str string) { + termbox.Clear(termbox.ColorDefault, termbox.ColorDefault) + for row, line := range strings.Split(str, "\n") { + draw_color_line(0, row, line) + } + termbox.Flush() +} + +func main() { + message := mop.Quote("coh,atvi,hpq,ibm,xxx") + for _, m := range message { + fmt.Printf("%s, %s, %s\n", m.Ticker, m.LastTrade, m.Change) + } + + err := termbox.Init() + if err != nil { + panic(err) + } + defer termbox.Close() + + markup := `line 1: Hello world +line 2: Hello again +line 3: Hello one more time :-)` + + template, err := template.New("screen").Parse(markup) + if err != nil { + panic(err) + } + + buffer := new(bytes.Buffer) + err = template.Execute(buffer, nil) + if err != nil { + panic(err) + } + draw_screen(buffer.String()) + +loop: + for { + switch ev := termbox.PollEvent(); ev.Type { + case termbox.EventKey: + if ev.Key == termbox.KeyEsc { + break loop + } + case termbox.EventResize: + //x, y := termbox.Size() + str := fmt.Sprintf("(%d:%d)", ev.Width, ev.Height) + draw_screen(str + ": Hello world, how are you?") + } + } +}