From 97a0daa1aa628bfd3454303bf15990e3bdd34ee4 Mon Sep 17 00:00:00 2001 From: Qstick Date: Mon, 19 Feb 2018 22:34:44 -0500 Subject: [PATCH] Fixed: Gazelle Issues, Plus add feed parse test Fixes #217 --- .../Files/Indexers/Gazelle/Gazelle.json | 166 ++++++++++++++++++ .../Files/Indexers/Gazelle/GazelleIndex.json | 22 +++ .../GazelleTests/GazelleFixture.cs | 66 +++++++ .../NzbDrone.Core.Test.csproj | 7 + .../Indexers/Gazelle/GazelleParser.cs | 18 +- .../Gazelle/GazelleRequestGenerator.cs | 2 +- 6 files changed, 272 insertions(+), 9 deletions(-) create mode 100644 src/NzbDrone.Core.Test/Files/Indexers/Gazelle/Gazelle.json create mode 100644 src/NzbDrone.Core.Test/Files/Indexers/Gazelle/GazelleIndex.json create mode 100644 src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleFixture.cs diff --git a/src/NzbDrone.Core.Test/Files/Indexers/Gazelle/Gazelle.json b/src/NzbDrone.Core.Test/Files/Indexers/Gazelle/Gazelle.json new file mode 100644 index 000000000..f357c1cbd --- /dev/null +++ b/src/NzbDrone.Core.Test/Files/Indexers/Gazelle/Gazelle.json @@ -0,0 +1,166 @@ +{ + "status": "success", + "response": { + "currentPage": 1, + "pages": 1, + "results": [ + { + "groupId": 106951, + "groupName": "Shania Twain", + "artist": "Shania Twain", + "cover": "https:\\/\\/ptpimg.me\\/460az6.jpg", + "tags": [ + "rock", + "country" + ], + "bookmarked": false, + "vanityHouse": false, + "groupYear": 1993, + "releaseType": "Album", + "groupTime": "1512951473", + "maxSize": 653734702, + "totalSnatched": 33, + "totalSeeders": 27, + "totalLeechers": 0, + "torrents": [ + { + "torrentId": 194008, + "editionId": 1, + "artists": [ + { + "id": 9504, + "name": "Shania Twain", + "aliasid": 9506 + } + ], + "remastered": false, + "remasterYear": 0, + "remasterCatalogueNumber": "", + "remasterTitle": "", + "media": "CD", + "encoding": "Lossless", + "format": "FLAC", + "hasLog": true, + "logScore": 100, + "hasCue": true, + "scene": false, + "vanityHouse": false, + "fileCount": 14, + "time": "2016-12-02 16:02:39", + "size": 198741350, + "snatches": 19, + "seeders": 17, + "leechers": 0, + "isFreeleech": false, + "isNeutralLeech": false, + "isPersonalFreeleech": false, + "canUseToken": false, + "hasSnatched": false + }, + { + "torrentId": 230096, + "editionId": 1, + "artists": [ + { + "id": 9504, + "name": "Shania Twain", + "aliasid": 9506 + } + ], + "remastered": false, + "remasterYear": 0, + "remasterCatalogueNumber": "", + "remasterTitle": "", + "media": "CD", + "encoding": "320", + "format": "MP3", + "hasLog": false, + "logScore": 0, + "hasCue": false, + "scene": false, + "vanityHouse": false, + "fileCount": 13, + "time": "2016-12-03 21:46:04", + "size": 74275018, + "snatches": 3, + "seeders": 3, + "leechers": 0, + "isFreeleech": false, + "isNeutralLeech": false, + "isPersonalFreeleech": false, + "canUseToken": false, + "hasSnatched": false + }, + { + "torrentId": 230086, + "editionId": 1, + "artists": [ + { + "id": 9504, + "name": "Shania Twain", + "aliasid": 9506 + } + ], + "remastered": false, + "remasterYear": 0, + "remasterCatalogueNumber": "", + "remasterTitle": "", + "media": "CD", + "encoding": "V0 (VBR)", + "format": "MP3", + "hasLog": false, + "logScore": 0, + "hasCue": false, + "scene": false, + "vanityHouse": false, + "fileCount": 13, + "time": "2016-12-03 21:45:41", + "size": 61191629, + "snatches": 7, + "seeders": 5, + "leechers": 0, + "isFreeleech": false, + "isNeutralLeech": false, + "isPersonalFreeleech": false, + "canUseToken": false, + "hasSnatched": false + }, + { + "torrentId": 1541452, + "editionId": 2, + "artists": [ + { + "id": 9504, + "name": "Shania Twain", + "aliasid": 9506 + } + ], + "remastered": true, + "remasterYear": 2017, + "remasterCatalogueNumber": "", + "remasterTitle": "", + "media": "WEB", + "encoding": "24bit Lossless", + "format": "FLAC", + "hasLog": false, + "logScore": 0, + "hasCue": false, + "scene": false, + "vanityHouse": false, + "fileCount": 13, + "time": "2017-12-11 00:17:53", + "size": 653734702, + "snatches": 4, + "seeders": 2, + "leechers": 0, + "isFreeleech": false, + "isNeutralLeech": false, + "isPersonalFreeleech": false, + "canUseToken": false, + "hasSnatched": false + } + ] + } + ] + } +} \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/Files/Indexers/Gazelle/GazelleIndex.json b/src/NzbDrone.Core.Test/Files/Indexers/Gazelle/GazelleIndex.json new file mode 100644 index 000000000..ea3406bde --- /dev/null +++ b/src/NzbDrone.Core.Test/Files/Indexers/Gazelle/GazelleIndex.json @@ -0,0 +1,22 @@ +{ + "status": "success", + "response": { + "username": "dr4g0n", + "id": 469, + "authkey": "redacted", + "passkey": "redacted", + "notifications": { + "messages": 0, + "notifications": 9000, + "newAnnouncement": false, + "newBlog": false + }, + "userstats": { + "uploaded": 585564424629, + "downloaded": 177461229738, + "ratio": 3.29, + "requiredratio": 0.6, + "class": "VIP" + } + } +} \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleFixture.cs new file mode 100644 index 000000000..7e8c11e90 --- /dev/null +++ b/src/NzbDrone.Core.Test/IndexerTests/GazelleTests/GazelleFixture.cs @@ -0,0 +1,66 @@ +using System; +using System.Linq; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common.Http; +using NzbDrone.Core.Indexers; +using NzbDrone.Core.Indexers.Gazelle; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.IndexerTests.GazelleTests +{ + [TestFixture] + public class GazelleFixture : CoreTest + { + [SetUp] + public void Setup() + { + Subject.Definition = new IndexerDefinition() + { + Name = "Gazelle", + Settings = new GazelleSettings + { + Username = "user", + Password = "pass", + BaseUrl = "http://someurl.ch" + } + }; + } + + [Test] + public void should_parse_recent_feed_from_gazelle() + { + var recentFeed = ReadAllText(@"Files/Indexers/Gazelle/Gazelle.json"); + var indexFeed = ReadAllText(@"Files/Indexers/Gazelle/GazelleIndex.json"); + + Mocker.GetMock() + .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.GET && v.Url.FullUri.Contains("ajax.php?action=browse")))) + .Returns(r => new HttpResponse(r, new HttpHeader{ContentType = "application/json" }, recentFeed)); + + Mocker.GetMock() + .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.POST && v.Url.FullUri.Contains("ajax.php?action=index")))) + .Returns(r => new HttpResponse(r, new HttpHeader(), indexFeed)); + + Mocker.GetMock() + .Setup(o => o.Execute(It.Is(v => v.Method == HttpMethod.POST && v.Url.FullUri.Contains("login.php")))) + .Returns(r => new HttpResponse(r, new HttpHeader(), indexFeed)); + + var releases = Subject.FetchRecent(); + + releases.Should().HaveCount(4); + + var releaseInfo = releases.First(); + + releaseInfo.Title.Should().Be("Shania Twain - Shania Twain (1993) [FLAC 24bit Lossless]"); + releaseInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent); + releaseInfo.DownloadUrl.Should() + .Be("http://someurl.ch/torrents.php?action=download&id=1541452&authkey=redacted&torrent_pass=redacted"); + releaseInfo.InfoUrl.Should().Be("http://someurl.ch/torrents.php?id=106951&torrentid=1541452"); + releaseInfo.CommentUrl.Should().Be(null); + releaseInfo.Indexer.Should().Be(Subject.Definition.Name); + releaseInfo.PublishDate.Should().Be(DateTime.Parse("2017-12-11 00:17:53")); + releaseInfo.Size.Should().Be(653734702); + } + } +} diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index ca00b2df7..59daab438 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -184,6 +184,9 @@ + + Always + Always @@ -239,6 +242,7 @@ + @@ -412,6 +416,9 @@ sqlite3.dll Always + + Always + Always diff --git a/src/NzbDrone.Core/Indexers/Gazelle/GazelleParser.cs b/src/NzbDrone.Core/Indexers/Gazelle/GazelleParser.cs index d9b3a243a..74a41232a 100644 --- a/src/NzbDrone.Core/Indexers/Gazelle/GazelleParser.cs +++ b/src/NzbDrone.Core/Indexers/Gazelle/GazelleParser.cs @@ -40,30 +40,32 @@ namespace NzbDrone.Core.Indexers.Gazelle throw new IndexerException(indexerResponse, $"Unexpected response header {indexerResponse.HttpResponse.Headers.ContentType} from API request, expected {HttpAccept.Json.Value}"); } - var jsonResponse = JsonConvert.DeserializeObject(WebUtility.HtmlDecode(indexerResponse.Content)); - if (jsonResponse.Status != "success" || - jsonResponse.Status.IsNullOrWhiteSpace() || - jsonResponse.Response == null) + var jsonResponse = new HttpResponse(indexerResponse.HttpResponse); + if (jsonResponse.Resource.Status != "success" || + jsonResponse.Resource.Status.IsNullOrWhiteSpace() || + jsonResponse.Resource.Response == null) { return torrentInfos; } - foreach (var result in jsonResponse.Response.Results) + foreach (var result in jsonResponse.Resource.Response.Results) { if (result.Torrents != null) { foreach (var torrent in result.Torrents) { var id = torrent.TorrentId; + var artist = WebUtility.HtmlDecode(result.Artist); + var album = WebUtility.HtmlDecode(result.GroupName); torrentInfos.Add(new GazelleInfo() { Guid = string.Format("Gazelle-{0}", id), - Artist = result.Artist, + Artist = artist, // Splice Title from info to avoid calling API again for every torrent. - Title = result.Artist + " - " + result.GroupName + " (" + result.GroupYear +") (" + torrent.Format + " " + torrent.Encoding + ")", - Album = result.GroupName, + Title = WebUtility.HtmlDecode(result.Artist + " - " + result.GroupName + " (" + result.GroupYear +") [" + torrent.Format + " " + torrent.Encoding + "]"), + Album = album, Container = torrent.Encoding, Codec = torrent.Format, Size = long.Parse(torrent.Size), diff --git a/src/NzbDrone.Core/Indexers/Gazelle/GazelleRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Gazelle/GazelleRequestGenerator.cs index c27403193..7a9616ee3 100644 --- a/src/NzbDrone.Core/Indexers/Gazelle/GazelleRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Gazelle/GazelleRequestGenerator.cs @@ -72,7 +72,7 @@ namespace NzbDrone.Core.Indexers.Gazelle }; indexRequestBuilder.SetCookies(cookies); - indexRequestBuilder.Method = HttpMethod.GET; + indexRequestBuilder.Method = HttpMethod.POST; indexRequestBuilder.Resource("ajax.php?action=index"); var authIndexRequest = indexRequestBuilder