anilist/api.go

101 lines
1.8 KiB
Go
Raw Normal View History

2022-02-03 17:23:29 +01:00
package anilist
import (
"bytes"
"encoding/json"
"net/http"
)
type Api struct {
AccessToken string
}
func NewApi(accessToken string) *Api {
return &Api{AccessToken: accessToken}
}
type queryObj struct {
Query string `json:"query"`
Vars interface{} `json:"variables"`
}
type responseObj[T any] struct {
Data T `json:"data"`
}
func request[T any](api *Api, query string, vars map[string]interface{}, respObj *responseObj[T]) error {
q := &queryObj{
Query: query,
Vars: vars,
}
queryData, err := json.Marshal(q)
if err != nil {
return err
}
req, err := http.NewRequest("POST", "https://graphql.anilist.co/", bytes.NewReader(queryData))
if err != nil {
return err
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer "+api.AccessToken)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
//data, _ := ioutil.ReadAll(resp.Body)
//fmt.Println(string(data))
dec := json.NewDecoder(resp.Body)
err = dec.Decode(respObj)
if err != nil {
return err
}
return nil
}
func requestPaged[R any](api *Api, query string, vars map[string]interface{}, respObj *responseObj[*page[R]], onError func(error)) <-chan *R {
resp := responseObj[struct {
Page *page[R] `json:"Page"`
}]{}
out := make(chan *R, 50)
go func() {
defer close(out)
vars["page"] = 0
for {
if p, ok := vars["page"].(int); ok {
vars["page"] = p + 1
}
err := request(api, query, vars, &resp)
if err != nil {
if onError != nil {
onError(err)
}
return
}
for _, value := range resp.Data.Page.Data() {
value := value
out <- &value
}
if resp.Data.Page.PageInfo.CurrentPage == resp.Data.Page.PageInfo.LastPage {
return
}
}
}()
return out
}