Fixed: Fix Instances where DB MovieFileId Relationship is Screwy

This commit is contained in:
Qstick 2020-08-27 22:33:54 -04:00
parent 9a0f6cf931
commit ab7bb610a6
5 changed files with 112 additions and 20 deletions

View File

@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Housekeeping.Housekeepers;
using NzbDrone.Core.Languages;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
{
public class CleanupOrphanedMovieMovieFileIdsFixture : DbTest<CleanupOrphanedMovieMovieFileIds, Movie>
{
[Test]
public void should_remove_moviefileid_from_movie_referencing_deleted_moviefile()
{
var removedId = 2;
var movie = Builder<Movie>.CreateNew()
.With(e => e.MovieFileId = removedId)
.BuildNew();
Db.Insert(movie);
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
Db.All<Movie>().Should().Contain(e => e.MovieFileId == 0);
}
[Test]
public void should_not_remove_moviefileid_from_movie_referencing_valid_moviefile()
{
var movieFiles = Builder<MovieFile>.CreateListOfSize(2)
.All()
.With(h => h.Quality = new QualityModel())
.With(h => h.Languages = new List<Language> { Language.English })
.BuildListOfNew();
Db.InsertMany(movieFiles);
var movie = Builder<Movie>.CreateNew()
.With(e => e.MovieFileId = movieFiles.First().Id)
.BuildNew();
Db.Insert(movie);
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
Db.All<Movie>().Should().Contain(e => e.MovieFileId == movieFiles.First().Id);
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Disk;
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
{
WithoutRecycleBin();
var path = @"C:\Test\TV\30 Rock\S01E01.avi".AsOsAgnostic();
var path = @"C:\Test\Movie\The Mask (1994)\The Mask.avi".AsOsAgnostic();
Mocker.Resolve<RecycleBinProvider>().DeleteFile(path);
@ -40,11 +40,11 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
{
WithRecycleBin();
var path = @"C:\Test\TV\30 Rock\S01E01.avi".AsOsAgnostic();
var path = @"C:\Test\Movie\The Mask (1994)\The Mask.avi".AsOsAgnostic();
Mocker.Resolve<RecycleBinProvider>().DeleteFile(path);
Mocker.GetMock<IDiskTransferService>().Verify(v => v.TransferFile(path, @"C:\Test\Recycle Bin\S01E01.avi".AsOsAgnostic(), TransferMode.Move, false, true), Times.Once());
Mocker.GetMock<IDiskTransferService>().Verify(v => v.TransferFile(path, @"C:\Test\Recycle Bin\The Mask.avi".AsOsAgnostic(), TransferMode.Move, false, true), Times.Once());
}
[Test]
@ -52,15 +52,15 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
{
WithRecycleBin();
var path = @"C:\Test\TV\30 Rock\S01E01.avi".AsOsAgnostic();
var path = @"C:\Test\Movie\The Mask (1994)\The Mask.avi".AsOsAgnostic();
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.FileExists(@"C:\Test\Recycle Bin\S01E01.avi".AsOsAgnostic()))
.Setup(v => v.FileExists(@"C:\Test\Recycle Bin\The Mask.avi".AsOsAgnostic()))
.Returns(true);
Mocker.Resolve<RecycleBinProvider>().DeleteFile(path);
Mocker.GetMock<IDiskTransferService>().Verify(v => v.TransferFile(path, @"C:\Test\Recycle Bin\S01E01_2.avi".AsOsAgnostic(), TransferMode.Move, false, true), Times.Once());
Mocker.GetMock<IDiskTransferService>().Verify(v => v.TransferFile(path, @"C:\Test\Recycle Bin\The Mask_2.avi".AsOsAgnostic(), TransferMode.Move, false, true), Times.Once());
}
[Test]
@ -68,11 +68,23 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
{
WindowsOnly();
WithRecycleBin();
var path = @"C:\Test\TV\30 Rock\S01E01.avi".AsOsAgnostic();
var path = @"C:\Test\Movie\The Mask (1994)\The Mask.avi".AsOsAgnostic();
Mocker.Resolve<RecycleBinProvider>().DeleteFile(path);
Mocker.GetMock<IDiskProvider>().Verify(v => v.FileSetLastWriteTime(@"C:\Test\Recycle Bin\S01E01.avi".AsOsAgnostic(), It.IsAny<DateTime>()), Times.Once());
Mocker.GetMock<IDiskProvider>().Verify(v => v.FileSetLastWriteTime(@"C:\Test\Recycle Bin\The Mask.avi".AsOsAgnostic(), It.IsAny<DateTime>()), Times.Once());
}
[Test]
public void should_use_subfolder_when_passed_in()
{
WithRecycleBin();
var path = @"C:\Test\Movie\The Mask (1994)\The Mask.avi".AsOsAgnostic();
Mocker.Resolve<RecycleBinProvider>().DeleteFile(path, "The Mask (1994)");
Mocker.GetMock<IDiskTransferService>().Verify(v => v.TransferFile(path, @"C:\Test\Recycle Bin\The Mask (1994)\The Mask.avi".AsOsAgnostic(), TransferMode.Move, false, true), Times.Once());
}
}
}

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
@ -112,7 +113,8 @@ namespace NzbDrone.Core.Extras.Files
if (_diskProvider.FileExists(path))
{
// Send to the recycling bin so they can be recovered if necessary
_recycleBinProvider.DeleteFile(path);
var subfolder = _diskProvider.GetParentFolder(movie.Path).GetRelativePath(_diskProvider.GetParentFolder(path));
_recycleBinProvider.DeleteFile(path, subfolder);
}
}
}

