xdcc-cli/search/xdcc_eu.go

91 lines
2.0 KiB
Go

package search
import (
"errors"
"fmt"
"net/http"
"strconv"
"strings"
"xdcc-cli/xdcc"
"github.com/PuerkitoBio/goquery"
)
type XdccEuProvider struct{}
const (
xdccEuURL = "https://www.xdcc.eu/search.php"
xdccEuNumberOfEntries = 7
)
func (p *XdccEuProvider) parseFields(fields []string) (*XdccFileInfo, error) {
if len(fields) != xdccEuNumberOfEntries {
return nil, errors.New("unexpected number of search entry fields")
}
fInfo := &XdccFileInfo{}
fInfo.URL.Network = fields[0]
fInfo.URL.Channel = fields[1]
fInfo.URL.UserName = fields[2]
slot, err := strconv.Atoi(fields[3][1:])
if err != nil {
return nil, err
}
fInfo.Size, _ = parseFileSize(fields[5]) // ignoring error
fInfo.Name = fields[6]
if err != nil {
return nil, err
}
fInfo.Slot = slot
return fInfo, nil
}
func (p *XdccEuProvider) Search(keywords []string) ([]XdccFileInfo, error) {
keywordString := strings.Join(keywords, " ")
searchkey := strings.Join(strings.Fields(keywordString), "+")
res, err := http.Get(xdccEuURL + "?searchkey=" + searchkey)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("status code error: %d %s", res.StatusCode, res.Status)
}
// Load the HTML document
doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
return nil, err
}
fileInfos := make([]XdccFileInfo, 0)
doc.Find("tr").Each(func(_ int, s *goquery.Selection) {
fields := make([]string, 0)
var urlStr string
s.Children().Each(func(i int, si *goquery.Selection) {
if i == 1 {
value, exists := si.Find("a").First().Attr("href")
if exists {
urlStr = value
}
}
fields = append(fields, strings.TrimSpace(si.Text()))
})
info, err := p.parseFields(fields)
if err == nil {
url, err := xdcc.ParseURL(urlStr + "/" + info.URL.UserName + "/" + strconv.Itoa(info.Slot))
if err == nil {
info.URL = *url
fileInfos = append(fileInfos, *info)
}
}
})
return fileInfos, nil
}