mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-12 11:15:43 +02:00
Fixed: Include matching value of preferred word regex, not the actual regex
This commit is contained in:
parent
1222aeaab6
commit
78b3c9552b
@ -30,7 +30,7 @@ public void Setup()
|
||||
}
|
||||
};
|
||||
|
||||
Mocker.SetConstant<ITermMatcher>(Mocker.Resolve<TermMatcher>());
|
||||
Mocker.SetConstant<ITermMatcherService>(Mocker.Resolve<TermMatcherService>());
|
||||
}
|
||||
|
||||
private void GivenRestictions(string required, string ignored)
|
||||
|
@ -43,7 +43,7 @@ public void Setup()
|
||||
|
||||
private void GivenMatchingTerms(params string[] terms)
|
||||
{
|
||||
Mocker.GetMock<ITermMatcher>()
|
||||
Mocker.GetMock<ITermMatcherService>()
|
||||
.Setup(s => s.IsMatch(It.IsAny<string>(), _title))
|
||||
.Returns<string, string>((term, title) => terms.Contains(term));
|
||||
}
|
||||
|
@ -13,13 +13,13 @@ public class ReleaseRestrictionsSpecification : IDecisionEngineSpecification
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
private readonly IReleaseProfileService _releaseProfileService;
|
||||
private readonly ITermMatcher _termMatcher;
|
||||
private readonly ITermMatcherService _termMatcherService;
|
||||
|
||||
public ReleaseRestrictionsSpecification(ITermMatcher termMatcher, IReleaseProfileService releaseProfileService, Logger logger)
|
||||
public ReleaseRestrictionsSpecification(ITermMatcherService termMatcherService, IReleaseProfileService releaseProfileService, Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_releaseProfileService = releaseProfileService;
|
||||
_termMatcher = termMatcher;
|
||||
_termMatcherService = termMatcherService;
|
||||
}
|
||||
|
||||
public SpecificationPriority Priority => SpecificationPriority.Default;
|
||||
@ -67,7 +67,7 @@ public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase
|
||||
|
||||
private List<string> ContainsAny(List<string> terms, string title)
|
||||
{
|
||||
return terms.Where(t => _termMatcher.IsMatch(t, title)).ToList();
|
||||
return terms.Where(t => _termMatcherService.IsMatch(t, title)).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1012,6 +1012,9 @@
|
||||
<Compile Include="Profiles\Qualities\QualityProfileService.cs" />
|
||||
<Compile Include="Profiles\Qualities\QualityIndex.cs" />
|
||||
<Compile Include="Profiles\Releases\PreferredWordService.cs" />
|
||||
<Compile Include="Profiles\Releases\TermMatchers\CaseInsensitiveTermMatcher.cs" />
|
||||
<Compile Include="Profiles\Releases\TermMatchers\ITermMatcher.cs" />
|
||||
<Compile Include="Profiles\Releases\TermMatchers\RegexTermMatcher.cs" />
|
||||
<Compile Include="ProgressMessaging\ProgressMessageContext.cs" />
|
||||
<Compile Include="Qualities\QualityDetectionSource.cs" />
|
||||
<Compile Include="Qualities\QualityFinder.cs" />
|
||||
@ -1145,7 +1148,7 @@
|
||||
<Compile Include="Profiles\Releases\ReleaseProfile.cs" />
|
||||
<Compile Include="Profiles\Releases\ReleaseProfileRepository.cs" />
|
||||
<Compile Include="Profiles\Releases\ReleaseProfileService.cs" />
|
||||
<Compile Include="Profiles\Releases\TermMatcher.cs" />
|
||||
<Compile Include="Profiles\Releases\TermMatcherService.cs" />
|
||||
<Compile Include="Rest\JsonNetSerializer.cs" />
|
||||
<Compile Include="Rest\RestClientFactory.cs" />
|
||||
<Compile Include="Rest\RestException.cs" />
|
||||
|
@ -617,7 +617,7 @@ private void AddPreferredWords(Dictionary<string, Func<TokenMatch, string>> toke
|
||||
{
|
||||
if (preferredWords == null)
|
||||
{
|
||||
preferredWords = _preferredWordService.GetMatchingPreferredWords(series, episodeFile.GetSceneOrFileName(), true);
|
||||
preferredWords = _preferredWordService.GetMatchingPreferredWords(series, episodeFile.GetSceneOrFileName());
|
||||
}
|
||||
|
||||
tokenHandlers["{Preferred Words}"] = m => string.Join(" ", preferredWords);
|
||||
|
@ -2,25 +2,26 @@
|
||||
using NzbDrone.Core.Tv;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
||||
namespace NzbDrone.Core.Profiles.Releases
|
||||
{
|
||||
public interface IPreferredWordService
|
||||
{
|
||||
int Calculate(Series series, string title);
|
||||
List<string> GetMatchingPreferredWords(Series series, string title, bool isRenaming);
|
||||
List<string> GetMatchingPreferredWords(Series series, string title);
|
||||
}
|
||||
|
||||
public class PreferredWordService : IPreferredWordService
|
||||
{
|
||||
private readonly IReleaseProfileService _releaseProfileService;
|
||||
private readonly ITermMatcher _termMatcher;
|
||||
private readonly ITermMatcherService _termMatcherService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public PreferredWordService(IReleaseProfileService releaseProfileService, ITermMatcher termMatcher, Logger logger)
|
||||
public PreferredWordService(IReleaseProfileService releaseProfileService, ITermMatcherService termMatcherService, Logger logger)
|
||||
{
|
||||
_releaseProfileService = releaseProfileService;
|
||||
_termMatcher = termMatcher;
|
||||
_termMatcherService = termMatcherService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@ -28,7 +29,22 @@ public int Calculate(Series series, string title)
|
||||
{
|
||||
_logger.Trace("Calculating preferred word score for '{0}'", title);
|
||||
|
||||
var matchingPairs = GetMatchingPairs(series, title, false);
|
||||
var releaseProfiles = _releaseProfileService.AllForTags(series.Tags);
|
||||
var matchingPairs = new List<KeyValuePair<string, int>>();
|
||||
|
||||
foreach (var releaseProfile in releaseProfiles)
|
||||
{
|
||||
foreach (var preferredPair in releaseProfile.Preferred)
|
||||
{
|
||||
var term = preferredPair.Key;
|
||||
|
||||
if (_termMatcherService.IsMatch(term, title))
|
||||
{
|
||||
matchingPairs.Add(preferredPair);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var score = matchingPairs.Sum(p => p.Value);
|
||||
|
||||
_logger.Trace("Calculated preferred word score for '{0}': {1}", title, score);
|
||||
@ -36,25 +52,16 @@ public int Calculate(Series series, string title)
|
||||
return score;
|
||||
}
|
||||
|
||||
public List<string> GetMatchingPreferredWords(Series series, string title, bool isRenaming)
|
||||
{
|
||||
var matchingPairs = GetMatchingPairs(series, title, isRenaming);
|
||||
|
||||
return matchingPairs.OrderByDescending(p => p.Value)
|
||||
.Select(p => p.Key)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private List<KeyValuePair<string, int>> GetMatchingPairs(Series series, string title, bool isRenaming)
|
||||
public List<string> GetMatchingPreferredWords(Series series, string title)
|
||||
{
|
||||
var releaseProfiles = _releaseProfileService.AllForTags(series.Tags);
|
||||
var result = new List<KeyValuePair<string, int>>();
|
||||
var matchingPairs = new List<KeyValuePair<string, int>>();
|
||||
|
||||
_logger.Trace("Calculating preferred word score for '{0}'", title);
|
||||
|
||||
foreach (var releaseProfile in releaseProfiles)
|
||||
{
|
||||
if (isRenaming && !releaseProfile.IncludePreferredWhenRenaming)
|
||||
if (!releaseProfile.IncludePreferredWhenRenaming)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -62,15 +69,18 @@ private List<KeyValuePair<string, int>> GetMatchingPairs(Series series, string t
|
||||
foreach (var preferredPair in releaseProfile.Preferred)
|
||||
{
|
||||
var term = preferredPair.Key;
|
||||
var matchingTerm = _termMatcherService.MatchingTerm(term, title);
|
||||
|
||||
if (_termMatcher.IsMatch(term, title))
|
||||
if (matchingTerm.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
result.Add(preferredPair);
|
||||
matchingPairs.Add(new KeyValuePair<string, int>(matchingTerm, preferredPair.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return matchingPairs.OrderByDescending(p => p.Value)
|
||||
.Select(p => p.Key)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.Cache;
|
||||
|
||||
namespace NzbDrone.Core.Profiles.Releases
|
||||
{
|
||||
public interface ITermMatcher
|
||||
{
|
||||
bool IsMatch(string term, string value);
|
||||
}
|
||||
|
||||
public class TermMatcher : ITermMatcher
|
||||
{
|
||||
private ICached<Predicate<string>> _matcherCache;
|
||||
|
||||
public TermMatcher(ICacheManager cacheManager)
|
||||
{
|
||||
_matcherCache = cacheManager.GetCache<Predicate<string>>(GetType());
|
||||
}
|
||||
|
||||
public bool IsMatch(string term, string value)
|
||||
{
|
||||
return GetMatcher(term)(value);
|
||||
}
|
||||
|
||||
public Predicate<string> GetMatcher(string term)
|
||||
{
|
||||
return _matcherCache.Get(term, () => CreateMatcherInternal(term), TimeSpan.FromHours(24));
|
||||
}
|
||||
|
||||
private Predicate<string> CreateMatcherInternal(string term)
|
||||
{
|
||||
Regex regex;
|
||||
if (PerlRegexFactory.TryCreateRegex(term, out regex))
|
||||
{
|
||||
return regex.IsMatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CaseInsensitiveTermMatcher(term).IsMatch;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class CaseInsensitiveTermMatcher
|
||||
{
|
||||
private readonly string _term;
|
||||
|
||||
public CaseInsensitiveTermMatcher(string term)
|
||||
{
|
||||
_term = term.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public bool IsMatch(string value)
|
||||
{
|
||||
return value.ToLowerInvariant().Contains(_term);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
52
src/NzbDrone.Core/Profiles/Releases/TermMatcherService.cs
Normal file
52
src/NzbDrone.Core/Profiles/Releases/TermMatcherService.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Core.Profiles.Releases.TermMatchers;
|
||||
|
||||
namespace NzbDrone.Core.Profiles.Releases
|
||||
{
|
||||
public interface ITermMatcherService
|
||||
{
|
||||
bool IsMatch(string term, string value);
|
||||
string MatchingTerm(string term, string value);
|
||||
}
|
||||
|
||||
public class TermMatcherService : ITermMatcherService
|
||||
{
|
||||
private ICached<ITermMatcher> _matcherCache;
|
||||
|
||||
public TermMatcherService(ICacheManager cacheManager)
|
||||
{
|
||||
_matcherCache = cacheManager.GetCache<ITermMatcher>(GetType());
|
||||
}
|
||||
|
||||
public bool IsMatch(string term, string value)
|
||||
{
|
||||
return GetMatcher(term).IsMatch(value);
|
||||
}
|
||||
|
||||
public string MatchingTerm(string term, string value)
|
||||
{
|
||||
return GetMatcher(term).MatchingTerm(value);
|
||||
}
|
||||
|
||||
public ITermMatcher GetMatcher(string term)
|
||||
{
|
||||
return _matcherCache.Get(term, () => CreateMatcherInternal(term), TimeSpan.FromHours(24));
|
||||
}
|
||||
|
||||
private ITermMatcher CreateMatcherInternal(string term)
|
||||
{
|
||||
Regex regex;
|
||||
if (PerlRegexFactory.TryCreateRegex(term, out regex))
|
||||
{
|
||||
return new RegexTermMatcher(regex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CaseInsensitiveTermMatcher(term);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
namespace NzbDrone.Core.Profiles.Releases.TermMatchers
|
||||
{
|
||||
public sealed class CaseInsensitiveTermMatcher : ITermMatcher
|
||||
{
|
||||
private readonly string _term;
|
||||
|
||||
public CaseInsensitiveTermMatcher(string term)
|
||||
{
|
||||
_term = term.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public bool IsMatch(string value)
|
||||
{
|
||||
return value.ToLowerInvariant().Contains(_term);
|
||||
}
|
||||
|
||||
public string MatchingTerm(string value)
|
||||
{
|
||||
return _term;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace NzbDrone.Core.Profiles.Releases.TermMatchers
|
||||
{
|
||||
public interface ITermMatcher
|
||||
{
|
||||
bool IsMatch(string value);
|
||||
string MatchingTerm(string value);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NzbDrone.Core.Profiles.Releases.TermMatchers
|
||||
{
|
||||
public class RegexTermMatcher : ITermMatcher
|
||||
{
|
||||
private readonly Regex _regex;
|
||||
|
||||
public RegexTermMatcher(Regex regex)
|
||||
{
|
||||
_regex = regex;
|
||||
}
|
||||
|
||||
public bool IsMatch(string value)
|
||||
{
|
||||
return _regex.IsMatch(value);
|
||||
}
|
||||
|
||||
public string MatchingTerm(string value)
|
||||
{
|
||||
return _regex.Match(value).Value;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user