View File

@ -0,0 +1,29 @@
using Dapper;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Housekeeping.Housekeepers
{
public class CleanupOrphanedMovieMovieFileIds : IHousekeepingTask
{
private readonly IMainDatabase _database;
public CleanupOrphanedMovieMovieFileIds(IMainDatabase database)
{
_database = database;
}
public void Clean()
{
using (var mapper = _database.OpenConnection())
{
mapper.Execute(@"UPDATE Movies
SET MovieFileId = 0
WHERE Id IN (
SELECT Movies.Id FROM Movies
LEFT OUTER JOIN MovieFiles
ON Movies.MovieFileId = MovieFiles.Id
WHERE MovieFiles.Id IS NULL)");
}
}
}
}

View File

@ -1,6 +1,7 @@
using System.IO;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaFiles.MovieImport;
using NzbDrone.Core.Parser.Model;
@ -40,7 +41,7 @@ namespace NzbDrone.Core.MediaFiles
_logger.Trace("Upgrading existing movie file.");
var moveFileResult = new MovieFileMoveResult();
var existingFile = localMovie.Movie.MovieFile;
var existingFile = localMovie.Movie.MovieFileId > 0 ? localMovie.Movie.MovieFile : null;
var rootFolder = _diskProvider.GetParentFolder(localMovie.Movie.Path);
@ -53,21 +54,18 @@ namespace NzbDrone.Core.MediaFiles
if (existingFile != null)
{
var movieFilePath = Path.Combine(localMovie.Movie.Path, existingFile.RelativePath);
var subfolder = rootFolder.GetRelativePath(_diskProvider.GetParentFolder(movieFilePath));
if (_diskProvider.FileExists(movieFilePath))
{
_logger.Debug("Removing existing movie file: {0}", existingFile);
_recycleBinProvider.DeleteFile(movieFilePath);
_recycleBinProvider.DeleteFile(movieFilePath, subfolder);
}
moveFileResult.OldFiles.Add(existingFile);
_mediaFileService.Delete(existingFile, DeleteMediaFileReason.Upgrade);
}
//Temporary for correctly getting path
localMovie.Movie.MovieFileId = 1;
localMovie.Movie.MovieFile = movieFile;
if (copyOnly)
{
moveFileResult.MovieFile = _movieFileMover.CopyMovieFile(movieFile, localMovie);
@ -77,10 +75,6 @@ namespace NzbDrone.Core.MediaFiles
moveFileResult.MovieFile = _movieFileMover.MoveMovieFile(movieFile, localMovie);
}
localMovie.Movie.MovieFileId = existingFile?.Id ?? 0;
localMovie.Movie.MovieFile = existingFile;
//_movieFileRenamer.RenameMoviePath(localMovie.Movie, false);
return moveFileResult;
}
}