Files
seanime-docker/seanime-2.9.10/internal/torrents/nyaa/nyaa.go
2025-09-20 14:08:38 +01:00

260 lines
6.2 KiB
Go

package nyaa
import (
"fmt"
gourl "net/url"
"seanime/internal/util"
)
type (
Torrent struct {
Category string `json:"category"`
Name string `json:"name"`
Description string `json:"description"`
Date string `json:"date"`
Size string `json:"size"`
Seeders string `json:"seeders"`
Leechers string `json:"leechers"`
Downloads string `json:"downloads"`
IsTrusted string `json:"isTrusted"`
IsRemake string `json:"isRemake"`
Comments string `json:"comments"`
Link string `json:"link"`
GUID string `json:"guid"`
CategoryID string `json:"categoryID"`
InfoHash string `json:"infoHash"`
}
BuildURLOptions struct {
Provider string
Query string
Category string
SortBy string
Filter string
}
Comment struct {
User string `json:"user"`
Date string `json:"date"`
Text string `json:"text"`
}
)
func (t *Torrent) GetSizeInBytes() int64 {
bytes, _ := util.StringSizeToBytes(t.Size)
return bytes
}
var (
nyaaBaseURL = util.Decode("aHR0cHM6Ly9ueWFhLnNpLz9wYWdlPXJzcyZxPSs=")
sukebeiBaseURL = util.Decode("aHR0cHM6Ly9zdWtlYmVpLm55YWEuc2kvP3BhZ2U9cnNzJnE9Kw==")
nyaaView = util.Decode("aHR0cHM6Ly9ueWFhLnNpL3ZpZXcv")
sukebeiView = util.Decode("aHR0cHM6Ly9zdWtlYmVpLm55YWEuc2kvdmlldy8=")
)
const (
sortByComments = "&s=comments&o=desc"
sortBySeeders = "&s=seeders&o=desc"
sortByLeechers = "&s=leechers&o=desc"
sortByDownloads = "&s=downloads&o=desc"
sortBySizeDsc = "&s=size&o=desc"
sortBySizeAsc = "&s=size&o=asc"
sortByDate = "&s=id&o=desc"
filterNoFilter = "&f=0"
filterNoRemakes = "&f=1"
filterTrustedOnly = "&f=2"
categoryAll = "&c=0_0"
categoryAnime = "&c=1_0"
CategoryAnime = "&c=1_0"
categoryAnimeAMV = "&c=1_1"
categoryAnimeEng = "&c=1_2"
CategoryAnimeEng = "&c=1_2"
categoryAnimeNonEng = "&c=1_3"
CategoryAnimeNonEng = "&c=1_3"
categoryAnimeRaw = "&c=1_4"
categoryAudio = "&c=2_0"
categoryAudioLossless = "&c=2_1"
categoryAudioLossy = "&c=2_2"
categoryLiterature = "&c=3_0"
categoryLiteratureEng = "&c=3_1"
categoryLiteratureNonEng = "&c=3_2"
categoryLiteratureRaw = "&c=3_3"
categoryLiveAction = "&c=4_0"
categoryLiveActionRaw = "&c=4_4"
categoryLiveActionEng = "&c=4_1"
categoryLiveActionNonEng = "&c=4_3"
categoryLiveActionIdolProm = "&c=4_2"
categoryPictures = "&c=5_0"
categoryPicturesGraphics = "&c=5_1"
categoryPicturesPhotos = "&c=5_2"
categorySoftware = "&c=6_0"
categorySoftwareApps = "&c=6_1"
categorySoftwareGames = "&c=6_2"
categoryArt = "&c=1_0"
categoryArtAnime = "&c=1_1"
categoryArtDoujinshi = "&c=1_2"
categoryArtGames = "&c=1_3"
categoryArtManga = "&c=1_4"
categoryArtPictures = "&c=1_5"
categoryRealLife = "&c=2_0"
categoryRealLifePhotos = "&c=2_1"
categoryRealLifeVideos = "&c=2_2"
)
func buildURL(baseUrl string, opts BuildURLOptions) (string, error) {
var url string
if baseUrl == "" {
if opts.Provider == "nyaa" {
url = nyaaBaseURL
} else if opts.Provider == "sukebei" {
url = sukebeiBaseURL
} else {
err := fmt.Errorf("provider option could be nyaa or sukebei")
return "", err
}
} else {
url = baseUrl
}
if opts.Query != "" {
url += gourl.QueryEscape(opts.Query)
}
if opts.Provider == "nyaa" {
if opts.Category != "" {
switch opts.Category {
case "all":
url += categoryAll
case "anime":
url += categoryAnime
case "anime-amv":
url += categoryAnimeAMV
case "anime-eng":
url += categoryAnimeEng
case "anime-non-eng":
url += categoryAnimeNonEng
case "anime-raw":
url += categoryAnimeRaw
case "audio":
url += categoryAudio
case "audio-lossless":
url += categoryAudioLossless
case "audio-lossy":
url += categoryAudioLossy
case "literature":
url += categoryLiterature
case "literature-eng":
url += categoryLiteratureEng
case "literature-non-eng":
url += categoryLiteratureNonEng
case "literature-raw":
url += categoryLiteratureRaw
case "live-action":
url += categoryLiveAction
case "live-action-raw":
url += categoryLiveActionRaw
case "live-action-eng":
url += categoryLiveActionEng
case "live-action-non-eng":
url += categoryLiveActionNonEng
case "live-action-idol-prom":
url += categoryLiveActionIdolProm
case "pictures":
url += categoryPictures
case "pictures-graphics":
url += categoryPicturesGraphics
case "pictures-photos":
url += categoryPicturesPhotos
case "software":
url += categorySoftware
case "software-apps":
url += categorySoftwareApps
case "software-games":
url += categorySoftwareGames
default:
err := fmt.Errorf("such nyaa category option does not exitst")
return "", err
}
}
}
if opts.Provider == "sukebei" {
if opts.Category != "" {
switch opts.Category {
case "all":
url += categoryAll
case "art":
url += categoryArt
case "art-anime":
url += categoryArtAnime
case "art-doujinshi":
url += categoryArtDoujinshi
case "art-games":
url += categoryArtGames
case "art-manga":
url += categoryArtManga
case "art-pictures":
url += categoryArtPictures
case "real-life":
url += categoryRealLife
case "real-life-photos":
url += categoryRealLifePhotos
case "real-life-videos":
url += categoryRealLifeVideos
default:
err := fmt.Errorf("such sukebei category option does not exitst")
return "", err
}
}
}
if opts.SortBy != "" {
switch opts.SortBy {
case "downloads":
url += sortByDownloads
case "comments":
url += sortByComments
case "seeders":
url += sortBySeeders
case "leechers":
url += sortByLeechers
case "size-asc":
url += sortBySizeAsc
case "size-dsc":
url += sortBySizeDsc
case "date":
url += sortByDate
default:
err := fmt.Errorf("such sort option does not exitst")
return "", err
}
}
if opts.Filter != "" {
switch opts.Filter {
case "no-filter":
url += filterNoFilter
case "no-remakes":
url += filterNoRemakes
case "trusted-only":
url += filterTrustedOnly
default:
err := fmt.Errorf("such filter option does not exitst")
return "", err
}
}
return url, nil
}