Updated Rarbg to api v2.

fixes #752
ref rarbg/torrentapi#1
pull/210/merge
Taloth Saldono 10 years ago
parent 71f3435026
commit 569ef09f39

@ -0,0 +1,84 @@
{
"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"
}
]
}

@ -8,6 +8,7 @@ using NzbDrone.Core.Indexers;
using NzbDrone.Core.Indexers.Rarbg; using NzbDrone.Core.Indexers.Rarbg;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.IndexerTests.RarbgTests namespace NzbDrone.Core.Test.IndexerTests.RarbgTests
{ {
@ -31,7 +32,7 @@ namespace NzbDrone.Core.Test.IndexerTests.RarbgTests
[Test] [Test]
public void should_parse_recent_feed_from_Rarbg() public void should_parse_recent_feed_from_Rarbg()
{ {
var recentFeed = ReadAllText(@"Files/Indexers/Rarbg/RecentFeed.json"); var recentFeed = ReadAllText(@"Files/Indexers/Rarbg/RecentFeed_v2.json");
Mocker.GetMock<IHttpClient>() Mocker.GetMock<IHttpClient>()
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET))) .Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
@ -39,21 +40,49 @@ namespace NzbDrone.Core.Test.IndexerTests.RarbgTests
var releases = Subject.FetchRecent(); var releases = Subject.FetchRecent();
releases.Should().HaveCount(3); releases.Should().HaveCount(4);
releases.First().Should().BeOfType<TorrentInfo>(); releases.First().Should().BeOfType<TorrentInfo>();
var torrentInfo = releases.First() as TorrentInfo; var torrentInfo = releases.First() as TorrentInfo;
torrentInfo.Title.Should().Be("Thunderbirds.Are.Go.S01E09.Slingshot.1080p.WEB-DL.AAC2.0.H.264-Coo7[rartv]"); torrentInfo.Title.Should().Be("Sense8.S01E01.WEBRip.x264-FGT");
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent); torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
torrentInfo.DownloadUrl.Should().Be("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"); 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");
torrentInfo.Indexer.Should().Be(Subject.Definition.Name); torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2015-05-24 19:36:09")); torrentInfo.PublishDate.Should().Be(DateTime.Parse("2015-06-05 16:58:11 +0000").ToUniversalTime());
torrentInfo.Size.Should().Be(896238116); torrentInfo.Size.Should().Be(564198371);
torrentInfo.InfoHash.Should().BeNull(); torrentInfo.InfoHash.Should().BeNull();
torrentInfo.MagnetUrl.Should().BeNull(); torrentInfo.MagnetUrl.Should().BeNull();
torrentInfo.Peers.Should().Be(44+19); torrentInfo.Peers.Should().Be(304 + 200);
torrentInfo.Seeders.Should().Be(44); torrentInfo.Seeders.Should().Be(304);
torrentInfo.TvRageId.Should().Be(35197);
}
[Test]
public void should_parse_error_20_as_empty_results()
{
Mocker.GetMock<IHttpClient>()
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
.Returns<HttpRequest>(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<IHttpClient>()
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), "{ error_code: 25, error: \"some message\" }"));
var releases = Subject.FetchRecent();
releases.Should().HaveCount(0);
ExceptionVerification.ExpectedWarns(1);
} }
} }
} }

@ -168,7 +168,10 @@
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveRejectedFixture.cs" /> <Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveRejectedFixture.cs" />
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveGrabbedFixture.cs" /> <Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveGrabbedFixture.cs" />
<Compile Include="Download\Pending\PendingReleaseServiceTests\AddFixture.cs" /> <Compile Include="Download\Pending\PendingReleaseServiceTests\AddFixture.cs" />
<None Include="Files\Indexers\Rarbg\RecentFeed.json"> <None Include="Files\Indexers\Rarbg\RecentFeed_v1.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Files\Indexers\Rarbg\RecentFeed_v2.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<Compile Include="FluentTest.cs" /> <Compile Include="FluentTest.cs" />

