mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-16 10:03:51 -07:00
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
This commit is contained in:
parent
2af4a5004f
commit
9b0a7c60ed
4 changed files with 85 additions and 25 deletions
|
@ -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…
Add table
Add a link
Reference in a new issue