-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathAnimeList.go
More file actions
91 lines (69 loc) · 2.06 KB
/
AnimeList.go
File metadata and controls
91 lines (69 loc) · 2.06 KB
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
package mal
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/aerogo/http/client"
jsoniter "github.com/json-iterator/go"
)
// AnimeList is just a slice of anime list items.
type AnimeList []*AnimeListItem
// GetAnimeList returns the user's anime list.
func GetAnimeList(userName string) (AnimeList, error) {
animeList := AnimeList{}
offset := 0
ticker := time.NewTicker(1100 * time.Millisecond)
defer ticker.Stop()
for {
nextAnimeList, err := getAnimeListWithOffset(userName, offset)
if err != nil {
return nil, err
}
if len(nextAnimeList) == 0 {
break
}
animeList = append(animeList, nextAnimeList...)
offset += len(nextAnimeList)
// Wait for rate limiter to allow the next request
<-ticker.C
}
return animeList, nil
}
// getAnimeListWithOffset returns the anime list items starting with the given offset.
func getAnimeListWithOffset(userName string, offset int) (AnimeList, error) {
var response *client.Response
var err error
animeList := AnimeList{}
// Fetch the page
for {
url := fmt.Sprintf("https://myanimelist.net/animelist/%s/load.json?offset=%d&status=7", userName, offset)
response, err = client.Get(url).End()
if err != nil {
return nil, err
}
if !response.Ok() {
if response.StatusCode() == http.StatusTooManyRequests {
time.Sleep(time.Second)
continue
}
return nil, fmt.Errorf("Status code: %d", response.StatusCode())
}
break
}
// Get JSON string
dataItems := response.String()
// Fix is_rewatching field
dataItems = strings.ReplaceAll(dataItems, `"is_rewatching":""`, `"is_rewatching":false`)
dataItems = strings.ReplaceAll(dataItems, `"is_rewatching":0`, `"is_rewatching":false`)
dataItems = strings.ReplaceAll(dataItems, `"is_rewatching":1`, `"is_rewatching":true`)
// Fix anime_title field sometimes including numbers instead of strings
dataItems = strings.ReplaceAll(dataItems, `"anime_title":1`, `"anime_title":"1"`)
// Parse JSON
err = jsoniter.UnmarshalFromString(dataItems, &animeList)
fmt.Println(err)
if err != nil {
return nil, err
}
return animeList, nil
}