New: Update AutoTags on movies update

(cherry picked from commit 10e9735c1cb5f3b0d318c195a37df9e3a0407639)

Closes #10153
pull/10157/head
Mark McDowall 8 months ago committed by Bogdan
parent c63d08e7a0
commit 087f9e12aa

@ -1,6 +1,9 @@
using System.Collections.Generic;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
@ -17,9 +20,17 @@ namespace NzbDrone.Core.Test.MovieTests.MovieServiceTests
{ {
_fakeMovie = Builder<Movie>.CreateNew().Build(); _fakeMovie = Builder<Movie>.CreateNew().Build();
_existingMovie = Builder<Movie>.CreateNew().Build(); _existingMovie = Builder<Movie>.CreateNew().Build();
Mocker.GetMock<IAutoTaggingService>()
.Setup(s => s.GetTagChanges(It.IsAny<Movie>()))
.Returns(new AutoTaggingChanges());
Mocker.GetMock<IMovieRepository>()
.Setup(s => s.Update(It.IsAny<Movie>()))
.Returns<Movie>(r => r);
} }
private void GivenExistingSeries() private void GivenExistingMovie()
{ {
Mocker.GetMock<IMovieService>() Mocker.GetMock<IMovieService>()
.Setup(s => s.GetMovie(It.IsAny<int>())) .Setup(s => s.GetMovie(It.IsAny<int>()))
@ -29,12 +40,33 @@ namespace NzbDrone.Core.Test.MovieTests.MovieServiceTests
[Test] [Test]
public void should_update_movie_when_it_changes() public void should_update_movie_when_it_changes()
{ {
GivenExistingSeries(); GivenExistingMovie();
Subject.UpdateMovie(_fakeMovie); Subject.UpdateMovie(_fakeMovie);
Mocker.GetMock<IMovieRepository>() Mocker.GetMock<IMovieRepository>()
.Verify(v => v.Update(_fakeMovie), Times.Once()); .Verify(v => v.Update(_fakeMovie), Times.Once());
} }
[Test]
public void should_add_and_remove_tags()
{
GivenExistingMovie();
_fakeMovie.Tags = new HashSet<int> { 1, 2 };
_fakeMovie.Monitored = false;
Mocker.GetMock<IAutoTaggingService>()
.Setup(s => s.GetTagChanges(_fakeMovie))
.Returns(new AutoTaggingChanges
{
TagsToAdd = new HashSet<int> { 3 },
TagsToRemove = new HashSet<int> { 1 }
});
var result = Subject.UpdateMovie(_fakeMovie);
result.Tags.Should().BeEquivalentTo(new[] { 2, 3 });
}
} }
} }

