Files
polaris/pkg/torznab/torznab.go
2024-07-01 11:34:54 +08:00

135 lines
3.0 KiB
Go

package torznab
import (
"encoding/xml"
"io"
"net/http"
"net/url"
"polaris/log"
"strconv"
"github.com/pkg/errors"
)
type Response struct {
XMLName xml.Name `xml:"rss"`
Text string `xml:",chardata"`
Version string `xml:"version,attr"`
Atom string `xml:"atom,attr"`
Torznab string `xml:"torznab,attr"`
Channel struct {
Text string `xml:",chardata"`
Link struct {
Text string `xml:",chardata"`
Href string `xml:"href,attr"`
Rel string `xml:"rel,attr"`
Type string `xml:"type,attr"`
} `xml:"link"`
Title string `xml:"title"`
Description string `xml:"description"`
Language string `xml:"language"`
Category string `xml:"category"`
Item []Item `xml:"item"`
} `xml:"channel"`
}
type Item struct {
Text string `xml:",chardata"`
Title string `xml:"title"`
Guid string `xml:"guid"`
Jackettindexer struct {
Text string `xml:",chardata"`
ID string `xml:"id,attr"`
} `xml:"jackettindexer"`
Type string `xml:"type"`
Comments string `xml:"comments"`
PubDate string `xml:"pubDate"`
Size string `xml:"size"`
Description string `xml:"description"`
Link string `xml:"link"`
Category []string `xml:"category"`
Enclosure struct {
Text string `xml:",chardata"`
URL string `xml:"url,attr"`
Length string `xml:"length,attr"`
Type string `xml:"type,attr"`
} `xml:"enclosure"`
Attr []struct {
Text string `xml:",chardata"`
Name string `xml:"name,attr"`
Value string `xml:"value,attr"`
} `xml:"attr"`
}
func (i *Item) GetAttr(key string) string {
for _, a := range i.Attr {
if a.Name == key {
return a.Value
}
}
return ""
}
func (r *Response) ToResults() []Result {
var res []Result
for _, item := range r.Channel.Item {
r := Result{
Name: item.Title,
Magnet: item.Link,
Size: mustAtoI(item.Size),
Seeders: mustAtoI(item.GetAttr("seeders")),
Peers: mustAtoI(item.GetAttr("peers")),
Category: mustAtoI(item.GetAttr("category")),
Source: r.Channel.Title,
}
res = append(res, r)
}
return res
}
func mustAtoI(key string) int {
i, err := strconv.Atoi(key)
if err != nil {
log.Errorf("must atoi error: %v", err)
panic(err)
}
return i
}
func Search(torznabUrl, api, keyWord string) ([]Result, error) {
req, err := http.NewRequest(http.MethodGet, torznabUrl, nil)
if err != nil {
return nil, errors.Wrap(err, "new request")
}
var q = url.Values{}
q.Add("apikey", api)
q.Add("t", "search")
q.Add("q", keyWord)
req.URL.RawQuery = q.Encode()
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, errors.Wrap(err, "do http")
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "read http body")
}
var res Response
err = xml.Unmarshal(data, &res)
if err != nil {
return nil, errors.Wrap(err, "json unmarshal")
}
return res.ToResults(), nil
}
type Result struct {
Name string
Magnet string
Size int
Seeders int
Peers int
Category int
Source string
}