@ -9,12 +9,11 @@ namespace NzbDrone.Core.Indexers.Rarbg
public class Rarbg : HttpIndexerBase<RarbgSettings> public class Rarbg : HttpIndexerBase<RarbgSettings>
{ {
private readonly IRarbgTokenProvider _tokenProvider; private readonly IRarbgTokenProvider _tokenProvider;
private static DateTime _lastFetch;
public override string Name { get { return "Rarbg"; } } public override string Name { get { return "Rarbg"; } }
public override DownloadProtocol Protocol { get { return DownloadProtocol.Torrent; } } public override DownloadProtocol Protocol { get { return DownloadProtocol.Torrent; } }
public override TimeSpan RateLimit { get { return TimeSpan.FromSeconds(10); } } public override TimeSpan RateLimit { get { return TimeSpan.FromSeconds(2); } }
public Rarbg(IRarbgTokenProvider tokenProvider, IHttpClient httpClient, IConfigService configService, IParsingService parsingService, Logger logger) public Rarbg(IRarbgTokenProvider tokenProvider, IHttpClient httpClient, IConfigService configService, IParsingService parsingService, Logger logger)
: base(httpClient, configService, parsingService, logger) : base(httpClient, configService, parsingService, logger)

@ -27,33 +27,41 @@ namespace NzbDrone.Core.Indexers.Rarbg
break; break;
} }
var jsonResponse = new HttpResponse<object>(indexerResponse.HttpResponse).Resource as JContainer; var jsonResponse = new HttpResponse<RarbgResponse>(indexerResponse.HttpResponse);
var errorResponse = jsonResponse as JObject; if (jsonResponse.Resource.error_code.HasValue)
if (errorResponse != null && errorResponse["error"] != null)
{ {
var error = errorResponse["error"].ToString(); if (jsonResponse.Resource.error_code == 20)
if (error == "No results found")
{ {
// No results found
return results; return results;
} }
throw new IndexerException(indexerResponse, "Indexer API call returned an error [{0}]", errorResponse["error"]); throw new IndexerException(indexerResponse, "Indexer API call returned error {0}: {1}", jsonResponse.Resource.error_code, jsonResponse.Resource.error);
} }
var torrentResponse = jsonResponse.ToObject<List<RarbgTorrent>>(); if (jsonResponse.Resource.torrent_results == null)
{
return results;
}
foreach (var torrent in torrentResponse) foreach (var torrent in jsonResponse.Resource.torrent_results)
{ {
var torrentInfo = new TorrentInfo(); var torrentInfo = new TorrentInfo();
torrentInfo.Guid = GetGuid(torrent); torrentInfo.Guid = GetGuid(torrent);
torrentInfo.Title = torrent.Title; torrentInfo.Title = torrent.title;
torrentInfo.Size = torrent.Size; torrentInfo.Size = torrent.size;
torrentInfo.DownloadUrl = torrent.DownloadUrl; torrentInfo.DownloadUrl = torrent.download;
torrentInfo.PublishDate = torrent.PublishDate; torrentInfo.InfoUrl = torrent.info_page;
torrentInfo.Seeders = torrent.Seeders; torrentInfo.PublishDate = torrent.pubdate;
torrentInfo.Peers = torrent.Leechers + torrent.Seeders; torrentInfo.Seeders = torrent.seeders;
torrentInfo.Peers = torrent.leechers + torrent.seeders;
if (torrent.episode_info != null && torrent.episode_info.tvrage != null)
{
torrentInfo.TvRageId = torrent.episode_info.tvrage.Value;
}
results.Add(torrentInfo); results.Add(torrentInfo);
} }
@ -63,7 +71,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
private string GetGuid(RarbgTorrent torrent) private string GetGuid(RarbgTorrent torrent)
{ {
var match = RegexGuid.Match(torrent.DownloadUrl); var match = RegexGuid.Match(torrent.download);
if (match.Success) if (match.Success)
{ {
@ -71,7 +79,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
} }
else else
{ {
return string.Format("rarbg-{0}", torrent.DownloadUrl); return string.Format("rarbg-{0}", torrent.download);
} }
} }

