101 lines
1.8 KiB
Go
101 lines
1.8 KiB
Go
|
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
|
||
|
}
|