Added Nyaa to file search
Some checks failed
Run Integration Tests / test (push) Failing after 44s

This commit is contained in:
partisan 2025-06-28 17:33:36 +02:00
parent 40f322ef01
commit 67eefc2c7a
3 changed files with 129 additions and 30 deletions

View file

@ -94,7 +94,7 @@ var defaultConfig = Config{
Image: []string{"Qwant", "Bing", "DeviantArt"}, Image: []string{"Qwant", "Bing", "DeviantArt"},
// For Files search // For Files search
Files: []string{"TorrentGalaxy", "ThePirateBay"}, Files: []string{"TorrentGalaxy", "ThePirateBay", "Nyaa"},
// For Video (piped instances) // For Video (piped instances)
Video: []string{ Video: []string{

107
files-nyaa.go Normal file
View file

@ -0,0 +1,107 @@
package main
import (
"fmt"
"net/http"
"net/url"
"strings"
"github.com/PuerkitoBio/goquery"
)
const NYAA_DOMAIN = "nyaa.si"
type Nyaa struct{}
func NewNyaa() *Nyaa {
return &Nyaa{}
}
func (n *Nyaa) Name() string {
return "nyaa"
}
func (n *Nyaa) getCategoryCode(cat string) string {
switch cat {
case "all":
return ""
case "anime":
return "&c=1_0"
case "music":
return "&c=2_0"
case "game":
return "&c=6_2"
case "software":
return "&c=6_1"
default:
return "ignore"
}
}
func (n *Nyaa) Search(query string, category string) ([]TorrentResult, error) {
categoryCode := n.getCategoryCode(category)
if categoryCode == "ignore" {
return []TorrentResult{}, nil
}
searchURL := fmt.Sprintf("https://%s/?f=0&q=%s%s", NYAA_DOMAIN, url.QueryEscape(query), categoryCode)
userAgent, err := GetUserAgent("files-nyaa")
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", searchURL, nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", userAgent)
resp, err := DoMetaProxyRequest(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode)
}
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, err
}
var results []TorrentResult
doc.Find(".default, .success, .danger").Each(func(i int, s *goquery.Selection) {
tds := s.Find("td")
if tds.Length() < 7 {
return
}
title := tds.Eq(1).Find("a").Last().Text()
magnet, _ := tds.Eq(2).Find("a").Last().Attr("href")
sizeStr := strings.TrimSpace(tds.Eq(3).Text())
byteSize := parseSize(sizeStr)
seeders := parseInt(tds.Eq(5).Text())
leechers := parseInt(tds.Eq(6).Text())
results = append(results, TorrentResult{
URL: "https://" + NYAA_DOMAIN,
Title: title,
Magnet: applyTrackers(magnet),
Size: formatSize(byteSize),
Seeders: seeders,
Leechers: leechers,
Views: 0,
})
})
// Reverse the results slice, so It's from newest to oldest, but the orders is still kinda random
for i, j := 0, len(results)-1; i < j; i, j = i+1, j-1 {
results[i], results[j] = results[j], results[i]
}
return results, nil
}

View file

@ -32,7 +32,7 @@ func initFileEngines() {
torrentGalaxy = nil torrentGalaxy = nil
thePirateBay = nil thePirateBay = nil
// nyaa = nil nyaa = nil
// rutor = nil // rutor = nil
for _, engineName := range config.MetaSearch.Files { for _, engineName := range config.MetaSearch.Files {
@ -41,8 +41,8 @@ func initFileEngines() {
torrentGalaxy = NewTorrentGalaxy() torrentGalaxy = NewTorrentGalaxy()
case "ThePirateBay": case "ThePirateBay":
thePirateBay = NewThePirateBay() thePirateBay = NewThePirateBay()
// case "Nyaa": case "Nyaa":
// nyaa = NewNyaa() nyaa = NewNyaa()
// case "Rutor": // case "Rutor":
// rutor = NewRutor() // rutor = NewRutor()
} }
@ -174,33 +174,34 @@ func parseSize(sizeStr string) int64 {
return 0 return 0
} }
// Use regex to extract numeric value and unit separately re := regexp.MustCompile(`(?i)([\d.]+)\s*(K?M?G?T?i?B)`)
re := regexp.MustCompile(`(?i)([\d.]+)\s*([KMGT]?B)`)
matches := re.FindStringSubmatch(sizeStr) matches := re.FindStringSubmatch(sizeStr)
if len(matches) < 3 { if len(matches) < 3 {
printWarn("Error parsing size: invalid format %s", sizeStr) printWarn("Error parsing size: invalid format %s", sizeStr)
return 0 return 0
} }
sizeStr = matches[1] numStr := matches[1]
unit := strings.ToUpper(matches[2]) unit := strings.ToUpper(matches[2])
var multiplier int64 = 1 var multiplier int64 = 1
switch unit { switch unit {
case "KB": case "B":
multiplier = 1
case "KB", "KIB":
multiplier = 1024 multiplier = 1024
case "MB": case "MB", "MIB":
multiplier = 1024 * 1024 multiplier = 1024 * 1024
case "GB": case "GB", "GIB":
multiplier = 1024 * 1024 * 1024 multiplier = 1024 * 1024 * 1024
case "TB": case "TB", "TIB":
multiplier = 1024 * 1024 * 1024 * 1024 multiplier = 1024 * 1024 * 1024 * 1024
default: default:
printWarn("Unknown unit: %s", unit) printWarn("Unknown unit: %s", unit)
return 0 return 0
} }
size, err := strconv.ParseFloat(sizeStr, 64) size, err := strconv.ParseFloat(numStr, 64)
if err != nil { if err != nil {
printWarn("Error parsing size: %v", err) printWarn("Error parsing size: %v", err)
return 0 return 0
@ -226,16 +227,16 @@ func applyTrackers(magnetLink string) string {
} }
func formatSize(size int64) string { func formatSize(size int64) string {
if size >= 1024*1024*1024*1024 { const unit = 1024
return fmt.Sprintf("%.2f TB", float64(size)/(1024*1024*1024*1024)) if size < unit {
} else if size >= 1024*1024*1024 { return fmt.Sprintf("%d B", size)
return fmt.Sprintf("%.2f GB", float64(size)/(1024*1024*1024))
} else if size >= 1024*1024 {
return fmt.Sprintf("%.2f MB", float64(size)/(1024*1024))
} else if size >= 1024 {
return fmt.Sprintf("%.2f KB", float64(size)/1024)
} }
return fmt.Sprintf("%d B", size) div, exp := unit, 0
for n := size / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %siB", float64(size)/float64(div), []string{"K", "M", "G", "T", "P", "E"}[exp])
} }
func sanitizeFileName(name string) string { func sanitizeFileName(name string) string {
@ -245,12 +246,3 @@ func sanitizeFileName(name string) string {
sanitized = regexp.MustCompile(`[^a-zA-Z0-9\-\(\)]`).ReplaceAllString(sanitized, "") sanitized = regexp.MustCompile(`[^a-zA-Z0-9\-\(\)]`).ReplaceAllString(sanitized, "")
return sanitized return sanitized
} }
func contains(slice []string, item string) bool {
for _, v := range slice {
if v == item {
return true
}
}
return false
}