@ -5,6 +5,7 @@ using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.Organizer; using NzbDrone.Core.Organizer;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
@ -27,6 +28,10 @@ namespace NzbDrone.Core.Test.MovieTests.MovieServiceTests
.With(s => s.Path = @"C:\Test\name".AsOsAgnostic()) .With(s => s.Path = @"C:\Test\name".AsOsAgnostic())
.With(s => s.RootFolderPath = "") .With(s => s.RootFolderPath = "")
.Build().ToList(); .Build().ToList();
Mocker.GetMock<IAutoTaggingService>()
.Setup(s => s.GetTagChanges(It.IsAny<Movie>()))
.Returns(new AutoTaggingChanges());
} }
[Test] [Test]
@ -78,5 +83,23 @@ namespace NzbDrone.Core.Test.MovieTests.MovieServiceTests
Subject.UpdateMovie(movies, false); Subject.UpdateMovie(movies, false);
} }
[Test]
public void should_add_and_remove_tags()
{
_movies[0].Tags = new HashSet<int> { 1, 2 };
Mocker.GetMock<IAutoTaggingService>()
.Setup(s => s.GetTagChanges(_movies[0]))
.Returns(new AutoTaggingChanges
{
TagsToAdd = new HashSet<int> { 3 },
TagsToRemove = new HashSet<int> { 1 }
});
var result = Subject.UpdateMovie(_movies, false);
result[0].Tags.Should().BeEquivalentTo(new[] { 2, 3 });
}
} }
} }

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
@ -40,11 +41,12 @@ namespace NzbDrone.Core.Movies
List<Movie> GetAllMovies(); List<Movie> GetAllMovies();
Dictionary<int, List<int>> AllMovieTags(); Dictionary<int, List<int>> AllMovieTags();
Movie UpdateMovie(Movie movie); Movie UpdateMovie(Movie movie);
List<Movie> UpdateMovie(List<Movie> movie, bool useExistingRelativeFolder); List<Movie> UpdateMovie(List<Movie> movies, bool useExistingRelativeFolder);
void UpdateLastSearchTime(Movie movie); void UpdateLastSearchTime(Movie movie);
List<int> GetRecommendedTmdbIds(); List<int> GetRecommendedTmdbIds();
bool MoviePathExists(string folder); bool MoviePathExists(string folder);
void RemoveAddOptions(Movie movie); void RemoveAddOptions(Movie movie);
bool UpdateTags(Movie movie);
bool ExistsByMetadataId(int metadataId); bool ExistsByMetadataId(int metadataId);
HashSet<int> AllMovieWithCollectionsTmdbIds(); HashSet<int> AllMovieWithCollectionsTmdbIds();
} }
@ -56,18 +58,21 @@ namespace NzbDrone.Core.Movies
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IBuildMoviePaths _moviePathBuilder; private readonly IBuildMoviePaths _moviePathBuilder;
private readonly IAutoTaggingService _autoTaggingService;
private readonly Logger _logger; private readonly Logger _logger;
public MovieService(IMovieRepository movieRepository, public MovieService(IMovieRepository movieRepository,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
IConfigService configService, IConfigService configService,
IBuildMoviePaths moviePathBuilder, IBuildMoviePaths moviePathBuilder,
IAutoTaggingService autoTaggingService,
Logger logger) Logger logger)
{ {
_movieRepository = movieRepository; _movieRepository = movieRepository;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_configService = configService; _configService = configService;
_moviePathBuilder = moviePathBuilder; _moviePathBuilder = moviePathBuilder;
_autoTaggingService = autoTaggingService;
_logger = logger; _logger = logger;
} }
@ -242,16 +247,19 @@ namespace NzbDrone.Core.Movies
{ {
var storedMovie = GetMovie(movie.Id); var storedMovie = GetMovie(movie.Id);
UpdateTags(movie);
var updatedMovie = _movieRepository.Update(movie); var updatedMovie = _movieRepository.Update(movie);
_eventAggregator.PublishEvent(new MovieEditedEvent(updatedMovie, storedMovie)); _eventAggregator.PublishEvent(new MovieEditedEvent(updatedMovie, storedMovie));
return updatedMovie; return updatedMovie;
} }
public List<Movie> UpdateMovie(List<Movie> movie, bool useExistingRelativeFolder) public List<Movie> UpdateMovie(List<Movie> movies, bool useExistingRelativeFolder)
{ {
_logger.Debug("Updating {0} movie", movie.Count); _logger.Debug("Updating {0} movies", movies.Count);
foreach (var m in movie)
foreach (var m in movies)
{ {
_logger.Trace("Updating: {0}", m.Title); _logger.Trace("Updating: {0}", m.Title);
@ -265,12 +273,14 @@ namespace NzbDrone.Core.Movies
{ {
_logger.Trace("Not changing path for: {0}", m.Title); _logger.Trace("Not changing path for: {0}", m.Title);
} }
UpdateTags(m);
} }
_movieRepository.UpdateMany(movie); _movieRepository.UpdateMany(movies);
_logger.Debug("{0} movie updated", movie.Count); _logger.Debug("{0} movies updated", movies.Count);
return movie; return movies;
} }
public void UpdateLastSearchTime(Movie movie) public void UpdateLastSearchTime(Movie movie)
@ -288,6 +298,42 @@ namespace NzbDrone.Core.Movies
_movieRepository.SetFields(movie, s => s.AddOptions); _movieRepository.SetFields(movie, s => s.AddOptions);
} }
public bool UpdateTags(Movie movie)
{
_logger.Trace("Updating tags for {0}", movie);
var tagsAdded = new HashSet<int>();
var tagsRemoved = new HashSet<int>();
var changes = _autoTaggingService.GetTagChanges(movie);
foreach (var tag in changes.TagsToRemove)
{
if (movie.Tags.Contains(tag))
{
movie.Tags.Remove(tag);
tagsRemoved.Add(tag);
}
}
foreach (var tag in changes.TagsToAdd)
{
if (!movie.Tags.Contains(tag))
{
movie.Tags.Add(tag);
tagsAdded.Add(tag);
}
}
if (tagsAdded.Any() || tagsRemoved.Any())
{
_logger.Debug("Updated tags for '{0}'. Added: {1}, Removed: {2}", movie.Title, tagsAdded.Count, tagsRemoved.Count);
return true;
}
return false;
}
public List<Movie> GetMoviesByFileId(int fileId) public List<Movie> GetMoviesByFileId(int fileId)
{ {
return _movieRepository.GetMoviesByFileId(fileId); return _movieRepository.GetMoviesByFileId(fileId);

@ -210,34 +210,11 @@ namespace NzbDrone.Core.Movies
private void UpdateTags(Movie movie) private void UpdateTags(Movie movie)
{ {
_logger.Trace("Updating tags for {0}", movie); var tagsUpdated = _movieService.UpdateTags(movie);
var tagsAdded = new HashSet<int>(); if (tagsUpdated)
var tagsRemoved = new HashSet<int>();
var changes = _autoTaggingService.GetTagChanges(movie);
foreach (var tag in changes.TagsToRemove)
{
if (movie.Tags.Contains(tag))
{
movie.Tags.Remove(tag);
tagsRemoved.Add(tag);
}
}
foreach (var tag in changes.TagsToAdd)
{
if (!movie.Tags.Contains(tag))
{
movie.Tags.Add(tag);
tagsAdded.Add(tag);
}
}
if (tagsAdded.Any() || tagsRemoved.Any())
{ {
_movieService.UpdateMovie(movie); _movieService.UpdateMovie(movie);
_logger.Debug("Updated tags for '{0}'. Added: {1}, Removed: {2}", movie.Title, tagsAdded.Count, tagsRemoved.Count);
} }
} }

Loading…
Cancel
Save