From 3aeac5b53032cbcafb57967947e7868e8791390a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 13 Dec 2023 16:33:29 +0200 Subject: [PATCH] Fixed: (Redacted) Improve title and filter by categories --- .../RedactedTests/RedactedFixture.cs | 4 +- .../Indexers/Redacted/RedactedParser.cs | 56 ++++++++++++++----- .../Redacted/RedactedRequestGenerator.cs | 24 +++++--- .../Indexers/Redacted/RedactedSettings.cs | 35 ++++++++++-- 4 files changed, 91 insertions(+), 28 deletions(-) diff --git a/src/NzbDrone.Core.Test/IndexerTests/RedactedTests/RedactedFixture.cs b/src/NzbDrone.Core.Test/IndexerTests/RedactedTests/RedactedFixture.cs index 06b4622834..f08bc8b1be 100644 --- a/src/NzbDrone.Core.Test/IndexerTests/RedactedTests/RedactedFixture.cs +++ b/src/NzbDrone.Core.Test/IndexerTests/RedactedTests/RedactedFixture.cs @@ -45,9 +45,9 @@ public async Task should_parse_recent_feed_from_redacted() var releaseInfo = releases.First(); - releaseInfo.Title.Should().Be("Shania Twain - Shania Twain (1993) [FLAC 24bit Lossless] [WEB]"); + releaseInfo.Title.Should().Be("Shania Twain - Shania Twain (1993) [Album] [FLAC 24bit Lossless / WEB]"); releaseInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent); - releaseInfo.DownloadUrl.Should().Be("https://redacted.ch/ajax.php?action=download&id=1541452&usetoken=0"); + releaseInfo.DownloadUrl.Should().Be("https://redacted.ch/ajax.php?action=download&id=1541452"); releaseInfo.InfoUrl.Should().Be("https://redacted.ch/torrents.php?id=106951&torrentid=1541452"); releaseInfo.CommentUrl.Should().Be(null); releaseInfo.Indexer.Should().Be(Subject.Definition.Name); diff --git a/src/NzbDrone.Core/Indexers/Redacted/RedactedParser.cs b/src/NzbDrone.Core/Indexers/Redacted/RedactedParser.cs index a6a174a796..bb536e07c6 100644 --- a/src/NzbDrone.Core/Indexers/Redacted/RedactedParser.cs +++ b/src/NzbDrone.Core/Indexers/Redacted/RedactedParser.cs @@ -47,28 +47,21 @@ public IList ParseResponse(IndexerResponse indexerResponse) foreach (var torrent in result.Torrents) { var id = torrent.TorrentId; + var title = WebUtility.HtmlDecode(GetTitle(result, torrent)); var artist = WebUtility.HtmlDecode(result.Artist); var album = WebUtility.HtmlDecode(result.GroupName); - var title = $"{result.Artist} - {result.GroupName} ({result.GroupYear}) [{torrent.Format} {torrent.Encoding}] [{torrent.Media}]"; - if (torrent.HasCue) - { - title += " [Cue]"; - } - torrentInfos.Add(new GazelleInfo { Guid = $"Redacted-{id}", + InfoUrl = GetInfoUrl(result.GroupId, id), + DownloadUrl = GetDownloadUrl(id, torrent.CanUseToken), + Title = title, Artist = artist, - - // Splice Title from info to avoid calling API again for every torrent. - Title = WebUtility.HtmlDecode(title), Album = album, Container = torrent.Encoding, Codec = torrent.Format, Size = long.Parse(torrent.Size), - DownloadUrl = GetDownloadUrl(id, torrent.CanUseToken), - InfoUrl = GetInfoUrl(result.GroupId, id), Seeders = int.Parse(torrent.Seeders), Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders), PublishDate = torrent.Time.ToUniversalTime(), @@ -85,13 +78,50 @@ public IList ParseResponse(IndexerResponse indexerResponse) .ToArray(); } + private string GetTitle(GazelleRelease result, GazelleTorrent torrent) + { + var title = $"{result.Artist} - {result.GroupName} ({result.GroupYear})"; + + if (result.ReleaseType.IsNotNullOrWhiteSpace() && result.ReleaseType != "Unknown") + { + title += " [" + result.ReleaseType + "]"; + } + + if (torrent.RemasterTitle.IsNotNullOrWhiteSpace()) + { + title += $" [{$"{torrent.RemasterTitle} {torrent.RemasterYear}".Trim()}]"; + } + + var flags = new List + { + $"{torrent.Format} {torrent.Encoding}", + $"{torrent.Media}" + }; + + if (torrent.HasLog) + { + flags.Add("Log (" + torrent.LogScore + "%)"); + } + + if (torrent.HasCue) + { + flags.Add("Cue"); + } + + return $"{title} [{string.Join(" / ", flags)}]"; + } + private string GetDownloadUrl(int torrentId, bool canUseToken) { var url = new HttpUri(_settings.BaseUrl) .CombinePath("/ajax.php") .AddQueryParam("action", "download") - .AddQueryParam("id", torrentId) - .AddQueryParam("usetoken", _settings.UseFreeleechToken && canUseToken ? 1 : 0); + .AddQueryParam("id", torrentId); + + if (_settings.UseFreeleechToken && canUseToken) + { + url = url.AddQueryParam("usetoken", "1"); + } return url.FullUri; } diff --git a/src/NzbDrone.Core/Indexers/Redacted/RedactedRequestGenerator.cs b/src/NzbDrone.Core/Indexers/Redacted/RedactedRequestGenerator.cs index 84d34c9538..754a1ef3c3 100644 --- a/src/NzbDrone.Core/Indexers/Redacted/RedactedRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/Redacted/RedactedRequestGenerator.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using NzbDrone.Common.Http; using NzbDrone.Core.IndexerSearch.Definitions; @@ -28,11 +29,11 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC if (searchCriteria.CleanArtistQuery == "VA") { - pageableRequests.Add(GetRequest($"&groupname={searchCriteria.CleanAlbumQuery}")); + pageableRequests.Add(GetRequest($"groupname={searchCriteria.CleanAlbumQuery}")); } else { - pageableRequests.Add(GetRequest($"&artistname={searchCriteria.CleanArtistQuery}&groupname={searchCriteria.CleanAlbumQuery}")); + pageableRequests.Add(GetRequest($"artistname={searchCriteria.CleanArtistQuery}&groupname={searchCriteria.CleanAlbumQuery}")); } return pageableRequests; @@ -41,17 +42,26 @@ public IndexerPageableRequestChain GetSearchRequests(AlbumSearchCriteria searchC public IndexerPageableRequestChain GetSearchRequests(ArtistSearchCriteria searchCriteria) { var pageableRequests = new IndexerPageableRequestChain(); - pageableRequests.Add(GetRequest($"&artistname={searchCriteria.CleanArtistQuery}")); + pageableRequests.Add(GetRequest($"artistname={searchCriteria.CleanArtistQuery}")); return pageableRequests; } private IEnumerable GetRequest(string searchParameters) { - var req = RequestBuilder() - .Resource($"ajax.php?action=browse&searchstr={searchParameters}") - .Build(); + var requestBuilder = RequestBuilder() + .Resource($"ajax.php?{searchParameters}") + .AddQueryParam("action", "browse") + .AddQueryParam("order_by", "time") + .AddQueryParam("order_way", "desc"); - yield return new IndexerRequest(req); + var categories = _settings.Categories.ToList(); + + if (categories.Any()) + { + categories.ForEach(cat => requestBuilder.AddQueryParam($"filter_cat[{cat}]", "1")); + } + + yield return new IndexerRequest(requestBuilder.Build()); } private HttpRequestBuilder RequestBuilder() diff --git a/src/NzbDrone.Core/Indexers/Redacted/RedactedSettings.cs b/src/NzbDrone.Core/Indexers/Redacted/RedactedSettings.cs index 7c511cbb3e..772f92b60c 100644 --- a/src/NzbDrone.Core/Indexers/Redacted/RedactedSettings.cs +++ b/src/NzbDrone.Core/Indexers/Redacted/RedactedSettings.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Validation; @@ -19,6 +20,7 @@ public class RedactedSettings : ITorrentIndexerSettings public RedactedSettings() { BaseUrl = "https://redacted.ch"; + Categories = new[] { (int)RedactedCategory.Music }; MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS; } @@ -27,21 +29,42 @@ public RedactedSettings() [FieldDefinition(1, Label = "ApiKey", HelpText = "Generate this in 'Access Settings' in your Redacted profile", Privacy = PrivacyLevel.ApiKey)] public string ApiKey { get; set; } - [FieldDefinition(2, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)] + [FieldDefinition(2, Label = "Categories", Type = FieldType.Select, SelectOptions = typeof(RedactedCategory), HelpText = "If unspecified, all options are used.")] + public IEnumerable Categories { get; set; } + + [FieldDefinition(3, Type = FieldType.Checkbox, Label = "Use Freeleech Token", HelpText = "Will cause grabbing to fail if you do not have any tokens available", Advanced = true)] + public bool UseFreeleechToken { get; set; } + + [FieldDefinition(4, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)] public int MinimumSeeders { get; set; } - [FieldDefinition(3)] + [FieldDefinition(5)] public SeedCriteriaSettings SeedCriteria { get; set; } = new (); - [FieldDefinition(4, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)] + [FieldDefinition(6, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)] public int? EarlyReleaseLimit { get; set; } - [FieldDefinition(5, Type = FieldType.Checkbox, Label = "Use Freeleech Token", HelpText = "Will cause grabbing to fail if you do not have any tokens available", Advanced = true)] - public bool UseFreeleechToken { get; set; } - public NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } } + + public enum RedactedCategory + { + [FieldOption(label: "Music")] + Music = 1, + [FieldOption(label: "Applications")] + Applications = 2, + [FieldOption(label: "E-Books")] + EBooks = 3, + [FieldOption(label: "Audiobooks")] + Audiobooks = 4, + [FieldOption(label: "E-Learning Videos")] + ELearningVideos = 5, + [FieldOption(label: "Comedy")] + Comedy = 6, + [FieldOption(label: "Comics")] + Comics = 7 + } }