diff --git a/hummhumm.go b/hummhumm.go index 4bb532e..021681f 100644 --- a/hummhumm.go +++ b/hummhumm.go @@ -9,7 +9,10 @@ import ( "log" // "math" "net/http" + //"sort" + "os/exec" "strconv" + "sync" "time" ) @@ -30,54 +33,44 @@ type HnItem struct { } const apiUrl string = "https://hacker-news.firebaseio.com/v0" +const numstories int = 30 -func (h *HnStories) populateStories(numstories int, done chan bool, widget *widgets.Gauge) { - var item string +func (h *HnStories) fetchHNStories(item string, wg *sync.WaitGroup) { + defer wg.Done() var itemUrl string - var counter int = 1 - for _, id := range h.Items[:numstories] { - item = strconv.Itoa(id) - itemUrl = apiUrl + "/item/" + item + ".json" - timeout := time.Duration(5 * time.Second) - client := &http.Client{ - Timeout: timeout, - } - request, err := http.NewRequest("GET", itemUrl, nil) - if err != nil { - log.Println(err) - } - response, err := client.Do(request) - if err != nil { - log.Println(err) - } - storydata, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Println(err) - } - - var item HnItem - - json.Unmarshal(storydata, &item) - - h.Stories = append(h.Stories, HnItem{ - By: item.By, - Id: item.Id, - Added: item.Added, - Title: item.Title, - Type: item.Type, - Url: item.Url, - Kids: item.Kids, - }) - counter++ - fcounter := float64(counter) - fnumstories := float64(numstories) - percentage := (fcounter / fnumstories) * 100 - widget.Percent = int(percentage) - termui.Render(widget) + itemUrl = apiUrl + "/item/" + item + ".json" + timeout := time.Duration(5 * time.Second) + client := &http.Client{ + Timeout: timeout, } - widget.Percent = 100 - done <- true + request, err := http.NewRequest("GET", itemUrl, nil) + if err != nil { + log.Println(err) + } + response, err := client.Do(request) + if err != nil { + log.Println(err) + } + storydata, err := ioutil.ReadAll(response.Body) + if err != nil { + log.Println(err) + } + + var story HnItem + + json.Unmarshal(storydata, &story) + + h.Stories = append(h.Stories, HnItem{ + By: story.By, + Id: story.Id, + Added: story.Added, + Title: story.Title, + Type: story.Type, + Url: story.Url, + Kids: story.Kids, + }) } + func (h *HnStories) httpHNFetchIds(url string, done chan bool) { timeout := time.Duration(5 * time.Second) client := &http.Client{ @@ -99,7 +92,7 @@ func (h *HnStories) httpHNFetchIds(url string, done chan bool) { done <- true } -func (h *HnStories) httpHNDisplayStories(numstories int, done chan []string) { +func (h *HnStories) httpHNDisplayStories(numstories int) []string { counter := 1 var termuiitems []string for _, item := range h.Stories[:numstories] { @@ -107,7 +100,7 @@ func (h *HnStories) httpHNDisplayStories(numstories int, done chan []string) { termuiitems = append(termuiitems, itemstring) counter++ } - done <- termuiitems + return termuiitems } func main() { @@ -127,84 +120,110 @@ func main() { g0.BorderStyle.Fg = termui.ColorWhite hnurl := apiUrl + "/topstories.json" var a HnStories - var numstories = 10 + var counter = 1 + var wg sync.WaitGroup done1 := make(chan bool, 10) - done2 := make(chan bool, 10) g0.Percent = 1 termui.Render(g0) go a.httpHNFetchIds(hnurl, done1) <-done1 - go a.populateStories(numstories, done2, g0) - <-done2 + for _, item := range a.Items[:numstories] { + wg.Add(1) + go a.fetchHNStories(strconv.Itoa(item), &wg) + fcounter := float64(counter) + fnumstories := float64(numstories) + percentage := (fcounter / fnumstories) * 100 + g0.Percent = int(percentage) + termui.Render(g0) + counter++ + } + wg.Wait() termui.Clear() l := widgets.NewList() + chanitems := make(chan []string, numstories) + var items []string //l.Title = "[Y] hacker news" - termuiitems := make(chan []string, numstories) - go a.httpHNDisplayStories(numstories, termuiitems) l.Border = false + x, y = termui.TerminalDimensions() l.SetRect(0, 1, x, y) - l.Rows = <-termuiitems l.TextStyle = termui.NewStyle(termui.ColorYellow) l.WrapText = true - x, y = termui.TerminalDimensions() - renderTab := func() { - switch tabpane.ActiveTabIndex { - case 0: - termui.Render(tabpane, l) - } - } - termui.Render(tabpane, l) - - previousKey := "" - uiEvents := termui.PollEvents() - for { - e := <-uiEvents - switch e.ID { - case "h": - tabpane.FocusLeft() - termui.Clear() - termui.Render(tabpane, l) - renderTab() - case "l": - tabpane.FocusRight() - termui.Clear() - termui.Render(tabpane, l) - renderTab() - case "q", "": - return - case "j", "": - l.ScrollDown() - case "k", "": - l.ScrollUp() - case "": - l.ScrollHalfPageDown() - case "": - l.ScrollHalfPageUp() - case "": - l.ScrollPageDown() - case "": - l.ScrollPageUp() - case "g": - if previousKey == "g" { - l.ScrollTop() + //sort.SliceStable(a.Stories, func(i, j int) bool { + // return a.Stories[i].Score > a.Stories[j].Score + //}) + go func(items []string) { + chanitems <- a.httpHNDisplayStories(numstories) + }(items) + select { + case items := <-chanitems: + l.Rows = items + renderTab := func() { + switch tabpane.ActiveTabIndex { + case 0: + termui.Render(tabpane, l) } - case "": - l.ScrollTop() - case "G", "": - l.ScrollBottom() - case "": - payload := e.Payload.(termui.Resize) - l.SetRect(0, 1, payload.Width, payload.Height) - termui.Clear() - termui.Render(l) } + termui.Render(tabpane, l) - if previousKey == "g" { - previousKey = "" - } else { - previousKey = e.ID + previousKey := "" + uiEvents := termui.PollEvents() + for { + e := <-uiEvents + switch e.ID { + case "h": + tabpane.FocusLeft() + termui.Clear() + termui.Render(tabpane, l) + renderTab() + case "l": + tabpane.FocusRight() + termui.Clear() + termui.Render(tabpane, l) + renderTab() + case "q", "": + return + case "r": + + case "j", "": + l.ScrollDown() + case "k", "": + l.ScrollUp() + case "": + l.ScrollHalfPageDown() + case "": + l.ScrollHalfPageUp() + case "": + l.ScrollPageDown() + case "": + l.ScrollPageUp() + case "g": + if previousKey == "g" { + l.ScrollTop() + } + case "": + l.ScrollTop() + case "G", "": + l.ScrollBottom() + case "": + url := a.Stories[l.SelectedRow].Url + err := exec.Command("open", "-a", "Safari", url).Start() + if err != nil { + log.Fatal(err) + } + case "": + payload := e.Payload.(termui.Resize) + l.SetRect(0, 1, payload.Width, payload.Height) + termui.Clear() + termui.Render(l) + } + + if previousKey == "g" { + previousKey = "" + } else { + previousKey = e.ID + } + + termui.Render(l, tabpane) } - - termui.Render(l, tabpane) } }