context and cursor introduced
This commit is contained in:
parent
d1cec22dcd
commit
0915ab09fa
@ -1,8 +1,10 @@
|
|||||||
package anilist
|
package anilist
|
||||||
|
|
||||||
func (api *Api) GetAiringSchedule(vars AiringScheduleQuery, onError func(error)) <-chan *AiringSchedule {
|
import "context"
|
||||||
|
|
||||||
|
func (api *Api) GetAiringSchedule(ctx context.Context, vars AiringScheduleQuery, onError func(error)) Cursor[AiringSchedule] {
|
||||||
resp := responseObj[*page[AiringSchedule]]{}
|
resp := responseObj[*page[AiringSchedule]]{}
|
||||||
return requestPaged(api, getAiringScheduleQuery, vars.toMap(), &resp, onError)
|
return requestPaged(api, ctx, getAiringScheduleQuery, vars.toMap(), &resp, onError)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
19
api.go
19
api.go
@ -2,6 +2,7 @@ package anilist
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
@ -60,15 +61,19 @@ func request[T any](api *Api, query string, vars map[string]interface{}, respObj
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func requestPaged[R any](api *Api, query string, vars map[string]interface{}, respObj *responseObj[*page[R]], onError func(error)) <-chan *R {
|
func requestPaged[R any](api *Api, ctx context.Context, query string, vars map[string]interface{}, respObj *responseObj[*page[R]], onError func(error)) Cursor[R] {
|
||||||
resp := responseObj[struct {
|
resp := responseObj[struct {
|
||||||
Page *page[R] `json:"Page"`
|
Page *page[R] `json:"Page"`
|
||||||
}]{}
|
}]{}
|
||||||
|
|
||||||
|
var cancelFunc context.CancelFunc
|
||||||
|
ctx, cancelFunc = context.WithCancel(ctx)
|
||||||
|
|
||||||
out := make(chan *R, 50)
|
out := make(chan *R, 50)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(out)
|
defer close(out)
|
||||||
|
defer cancelFunc()
|
||||||
|
|
||||||
vars["page"] = 0
|
vars["page"] = 0
|
||||||
|
|
||||||
@ -87,7 +92,11 @@ func requestPaged[R any](api *Api, query string, vars map[string]interface{}, re
|
|||||||
|
|
||||||
for _, value := range resp.Data.Page.Data() {
|
for _, value := range resp.Data.Page.Data() {
|
||||||
value := value
|
value := value
|
||||||
out <- &value
|
select {
|
||||||
|
case out <- &value:
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.Data.Page.PageInfo.CurrentPage == resp.Data.Page.PageInfo.LastPage {
|
if resp.Data.Page.PageInfo.CurrentPage == resp.Data.Page.PageInfo.LastPage {
|
||||||
@ -96,5 +105,9 @@ func requestPaged[R any](api *Api, query string, vars map[string]interface{}, re
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return out
|
return Cursor[R]{
|
||||||
|
Chan: out,
|
||||||
|
ctx: ctx,
|
||||||
|
cancelFunc: cancelFunc,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
31
cursor.go
Normal file
31
cursor.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package anilist
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type Cursor[T any] struct {
|
||||||
|
ctx context.Context
|
||||||
|
cancelFunc context.CancelFunc
|
||||||
|
Chan <-chan *T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Cursor[T]) First() *T {
|
||||||
|
defer c.cancelFunc()
|
||||||
|
return <-c.Chan
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Cursor[T]) Next() (*T, bool) {
|
||||||
|
if c.ctx.Err() == nil {
|
||||||
|
value, ok := <-c.Chan
|
||||||
|
return value, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Cursor[T]) Slice() []T {
|
||||||
|
s := make([]T, 0)
|
||||||
|
for value, ok := c.Next(); ok; value, ok = c.Next() {
|
||||||
|
s = append(s, *value)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
6
media.go
6
media.go
@ -1,8 +1,10 @@
|
|||||||
package anilist
|
package anilist
|
||||||
|
|
||||||
func (api *Api) GetMedia(vars MediaQuery, onError func(error)) <-chan *Media {
|
import "context"
|
||||||
|
|
||||||
|
func (api *Api) GetMedia(ctx context.Context, vars MediaQuery, onError func(error)) Cursor[Media] {
|
||||||
resp := responseObj[*page[Media]]{}
|
resp := responseObj[*page[Media]]{}
|
||||||
return requestPaged(api, getMediaQuery, vars.toMap(), &resp, onError)
|
return requestPaged(api, ctx, getMediaQuery, vars.toMap(), &resp, onError)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package anilist
|
package anilist
|
||||||
|
|
||||||
func (api *Api) GetMediaList(vars MediaListQuery, onError func(error)) <-chan *MediaList {
|
import "context"
|
||||||
|
|
||||||
|
func (api *Api) GetMediaList(ctx context.Context, vars MediaListQuery, onError func(error)) Cursor[MediaList] {
|
||||||
resp := responseObj[*page[MediaList]]{}
|
resp := responseObj[*page[MediaList]]{}
|
||||||
return requestPaged(api, getMediaListQuery, vars.toMap(), &resp, onError)
|
return requestPaged(api, ctx, getMediaListQuery, vars.toMap(), &resp, onError)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -7,7 +7,6 @@ const (
|
|||||||
airingAt
|
airingAt
|
||||||
timeUntilAiring
|
timeUntilAiring
|
||||||
episode
|
episode
|
||||||
media ` + subSelectionMedia + `
|
|
||||||
}`
|
}`
|
||||||
|
|
||||||
subSelectionMediaList = `{
|
subSelectionMediaList = `{
|
||||||
@ -93,7 +92,7 @@ const (
|
|||||||
isAdult
|
isAdult
|
||||||
userId
|
userId
|
||||||
}
|
}
|
||||||
nextAiringEpisode
|
nextAiringEpisode ` + subSelectionAiringSchedule + `
|
||||||
}`
|
}`
|
||||||
|
|
||||||
subSelectionFuzzyDate = `{
|
subSelectionFuzzyDate = `{
|
||||||
|
1
types.go
1
types.go
@ -211,5 +211,4 @@ type AiringSchedule struct {
|
|||||||
AiringAt UnixTime `json:"airingAt"`
|
AiringAt UnixTime `json:"airingAt"`
|
||||||
TimeUntilAiring Seconds `json:"timeUntilAiring"`
|
TimeUntilAiring Seconds `json:"timeUntilAiring"`
|
||||||
Episode int `json:"episode"`
|
Episode int `json:"episode"`
|
||||||
Media *Media `json:"media"`
|
|
||||||
}
|
}
|
||||||
|
6
user.go
6
user.go
@ -1,5 +1,7 @@
|
|||||||
package anilist
|
package anilist
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
func (api *Api) GetUserByName(name string) (*User, error) {
|
func (api *Api) GetUserByName(name string) (*User, error) {
|
||||||
query := `query ($name: String) {
|
query := `query ($name: String) {
|
||||||
User (name: $name) ` + subSelectionUser + `
|
User (name: $name) ` + subSelectionUser + `
|
||||||
@ -42,10 +44,10 @@ func (api *Api) GetUserByID(id int) (*User, error) {
|
|||||||
return resp.Data.User, nil
|
return resp.Data.User, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *Api) SearchUsers(search string, onError func(error)) <-chan *User {
|
func (api *Api) SearchUsers(ctx context.Context, search string, onError func(error)) Cursor[User] {
|
||||||
vars := map[string]interface{}{"search": search}
|
vars := map[string]interface{}{"search": search}
|
||||||
resp := responseObj[*page[User]]{}
|
resp := responseObj[*page[User]]{}
|
||||||
return requestPaged(api, searchUsersQuery, vars, &resp, onError)
|
return requestPaged(api, ctx, searchUsersQuery, vars, &resp, onError)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
Loading…
Reference in New Issue
Block a user