/
client.go
81 lines (73 loc) · 1.56 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package gohn
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
)
const rootUrl = "https://hacker-news.firebaseio.com/v0"
const maxStories = 10
const timeBetweenReqMs = 10
const maxRetries = 100
const waitTimeMeanMs = 10
func jsonBytes(url string) ([]byte, error) {
var err error
var resp *http.Response
for i := 0; i < maxRetries; i++ {
if i > 0 {
log.Printf("Retrying again %d\n", i)
}
resp, err = http.Get(url)
if err == nil {
defer resp.Body.Close()
break
}
waitTime := time.Millisecond * time.Duration(i+1) * ExpWithMax(waitTimeMeanMs, 100.0)
time.Sleep(waitTime)
}
if err != nil {
return nil, err
}
return ioutil.ReadAll(resp.Body)
}
// Current top 500 stories
func TopStories() ([]*Item, error) {
body, err := jsonBytes(rootUrl + "/topstories.json")
list := make([]*Item, 0, 500)
if err != nil {
return list, err
}
itemids := make([]int, 0, 500)
if err := json.Unmarshal(body, &itemids); err != nil {
return list, err
}
num_stories := 0
for _, id := range itemids {
it, err := GetItem(id)
if err != nil {
log.Printf("Failed to get story %d, %s", id, err)
}
list = append(list, it)
time.Sleep(timeBetweenReqMs * time.Millisecond)
num_stories += 1
if num_stories == maxStories {
break
}
}
return list, nil
}
// Get post or comment with given ID
func GetItem(id int) (*Item, error) {
i := Item{}
body, err := jsonBytes(fmt.Sprintf("%s/item/%d.json", rootUrl, id))
if err != nil {
return &i, err
}
err = json.Unmarshal(body, &i)
if err != nil {
return &i, err
}
return &i, nil
}