mirror of https://github.com/Radarr/Radarr
Fix: Successful downloads that are not moved properly should be retried.
This commit is contained in:
parent
5650f891ee
commit
c0d1d2c502
|
@ -212,5 +212,104 @@ namespace NzbDrone.Core.Test.ProviderTests
|
|||
//Assert
|
||||
result.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanUpDropFolder_should_do_nothing_if_no_files_are_found()
|
||||
{
|
||||
//Setup
|
||||
var folder = @"C:\Test\DropDir\The Office";
|
||||
|
||||
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
|
||||
.Returns(new string[0]);
|
||||
|
||||
//Act
|
||||
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
|
||||
|
||||
//Assert
|
||||
Mocker.GetMock<MediaFileProvider>().Verify(v => v.GetFileByPath(It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanUpDropFolder_should_do_nothing_if_no_conflicting_files_are_found()
|
||||
{
|
||||
//Setup
|
||||
var folder = @"C:\Test\DropDir\The Office";
|
||||
var filename = Path.Combine(folder, "NotAProblem.avi");
|
||||
|
||||
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||
.With(f => f.Path = filename.NormalizePath())
|
||||
.With(f => f.SeriesId = 12345)
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
|
||||
.Returns(new string[] { filename });
|
||||
|
||||
Mocker.GetMock<MediaFileProvider>().Setup(s => s.GetFileByPath(filename))
|
||||
.Returns(() => null);
|
||||
|
||||
//Act
|
||||
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
|
||||
|
||||
//Assert
|
||||
Mocker.GetMock<MediaFileProvider>().Verify(v => v.GetFileByPath(filename), Times.Once());
|
||||
Mocker.GetMock<SeriesProvider>().Verify(v => v.GetSeries(It.IsAny<int>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanUpDropFolder_should_move_file_if_a_conflict_is_found()
|
||||
{
|
||||
//Setup
|
||||
var folder = @"C:\Test\DropDir\The Office";
|
||||
var filename = Path.Combine(folder, "Problem.avi");
|
||||
var seriesId = 12345;
|
||||
var newFilename = "S01E01 - Title";
|
||||
var newFilePath = @"C:\Test\TV\The Office\Season 01\S01E01 - Title.avi";
|
||||
|
||||
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||
.With(f => f.Path = filename.NormalizePath())
|
||||
.With(f => f.SeriesId = seriesId)
|
||||
.Build();
|
||||
|
||||
var series = Builder<Series>.CreateNew()
|
||||
.With(s => s.SeriesId = seriesId)
|
||||
.With(s => s.Title = "The Office")
|
||||
.Build();
|
||||
|
||||
var episode = Builder<Episode>.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(e => e.SeriesId = seriesId)
|
||||
.With(e => e.EpisodeFileId = episodeFile.EpisodeFileId)
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<MediaFileProvider>().Setup(v => v.GetFileByPath(filename))
|
||||
.Returns(() => null);
|
||||
|
||||
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
|
||||
.Returns(new string[] { filename });
|
||||
|
||||
Mocker.GetMock<MediaFileProvider>().Setup(s => s.GetFileByPath(filename))
|
||||
.Returns(episodeFile);
|
||||
|
||||
Mocker.GetMock<SeriesProvider>().Setup(s => s.GetSeries(It.IsAny<int>()))
|
||||
.Returns(series);
|
||||
|
||||
Mocker.GetMock<EpisodeProvider>().Setup(s => s.GetEpisodesByFileId(episodeFile.EpisodeFileId))
|
||||
.Returns(episode);
|
||||
|
||||
Mocker.GetMock<MediaFileProvider>().Setup(s => s.GetNewFilename(It.IsAny<IList<Episode>>(), series.Title, QualityTypes.Unknown, false))
|
||||
.Returns(newFilename);
|
||||
|
||||
Mocker.GetMock<MediaFileProvider>().Setup(s => s.CalculateFilePath(It.IsAny<Series>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(new FileInfo(newFilePath));
|
||||
|
||||
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveFile(episodeFile.Path, newFilePath));
|
||||
|
||||
//Act
|
||||
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
|
||||
|
||||
//Assert
|
||||
Mocker.GetMock<MediaFileProvider>().Verify(v => v.GetFileByPath(filename), Times.Once());
|
||||
Mocker.GetMock<DiskProvider>().Verify(v => v.MoveFile(filename.NormalizePath(), newFilePath), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,5 +158,40 @@ namespace NzbDrone.Core.Test.ProviderTests
|
|||
result.Should().HaveCount(9);
|
||||
result.Should().NotContain(e => e.EpisodeFileId == 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetFileByPath_should_return_null_if_file_does_not_exist_in_database()
|
||||
{
|
||||
//Setup
|
||||
WithRealDb();
|
||||
|
||||
//Act
|
||||
var result = Mocker.Resolve<MediaFileProvider>().GetFileByPath(@"C:\Test\EpisodeFile.avi");
|
||||
|
||||
//Resolve
|
||||
result.Should().BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetFileByPath_should_return_EpisodeFile_if_file_exists_in_database()
|
||||
{
|
||||
var path = @"C:\Test\EpisodeFile.avi";
|
||||
|
||||
//Setup
|
||||
WithRealDb();
|
||||
var episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||
.With(f => f.Path = path.NormalizePath())
|
||||
.Build();
|
||||
|
||||
var episodeFileId = Convert.ToInt32(Db.Insert(episodeFile));
|
||||
|
||||
//Act
|
||||
var result = Mocker.Resolve<MediaFileProvider>().GetFileByPath(path);
|
||||
|
||||
//Resolve
|
||||
result.Should().NotBeNull();
|
||||
result.Path.Should().Be(path.NormalizePath());
|
||||
result.EpisodeFileId.Should().Be(episodeFileId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -279,6 +279,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
|
|||
.Build().ToList();
|
||||
|
||||
Mocker.GetMock<SeriesProvider>().Setup(s => s.FindSeries("office")).Returns(fakeSeries);
|
||||
Mocker.GetMock<DiskScanProvider>().Setup(s => s.CleanUpDropFolder(droppedFolder.FullName));
|
||||
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles);
|
||||
Mocker.GetMock<DiskScanProvider>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(true);
|
||||
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize - 1.Megabytes());
|
||||
|
|
|
@ -253,6 +253,33 @@ namespace NzbDrone.Core.Providers
|
|||
}
|
||||
}
|
||||
|
||||
public virtual void CleanUpDropFolder(string path)
|
||||
{
|
||||
//Todo: We should rename files before importing them to prevent this issue from ever happening
|
||||
|
||||
var filesOnDisk = GetVideoFiles(path);
|
||||
|
||||
foreach(var file in filesOnDisk)
|
||||
{
|
||||
try
|
||||
{
|
||||
var episodeFile = _mediaFileProvider.GetFileByPath(file);
|
||||
|
||||
if (episodeFile != null)
|
||||
{
|
||||
Logger.Trace("[{0}] was imported but not moved, moving it now", file);
|
||||
|
||||
MoveEpisodeFile(episodeFile);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WarnException("Failed to move epiosde file from drop folder: " + file, ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> GetVideoFiles(string path)
|
||||
{
|
||||
|
|
|
@ -52,6 +52,11 @@ namespace NzbDrone.Core.Providers
|
|||
return _database.Exists<EpisodeFile>("WHERE Path =@0", path.NormalizePath());
|
||||
}
|
||||
|
||||
public virtual EpisodeFile GetFileByPath(string path)
|
||||
{
|
||||
return _database.SingleOrDefault<EpisodeFile>("WHERE Path =@0", path.NormalizePath());
|
||||
}
|
||||
|
||||
public virtual EpisodeFile GetEpisodeFile(int episodeFileId)
|
||||
{
|
||||
return _database.Single<EpisodeFile>(episodeFileId);
|
||||
|
@ -133,7 +138,7 @@ namespace NzbDrone.Core.Providers
|
|||
|
||||
if (updated > 0)
|
||||
{
|
||||
Logger.Debug("Removed {0} orphan file(s) from database.S", updated);
|
||||
Logger.Debug("Removed {0} orphan file(s) from database.", updated);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ namespace NzbDrone.Core.Providers
|
|||
return;
|
||||
}
|
||||
|
||||
_diskScanProvider.CleanUpDropFolder(subfolderInfo.FullName);
|
||||
|
||||
var importedFiles = _diskScanProvider.Scan(series, subfolderInfo.FullName);
|
||||
importedFiles.ForEach(file => _diskScanProvider.MoveEpisodeFile(file, true));
|
||||
|
||||
|
|
Loading…
Reference in New Issue