From 9442666493211d3084f797e2c91fd1d74414e615 Mon Sep 17 00:00:00 2001 From: Qstick Date: Sun, 28 Nov 2021 22:06:24 -0600 Subject: [PATCH] Fixed: Duplicates on index before housekeeper runs when manual importing over existing file --- .../HistoryTests/HistoryRepositoryFixture.cs | 79 ------------------- .../MediaFiles/MediaFileRepository.cs | 7 ++ .../MediaFiles/MediaFileService.cs | 6 ++ .../MovieImport/ImportApprovedMovie.cs | 8 ++ src/NzbDrone.Core/Movies/MovieRepository.cs | 2 +- 5 files changed, 22 insertions(+), 80 deletions(-) diff --git a/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs b/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs index 563e0f10a..1611dbf6c 100644 --- a/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs @@ -70,84 +70,5 @@ namespace NzbDrone.Core.Test.HistoryTests downloadHistory.Should().HaveCount(1); } - - [Test] - public void should_get_movie_history() - { - var historyMovie1 = Builder.CreateNew() - .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) - .With(c => c.Languages = new List { Language.English }) - .With(c => c.MovieId = 12) - .With(c => c.EventType = MovieHistoryEventType.Grabbed) - .BuildNew(); - - var historyMovie2 = Builder.CreateNew() - .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) - .With(c => c.Languages = new List { Language.English }) - .With(c => c.MovieId = 13) - .With(c => c.EventType = MovieHistoryEventType.Grabbed) - .BuildNew(); - - Subject.Insert(historyMovie1); - Subject.Insert(historyMovie2); - - var movieHistory = Subject.GetByMovieId(12, null); - - movieHistory.Should().HaveCount(1); - } - - [Test] - public void should_sort_movie_history_by_date() - { - var historyFirst = Builder.CreateNew() - .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) - .With(c => c.Languages = new List { Language.English }) - .With(c => c.MovieId = 12) - .With(c => c.EventType = MovieHistoryEventType.MovieFileRenamed) - .With(c => c.Date = DateTime.UtcNow) - .BuildNew(); - - var historySecond = Builder.CreateNew() - .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) - .With(c => c.Languages = new List { Language.English }) - .With(c => c.MovieId = 12) - .With(c => c.EventType = MovieHistoryEventType.Grabbed) - .With(c => c.Date = DateTime.UtcNow.AddMinutes(10)) - .BuildNew(); - - Subject.Insert(historyFirst); - Subject.Insert(historySecond); - - var movieHistory = Subject.GetByMovieId(12, null); - - movieHistory.Should().HaveCount(2); - movieHistory.First().EventType.Should().Be(MovieHistoryEventType.Grabbed); - } - - [Test] - public void should_delete_history_items_by_movieId() - { - var items = Builder.CreateListOfSize(5) - .TheFirst(1) - .With(c => c.MovieId = _movie2.Id) - .TheRest() - .With(c => c.MovieId = _movie1.Id) - .All() - .With(c => c.Id = 0) - .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) - .With(c => c.Languages = new List { Language.English }) - .With(c => c.EventType = MovieHistoryEventType.Grabbed) - .BuildListOfNew(); - - Db.InsertMany(items); - - Subject.DeleteForMovies(new List { _movie1.Id }); - - var removedItems = Subject.GetByMovieId(_movie1.Id, null); - var nonRemovedItems = Subject.GetByMovieId(_movie2.Id, null); - - removedItems.Should().HaveCount(0); - nonRemovedItems.Should().HaveCount(1); - } } } diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs b/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs index 737f3ef0d..088c95d5d 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs @@ -9,6 +9,8 @@ namespace NzbDrone.Core.MediaFiles List GetFilesByMovie(int movieId); List GetFilesWithoutMediaInfo(); void DeleteForMovies(List movieIds); + + List GetFilesWithRelativePath(int movieId, string relativePath); } public class MediaFileRepository : BasicRepository, IMediaFileRepository @@ -32,5 +34,10 @@ namespace NzbDrone.Core.MediaFiles { Delete(x => movieIds.Contains(x.MovieId)); } + + public List GetFilesWithRelativePath(int movieId, string relativePath) + { + return Query(c => c.MovieId == movieId && c.RelativePath == relativePath); + } } } diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileService.cs b/src/NzbDrone.Core/MediaFiles/MediaFileService.cs index fb5981dc7..0fcf29fb9 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileService.cs @@ -20,6 +20,7 @@ namespace NzbDrone.Core.MediaFiles List FilterExistingFiles(List files, Movie movie); MovieFile GetMovie(int id); List GetMovies(IEnumerable ids); + List GetFilesWithRelativePath(int movieIds, string relativePath); } public class MediaFileService : IMediaFileService, IHandleAsync @@ -106,6 +107,11 @@ namespace NzbDrone.Core.MediaFiles return _mediaFileRepository.Get(id); } + public List GetFilesWithRelativePath(int movieId, string relativePath) + { + return _mediaFileRepository.GetFilesWithRelativePath(movieId, relativePath); + } + public void HandleAsync(MoviesDeletedEvent message) { _mediaFileRepository.DeleteForMovies(message.Movies.Select(m => m.Id).ToList()); diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs index 5b4e9845f..9548c5341 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs @@ -126,6 +126,14 @@ namespace NzbDrone.Core.MediaFiles.MovieImport else { movieFile.RelativePath = localMovie.Movie.Path.GetRelativePath(movieFile.Path); + + // Delete existing files from the DB mapped to this path + var previousFiles = _mediaFileService.GetFilesWithRelativePath(localMovie.Movie.Id, movieFile.RelativePath); + + foreach (var previousFile in previousFiles) + { + _mediaFileService.Delete(previousFile, DeleteMediaFileReason.ManualOverride); + } } movieFile = _mediaFileService.Add(movieFile); diff --git a/src/NzbDrone.Core/Movies/MovieRepository.cs b/src/NzbDrone.Core/Movies/MovieRepository.cs index fb55ec880..777cf50b6 100644 --- a/src/NzbDrone.Core/Movies/MovieRepository.cs +++ b/src/NzbDrone.Core/Movies/MovieRepository.cs @@ -95,7 +95,7 @@ namespace NzbDrone.Core.Movies // the skips the join on profile and alternative title and populates manually // to avoid repeatedly deserializing the same profile / movie var builder = new SqlBuilder() - .LeftJoin((m, f) => m.Id == f.MovieId); + .LeftJoin((m, f) => m.MovieFileId == f.Id); var profiles = _profileRepository.All().ToDictionary(x => x.Id); var titles = _alternativeTitleRepository.All()