Fixed: Improve TrackMatching when title is slightly longer/shorter than DB (#491)

* improve TrackMatching

* Add unit test for TrackMatching

* rename NormalizeEpisodeTitle to NormalizeTrackTitle

* correct typo
pull/6/head
gismo2004 6 years ago committed by Qstick
parent 2af4a5004f
commit 9b0a7c60ed

@ -0,0 +1,69 @@
using System.Linq;
using FluentAssertions;
using NLog;
using NUnit.Framework;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Music;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.MusicTests.TitleMatchingTests
{
[TestFixture]
public class TitleMatchingFixture : DbTest<TrackService, Track>
{
private TrackRepository _trackRepository;
private TrackService _trackService;
[SetUp]
public void Setup()
{
_trackRepository = Mocker.Resolve<TrackRepository>();
_trackService =
new TrackService(_trackRepository, Mocker.Resolve<ConfigService>(), Mocker.Resolve<Logger>());
_trackRepository.Insert(new Track
{
Title = "This is the short test title",
ForeignTrackId = "this is a fake id2",
AlbumId = 4321,
AbsoluteTrackNumber = 1,
MediumNumber = 1,
TrackFileId = 1
});
_trackRepository.Insert(new Track
{
Title = "This is the long test title",
ForeignTrackId = "this is a fake id",
AlbumId = 4321,
AbsoluteTrackNumber = 2,
MediumNumber = 1,
TrackFileId = 2
});
}
[Test]
public void should_find_track_in_db_by_tracktitle_longer_then_relaeasetitle()
{
var track = _trackService.FindTrackByTitle(1234, 4321, 1, 1, "This is the short test title with some bla");
track.Title.Should().Be(_trackRepository.GetTracksByFileId(1).First().Title);
}
[Test]
public void should_find_track_in_db_by_tracktitle_shorter_then_relaeasetitle()
{
var track = _trackService.FindTrackByTitle(1234, 4321, 1, 2, "test title");
track.Title.Should().Be(_trackRepository.GetTracksByFileId(2).First().Title);
}
[Test]
public void should_not_find_track_in_db_by_wrong_title()
{
var track = _trackService.FindTrackByTitle(1234, 4321, 1, 1, "the short title");
track.Should().BeNull();
}
}
}

@ -306,6 +306,7 @@
<Compile Include="MusicTests\ArtistServiceTests\UpdateMultipleArtistFixture.cs" />
<Compile Include="MusicTests\RefreshAlbumServiceFixture.cs" />
<Compile Include="MusicTests\ShouldRefreshAlbumFixture.cs" />
<Compile Include="MusicTests\TitleMatchingTests\TitleMatchingFixture.cs" />
<Compile Include="NotificationTests\NotificationBaseFixture.cs" />
<Compile Include="NotificationTests\SynologyIndexerFixture.cs" />
<Compile Include="OrganizerTests\FileNameBuilderTests\CleanTitleFixture.cs" />

@ -79,35 +79,25 @@ namespace NzbDrone.Core.Music
public Track FindTrackByTitle(int artistId, int albumId, int mediumNumber, int trackNumber, string releaseTitle)
{
// TODO: can replace this search mechanism with something smarter/faster/better
var normalizedReleaseTitle = Parser.Parser.NormalizeEpisodeTitle(releaseTitle).Replace(".", " ");
var normalizedReleaseTitle = Parser.Parser.NormalizeTrackTitle(releaseTitle).Replace(".", " ");
var tracks = _trackRepository.GetTracksByMedium(albumId, mediumNumber);
var matches = tracks.Select(
track => new
var matches = from track in tracks
//if we have a trackNumber use it
let trackNumCheck = (trackNumber == 0 || track.AbsoluteTrackNumber == trackNumber)
//if release title is longer than track title
let posReleaseTitle = normalizedReleaseTitle.IndexOf(Parser.Parser.NormalizeTrackTitle(track.Title), StringComparison.CurrentCultureIgnoreCase)
//if track title is longer than release title
let posTrackTitle = Parser.Parser.NormalizeTrackTitle(track.Title).IndexOf(normalizedReleaseTitle, StringComparison.CurrentCultureIgnoreCase)
where track.Title.Length > 0 && trackNumCheck && (posReleaseTitle >= 0 || posTrackTitle >= 0)
orderby posReleaseTitle, posTrackTitle
select new
{
Position = normalizedReleaseTitle.IndexOf(Parser.Parser.NormalizeEpisodeTitle(track.Title), StringComparison.CurrentCultureIgnoreCase),
Length = Parser.Parser.NormalizeEpisodeTitle(track.Title).Length,
NormalizedLength = Parser.Parser.NormalizeTrackTitle(track.Title).Length,
Track = track
});
};
if (trackNumber == 0)
{
matches = matches.Where(e => e.Track.Title.Length > 0 && e.Position >= 0);
} else
{
matches = matches.Where(e => e.Track.Title.Length > 0 && e.Position >= 0 && e.Track.AbsoluteTrackNumber == trackNumber);
}
matches.OrderBy(e => e.Position)
.ThenByDescending(e => e.Length)
.ToList();
if (matches.Any())
{
return matches.First().Track;
}
return null;
return matches.OrderByDescending(e => e.NormalizedLength).FirstOrDefault()?.Track;
}
public List<Track> TracksWithFiles(int artistId)

@ -529,7 +529,7 @@ namespace NzbDrone.Core.Parser
return NormalizeRegex.Replace(name, string.Empty).ToLower().RemoveAccent();
}
public static string NormalizeEpisodeTitle(string title)
public static string NormalizeTrackTitle(string title)
{
title = SpecialEpisodeWordRegex.Replace(title, string.Empty);
title = PunctuationRegex.Replace(title, " ");

Loading…
Cancel
Save