@ -65,7 +65,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
private IEnumerable<IndexerRequest> GetPagedRequests(string mode, int? tvdbId, string query, params object[] args) private IEnumerable<IndexerRequest> GetPagedRequests(string mode, int? tvdbId, string query, params object[] args)
{ {
var httpRequest = new HttpRequest(Settings.BaseUrl + "/pubapi.php", HttpAccept.Json); var httpRequest = new HttpRequest(Settings.BaseUrl + "/pubapi_v2.php", HttpAccept.Json);
httpRequest.AddQueryParam("mode", mode); httpRequest.AddQueryParam("mode", mode);
@ -88,7 +88,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
httpRequest.AddQueryParam("limit", "100"); httpRequest.AddQueryParam("limit", "100");
httpRequest.AddQueryParam("token", _tokenProvider.GetToken(Settings)); httpRequest.AddQueryParam("token", _tokenProvider.GetToken(Settings));
httpRequest.AddQueryParam("format", "json_extended"); httpRequest.AddQueryParam("format", "json_extended");
httpRequest.AddQueryParam("response_type", "json"); httpRequest.AddQueryParam("app_id", "Sonarr");
yield return new IndexerRequest(httpRequest); yield return new IndexerRequest(httpRequest);
} }

@ -0,0 +1,33 @@
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 List<RarbgTorrent> 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; }
}
}

@ -27,7 +27,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
[FieldDefinition(0, Label = "API URL", HelpText = "URL to Rarbg api, not the website.")] [FieldDefinition(0, Label = "API URL", HelpText = "URL to Rarbg api, not the website.")]
public string BaseUrl { get; set; } public string BaseUrl { get; set; }
[FieldDefinition(1, Label = "Ranked Only", HelpText = "Only include ranked results.")] [FieldDefinition(1, Type = FieldType.Checkbox, Label = "Ranked Only", HelpText = "Only include ranked results.")]
public bool RankedOnly { get; set; } public bool RankedOnly { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()

@ -28,7 +28,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
{ {
return _tokenCache.Get(settings.BaseUrl, () => return _tokenCache.Get(settings.BaseUrl, () =>
{ {
var url = settings.BaseUrl.Trim('/') + "/pubapi.php?get_token=get_token&format=json&response_type=json"; var url = settings.BaseUrl.Trim('/') + "/pubapi_v2.php?get_token=get_token";
var response = _httpClient.Get<JObject>(new HttpRequest(url, HttpAccept.Json)); var response = _httpClient.Get<JObject>(new HttpRequest(url, HttpAccept.Json));

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NzbDrone.Core.Indexers.Rarbg
{
public class RarbgTorrent
{
[JsonProperty("f")]
public string Title { get; set; }
[JsonProperty("c")]
public string Category { get; set; }
[JsonProperty("d")]
public string DownloadUrl { get; set; }
[JsonProperty("s")]
public int Seeders { get; set; }
[JsonProperty("l")]
public int Leechers { get; set; }
[JsonProperty("t")]
public long Size { get; set; }
[JsonProperty("u")]
public DateTime PublishDate { get; set; }
}
}

@ -517,7 +517,7 @@
<Compile Include="Indexers\HttpIndexerBase.cs" /> <Compile Include="Indexers\HttpIndexerBase.cs" />
<Compile Include="Indexers\Rarbg\Rarbg.cs" /> <Compile Include="Indexers\Rarbg\Rarbg.cs" />
<Compile Include="Indexers\Rarbg\RarbgRequestGenerator.cs" /> <Compile Include="Indexers\Rarbg\RarbgRequestGenerator.cs" />
<Compile Include="Indexers\Rarbg\RarbgTorrent.cs" /> <Compile Include="Indexers\Rarbg\RarbgResponse.cs" />
<Compile Include="Indexers\Rarbg\RarbgSettings.cs" /> <Compile Include="Indexers\Rarbg\RarbgSettings.cs" />
<Compile Include="Indexers\Rarbg\RarbgParser.cs" /> <Compile Include="Indexers\Rarbg\RarbgParser.cs" />
<Compile Include="Indexers\Rarbg\RarbgTokenProvider.cs" /> <Compile Include="Indexers\Rarbg\RarbgTokenProvider.cs" />

Loading…
Cancel
Save