Fixed: Sorting of some titles with acronyms or common words at the start

Closes #4839
This commit is contained in:
Mark McDowall 2022-02-16 18:15:26 -08:00
parent 210768d7d6
commit 79436149eb
4 changed files with 55 additions and 11 deletions

View File

@ -8,9 +8,6 @@ namespace NzbDrone.Core.Test.TvTests
public class SeriesTitleNormalizerFixture public class SeriesTitleNormalizerFixture
{ {
[TestCase("A to Z", 281588, "a to z")] [TestCase("A to Z", 281588, "a to z")]
[TestCase("A.D. The Bible Continues", 289260, "ad bible continues")]
[TestCase("A.P. Bio", 328534, "ap bio")]
[TestCase("The A-Team", 77904, "ateam")]
public void should_use_precomputed_title(string title, int tvdbId, string expected) public void should_use_precomputed_title(string title, int tvdbId, string expected)
{ {
SeriesTitleNormalizer.Normalize(title, tvdbId).Should().Be(expected); SeriesTitleNormalizer.Normalize(title, tvdbId).Should().Be(expected);
@ -23,6 +20,12 @@ namespace NzbDrone.Core.Test.TvTests
[TestCase("The Good Wife", "good wife")] [TestCase("The Good Wife", "good wife")]
[TestCase("The Newsroom (2012)", "newsroom 2012")] [TestCase("The Newsroom (2012)", "newsroom 2012")]
[TestCase("Special Agent Oso", "special agent oso")] [TestCase("Special Agent Oso", "special agent oso")]
[TestCase("A.N.T. Farm", "ant farm")]
[TestCase("A.I.C.O. -Incarnation-", "aico incarnation")]
[TestCase("A.D. The Bible Continues", "ad the bible continues")]
[TestCase("A.P. Bio", "ap bio")]
[TestCase("The A-Team", "ateam")]
[TestCase("And Just Like That", "and just like that")]
public void should_normalize_title(string title, string expected) public void should_normalize_title(string title, string expected)
{ {
SeriesTitleNormalizer.Normalize(title, 0).Should().Be(expected); SeriesTitleNormalizer.Normalize(title, 0).Should().Be(expected);

View File

@ -0,0 +1,46 @@
using System.Data;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(166)]
public class update_series_sort_title : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Execute.WithConnection(UpdateSortTitles);
}
private void UpdateSortTitles(IDbConnection conn, IDbTransaction tran)
{
using (IDbCommand getSeriesCmd = conn.CreateCommand())
{
getSeriesCmd.Transaction = tran;
getSeriesCmd.CommandText = @"SELECT Id, TvdbId, Title FROM Series";
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
{
while (seriesReader.Read())
{
var id = seriesReader.GetInt32(0);
var tvdbId = seriesReader.GetInt32(1);
var title = seriesReader.GetString(2);
var sortTitle = SeriesTitleNormalizer.Normalize(title, tvdbId);
using (IDbCommand updateCmd = conn.CreateCommand())
{
updateCmd.Transaction = tran;
updateCmd.CommandText = "UPDATE Series SET SortTitle = ? WHERE Id = ?";
updateCmd.AddParameter(sortTitle);
updateCmd.AddParameter(id);
updateCmd.ExecuteNonQuery();
}
}
}
}
}
}
}

View File

@ -472,9 +472,8 @@ namespace NzbDrone.Core.Parser
private static readonly Regex TitleComponentsRegex = new Regex(@"^(?:(?<title>.+?) \((?<title>.+?)\)|(?<title>.+?) \| (?<title>.+?))$", private static readonly Regex TitleComponentsRegex = new Regex(@"^(?:(?<title>.+?) \((?<title>.+?)\)|(?<title>.+?) \| (?<title>.+?))$",
RegexOptions.IgnoreCase | RegexOptions.Compiled); RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex WordDelimiterRegex = new Regex(@"(\s|\.|,|_|-|=|\|)+", RegexOptions.Compiled);
private static readonly Regex PunctuationRegex = new Regex(@"[^\w\s]", RegexOptions.Compiled); private static readonly Regex PunctuationRegex = new Regex(@"[^\w\s]", RegexOptions.Compiled);
private static readonly Regex CommonWordRegex = new Regex(@"\b(a|an|the|and|or|of)\b\s?", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex ArticleWordRegex = new Regex(@"^(a|an|the)\s", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex SpecialEpisodeWordRegex = new Regex(@"\b(part|special|edition|christmas)\b\s?", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex SpecialEpisodeWordRegex = new Regex(@"\b(part|special|edition|christmas)\b\s?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex DuplicateSpacesRegex = new Regex(@"\s{2,}", RegexOptions.Compiled); private static readonly Regex DuplicateSpacesRegex = new Regex(@"\s{2,}", RegexOptions.Compiled);
@ -705,9 +704,8 @@ namespace NzbDrone.Core.Parser
public static string NormalizeTitle(string title) public static string NormalizeTitle(string title)
{ {
title = WordDelimiterRegex.Replace(title, " ");
title = PunctuationRegex.Replace(title, string.Empty); title = PunctuationRegex.Replace(title, string.Empty);
title = CommonWordRegex.Replace(title, string.Empty); title = ArticleWordRegex.Replace(title, string.Empty);
title = DuplicateSpacesRegex.Replace(title, " "); title = DuplicateSpacesRegex.Replace(title, " ");
return title.Trim().ToLower(); return title.Trim().ToLower();

View File

@ -6,10 +6,7 @@ namespace NzbDrone.Core.Tv
{ {
private static readonly Dictionary<int, string> PreComputedTitles = new Dictionary<int, string> private static readonly Dictionary<int, string> PreComputedTitles = new Dictionary<int, string>
{ {
{ 281588, "a to z" }, { 281588, "a to z" }
{ 289260, "ad bible continues"},
{ 328534, "ap bio"},
{ 77904, "ateam" }
}; };
public static string Normalize(string title, int tvdbId) public static string Normalize(string title, int tvdbId)