From d44656bca19b6b7df7942a803f2648823b4ca229 Mon Sep 17 00:00:00 2001 From: Zak Saunders Date: Mon, 20 Mar 2023 17:14:19 +0000 Subject: [PATCH] New: Remove Rarbg Indexer due to site shutdown --- .../Files/Indexers/Rarbg/RecentFeed_v1.json | 29 ---- .../Files/Indexers/Rarbg/RecentFeed_v2.json | 84 ---------- .../IndexerTests/RarbgTests/RarbgFixture.cs | 144 ------------------ src/NzbDrone.Core/Indexers/Rarbg/Rarbg.cs | 113 -------------- .../Indexers/Rarbg/RarbgParser.cs | 108 ------------- .../Indexers/Rarbg/RarbgRequestGenerator.cs | 126 --------------- .../Indexers/Rarbg/RarbgResponse.cs | 34 ----- .../Indexers/Rarbg/RarbgSettings.cs | 48 ------ .../Indexers/Rarbg/RarbgTokenProvider.cs | 51 ------- 9 files changed, 737 deletions(-) delete mode 100644 src/NzbDrone.Core.Test/Files/Indexers/Rarbg/RecentFeed_v1.json delete mode 100644 src/NzbDrone.Core.Test/Files/Indexers/Rarbg/RecentFeed_v2.json delete mode 100644 src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs delete mode 100644 src/NzbDrone.Core/Indexers/Rarbg/Rarbg.cs delete mode 100644 src/NzbDrone.Core/Indexers/Rarbg/RarbgParser.cs delete mode 100644 src/NzbDrone.Core/Indexers/Rarbg/RarbgRequestGenerator.cs delete mode 100644 src/NzbDrone.Core/Indexers/Rarbg/RarbgResponse.cs delete mode 100644 src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs delete mode 100644 src/NzbDrone.Core/Indexers/Rarbg/RarbgTokenProvider.cs diff --git a/src/NzbDrone.Core.Test/Files/Indexers/Rarbg/RecentFeed_v1.json b/src/NzbDrone.Core.Test/Files/Indexers/Rarbg/RecentFeed_v1.json deleted file mode 100644 index 2cdbd41e1..000000000 --- a/src/NzbDrone.Core.Test/Files/Indexers/Rarbg/RecentFeed_v1.json +++ /dev/null @@ -1,29 +0,0 @@ -[ - { - "f": "Thunderbirds.Are.Go.S01E09.Slingshot.1080p.WEB-DL.AAC2.0.H.264-Coo7[rartv]", - "c": "TV HD Episodes", - "d": "magnet:?xt=urn:btih:ff4737b5230307836ec8abce6ab73727f1358bf3&dn=Thunderbirds.Are.Go.S01E09.Slingshot.1080p.WEB-DL.AAC2.0.H.264-Coo7%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce", - "s": "44", - "l": "19", - "t": "896238116", - "u": "2015-05-24 19:36:09" - }, - { - "f": "Thunderbirds.Are.Go.S01E10.Tunnels.Of.Time.720p.HDTV.x264-RDVAS[rartv]", - "c": "TV HD Episodes", - "d": "magnet:?xt=urn:btih:47bf1d7bfb72a83300bbe68d0b6aa09591e7a0a1&dn=Thunderbirds.Are.Go.S01E10.Tunnels.Of.Time.720p.HDTV.x264-RDVAS%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce", - "s": "179", - "l": "125", - "t": "556055350", - "u": "2015-05-24 19:07:59" - }, - { - "f": "Tatau.S01E06.1080p.WEB-DL.AAC2.0.H.264-BS[rartv]", - "c": "TV HD Episodes", - "d": "magnet:?xt=urn:btih:8857e9b011c7a0483351371721fa9f3ba356dd73&dn=Tatau.S01E06.1080p.WEB-DL.AAC2.0.H.264-BS%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce", - "s": "27", - "l": "22", - "t": "1652442143", - "u": "2015-05-24 18:54:49" - } -] diff --git a/src/NzbDrone.Core.Test/Files/Indexers/Rarbg/RecentFeed_v2.json b/src/NzbDrone.Core.Test/Files/Indexers/Rarbg/RecentFeed_v2.json deleted file mode 100644 index 94ed8092a..000000000 --- a/src/NzbDrone.Core.Test/Files/Indexers/Rarbg/RecentFeed_v2.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "torrent_results": [ - { - "title": "Sense8.S01E01.WEBRip.x264-FGT", - "category": "TV Episodes", - "download": "magnet:?xt=urn:btih:d8bde635f573acb390c7d7e7efc1556965fdc802&dn=Sense8.S01E01.WEBRip.x264-FGT&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce", - "seeders": 304, - "leechers": 200, - "size": 564198371, - "pubdate": "2015-06-05 16:58:11 +0000", - "episode_info": { - "imdb": "tt2431438", - "tvrage": "35197", - "tvdb": "268156", - "airdate": "2015-06-05", - "epnum": "01", - "seasonnum": "1", - "title": "Limbic Resonance" - }, - "ranked": 1, - "info_page": "https:\/\/torrentapi.org\/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_5_6__d8bde635f5" - }, - { - "title": "Sense8.S01E02.WEBRip.x264-FGT", - "category": "TV Episodes", - "download": "magnet:?xt=urn:btih:e5ab5f398d929c791ac4f1d5bb2fba0997372a91&dn=Sense8.S01E02.WEBRip.x264-FGT&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce", - "seeders": 299, - "leechers": 209, - "size": 486918696, - "pubdate": "2015-06-05 16:58:23 +0000", - "episode_info": { - "imdb": "tt2431438", - "tvrage": "35197", - "tvdb": "268156", - "airdate": "2015-06-05", - "epnum": "02", - "seasonnum": "1", - "title": "I Am Also A We" - }, - "ranked": 1, - "info_page": "https:\/\/torrentapi.org\/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_5_7__e5ab5f398d" - }, - { - "title": "Comedy.Bang.Bang.S04E20.HDTV.x264-YesTV[rartv]", - "category": "TV Episodes", - "download": "magnet:?xt=urn:btih:0ed8bd14206e211eef9d3d36a48b038f280ef20c&dn=Comedy.Bang.Bang.S04E20.HDTV.x264-YesTV%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce", - "seeders": 45, - "leechers": 15, - "size": 154208067, - "pubdate": "2015-06-05 17:33:37 +0000", - "episode_info": { - "imdb": "tt2176287", - "tvrage": "31483", - "tvdb": "258310", - "airdate": "2015-06-05", - "epnum": "20", - "seasonnum": "4", - "title": "Judd Apatow Wears a Polo and Blue Suede Shoes" - }, - "ranked": 1, - "info_page": "https:\/\/torrentapi.org\/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_6_7__0ed8bd1420" - }, - { - "title": "Comedy.Bang.Bang.S04E20.720p.HDTV.x264-YesTV[rartv]", - "category": "TV HD Episodes", - "download": "magnet:?xt=urn:btih:10257dee06327ba66cc2674e08d71b3bb2089b06&dn=Comedy.Bang.Bang.S04E20.720p.HDTV.x264-YesTV%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce", - "seeders": 22, - "leechers": 6, - "size": 514574549, - "pubdate": "2015-06-05 17:33:49 +0000", - "episode_info": { - "imdb": "tt2176287", - "tvrage": "31483", - "tvdb": "258310", - "airdate": "2015-06-05", - "epnum": "20", - "seasonnum": "4", - "title": "Judd Apatow Wears a Polo and Blue Suede Shoes" - }, - "ranked": 1, - "info_page": "https:\/\/torrentapi.org\/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_6_8__10257dee06" - } - ] -} diff --git a/src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs deleted file mode 100644 index 9bddff158..000000000 --- a/src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System; -using System.Linq; -using System.Net; -using System.Net.Http; -using FluentAssertions; -using Moq; -using NUnit.Framework; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Http; -using NzbDrone.Core.Indexers; -using NzbDrone.Core.Indexers.Rarbg; -using NzbDrone.Core.Parser.Model; -using NzbDrone.Core.Test.Framework; -using NzbDrone.Test.Common; - -namespace NzbDrone.Core.Test.IndexerTests.RarbgTests -{ - [TestFixture] - public class RarbgFixture : CoreTest - { - [SetUp] - public void Setup() - { - Subject.Definition = new IndexerDefinition() - { - Name = "Rarbg", - Settings = new RarbgSettings() - }; - - Mocker.GetMock() - .Setup(v => v.GetToken(It.IsAny())) - .Returns("validtoken"); - } - - [Test] - public void should_parse_recent_feed_from_Rarbg() - { - var recentFeed = ReadAllText(@"Files/Indexers/Rarbg/RecentFeed_v2.json"); - - Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), recentFeed)); - - var releases = Subject.FetchRecent(); - - releases.Should().HaveCount(4); - releases.First().Should().BeOfType(); - - var torrentInfo = releases.First() as TorrentInfo; - - torrentInfo.Title.Should().Be("Sense8.S01E01.WEBRip.x264-FGT"); - torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent); - torrentInfo.DownloadUrl.Should().Be("magnet:?xt=urn:btih:d8bde635f573acb390c7d7e7efc1556965fdc802&dn=Sense8.S01E01.WEBRip.x264-FGT&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce"); - torrentInfo.InfoUrl.Should().Be($"https://torrentapi.org/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_5_6__d8bde635f5&app_id={BuildInfo.AppName}"); - torrentInfo.Indexer.Should().Be(Subject.Definition.Name); - torrentInfo.PublishDate.Should().Be(DateTime.Parse("2015-06-05 16:58:11 +0000").ToUniversalTime()); - torrentInfo.Size.Should().Be(564198371); - torrentInfo.InfoHash.Should().BeNull(); - torrentInfo.MagnetUrl.Should().BeNull(); - torrentInfo.Peers.Should().Be(304 + 200); - torrentInfo.Seeders.Should().Be(304); - torrentInfo.TvdbId.Should().Be(268156); - torrentInfo.TvRageId.Should().Be(35197); - } - - [Test] - public void should_parse_error_20_as_empty_results() - { - Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), "{ error_code: 20, error: \"some message\" }")); - - var releases = Subject.FetchRecent(); - - releases.Should().HaveCount(0); - } - - [Test] - public void should_warn_on_unknown_error() - { - Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), "{ error_code: 25, error: \"some message\" }")); - - var releases = Subject.FetchRecent(); - - releases.Should().HaveCount(0); - - ExceptionVerification.ExpectedWarns(1); - } - - [Test] - public void should_warn_and_record_failure_on_429_response() - { - Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), "", HttpStatusCode.TooManyRequests)); - - var releases = Subject.FetchRecent(); - - releases.Should().HaveCount(0); - - ExceptionVerification.ExpectedWarns(1); - - Mocker.GetMock() - .Verify(v => v.RecordFailure(It.IsAny(), It.Is(t => t == TimeSpan.FromMinutes(2)))); - } - - [Test] - public void should_warn_and_record_failure_on_520_response() - { - Mocker.GetMock() - .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - .Returns(r => new HttpResponse(r, new HttpHeader(), "", (HttpStatusCode)520)); - - var releases = Subject.FetchRecent(); - - releases.Should().HaveCount(0); - - ExceptionVerification.ExpectedWarns(1); - - Mocker.GetMock() - .Verify(v => v.RecordFailure(It.IsAny(), It.Is(t => t == TimeSpan.FromMinutes(3)))); - } - - // Uncomment when RarbgParser is updated - // [Test] - // public void should_warn_and_record_failure_on_200_response_with_rate_limit() - // { - // Mocker.GetMock() - // .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.Get))) - // .Returns(r => new HttpResponse(r, new HttpHeader(), "{ rate_limit: 1 }")); - // - // var releases = Subject.FetchRecent(); - // - // releases.Should().HaveCount(0); - // - // ExceptionVerification.ExpectedWarns(1); - // - // Mocker.GetMock() - // .Verify(v => v.RecordFailure(It.IsAny(), It.Is(t => t == TimeSpan.FromMinutes(5)))); - // } - } -} diff --git a/src/NzbDrone.Core/Indexers/Rarbg/Rarbg.cs b/src/NzbDrone.Core/Indexers/Rarbg/Rarbg.cs deleted file mode 100644 index e180695ef..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/Rarbg.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Collections.Generic; -using NLog; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; -using NzbDrone.Core.Configuration; -using NzbDrone.Core.Exceptions; -using NzbDrone.Core.Http.CloudFlare; -using NzbDrone.Core.Parser; -using NzbDrone.Core.Validation; - -namespace NzbDrone.Core.Indexers.Rarbg -{ - public class Rarbg : HttpIndexerBase - { - private readonly IRarbgTokenProvider _tokenProvider; - - public override string Name => "Rarbg"; - - public override DownloadProtocol Protocol => DownloadProtocol.Torrent; - public override TimeSpan RateLimit => TimeSpan.FromSeconds(4); - - public Rarbg(IRarbgTokenProvider tokenProvider, IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger) - : base(httpClient, indexerStatusService, configService, parsingService, logger) - { - _tokenProvider = tokenProvider; - } - - public override IIndexerRequestGenerator GetRequestGenerator() - { - return new RarbgRequestGenerator(_tokenProvider) { Settings = Settings }; - } - - public override IParseIndexerResponse GetParser() - { - return new RarbgParser(); - } - - public override object RequestAction(string action, IDictionary query) - { - if (action == "checkCaptcha") - { - Settings.Validate().Filter("BaseUrl").ThrowOnError(); - - try - { - var request = new HttpRequestBuilder(Settings.BaseUrl.Trim('/')) - .Resource($"/pubapi_v2.php?get_token=get_token&app_id={BuildInfo.AppName}") - .Accept(HttpAccept.Json) - .Build(); - - _httpClient.Get(request); - } - catch (CloudFlareCaptchaException ex) - { - return new - { - captchaRequest = new - { - host = ex.CaptchaRequest.Host, - ray = ex.CaptchaRequest.Ray, - siteKey = ex.CaptchaRequest.SiteKey, - secretToken = ex.CaptchaRequest.SecretToken, - responseUrl = ex.CaptchaRequest.ResponseUrl.FullUri, - } - }; - } - - return new - { - captchaToken = "" - }; - } - else if (action == "getCaptchaCookie") - { - if (query["responseUrl"].IsNullOrWhiteSpace()) - { - throw new BadRequestException("QueryParam responseUrl invalid."); - } - - if (query["ray"].IsNullOrWhiteSpace()) - { - throw new BadRequestException("QueryParam ray invalid."); - } - - if (query["captchaResponse"].IsNullOrWhiteSpace()) - { - throw new BadRequestException("QueryParam captchaResponse invalid."); - } - - var request = new HttpRequestBuilder(query["responseUrl"]) - .AddQueryParam("id", query["ray"]) - .AddQueryParam("g-recaptcha-response", query["captchaResponse"]) - .Build(); - - request.UseSimplifiedUserAgent = true; - request.AllowAutoRedirect = false; - - var response = _httpClient.Get(request); - - var cfClearanceCookie = response.GetCookies()["cf_clearance"]; - - return new - { - captchaToken = cfClearanceCookie - }; - } - - return new { }; - } - } -} diff --git a/src/NzbDrone.Core/Indexers/Rarbg/RarbgParser.cs b/src/NzbDrone.Core/Indexers/Rarbg/RarbgParser.cs deleted file mode 100644 index cf1cd8fb2..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgParser.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Text.RegularExpressions; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Http; -using NzbDrone.Core.Indexers.Exceptions; -using NzbDrone.Core.Parser.Model; - -namespace NzbDrone.Core.Indexers.Rarbg -{ - public class RarbgParser : IParseIndexerResponse - { - private static readonly Regex RegexGuid = new Regex(@"^magnet:\?xt=urn:btih:([a-f0-9]+)", RegexOptions.Compiled); - - public IList ParseResponse(IndexerResponse indexerResponse) - { - var results = new List(); - - switch (indexerResponse.HttpResponse.StatusCode) - { - case HttpStatusCode.TooManyRequests: - throw new RequestLimitReachedException("Indexer API limit reached", TimeSpan.FromMinutes(2)); - case (HttpStatusCode)520: - throw new RequestLimitReachedException("Indexer API error. Likely rate limited by origin server", TimeSpan.FromMinutes(3)); - default: - if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK) - { - throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected status code [{0}]", indexerResponse.HttpResponse.StatusCode); - } - - break; - } - - var jsonResponse = new HttpResponse(indexerResponse.HttpResponse); - - if (jsonResponse.Resource.error_code.HasValue) - { - if (jsonResponse.Resource.error_code == 5 || jsonResponse.Resource.error_code == 8 - || jsonResponse.Resource.error_code == 9 || jsonResponse.Resource.error_code == 10 - || jsonResponse.Resource.error_code == 13 || jsonResponse.Resource.error_code == 14 - || jsonResponse.Resource.error_code == 20) - { - // No results, rate limit, tvdbid not found/invalid, or imdbid not found/invalid - return results; - } - - throw new IndexerException(indexerResponse, "Indexer API call returned error {0}: {1}", jsonResponse.Resource.error_code, jsonResponse.Resource.error); - } - - if (jsonResponse.Resource.torrent_results == null) - { - // Despite this being the requested behaviour it appears to be problematic, commenting it out for now - // if (jsonResponse.Resource.rate_limit == 1) - // { - // throw new RequestLimitReachedException("Indexer API limit reached", TimeSpan.FromMinutes(5)); - // } - - return results; - } - - foreach (var torrent in jsonResponse.Resource.torrent_results) - { - var torrentInfo = new TorrentInfo(); - - torrentInfo.Guid = GetGuid(torrent); - torrentInfo.Title = torrent.title; - torrentInfo.Size = torrent.size; - torrentInfo.DownloadUrl = torrent.download; - torrentInfo.InfoUrl = $"{torrent.info_page}&app_id={BuildInfo.AppName}"; - torrentInfo.PublishDate = torrent.pubdate.ToUniversalTime(); - torrentInfo.Seeders = torrent.seeders; - torrentInfo.Peers = torrent.leechers + torrent.seeders; - - if (torrent.episode_info != null) - { - if (torrent.episode_info.tvdb != null) - { - torrentInfo.TvdbId = torrent.episode_info.tvdb.Value; - } - - if (torrent.episode_info.tvrage != null) - { - torrentInfo.TvRageId = torrent.episode_info.tvrage.Value; - } - } - - results.Add(torrentInfo); - } - - return results; - } - - private string GetGuid(RarbgTorrent torrent) - { - var match = RegexGuid.Match(torrent.download); - - if (match.Success) - { - return string.Format("rarbg-{0}", match.Groups[1].Value); - } - else - { - return string.Format("rarbg-{0}", torrent.download); - } - } - } -} diff --git a/src/NzbDrone.Core/Indexers/Rarbg/RarbgRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Rarbg/RarbgRequestGenerator.cs deleted file mode 100644 index c35ae1f3a..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgRequestGenerator.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System.Collections.Generic; -using System.Net; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; -using NzbDrone.Core.IndexerSearch.Definitions; - -namespace NzbDrone.Core.Indexers.Rarbg -{ - public class RarbgRequestGenerator : IIndexerRequestGenerator - { - private readonly IRarbgTokenProvider _tokenProvider; - - public RarbgSettings Settings { get; set; } - - public RarbgRequestGenerator(IRarbgTokenProvider tokenProvider) - { - _tokenProvider = tokenProvider; - } - - public virtual IndexerPageableRequestChain GetRecentRequests() - { - var pageableRequests = new IndexerPageableRequestChain(); - - pageableRequests.Add(GetPagedRequests("list", null, null)); - - return pageableRequests; - } - - public virtual IndexerPageableRequestChain GetSearchRequests(SingleEpisodeSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - pageableRequests.Add(GetPagedRequests("search", searchCriteria.Series.TvdbId, "S{0:00}E{1:00}", searchCriteria.SeasonNumber, searchCriteria.EpisodeNumber)); - - return pageableRequests; - } - - public virtual IndexerPageableRequestChain GetSearchRequests(SeasonSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - pageableRequests.Add(GetPagedRequests("search", searchCriteria.Series.TvdbId, "S{0:00}", searchCriteria.SeasonNumber)); - - return pageableRequests; - } - - public virtual IndexerPageableRequestChain GetSearchRequests(DailyEpisodeSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - pageableRequests.Add(GetPagedRequests("search", searchCriteria.Series.TvdbId, "\"{0:yyyy MM dd}\"", searchCriteria.AirDate)); - - return pageableRequests; - } - - public virtual IndexerPageableRequestChain GetSearchRequests(DailySeasonSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - pageableRequests.Add(GetPagedRequests("search", searchCriteria.Series.TvdbId, "\"{0}\"", searchCriteria.Year)); - - return pageableRequests; - } - - public virtual IndexerPageableRequestChain GetSearchRequests(AnimeEpisodeSearchCriteria searchCriteria) - { - return new IndexerPageableRequestChain(); - } - - public virtual IndexerPageableRequestChain GetSearchRequests(SpecialEpisodeSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - - foreach (var queryTitle in searchCriteria.EpisodeQueryTitles) - { - var query = queryTitle.Replace('+', ' '); - query = System.Web.HttpUtility.UrlEncode(query); - - pageableRequests.Add(GetPagedRequests("search", searchCriteria.Series.TvdbId, query)); - } - - return pageableRequests; - } - - private IEnumerable GetPagedRequests(string mode, int? tvdbId, string query, params object[] args) - { - var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl) - .Resource("/pubapi_v2.php") - .Accept(HttpAccept.Json); - - requestBuilder.SuppressHttpErrorStatusCodes = new[] { HttpStatusCode.TooManyRequests, (HttpStatusCode)520 }; - - if (Settings.CaptchaToken.IsNotNullOrWhiteSpace()) - { - requestBuilder.UseSimplifiedUserAgent = true; - requestBuilder.SetCookie("cf_clearance", Settings.CaptchaToken); - } - - requestBuilder.AddQueryParam("mode", mode); - - if (tvdbId.HasValue) - { - requestBuilder.AddQueryParam("search_tvdb", tvdbId.Value); - } - - if (query.IsNotNullOrWhiteSpace()) - { - requestBuilder.AddQueryParam("search_string", string.Format(query, args)); - } - - if (!Settings.RankedOnly) - { - requestBuilder.AddQueryParam("ranked", "0"); - } - - requestBuilder.AddQueryParam("category", "18;41;49"); - requestBuilder.AddQueryParam("limit", "100"); - requestBuilder.AddQueryParam("token", _tokenProvider.GetToken(Settings)); - requestBuilder.AddQueryParam("format", "json_extended"); - requestBuilder.AddQueryParam("app_id", BuildInfo.AppName); - - yield return new IndexerRequest(requestBuilder.Build()); - } - } -} diff --git a/src/NzbDrone.Core/Indexers/Rarbg/RarbgResponse.cs b/src/NzbDrone.Core/Indexers/Rarbg/RarbgResponse.cs deleted file mode 100644 index d9294c9d3..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgResponse.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace NzbDrone.Core.Indexers.Rarbg -{ - public class RarbgResponse - { - public string error { get; set; } - public int? error_code { get; set; } - public int? rate_limit { get; set; } - public List torrent_results { get; set; } - } - - public class RarbgTorrent - { - public string title { get; set; } - public string category { get; set; } - public string download { get; set; } - public int? seeders { get; set; } - public int? leechers { get; set; } - public long size { get; set; } - public DateTime pubdate { get; set; } - public RarbgTorrentInfo episode_info { get; set; } - public int? ranked { get; set; } - public string info_page { get; set; } - } - - public class RarbgTorrentInfo - { - public string imdb { get; set; } - public int? tvrage { get; set; } - public int? tvdb { get; set; } - } -} diff --git a/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs b/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs deleted file mode 100644 index b1b4fe7d3..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs +++ /dev/null @@ -1,48 +0,0 @@ -using FluentValidation; -using NzbDrone.Core.Annotations; -using NzbDrone.Core.Validation; - -namespace NzbDrone.Core.Indexers.Rarbg -{ - public class RarbgSettingsValidator : AbstractValidator - { - public RarbgSettingsValidator() - { - RuleFor(c => c.BaseUrl).ValidRootUrl(); - - RuleFor(c => c.SeedCriteria).SetValidator(_ => new SeedCriteriaSettingsValidator()); - } - } - - public class RarbgSettings : ITorrentIndexerSettings - { - private static readonly RarbgSettingsValidator Validator = new RarbgSettingsValidator(); - - public RarbgSettings() - { - BaseUrl = "https://torrentapi.org"; - RankedOnly = false; - MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS; - } - - [FieldDefinition(0, Label = "API URL", HelpText = "URL to Rarbg api, not the website.")] - public string BaseUrl { get; set; } - - [FieldDefinition(1, Type = FieldType.Checkbox, Label = "Ranked Only", HelpText = "Only include ranked results.")] - public bool RankedOnly { get; set; } - - [FieldDefinition(2, Type = FieldType.Captcha, Label = "CAPTCHA Token", HelpText = "CAPTCHA Clearance token used to handle CloudFlare Anti-DDOS measures on shared-ip VPNs.")] - public string CaptchaToken { get; set; } - - [FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)] - public int MinimumSeeders { get; set; } - - [FieldDefinition(4)] - public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings(); - - public NzbDroneValidationResult Validate() - { - return new NzbDroneValidationResult(Validator.Validate(this)); - } - } -} diff --git a/src/NzbDrone.Core/Indexers/Rarbg/RarbgTokenProvider.cs b/src/NzbDrone.Core/Indexers/Rarbg/RarbgTokenProvider.cs deleted file mode 100644 index 2efc0fd8c..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgTokenProvider.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using Newtonsoft.Json.Linq; -using NLog; -using NzbDrone.Common.Cache; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http; - -namespace NzbDrone.Core.Indexers.Rarbg -{ - public interface IRarbgTokenProvider - { - string GetToken(RarbgSettings settings); - } - - public class RarbgTokenProvider : IRarbgTokenProvider - { - private readonly IHttpClient _httpClient; - private readonly ICached _tokenCache; - private readonly Logger _logger; - - public RarbgTokenProvider(IHttpClient httpClient, ICacheManager cacheManager, Logger logger) - { - _httpClient = httpClient; - _tokenCache = cacheManager.GetCache(GetType()); - _logger = logger; - } - - public string GetToken(RarbgSettings settings) - { - return _tokenCache.Get(settings.BaseUrl, - () => - { - var requestBuilder = new HttpRequestBuilder(settings.BaseUrl.Trim('/')) - .WithRateLimit(3.0) - .Resource($"/pubapi_v2.php?get_token=get_token&app_id={BuildInfo.AppName}") - .Accept(HttpAccept.Json); - - if (settings.CaptchaToken.IsNotNullOrWhiteSpace()) - { - requestBuilder.UseSimplifiedUserAgent = true; - requestBuilder.SetCookie("cf_clearance", settings.CaptchaToken); - } - - var response = _httpClient.Get(requestBuilder.Build()); - - return response.Resource["token"].ToString(); - }, TimeSpan.FromMinutes(14.0)); - } - } -}