From ef6dcc86c1b3a96b71e0064f063a05481ade2709 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 11 Jun 2019 20:39:30 -0500 Subject: [PATCH] basic origin: implementation --- .../ReleaseRestrictionsSpecification.cs | 72 +++++++++++-------- src/NzbDrone.Core/NzbDrone.Core.csproj | 2 + .../Releases/ReleaseFilters/IReleaseFilter.cs | 13 ++++ .../ReleaseFilters/OriginReleaseFilter.cs | 15 ++++ .../Releases/ReleaseProfileService.cs | 2 +- 5 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 src/NzbDrone.Core/Profiles/Releases/ReleaseFilters/IReleaseFilter.cs create mode 100644 src/NzbDrone.Core/Profiles/Releases/ReleaseFilters/OriginReleaseFilter.cs diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/ReleaseRestrictionsSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/ReleaseRestrictionsSpecification.cs index 8c0125410..4cb6a5d9d 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/ReleaseRestrictionsSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/ReleaseRestrictionsSpecification.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -16,6 +17,8 @@ namespace NzbDrone.Core.DecisionEngine.Specifications private readonly IReleaseProfileService _releaseProfileService; private readonly ITermMatcherService _termMatcherService; + private static readonly Regex keyValueRegex = new Regex(@"^([^:]+):([^:]+)$"); + public ReleaseRestrictionsSpecification(ITermMatcherService termMatcherService, IReleaseProfileService releaseProfileService, Logger logger) { _logger = logger; @@ -36,8 +39,6 @@ namespace NzbDrone.Core.DecisionEngine.Specifications var required = releaseProfiles.Where(r => r.Required.IsNotNullOrWhiteSpace()); var ignored = releaseProfiles.Where(r => r.Ignored.IsNotNullOrWhiteSpace()); - var keyValueRegex = new Regex(@"\b\w+:\w+\b"); - foreach (var r in required) { var requiredTerms = r.Required.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); @@ -50,33 +51,8 @@ namespace NzbDrone.Core.DecisionEngine.Specifications var foundTerms = ContainsAny(reqTitleTerms, title); // check key-value terms - foreach (var kv in reqKeyValues) - { - var key = kv.Split(':')[0]; - var value = kv.Split(':')[1]; + foundTerms.AddRange(ContainsAnyKeyValues(reqKeyValues, subject)); - switch (key) - { - case "origin": - var origin = subject.Release.Origin; - if (origin.IsNotNullOrWhiteSpace()) - { - if (string.Equals(origin, value, StringComparison.InvariantCultureIgnoreCase)) - { - foundTerms.Add(kv); - } - } - else - { - _logger.Debug("{0} not found in release", key); - } - break; - default: - _logger.Debug("{0} is not a supported key", key); - break; - } - - } if (foundTerms.Empty()) { @@ -91,7 +67,16 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { var ignoredTerms = r.Ignored.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); - var foundTerms = ContainsAny(ignoredTerms, title); + // separate key-value terms and normal terms + var ignKeyValues = ignoredTerms.Where(kv => keyValueRegex.IsMatch(kv)).ToList(); + var ignTitleTerms = ignoredTerms.Where(t => !keyValueRegex.IsMatch(t)).ToList(); + + // check title terms + var foundTerms = ContainsAny(ignTitleTerms, title); + + // check key-value terms + foundTerms.AddRange(ContainsAnyKeyValues(ignKeyValues, subject)); + if (foundTerms.Any()) { var terms = string.Join(", ", foundTerms); @@ -107,5 +92,34 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { return terms.Where(t => _termMatcherService.IsMatch(t, title)).ToList(); } + + private List ContainsAnyKeyValues(List terms, RemoteEpisode subject) + { + var foundTerms = new List(); + + foreach (var kv in terms) + { + var match = keyValueRegex.Match(kv); + var key = match.Groups[1].Value; + var value = match.Groups[2].Value; + + try + { + IReleaseFilter releaseFilter = Assembly.GetExecutingAssembly(). + CreateInstance("NzbDrone.Core.Profiles.Releases." + key + "ReleaseFilter", true) as IReleaseFilter; + + if (releaseFilter.Matches(value, subject)) + { + foundTerms.Add(kv); + } + } + catch (NullReferenceException) + { + _logger.Debug("Unsupported key {0}", key); + } + } + + return foundTerms; + } } } diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 99c61804f..867855908 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -1170,6 +1170,8 @@ + + diff --git a/src/NzbDrone.Core/Profiles/Releases/ReleaseFilters/IReleaseFilter.cs b/src/NzbDrone.Core/Profiles/Releases/ReleaseFilters/IReleaseFilter.cs new file mode 100644 index 000000000..1d7320f90 --- /dev/null +++ b/src/NzbDrone.Core/Profiles/Releases/ReleaseFilters/IReleaseFilter.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System; +using NzbDrone.Core.Parser.Model; + +namespace NzbDrone.Core.Profiles.Releases +{ + public interface IReleaseFilter + { + string Key { get; } + bool Matches(string filterValue, RemoteEpisode subject); + //List SuggestAutoComplete(string filterValue, int indexerId); + } +} diff --git a/src/NzbDrone.Core/Profiles/Releases/ReleaseFilters/OriginReleaseFilter.cs b/src/NzbDrone.Core/Profiles/Releases/ReleaseFilters/OriginReleaseFilter.cs new file mode 100644 index 000000000..b79849b8c --- /dev/null +++ b/src/NzbDrone.Core/Profiles/Releases/ReleaseFilters/OriginReleaseFilter.cs @@ -0,0 +1,15 @@ +using System; +using NzbDrone.Core.Parser.Model; + +namespace NzbDrone.Core.Profiles.Releases +{ + public class OriginReleaseFilter : IReleaseFilter + { + public string Key => "Origin"; + + public bool Matches(string filterValue, RemoteEpisode subject) + { + return filterValue.Equals(subject.Release.Origin, StringComparison.InvariantCultureIgnoreCase); + } + } +} diff --git a/src/NzbDrone.Core/Profiles/Releases/ReleaseProfileService.cs b/src/NzbDrone.Core/Profiles/Releases/ReleaseProfileService.cs index f7bab3ae0..d7a2069b2 100644 --- a/src/NzbDrone.Core/Profiles/Releases/ReleaseProfileService.cs +++ b/src/NzbDrone.Core/Profiles/Releases/ReleaseProfileService.cs @@ -47,7 +47,7 @@ namespace NzbDrone.Core.Profiles.Releases { return (List)AllForTags(tagIds) .Where(r => r.Enabled) - .Where(r => r.IndexerId == indexerId || r.IndexerId == 0); + .Where(r => r.IndexerId == indexerId || r.IndexerId == 0).ToList(); } public ReleaseProfile Get(int id)