refactor, bypass dns filtering using google dns, yts host resolution using qwant

This commit is contained in:
2020-05-31 15:54:24 +02:00
parent 6099b72570
commit 1fd24d0536
1164 changed files with 437 additions and 582974 deletions

81
ytsclient/yts_resolver.go Normal file
View File

@ -0,0 +1,81 @@
package ytsclient
import (
"errors"
"strings"
r "github.com/levigross/grequests"
)
var ErrNotFound = errors.New("not found")
type SearchResponse struct {
Status string `json:"status"`
Data struct {
Query struct {
Locale string `json:"locale"`
Query string `json:"query"`
Offset int `json:"offset"`
} `json:"query"`
Cache struct {
Key string `json:"key"`
Created int `json:"created"`
Expiration int `json:"expiration"`
Status string `json:"status"`
Age int `json:"age"`
Version int `json:"version"`
System string `json:"system"`
Mode int `json:"mode"`
} `json:"cache"`
Result struct {
Total int `json:"total"`
Items []struct {
Title string `json:"title"`
Favicon string `json:"favicon"`
URL string `json:"url"`
Source string `json:"source"`
Desc string `json:"desc"`
ID string `json:"_id"`
Score int `json:"score"`
Position int `json:"position"`
} `json:"items"`
Filters struct {
Freshness struct {
Label string `json:"label"`
Name string `json:"name"`
Type string `json:"type"`
Selected string `json:"selected"`
Values []struct {
Value string `json:"value"`
Label string `json:"label"`
Translate bool `json:"translate"`
} `json:"values"`
} `json:"freshness"`
} `json:"filters"`
Ads []interface{} `json:"ads"`
} `json:"result"`
} `json:"data"`
}
func ResolveYts() (url string, err error) {
res, err := r.Get("https://api.qwant.com/api/search/web?count=10&q=yts&t=web&uiv=4", nil)
if err != nil {
return "", err
}
sr := &SearchResponse{}
if err := res.JSON(sr); err != nil{
return "", err
}
if len(sr.Data.Result.Items) == 0 {
return "", ErrNotFound
}
for _, v := range sr.Data.Result.Items {
if !strings.HasPrefix(v.URL, "https://yts.") {
continue
}
return v.URL, nil
}
return "", ErrNotFound
}

View File

@ -1,31 +1,56 @@
package ytsclient
import (
r "github.com/levigross/grequests"
"context"
"fmt"
"net"
"strconv"
"strings"
"time"
r "github.com/levigross/grequests"
)
type Client struct {
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(url string) *Client {
if url == "" {
url = "https://yts.am/api/v2"
func NewClient(host ...string) Client {
if len(host) == 0 || host[0] == "" {
if host, err := ResolveYts(); err == nil {
defaultHost = strings.TrimSuffix(host, "/")
}
host = []string{defaultHost}
}
return &Client{url, url + list, url + get, url + suggestions}
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) {
func (y *client) List(params *ListParams) ([]Movie, error) {
if params == nil {
params = &ListParams{}
}
@ -40,7 +65,7 @@ func (y *Client) List(params *ListParams) ([]Movie, error) {
return resp.Data.Movies, nil
}
func (y *Client) Search(search string, params *ListParams) ([]Movie, error) {
func (y *client) Search(search string, params *ListParams) ([]Movie, error) {
if params == nil {
params = &ListParams{}
}
@ -56,7 +81,7 @@ func (y *Client) Search(search string, params *ListParams) ([]Movie, error) {
return resp.Data.Movies, nil
}
func (y *Client) Get(id string, params *MovieParams) (Movie, error) {
func (y *client) Get(id string, params *MovieParams) (Movie, error) {
if params == nil {
params = &MovieParams{}
}
@ -73,7 +98,7 @@ func (y *Client) Get(id string, params *MovieParams) (Movie, error) {
return resp.Data.Movie, nil
}
func (y *Client) Suggestions(id int) ([]Movie, error) {
func (y *client) Suggestions(id int) ([]Movie, error) {
ro := &r.RequestOptions{
Params: map[string]string{"movie_id": strconv.Itoa(id)},
}
@ -87,3 +112,10 @@ func (y *Client) Suggestions(id int) ([]Movie, error) {
}
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)
}

View File

@ -2,6 +2,8 @@ package ytsclient
import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"strconv"
"strings"
"testing"
@ -24,31 +26,45 @@ var (
name string
test func(t *testing.T)
}{{
name: "no dns server",
test: func(t *testing.T) {
dnsServer = "192.168.1.1"
yc := NewClient()
ms, err := yc.List(nil)
require.Error(t, err)
t.Log(err)
require.Nil(t, ms)
dnsServer = "8.8.8.8"
},
},{
name: "default url",
test: func(t *testing.T) {
c := NewClient("")
assert.Equal(t, "https://yts.am/api/v2", c.url)
yc := NewClient()
c, ok := yc.(*client)
require.True(t, ok)
assert.Contains(t, c.url,"https://yts.")
},
}, {
name: "list",
test: func(t *testing.T) {
c := NewClient("")
c := NewClient()
_, err := c.List(nil)
assert.NoError(t, err)
},
}, {
name: "search",
test: func(t *testing.T) {
c := NewClient("")
c := NewClient()
l, err := c.Search("South Park", nil)
assert.NoError(t, err)
require.NotEmpty(t, l)
southParkMovie = l[0]
assert.Equal(t, southParkID, strconv.Itoa(southParkMovie.ID))
},
}, {
name: "list 50",
test: func(t *testing.T) {
c := NewClient("")
c := NewClient()
p := &ListParams{Limit: 50}
l, err := c.List(p)
assert.NoError(t, err)
@ -57,7 +73,7 @@ var (
}, {
name: "get",
test: func(t *testing.T) {
c := NewClient("")
c := NewClient()
m, err := c.Get(southParkID, nil)
assert.NoError(t, err)
assert.NotEmpty(t, m)
@ -66,6 +82,7 @@ var (
}, {
name: "magnet",
test: func(t *testing.T) {
require.NotEmpty(t, southParkMovie.Torrents)
m, err := southParkMovie.Magnet(southParkMovie.Torrents[1])
assert.NoError(t, err)
// Don't test trackers list nor YTS extension
@ -76,7 +93,7 @@ var (
}, {
name: "suggestions",
test: func(t *testing.T) {
c := NewClient("")
c := NewClient()
s, err := c.Suggestions(10)
assert.NoError(t, err)
assert.NotEmpty(t, s)
@ -89,3 +106,12 @@ func TestYTSClient(t *testing.T) {
t.Run(test.name, test.test)
}
}
func TestResolveYts(t *testing.T) {
defaultHost = ""
host, err := ResolveYts()
require.NoError(t, err)
require.Contains(t, host, "https://yts.")
t.Log(host)
}