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

pull/3113/head
Taloth Saldono 10 years ago
parent 754c1ea331
commit b3f11564a7

@ -26,6 +26,14 @@ namespace NzbDrone.Core.Test.MediaCoverTests
Mocker.GetMock<IDiskProvider>() Mocker.GetMock<IDiskProvider>()
.Setup(v => v.OpenWriteStream(It.IsAny<string>())) .Setup(v => v.OpenWriteStream(It.IsAny<string>()))
.Returns<string>(s => new FileStream(s, FileMode.Create)); .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] [Test]
@ -46,5 +54,18 @@ namespace NzbDrone.Core.Test.MediaCoverTests
image.Height.Should().Be(170); image.Height.Should().Be(170);
image.Width.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();
}
} }
} }

@ -11,6 +11,7 @@ using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events; using NzbDrone.Core.Tv.Events;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.MediaCoverTests namespace NzbDrone.Core.Test.MediaCoverTests
{ {
@ -110,10 +111,55 @@ namespace NzbDrone.Core.Test.MediaCoverTests
.Setup(v => v.FileExists(It.IsAny<string>())) .Setup(v => v.FileExists(It.IsAny<string>()))
.Returns(true); .Returns(true);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.GetFileSize(It.IsAny<string>()))
.Returns(1000);
Subject.HandleAsync(new SeriesUpdatedEvent(_series)); Subject.HandleAsync(new SeriesUpdatedEvent(_series));
Mocker.GetMock<IImageResizer>() Mocker.GetMock<IImageResizer>()
.Verify(v => v.Resize(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.Never()); .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);
}
} }
} }

@ -22,18 +22,29 @@ namespace NzbDrone.Core.MediaCover
public void Resize(string source, string destination, int height) 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(); using (var outputStream = _diskProvider.OpenWriteStream(destination))
settings.Height = height; {
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;
}
} }
} }
} }

@ -88,16 +88,13 @@ namespace NzbDrone.Core.MediaCover
foreach (var cover in series.Images) foreach (var cover in series.Images)
{ {
var fileName = GetCoverPath(series.Id, cover.CoverType); var fileName = GetCoverPath(series.Id, cover.CoverType);
var alreadyExists = false;
try try
{ {
if (!_coverExistsSpecification.AlreadyExists(cover.Url, fileName)) alreadyExists = _coverExistsSpecification.AlreadyExists(cover.Url, fileName);
if (!alreadyExists)
{ {
DownloadCover(series, cover); DownloadCover(series, cover);
EnsureResizedCovers(series, cover, true);
}
else
{
EnsureResizedCovers(series, cover, false);
} }
} }
catch (WebException e) catch (WebException e)
@ -108,6 +105,15 @@ namespace NzbDrone.Core.MediaCover
{ {
_logger.ErrorException("Couldn't download media cover for " + series, e); _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 mainFileName = GetCoverPath(series.Id, cover.CoverType);
var resizeFileName = GetCoverPath(series.Id, cover.CoverType, height); 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); _logger.Debug("Resizing {0}-{1} for {2}", cover.CoverType, height, series);

Loading…
Cancel
Save