forked from beefsack/bgg-ranked-csv
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
124 lines (119 loc) · 2.77 KB
/
main.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"encoding/csv"
"fmt"
"log"
"os"
"time"
"github.com/beefsack/go-geekdo"
)
const MAX_RETRIES = 5
func main() {
stderr := log.New(os.Stderr, "", log.Ldate|log.Ltime)
client, err := geekdo.NewClient()
if err != nil {
stderr.Fatalf("Error creating client, %v\n", err)
}
username := os.Getenv("BGG_USERNAME")
password := os.Getenv("BGG_PASSWORD")
if username != "" && password != "" {
stderr.Println("Logging in")
if err = client.Login(username, password); err != nil {
stderr.Fatalf("Error logging in, %v\n", err)
}
}
w := csv.NewWriter(os.Stdout)
defer w.Flush()
if err := w.Write([]string{
"ID",
"Name",
"Year",
"Rank",
"Average",
"Bayes average",
"Users rated",
"URL",
"Thumbnail",
}); err != nil {
stderr.Fatalf("Error writing line of CSV, %v\n", err)
}
page := 0
for {
page++
url := fmt.Sprintf(
"https://boardgamegeek.com/browse/boardgame/page/%d?sort=rank&sortdir=asc",
page,
)
stderr.Printf("GET %s\n", url)
r := []geekdo.SearchCollectionItem{}
tries := 0
for {
tries++
// The request can sometimes fail, or hit a cache with an empty page, so
// we will have a number of retries
var err error
r, err = client.AdvSearch(url)
if err != nil {
stderr.Printf("Error querying %s, %v\n", url, err)
if tries == MAX_RETRIES {
os.Exit(1)
}
continue
}
if len(r) == 0 {
stderr.Println("No results")
// We will still retry because BGG sometimes has a caching issue
// where no ranked games appear on an index page
if tries == MAX_RETRIES {
break
}
continue
}
// Check for any unranked games, which will also trigger a retry
hasUnranked := false
for _, thing := range r {
if thing.Rank == 0 {
hasUnranked = true
}
}
if hasUnranked {
stderr.Println("Result contains some unranked games")
// We will still retry because BGG sometimes has a caching issue
// where no ranked games appear on an index page
if tries == MAX_RETRIES {
break
}
continue
}
// We got here with a full page of ranked games
break
}
rankedOnPage := 0
for _, thing := range r {
if thing.Rank == 0 {
continue
}
rankedOnPage++
if err := w.Write([]string{
fmt.Sprintf("%v", thing.ID),
thing.Name,
fmt.Sprintf("%v", thing.Year),
fmt.Sprintf("%v", thing.Rank),
fmt.Sprintf("%v", thing.Average),
fmt.Sprintf("%v", thing.BayesAverage),
fmt.Sprintf("%v", thing.UsersRated),
thing.URL,
thing.Thumbnail,
}); err != nil {
stderr.Fatalf("Error writing line of CSV, %v\n", err)
}
}
if rankedOnPage == 0 {
stderr.Printf("No ranked games on page %d, stopping\n", page)
break
}
// Rate limit
time.Sleep(30 * time.Second)
}
stderr.Printf("Finished on page %d\n", page)
}