Fixed: No longer leaves a corrupt file if MediaCover resize failed.

This commit is contained in:
Taloth Saldono 2015-02-03 20:46:51 +01:00
parent 754c1ea331
commit b3f11564a7
4 changed files with 97 additions and 13 deletions

View File

@ -26,6 +26,14 @@ namespace NzbDrone.Core.Test.MediaCoverTests
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.OpenWriteStream(It.IsAny<string>()))
.Returns<string>(s => new FileStream(s, FileMode.Create));
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.FileExists(It.IsAny<string>()))
.Returns<string>(s => File.Exists(s));
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.DeleteFile(It.IsAny<string>()))
.Callback<string>(s => File.Delete(s));
}
[Test]
@ -46,5 +54,18 @@ namespace NzbDrone.Core.Test.MediaCoverTests
image.Height.Should().Be(170);
image.Width.Should().Be(170);
}
[Test]
public void should_delete_file_if_failed()
{
var mainFile = Path.Combine(TempFolder, "junk.png");
var resizedFile = Path.Combine(TempFolder, "junk-170.png");
File.WriteAllText(mainFile, "Just some junk data that should make it throw an Exception.");
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.Resize(mainFile, resizedFile, 170));
File.Exists(resizedFile).Should().BeFalse();
}
}
}

View File

@ -11,6 +11,7 @@ using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.MediaCoverTests
{
@ -110,10 +111,55 @@ namespace NzbDrone.Core.Test.MediaCoverTests
.Setup(v => v.FileExists(It.IsAny<string>()))
.Returns(true);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.GetFileSize(It.IsAny<string>()))
.Returns(1000);
Subject.HandleAsync(new SeriesUpdatedEvent(_series));
Mocker.GetMock<IImageResizer>()
.Verify(v => v.Resize(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.Never());
}
[Test]
public void should_resize_covers_if_existing_is_empty()
{
Mocker.GetMock<ICoverExistsSpecification>()
.Setup(v => v.AlreadyExists(It.IsAny<string>(), It.IsAny<string>()))
.Returns(true);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.FileExists(It.IsAny<string>()))
.Returns(true);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.GetFileSize(It.IsAny<string>()))
.Returns(0);
Subject.HandleAsync(new SeriesUpdatedEvent(_series));
Mocker.GetMock<IImageResizer>()
.Verify(v => v.Resize(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.Exactly(2));
}
[Test]
public void should_log_error_if_resize_failed()
{
Mocker.GetMock<ICoverExistsSpecification>()
.Setup(v => v.AlreadyExists(It.IsAny<string>(), It.IsAny<string>()))
.Returns(true);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.FileExists(It.IsAny<string>()))
.Returns(false);
Mocker.GetMock<IImageResizer>()
.Setup(v => v.Resize(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()))
.Throws<ApplicationException>();
Subject.HandleAsync(new SeriesUpdatedEvent(_series));
ExceptionVerification.ExpectedErrors(1);
}
}
}

View File

@ -22,18 +22,29 @@ namespace NzbDrone.Core.MediaCover
public void Resize(string source, string destination, int height)
{
using (var sourceStream = _diskProvider.OpenReadStream(source))
try
{
using (var outputStream = _diskProvider.OpenWriteStream(destination))
using (var sourceStream = _diskProvider.OpenReadStream(source))
{
var settings = new Instructions();
settings.Height = height;
using (var outputStream = _diskProvider.OpenWriteStream(destination))
{
var settings = new Instructions();
settings.Height = height;
var job = new ImageJob(sourceStream, outputStream, settings);
var job = new ImageJob(sourceStream, outputStream, settings);
ImageBuilder.Current.Build(job);
ImageBuilder.Current.Build(job);
}
}
}
catch
{
if (_diskProvider.FileExists(destination))
{
_diskProvider.DeleteFile(destination);
}
throw;
}
}
}
}

View File

@ -88,16 +88,13 @@ namespace NzbDrone.Core.MediaCover
foreach (var cover in series.Images)
{
var fileName = GetCoverPath(series.Id, cover.CoverType);
var alreadyExists = false;
try
{
if (!_coverExistsSpecification.AlreadyExists(cover.Url, fileName))
alreadyExists = _coverExistsSpecification.AlreadyExists(cover.Url, fileName);
if (!alreadyExists)
{
DownloadCover(series, cover);
EnsureResizedCovers(series, cover, true);
}
else
{
EnsureResizedCovers(series, cover, false);
}
}
catch (WebException e)
@ -108,6 +105,15 @@ namespace NzbDrone.Core.MediaCover
{
_logger.ErrorException("Couldn't download media cover for " + series, e);
}
try
{
EnsureResizedCovers(series, cover, !alreadyExists);
}
catch (Exception e)
{
_logger.ErrorException("Couldn't resize media cover for " + series + " using full size image instead.", e);
}
}
}
@ -148,7 +154,7 @@ namespace NzbDrone.Core.MediaCover
var mainFileName = GetCoverPath(series.Id, cover.CoverType);
var resizeFileName = GetCoverPath(series.Id, cover.CoverType, height);
if (forceResize || !_diskProvider.FileExists(resizeFileName))
if (forceResize || !_diskProvider.FileExists(resizeFileName) || _diskProvider.GetFileSize(resizeFileName) == 0)
{
_logger.Debug("Resizing {0}-{1} for {2}", cover.CoverType, height, series);