diff --git a/src/NzbDrone.Core.Test/Files/Indexers/Newznab/newznab_indexerflags.xml b/src/NzbDrone.Core.Test/Files/Indexers/Newznab/newznab_indexerflags.xml new file mode 100644 index 000000000..0d70b3707 --- /dev/null +++ b/src/NzbDrone.Core.Test/Files/Indexers/Newznab/newznab_indexerflags.xml @@ -0,0 +1,128 @@ + + + somenewznabindexer.com + somenewznabindexer.com Feed + https://somenewznabindexer.com/ + en-gb + contact@somenewznabindexer.com + + + + title + no custom attributes + link + comments + Sat, 31 Aug 2024 12:28:40 +0300 + category + description + + + + + title + prematch=1 attribute + link + comments + Sat, 31 Aug 2024 12:28:40 +0300 + category + description + + + + + + + title + haspretime=1 attribute + link + comments + Sat, 31 Aug 2024 12:28:40 +0300 + category + description + + + + + + + title + prematch=0 attribute + link + comments + Sat, 31 Aug 2024 12:28:40 +0300 + category + description + + + + + + + title + haspretime=0 attribute + link + comments + Sat, 31 Aug 2024 12:28:40 +0300 + category + description + + + + + + + title + nuked=1 attribute + link + comments + Sat, 31 Aug 2024 12:28:40 +0300 + category + description + + + + + + + title + nuked=0 attribute + link + comments + Sat, 31 Aug 2024 12:28:40 +0300 + category + description + + + + + + + title + prematch=1 and nuked=1 attributes + link + comments + Sat, 31 Aug 2024 12:28:40 +0300 + category + description + + + + + + + + title + haspretime=0 and nuked=0 attributes + link + comments + Sat, 31 Aug 2024 12:28:40 +0300 + category + description + + + + + + + + \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.cs index 564638f59..1fdf91757 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/NewznabTests/NewznabFixture.cs @@ -9,6 +9,7 @@ using NzbDrone.Common.Http; using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers.Newznab; using NzbDrone.Core.Languages; +using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.IndexerTests.NewznabTests @@ -98,5 +99,29 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests releases[1].Languages.Should().BeEquivalentTo(new[] { Language.English, Language.Spanish }); releases[2].Languages.Should().BeEquivalentTo(new[] { Language.French }); } + + [TestCase("no custom attributes")] + [TestCase("prematch=1 attribute", IndexerFlags.G_Scene)] + [TestCase("haspretime=1 attribute", IndexerFlags.G_Scene)] + [TestCase("prematch=0 attribute")] + [TestCase("haspretime=0 attribute")] + [TestCase("nuked=1 attribute", IndexerFlags.Nuked)] + [TestCase("nuked=0 attribute")] + [TestCase("prematch=1 and nuked=1 attributes", IndexerFlags.G_Scene, IndexerFlags.Nuked)] + [TestCase("haspretime=0 and nuked=0 attributes")] + public async Task should_parse_indexer_flags(string releaseGuid, params IndexerFlags[] indexerFlags) + { + var feed = ReadAllText(@"Files/Indexers/Newznab/newznab_indexerflags.xml"); + + Mocker.GetMock() + .Setup(o => o.ExecuteAsync(It.Is(v => v.Method == HttpMethod.Get))) + .Returns(r => Task.FromResult(new HttpResponse(r, new HttpHeader(), feed))); + + var releases = await Subject.FetchRecent(); + + var release = releases.Should().ContainSingle(r => r.Guid == releaseGuid).Subject; + + indexerFlags.ToList().ForEach(f => release.IndexerFlags.Should().HaveFlag(f)); + } } } diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs index 56806f3f8..76f138e4d 100644 --- a/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs +++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs @@ -92,6 +92,7 @@ namespace NzbDrone.Core.Indexers.Newznab { releaseInfo = base.ProcessItem(item, releaseInfo); releaseInfo.ImdbId = GetImdbId(item); + releaseInfo.IndexerFlags = GetFlags(item); return releaseInfo; } @@ -209,6 +210,23 @@ namespace NzbDrone.Core.Indexers.Newznab return 1900; } + protected IndexerFlags GetFlags(XElement item) + { + IndexerFlags flags = 0; + + if (TryGetNewznabAttribute(item, "prematch") == "1" || TryGetNewznabAttribute(item, "haspretime") == "1") + { + flags |= IndexerFlags.G_Scene; + } + + if (TryGetNewznabAttribute(item, "nuked") == "1") + { + flags |= IndexerFlags.Nuked; + } + + return flags; + } + protected string TryGetNewznabAttribute(XElement item, string key, string defaultValue = "") { var attrElement = item.Elements(ns + "attr").FirstOrDefault(e => e.Attribute("name").Value.Equals(key, StringComparison.OrdinalIgnoreCase)); diff --git a/src/NzbDrone.Core/Parser/Model/IndexerFlags.cs b/src/NzbDrone.Core/Parser/Model/IndexerFlags.cs new file mode 100644 index 000000000..2cf018d67 --- /dev/null +++ b/src/NzbDrone.Core/Parser/Model/IndexerFlags.cs @@ -0,0 +1,66 @@ +using System; + +namespace NzbDrone.Core.Parser.Model +{ + [Flags] + public enum IndexerFlags + { + /// + /// Torrent download amount does not count + /// + G_Freeleech = 1, + + /// + /// Torrent download amount only counts 50% + /// + G_Halfleech = 2, + + /// + /// Torrent upload amount is doubled + /// + G_DoubleUpload = 4, + + /// + /// Torrent is a very high quality encode, as applied manually by the PTP staff + /// + PTP_Golden = 8, + + /// + /// Torrent from PTP that has been checked (by staff or torrent checkers) for release description requirements + /// + PTP_Approved = 16, + + /// + /// Uploader is an internal release group + /// + G_Internal = 32, + + // AHD, internal + [Obsolete] + AHD_Internal = 64, + + /// + /// The release comes from a scene group + /// + G_Scene = 128, + + /// + /// Torrent download amount only counts 75% + /// + G_Freeleech75 = 256, + + /// + /// Torrent download amount only counts 25% + /// + G_Freeleech25 = 512, + + // AHD, internal + [Obsolete] + AHD_UserRelease = 1024, + + /// + /// The release is nuked + /// + Nuked = 2048 + } +} diff --git a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs index d21188c85..9aeb138f2 100644 --- a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs @@ -99,22 +99,4 @@ namespace NzbDrone.Core.Parser.Model } } } - - [Flags] - public enum IndexerFlags - { - G_Freeleech = 1, // General - G_Halfleech = 2, // General, only 1/2 of download counted - G_DoubleUpload = 4, // General - PTP_Golden = 8, // PTP - PTP_Approved = 16, // PTP - G_Internal = 32, // General, uploader is an internal release group - [Obsolete] - AHD_Internal = 64, // AHD, internal - G_Scene = 128, // General, the torrent comes from a "scene" group - G_Freeleech75 = 256, // Signifies a torrent counts towards 75 percent of your download quota. - G_Freeleech25 = 512, // Signifies a torrent counts towards 25 percent of your download quota. - [Obsolete] - AHD_UserRelease = 1024 // AHD, internal - } }