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 }