diff --git a/lib/format.go b/lib/format.go new file mode 100644 index 0000000..b6e62ea --- /dev/null +++ b/lib/format.go @@ -0,0 +1,26 @@ +// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved. +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +package mop + +import ( + "bytes" + "text/template" +) + +//----------------------------------------------------------------------------- +func Format(message []Message) string { + markup := `{{range .}}{{.Ticker}} ${{.LastTrade}} {{.Change}} +{{end}}...` + + template, err := template.New("screen").Parse(markup) + if err != nil { + panic(err) + } + + buffer := new(bytes.Buffer) + err = template.Execute(buffer, message) + if err != nil { + panic(err) + } + return buffer.String() +} diff --git a/lib/google.go b/lib/google_finance.go similarity index 78% rename from lib/google.go rename to lib/google_finance.go index dc10354..9d6cc77 100644 --- a/lib/google.go +++ b/lib/google_finance.go @@ -72,20 +72,21 @@ type Message struct { 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) + // // 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) // Parse JSON. var message []Message @@ -96,6 +97,7 @@ func Quote(ticker string) []Message { return message } +//----------------------------------------------------------------------------- func sanitize(ascii []byte) []byte { return bytes.Replace(ascii, []byte{'/'}, []byte{}, -1) } diff --git a/lib/profile.go b/lib/profile.go new file mode 100644 index 0000000..b418aab --- /dev/null +++ b/lib/profile.go @@ -0,0 +1,8 @@ +// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved. +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +package mop + +//----------------------------------------------------------------------------- +func LoadProfile() string { + return "coh,atvi,hpq,ibm" +} diff --git a/lib/screen.go b/lib/screen.go new file mode 100644 index 0000000..36c661d --- /dev/null +++ b/lib/screen.go @@ -0,0 +1,123 @@ +// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved. +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +package mop + +import ( + "fmt" + "github.com/michaeldv/just" + "github.com/nsf/termbox-go" + "regexp" + "strings" +) + +// 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, +} + +//----------------------------------------------------------------------------- +func Draw(stocks string) { + message := Quote(stocks) + // for _, m := range message { + // fmt.Printf("%s, %s, %s\n", m.Ticker, m.LastTrade, m.Change) + // } + + drawScreen(Format(message)) +} + +//----------------------------------------------------------------------------- +func Refresh(profile string) { +loop: + for { + switch ev := termbox.PollEvent(); ev.Type { + case termbox.EventKey: + if ev.Key == termbox.KeyEsc { + break loop + } + case termbox.EventResize: + // Draw(profile) + // x, y := termbox.Size() + str := fmt.Sprintf("(%d:%d)", ev.Width, ev.Height) + drawScreen(str + ": Hello world, how are you?") + } + } +} + +// +// Return regular expression that matches all possible color tags, i.e. +// || ... | +//----------------------------------------------------------------------------- +func tagsRegexp() *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 isTag(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 tagName(str string) string { + if str[1:2] != "/" { + return str[1 : len(str)-1] + } else { + return str[2 : len(str)-1] + } +} + +//----------------------------------------------------------------------------- +func drawLine(x int, y int, str string) { + column := 0 + foreground, background := termbox.ColorDefault, termbox.ColorDefault + + for _, token := range just.Split(tagsRegexp(), str) { + if tag, open := isTag(token); tag { + if color, ok := colors[tagName(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 drawScreen(str string) { + termbox.Clear(termbox.ColorDefault, termbox.ColorDefault) + for row, line := range strings.Split(str, "\n") { + drawLine(0, row, line) + } + termbox.Flush() +} diff --git a/mop.go b/mop.go index 0b7cf8d..482dd30 100644 --- a/mop.go +++ b/mop.go @@ -3,103 +3,13 @@ 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) - } + profile := mop.LoadProfile() err := termbox.Init() if err != nil { @@ -107,32 +17,6 @@ func main() { } defer termbox.Close() - markup := `{{range .}}{{.Ticker}} ${{.LastTrade}} {{.Change}} -{{end}}...` - - template, err := template.New("screen").Parse(markup) - if err != nil { - panic(err) - } - - buffer := new(bytes.Buffer) - err = template.Execute(buffer, message) - 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?") - } - } + mop.Draw(profile) + mop.Refresh(profile) }