mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-11 12:02:35 +02:00
Fixed: When refreshing info about a movie, the alt titles should now correctly be deleted / updated, even from TMDB. (#3603)
* Fixed: When refreshing info about a movie, the alt titles should now correctly be deleted / updated, even from TMDB. Fixes #3542 * Fixed: Small things fixup.
This commit is contained in:
parent
bd374825f1
commit
be3152e630
@ -0,0 +1,32 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Movies.AlternativeTitles;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class AlternativeTitleFixture : CoreTest
|
||||
{
|
||||
private AlternativeTitle CreateFakeTitle(SourceType source, int votes)
|
||||
{
|
||||
return Builder<AlternativeTitle>.CreateNew().With(t => t.SourceType = source).With(t => t.Votes = votes)
|
||||
.Build();
|
||||
}
|
||||
|
||||
[TestCase(SourceType.TMDB, -1, true)]
|
||||
[TestCase(SourceType.TMDB, 1000, true)]
|
||||
[TestCase(SourceType.Mappings, 0, false)]
|
||||
[TestCase(SourceType.Mappings, 4, true)]
|
||||
[TestCase(SourceType.Mappings, -1, false)]
|
||||
[TestCase(SourceType.Indexer, 0, true)]
|
||||
[TestCase(SourceType.User, 0, true)]
|
||||
public void should_be_trusted(SourceType source, int votes, bool trusted)
|
||||
{
|
||||
var fakeTitle = CreateFakeTitle(source, votes);
|
||||
|
||||
fakeTitle.IsTrusted().Should().Be(trusted);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Movies.AlternativeTitles;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class AlternativeTitleServiceFixture : CoreTest<AlternativeTitleService>
|
||||
{
|
||||
private AlternativeTitle _title1;
|
||||
private AlternativeTitle _title2;
|
||||
private AlternativeTitle _title3;
|
||||
|
||||
private Movie _movie;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var titles = Builder<AlternativeTitle>.CreateListOfSize(3).All().With(t => t.MovieId = 0).Build();
|
||||
_title1 = titles[0];
|
||||
_title2 = titles[1];
|
||||
_title3 = titles[2];
|
||||
_movie = Builder<Movie>.CreateNew().With(m => m.CleanTitle = "myothertitle").With(m => m.Id = 1).Build();
|
||||
}
|
||||
|
||||
private void GivenExistingTitles(params AlternativeTitle[] titles)
|
||||
{
|
||||
Mocker.GetMock<IAlternativeTitleRepository>().Setup(r => r.FindByMovieId(_movie.Id))
|
||||
.Returns(titles.ToList());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_update_insert_remove_titles()
|
||||
{
|
||||
var titles = new List<AlternativeTitle> {_title2, _title3};
|
||||
var updates = new List<AlternativeTitle> {_title2};
|
||||
var deletes = new List<AlternativeTitle> {_title1};
|
||||
var inserts = new List<AlternativeTitle> {_title3};
|
||||
GivenExistingTitles(_title1, _title2);
|
||||
|
||||
Subject.UpdateTitles(titles, _movie);
|
||||
|
||||
Mocker.GetMock<IAlternativeTitleRepository>().Verify(r => r.InsertMany(inserts), Times.Once());
|
||||
Mocker.GetMock<IAlternativeTitleRepository>().Verify(r => r.UpdateMany(updates), Times.Once());
|
||||
Mocker.GetMock<IAlternativeTitleRepository>().Verify(r => r.DeleteMany(deletes), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_insert_duplicates()
|
||||
{
|
||||
GivenExistingTitles();
|
||||
var titles = new List<AlternativeTitle> {_title1, _title1};
|
||||
var inserts = new List<AlternativeTitle>{ _title1 };
|
||||
|
||||
Subject.UpdateTitles(titles, _movie);
|
||||
|
||||
Mocker.GetMock<IAlternativeTitleRepository>().Verify(r => r.InsertMany(inserts), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_insert_main_title()
|
||||
{
|
||||
GivenExistingTitles();
|
||||
var titles = new List<AlternativeTitle>{_title1};
|
||||
var movie = Builder<Movie>.CreateNew().With(m => m.CleanTitle = _title1.CleanTitle).Build();
|
||||
|
||||
Subject.UpdateTitles(titles, movie);
|
||||
|
||||
Mocker.GetMock<IAlternativeTitleRepository>().Verify(r => r.InsertMany(new List<AlternativeTitle>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_update_movie_id()
|
||||
{
|
||||
GivenExistingTitles();
|
||||
var titles = new List<AlternativeTitle> {_title1, _title2};
|
||||
|
||||
Subject.UpdateTitles(titles, _movie);
|
||||
|
||||
_title1.MovieId.Should().Be(_movie.Id);
|
||||
_title2.MovieId.Should().Be(_movie.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_update_with_correct_id()
|
||||
{
|
||||
var existingTitle = Builder<AlternativeTitle>.CreateNew().With(t => t.Id = 2).Build();
|
||||
GivenExistingTitles(existingTitle);
|
||||
var updateTitle = existingTitle.JsonClone();
|
||||
updateTitle.Id = 0;
|
||||
|
||||
Subject.UpdateTitles(new List<AlternativeTitle> {updateTitle}, _movie);
|
||||
|
||||
Mocker.GetMock<IAlternativeTitleRepository>().Verify(r => r.UpdateMany(It.Is<IList<AlternativeTitle>>(list => list.First().Id == existingTitle.Id)), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
@ -33,15 +33,15 @@ public AlternativeTitle(string title, SourceType sourceType = SourceType.TMDB, i
|
||||
Language = language ?? Language.English;
|
||||
}
|
||||
|
||||
public bool IsTrusted(int minVotes = 3)
|
||||
public bool IsTrusted(int minVotes = 4)
|
||||
{
|
||||
switch (SourceType)
|
||||
{
|
||||
case SourceType.TMDB:
|
||||
case SourceType.Mappings:
|
||||
return Votes >= minVotes;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using Marr.Data;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
@ -3,6 +3,7 @@
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Movies.Events;
|
||||
|
||||
namespace NzbDrone.Core.Movies.AlternativeTitles
|
||||
@ -14,7 +15,7 @@ public interface IAlternativeTitleService
|
||||
List<AlternativeTitle> AddAltTitles(List<AlternativeTitle> titles, Movie movie);
|
||||
AlternativeTitle GetById(int id);
|
||||
List<AlternativeTitle> GetAllTitles();
|
||||
void DeleteNotEnoughVotes(List<AlternativeTitle> mappingsTitles);
|
||||
List<AlternativeTitle> UpdateTitles(List<AlternativeTitle> titles, Movie movie);
|
||||
}
|
||||
|
||||
public class AlternativeTitleService : IAlternativeTitleService, IHandleAsync<MovieDeletedEvent>
|
||||
@ -69,11 +70,28 @@ public void RemoveTitle(AlternativeTitle title)
|
||||
_titleRepo.Delete(title);
|
||||
}
|
||||
|
||||
public void DeleteNotEnoughVotes(List<AlternativeTitle> mappingsTitles)
|
||||
public List<AlternativeTitle> UpdateTitles(List<AlternativeTitle> titles, Movie movie)
|
||||
{
|
||||
var toRemove = mappingsTitles.Where(t => t.SourceType == SourceType.Mappings && t.Votes < 4);
|
||||
var realT = _titleRepo.FindBySourceIds(toRemove.Select(t => t.SourceId).ToList());
|
||||
_titleRepo.DeleteMany(realT);
|
||||
int movieId = movie.Id;
|
||||
// First update the movie ids so we can correlate them later.
|
||||
titles.ForEach(t => t.MovieId = movieId);
|
||||
// Then make sure none of them are the same as the main title.
|
||||
titles = titles.Where(t => t.CleanTitle != movie.CleanTitle).ToList();
|
||||
// Then make sure they are all distinct titles
|
||||
titles = titles.DistinctBy(t => t.CleanTitle).ToList();
|
||||
|
||||
// Now find titles to delete, update and insert.
|
||||
var existingTitles = _titleRepo.FindByMovieId(movieId);
|
||||
|
||||
var insert = titles.Where(t => !existingTitles.Contains(t));
|
||||
var update = existingTitles.Where(t => titles.Contains(t));
|
||||
var delete = existingTitles.Where(t => !titles.Contains(t));
|
||||
|
||||
_titleRepo.DeleteMany(delete.ToList());
|
||||
_titleRepo.UpdateMany(update.ToList());
|
||||
_titleRepo.InsertMany(insert.ToList());
|
||||
|
||||
return titles;
|
||||
}
|
||||
|
||||
public void HandleAsync(MovieDeletedEvent message)
|
||||
|
@ -104,26 +104,16 @@ private void RefreshMovieInfo(Movie movie)
|
||||
_logger.Warn(e, "Couldn't update movie path for " + movie.Path);
|
||||
}
|
||||
|
||||
movieInfo.AlternativeTitles = movieInfo.AlternativeTitles.Where(t => t.CleanTitle != movie.CleanTitle)
|
||||
.DistinctBy(t => t.CleanTitle)
|
||||
.ExceptBy(t => t.CleanTitle, movie.AlternativeTitles, t => t.CleanTitle, EqualityComparer<string>.Default).ToList();
|
||||
|
||||
try
|
||||
{
|
||||
movie.AlternativeTitles.AddRange(_titleService.AddAltTitles(movieInfo.AlternativeTitles, movie));
|
||||
|
||||
var mappings = _apiClient.AlternativeTitlesAndYearForMovie(movieInfo.TmdbId);
|
||||
var mappingsTitles = mappings.Item1;
|
||||
|
||||
_titleService.DeleteNotEnoughVotes(mappingsTitles);
|
||||
mappingsTitles = mappingsTitles.Where(t => t.IsTrusted()).ToList();
|
||||
|
||||
mappingsTitles = mappingsTitles.ExceptBy(t => t.CleanTitle, movie.AlternativeTitles,
|
||||
t => t.CleanTitle, EqualityComparer<string>.Default).ToList();
|
||||
|
||||
|
||||
mappingsTitles = mappingsTitles.Where(t => t.Votes > 3).ToList();
|
||||
|
||||
movie.AlternativeTitles.AddRange(_titleService.AddAltTitles(mappingsTitles, movie));
|
||||
movieInfo.AlternativeTitles.AddRange(mappingsTitles);
|
||||
|
||||
movie.AlternativeTitles = _titleService.UpdateTitles(movieInfo.AlternativeTitles, movie);
|
||||
|
||||
if (mappings.Item2 != null)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user