1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-11-19 17:32:38 +01:00

New: Update AutoTags on movies update

(cherry picked from commit 10e9735c1cb5f3b0d318c195a37df9e3a0407639)

Closes #10153
This commit is contained in:
Mark McDowall 2024-07-09 22:02:23 -07:00 committed by Bogdan
parent c63d08e7a0
commit 087f9e12aa
4 changed files with 112 additions and 34 deletions

View File

@ -1,6 +1,9 @@
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Test.Framework;
@ -17,9 +20,17 @@ public void Setup()
{
_fakeMovie = 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>()
.Setup(s => s.GetMovie(It.IsAny<int>()))
@ -29,12 +40,33 @@ private void GivenExistingSeries()
[Test]
public void should_update_movie_when_it_changes()
{
GivenExistingSeries();
GivenExistingMovie();
Subject.UpdateMovie(_fakeMovie);
Mocker.GetMock<IMovieRepository>()
.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 });
}
}
}

View File

@ -5,6 +5,7 @@
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Test.Framework;
@ -27,6 +28,10 @@ public void Setup()
.With(s => s.Path = @"C:\Test\name".AsOsAgnostic())
.With(s => s.RootFolderPath = "")
.Build().ToList();
Mocker.GetMock<IAutoTaggingService>()
.Setup(s => s.GetTagChanges(It.IsAny<Movie>()))
.Returns(new AutoTaggingChanges());
}
[Test]
@ -78,5 +83,23 @@ public void should_be_able_to_update_many_movies()
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 });
}
}
}

View File

@ -3,6 +3,7 @@
using System.Linq;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.MediaFiles;
@ -40,11 +41,12 @@ public interface IMovieService
List<Movie> GetAllMovies();
Dictionary<int, List<int>> AllMovieTags();
Movie UpdateMovie(Movie movie);
List<Movie> UpdateMovie(List<Movie> movie, bool useExistingRelativeFolder);
List<Movie> UpdateMovie(List<Movie> movies, bool useExistingRelativeFolder);
void UpdateLastSearchTime(Movie movie);
List<int> GetRecommendedTmdbIds();
bool MoviePathExists(string folder);
void RemoveAddOptions(Movie movie);
bool UpdateTags(Movie movie);
bool ExistsByMetadataId(int metadataId);
HashSet<int> AllMovieWithCollectionsTmdbIds();
}
@ -56,18 +58,21 @@ public class MovieService : IMovieService, IHandle<MovieFileAddedEvent>,
private readonly IConfigService _configService;
private readonly IEventAggregator _eventAggregator;
private readonly IBuildMoviePaths _moviePathBuilder;
private readonly IAutoTaggingService _autoTaggingService;
private readonly Logger _logger;
public MovieService(IMovieRepository movieRepository,
IEventAggregator eventAggregator,
IConfigService configService,
IBuildMoviePaths moviePathBuilder,
IAutoTaggingService autoTaggingService,
Logger logger)
{
_movieRepository = movieRepository;
_eventAggregator = eventAggregator;
_configService = configService;
_moviePathBuilder = moviePathBuilder;
_autoTaggingService = autoTaggingService;
_logger = logger;
}
@ -242,16 +247,19 @@ public Movie UpdateMovie(Movie movie)
{
var storedMovie = GetMovie(movie.Id);
UpdateTags(movie);
var updatedMovie = _movieRepository.Update(movie);
_eventAggregator.PublishEvent(new MovieEditedEvent(updatedMovie, storedMovie));
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);
foreach (var m in movie)
_logger.Debug("Updating {0} movies", movies.Count);
foreach (var m in movies)
{
_logger.Trace("Updating: {0}", m.Title);
@ -265,12 +273,14 @@ public List<Movie> UpdateMovie(List<Movie> movie, bool useExistingRelativeFolder
{
_logger.Trace("Not changing path for: {0}", m.Title);
}
UpdateTags(m);
}
_movieRepository.UpdateMany(movie);
_logger.Debug("{0} movie updated", movie.Count);
_movieRepository.UpdateMany(movies);
_logger.Debug("{0} movies updated", movies.Count);
return movie;
return movies;
}
public void UpdateLastSearchTime(Movie movie)
@ -288,6 +298,42 @@ public void RemoveAddOptions(Movie movie)
_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)
{
return _movieRepository.GetMoviesByFileId(fileId);

View File

@ -210,34 +210,11 @@ private void RescanMovie(Movie movie, bool isNew, CommandTrigger trigger)
private void UpdateTags(Movie movie)
{
_logger.Trace("Updating tags for {0}", movie);
var tagsUpdated = _movieService.UpdateTags(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())
if (tagsUpdated)
{
_movieService.UpdateMovie(movie);
_logger.Debug("Updated tags for '{0}'. Added: {1}, Removed: {2}", movie.Title, tagsAdded.Count, tagsRemoved.Count);
}
}