package main import ( "fmt" "net/http" "regexp" "strconv" "strings" "time" "git.milar.in/nyaanime/model" "github.com/PuerkitoBio/goquery" ) var torrentLinkRegex = regexp.MustCompile(`https:\/\/nyaa\.si\/download\/(\d+?)\.torrent`) func GetTorrents() ([]model.Torrent, error) { resp, err := http.Get("https://nyaa.si/?page=rss&f=0&c=1_0") if err != nil { return nil, ErrTorrentNotObtainable.Wrap(err, "torrent data acqusition failed") } defer resp.Body.Close() if resp.StatusCode != 200 { return nil, ErrTorrentNotObtainable.New("invalid status code from nyaa.si: " + strconv.Itoa(resp.StatusCode)) } nyaa, err := goquery.NewDocumentFromReader(resp.Body) if err != nil { return nil, ErrTorrentNotObtainable.Wrap(err, "nyaa.si response parsing failed") } torrents := make([]model.Torrent, 0, 75) nyaa.Find("item").Each(func(i int, s *goquery.Selection) { time, err := time.Parse(time.RFC1123Z, s.Find("pubDate").Text()) if err != nil { fmt.Println("could not parse time:", s.Find("pubDate")) return } seeders, err := strconv.Atoi(s.Find("nyaa\\:seeders").Text()) if err != nil { fmt.Println("could not parse seeders:", s.Find("nyaa\\:seeders").Text()) return } leechers, err := strconv.Atoi(s.Find("nyaa\\:leechers").Text()) if err != nil { fmt.Println("could not parse leechers:", s.Find("nyaa\\:leechers").Text()) return } downloads, err := strconv.Atoi(s.Find("nyaa\\:downloads").Text()) if err != nil { fmt.Println("could not parse downloads:", s.Find("nyaa\\:downloads").Text()) return } // goquery can't parse the link tag for some reason // therefore I have to get around this bug by exploiting regex matches := torrentLinkRegex.FindStringSubmatch(s.Text()) link := matches[0] id := matches[1] torrents = append(torrents, model.Torrent{ ID: model.TorrentID(id), Title: s.Find("title").Text(), Link: link, Time: time, Seeders: seeders, Leechers: leechers, Downloads: downloads, Trusted: strings.Contains(strings.ToLower(s.Find("nyaa\\:trusted").Text()), "yes"), }) }) return torrents, nil }