diff --git a/src/NzbDrone.Core.Test/MetadataSourceTests/TraktSearchSeriesComparerFixture.cs b/src/NzbDrone.Core.Test/MetadataSourceTests/TraktSearchSeriesComparerFixture.cs new file mode 100644 index 000000000..383edc93e --- /dev/null +++ b/src/NzbDrone.Core.Test/MetadataSourceTests/TraktSearchSeriesComparerFixture.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.MetadataSource; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.Test.MetadataSourceTests +{ + [TestFixture] + public class TraktSearchSeriesComparerFixture : CoreTest + { + private List _series; + + [SetUp] + public void Setup() + { + _series = new List(); + } + + private void WithSeries(string title) + { + _series.Add(new Series { Title = title }); + } + + [Test] + public void should_prefer_the_walking_dead_over_talking_dead_when_searching_for_the_walking_dead() + { + WithSeries("Talking Dead"); + WithSeries("The Walking Dead"); + + _series.Sort(new TraktSearchSeriesComparer("the walking dead")); + + _series.First().Title.Should().Be("The Walking Dead"); + } + + [Test] + public void should_prefer_the_walking_dead_over_talking_dead_when_searching_for_walking_dead() + { + WithSeries("Talking Dead"); + WithSeries("The Walking Dead"); + + _series.Sort(new TraktSearchSeriesComparer("walking dead")); + + _series.First().Title.Should().Be("The Walking Dead"); + } + + [Test] + public void should_prefer_blacklist_over_the_blacklist_when_searching_for_blacklist() + { + WithSeries("The Blacklist"); + WithSeries("Blacklist"); + + _series.Sort(new TraktSearchSeriesComparer("blacklist")); + + _series.First().Title.Should().Be("Blacklist"); + } + + [Test] + public void should_prefer_the_blacklist_over_blacklist_when_searching_for_the_blacklist() + { + WithSeries("Blacklist"); + WithSeries("The Blacklist"); + + _series.Sort(new TraktSearchSeriesComparer("the blacklist")); + + _series.First().Title.Should().Be("The Blacklist"); + } + } +} diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index ea41e0de4..b85256ae3 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -225,6 +225,7 @@ + diff --git a/src/NzbDrone.Core/MetadataSource/TraktSearchSeriesComparer.cs b/src/NzbDrone.Core/MetadataSource/TraktSearchSeriesComparer.cs index 94b0135ba..b3c31cba4 100644 --- a/src/NzbDrone.Core/MetadataSource/TraktSearchSeriesComparer.cs +++ b/src/NzbDrone.Core/MetadataSource/TraktSearchSeriesComparer.cs @@ -10,6 +10,7 @@ namespace NzbDrone.Core.MetadataSource { private static readonly Regex RegexCleanPunctuation = new Regex("[-._:]", RegexOptions.Compiled); private static readonly Regex RegexCleanCountryYearPostfix = new Regex(@"(?<=.+)( \([A-Z]{2}\)| \(\d{4}\)| \([A-Z]{2}\) \(\d{4}\))$", RegexOptions.Compiled); + private static readonly Regex ArticleRegex = new Regex(@"^(a|an|the)\s", RegexOptions.IgnoreCase | RegexOptions.Compiled); public String SearchQuery { get; private set; } @@ -37,6 +38,14 @@ namespace NzbDrone.Core.MetadataSource int result = 0; // Prefer exact matches + result = Compare(x, y, s => CleanPunctuation(s.Title).Equals(CleanPunctuation(SearchQuery))); + if (result != 0) return -result; + + // Remove Articles (a/an/the) + result = Compare(x, y, s => CleanArticles(s.Title).Equals(CleanArticles(SearchQuery))); + if (result != 0) return -result; + + // Prefer close matches result = Compare(x, y, s => CleanPunctuation(s.Title).LevenshteinDistance(CleanPunctuation(SearchQuery)) <= 1); if (result != 0) return -result; @@ -47,7 +56,7 @@ namespace NzbDrone.Core.MetadataSource // Compare prefix matches by year "(CSI: ..." result = CompareWithYear(x, y, s => s.Title.ToLowerInvariant().StartsWith(_searchQueryWithoutYear + ":")); if (result != 0) return -result; - + return Compare(x, y, s => SearchQuery.LevenshteinDistanceClean(s.Title) - GetYearFactor(s)); } @@ -94,6 +103,13 @@ namespace NzbDrone.Core.MetadataSource return title.ToLowerInvariant(); } + private String CleanArticles(String title) + { + title = ArticleRegex.Replace(title, ""); + + return title.Trim().ToLowerInvariant(); + } + private Int32 GetYearFactor(Series series) { if (_year.HasValue) diff --git a/src/UI/AddSeries/AddSeriesView.js b/src/UI/AddSeries/AddSeriesView.js index 04132578a..52ed6d880 100644 --- a/src/UI/AddSeries/AddSeriesView.js +++ b/src/UI/AddSeries/AddSeriesView.js @@ -167,6 +167,7 @@ define( if (!this.isClosed) { this.ui.searchBar.show(); this.searchResult.show(new ErrorView({term: this.collection.term})); + this.collection.term = ''; } } });