package ytsclient import ( "context" "fmt" "net" "strconv" "strings" "time" r "github.com/levigross/grequests" ) type client struct { url string list string get string suggestions string } var ( defaultHost = "https://yts.am" apiPrefix = "/api/v2" dnsServer = "8.8.4.4" ) const ( list = "/list_movies.json" get = "/movie_details.json" suggestions = "/movie_suggestions.json" ) func NewClient(host ...string) Client { if len(host) == 0 || host[0] == "" { if host, err := ResolveYts(); err == nil { defaultHost = strings.TrimSuffix(host, "/") } host = []string{defaultHost} } d := net.Dialer{ Timeout: 5 * time.Second, } net.DefaultResolver = &net.Resolver{ PreferGo: true, Dial: func(ctx context.Context, network, address string) (net.Conn, error) { return d.DialContext(ctx, network, fmt.Sprintf("%s:53", dnsServer)) }, } return &client{host[0], host[0] + apiPrefix + list, host[0] + apiPrefix + get, host[0] + apiPrefix + suggestions} } func (y *client) List(params *ListParams) ([]Movie, error) { if params == nil { params = &ListParams{} } res, err := r.Get(y.list, params.format()) if err != nil { return nil, err } var resp ListResponse if err := res.JSON(&resp); err != nil { return nil, err } return resp.Data.Movies, nil } func (y *client) Search(search string, params *ListParams) ([]Movie, error) { if params == nil { params = &ListParams{} } params.QueryTerm = search res, err := r.Get(y.list, params.format()) if err != nil { return nil, err } var resp ListResponse if err := res.JSON(&resp); err != nil { return nil, err } return resp.Data.Movies, nil } func (y *client) Get(id string, params *MovieParams) (Movie, error) { if params == nil { params = &MovieParams{} } p := params.format() p.Params["movie_id"] = id res, err := r.Get(y.get, p) if err != nil { return Movie{}, err } var resp MovieResponse if err := res.JSON(&resp); err != nil { return Movie{}, err } return resp.Data.Movie, nil } func (y *client) Suggestions(id int) ([]Movie, error) { ro := &r.RequestOptions{ Params: map[string]string{"movie_id": strconv.Itoa(id)}, } res, err := r.Get(y.suggestions, ro) if err != nil { return nil, err } var resp ListResponse if err := res.JSON(&resp); err != nil { return nil, err } return resp.Data.Movies, nil } type Client interface { List(params *ListParams) ([]Movie, error) Search(search string, params *ListParams) ([]Movie, error) Get(id string, params *MovieParams) (Movie, error) Suggestions(id int) ([]Movie, error) }