From 471a34eabfe875fc7bd2976d440c09d59df2236d 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 | 141 ------------------ .../Datastore/Migration/222_remove_rarbg.cs | 14 ++ src/NzbDrone.Core/Indexers/Rarbg/Rarbg.cs | 113 -------------- .../Indexers/Rarbg/RarbgParser.cs | 110 -------------- .../Indexers/Rarbg/RarbgRequestGenerator.cs | 125 ---------------- .../Indexers/Rarbg/RarbgResponse.cs | 37 ----- .../Indexers/Rarbg/RarbgSettings.cs | 107 ------------- .../Indexers/Rarbg/RarbgTokenProvider.cs | 51 ------- 10 files changed, 14 insertions(+), 797 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 create mode 100644 src/NzbDrone.Core/Datastore/Migration/222_remove_rarbg.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 fc4e6750e..000000000 --- a/src/NzbDrone.Core.Test/IndexerTests/RarbgTests/RarbgFixture.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Linq; -using System.Net; -using System.Net.Http; -using FluentAssertions; -using Moq; -using NUnit.Framework; -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=Radarr"); - 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); - } - - [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/Datastore/Migration/222_remove_rarbg.cs b/src/NzbDrone.Core/Datastore/Migration/222_remove_rarbg.cs new file mode 100644 index 000000000..c26d44708 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/222_remove_rarbg.cs @@ -0,0 +1,14 @@ +using FluentMigrator; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(222)] + public class remove_rarbg : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Delete.FromTable("Indexers").Row(new { Implementation = "Rarbg" }); + } + } +} 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 7a444d9f9..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgParser.cs +++ /dev/null @@ -1,110 +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, tmdbid 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.imdb != null) - { - torrentInfo.ImdbId = int.Parse(torrent.episode_info.imdb.Substring(2)); - } - - if (torrent.episode_info.themoviedb != null) - { - torrentInfo.TmdbId = torrent.episode_info.themoviedb.Value; - } - } - - results.Add(torrentInfo); - } - - return results; - } - - public Action, DateTime?> CookiesUpdater { get; set; } - - 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 53f13aaff..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgRequestGenerator.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -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 IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria) - { - var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetMovieRequest(searchCriteria)); - return pageableRequests; - } - - private IEnumerable GetPagedRequests(string mode, int? imdbId, 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 (imdbId.HasValue) - { - requestBuilder.AddQueryParam("search_imdb", imdbId.Value); - } - - if (query.IsNotNullOrWhiteSpace()) - { - requestBuilder.AddQueryParam("search_string", string.Format(query, args)); - } - - if (!Settings.RankedOnly) - { - requestBuilder.AddQueryParam("ranked", "0"); - } - - var categoryParam = string.Join(";", Settings.Categories.Distinct()); - - requestBuilder.AddQueryParam("category", categoryParam); - 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()); - } - - private IEnumerable GetMovieRequest(MovieSearchCriteria searchCriteria) - { - var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl) - .Resource("/pubapi_v2.php") - .Accept(HttpAccept.Json); - - if (Settings.CaptchaToken.IsNotNullOrWhiteSpace()) - { - requestBuilder.UseSimplifiedUserAgent = true; - requestBuilder.SetCookie("cf_clearance", Settings.CaptchaToken); - } - - requestBuilder.AddQueryParam("mode", "search"); - - if (searchCriteria.Movie.MovieMetadata.Value.ImdbId.IsNotNullOrWhiteSpace()) - { - requestBuilder.AddQueryParam("search_imdb", searchCriteria.Movie.MovieMetadata.Value.ImdbId); - } - else if (searchCriteria.Movie.MovieMetadata.Value.TmdbId > 0) - { - requestBuilder.AddQueryParam("search_themoviedb", searchCriteria.Movie.TmdbId); - } - else - { - requestBuilder.AddQueryParam("search_string", $"{searchCriteria.Movie.Title} {searchCriteria.Movie.Year}"); - } - - if (!Settings.RankedOnly) - { - requestBuilder.AddQueryParam("ranked", "0"); - } - - var categoryParam = string.Join(";", Settings.Categories.Distinct()); - - requestBuilder.AddQueryParam("category", categoryParam); - 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()); - } - - public Func> GetCookies { get; set; } - public Action, DateTime?> CookiesUpdater { get; set; } - } -} diff --git a/src/NzbDrone.Core/Indexers/Rarbg/RarbgResponse.cs b/src/NzbDrone.Core/Indexers/Rarbg/RarbgResponse.cs deleted file mode 100644 index 9b53bdc90..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgResponse.cs +++ /dev/null @@ -1,37 +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; } - - // This is named episode_info for movies as well as shows - 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; } - public int? themoviedb { 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 33f1379b9..000000000 --- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System.Collections.Generic; -using FluentValidation; -using NzbDrone.Core.Annotations; -using NzbDrone.Core.Languages; -using NzbDrone.Core.Parser.Model; -using NzbDrone.Core.Validation; - -namespace NzbDrone.Core.Indexers.Rarbg -{ - public class RarbgSettingsValidator : AbstractValidator - { - public RarbgSettingsValidator() - { - RuleFor(c => c.BaseUrl).ValidRootUrl(); - - RuleFor(c => c.Categories).NotEmpty(); - - 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; - Categories = new int[] - { - (int)RarbgCategories.Movie_Xvid, - (int)RarbgCategories.Movie_Xvid_720p, - (int)RarbgCategories.Movie_x264, - (int)RarbgCategories.Movie_x264_720p, - (int)RarbgCategories.Movie_x264_1080p, - (int)RarbgCategories.Movie_x264_4K, - (int)RarbgCategories.Movie_x265_1080p, - (int)RarbgCategories.Movie_x265_4K, - (int)RarbgCategories.Movie_x265_4K_HDR, - (int)RarbgCategories.Movie_BD_Remux - }; - MultiLanguages = new List(); - RequiredFlags = new List(); - } - - [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.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)] - public IEnumerable MultiLanguages { get; set; } - - [FieldDefinition(4, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)] - public int MinimumSeeders { get; set; } - - [FieldDefinition(5, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)] - public IEnumerable RequiredFlags { get; set; } - - [FieldDefinition(6, Type = FieldType.Select, Label = "Categories", SelectOptions = typeof(RarbgCategories), HelpText = "Categories for use in search and feeds. If unspecified, all options are used.")] - public IEnumerable Categories { get; set; } - - [FieldDefinition(7)] - public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings(); - - public NzbDroneValidationResult Validate() - { - return new NzbDroneValidationResult(Validator.Validate(this)); - } - } - - public enum RarbgCategories - { - [FieldOption] - Movie_Xvid = 14, - [FieldOption] - Movie_Xvid_720p = 48, - [FieldOption] - Movie_x264 = 17, - [FieldOption] - Movie_x264_720p = 45, - [FieldOption] - Movie_x264_1080p = 44, - [FieldOption] - Movie_x264_4K = 50, - [FieldOption] - Movie_x264_3D = 47, - [FieldOption] - Movie_x265_1080p = 54, - [FieldOption] - Movie_x265_4K = 51, - [FieldOption] - Movie_x265_4K_HDR = 52, - [FieldOption] - Movie_BD_Remux = 46, - [FieldOption] - Movie_Full_BD = 42, - [FieldOption] - XXX = 4, - } -} 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)); - } - } -}