Fixed: Don't download artist images if match existing (#362)

* Fixed: Don't download artist images if existing exists

* fixup: Wrap FileSetWriteTime in try

* fixup! Tests and Rework
pull/6/head
Qstick 6 years ago committed by GitHub
parent 2969decf95
commit 73157534e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -117,6 +117,18 @@ namespace NzbDrone.Common.Http
}
}
public DateTime? LastModified
{
get
{
return GetSingleValue("Last-Modified", Convert.ToDateTime);
}
set
{
SetSingleValue("Last-Modified", value);
}
}
public new IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
return AllKeys.SelectMany(GetValues, (k, c) => new KeyValuePair<string, string>(k, c)).ToList().GetEnumerator();

@ -1,72 +1,51 @@
using System.Net;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Http;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Test.Framework;
using System;
namespace NzbDrone.Core.Test.MediaCoverTests
{
[TestFixture]
public class CoverAlreadyExistsSpecificationFixture : CoreTest<CoverAlreadyExistsSpecification>
{
private HttpResponse _httpResponse;
[SetUp]
public void Setup()
{
_httpResponse = new HttpResponse(null, new HttpHeader(), "", HttpStatusCode.OK);
Mocker.GetMock<IDiskProvider>().Setup(c => c.GetFileSize(It.IsAny<string>())).Returns(100);
Mocker.GetMock<IHttpClient>().Setup(c => c.Head(It.IsAny<HttpRequest>())).Returns(_httpResponse);
}
private void GivenFileExistsOnDisk()
{
Mocker.GetMock<IDiskProvider>().Setup(c => c.FileExists(It.IsAny<string>())).Returns(true);
}
private void GivenExistingFileSize(long bytes)
private void GivenExistingFileDate(DateTime lastModifiedDate)
{
GivenFileExistsOnDisk();
Mocker.GetMock<IDiskProvider>().Setup(c => c.GetFileSize(It.IsAny<string>())).Returns(bytes);
Mocker.GetMock<IDiskProvider>().Setup(c => c.FileGetLastWrite(It.IsAny<string>())).Returns(lastModifiedDate);
}
[Test]
public void should_return_false_if_file_not_exists()
{
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse();
Subject.AlreadyExists(DateTime.Now, "c:\\file.exe").Should().BeFalse();
}
[Test]
public void should_return_false_if_file_exists_but_diffrent_size()
public void should_return_false_if_file_exists_but_diffrent_date()
{
GivenExistingFileSize(100);
_httpResponse.Headers.ContentLength = 200;
GivenExistingFileDate(DateTime.Now);
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse();
Subject.AlreadyExists(DateTime.Now.AddHours(-5), "c:\\file.exe").Should().BeFalse();
}
[Test]
public void should_return_ture_if_file_exists_and_same_size()
public void should_return_ture_if_file_exists_and_same_date()
{
GivenExistingFileSize(100);
_httpResponse.Headers.ContentLength = 100;
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeTrue();
}
var givenDate = DateTime.Now;
[Test]
public void should_return_true_if_there_is_no_size_header_and_file_exist()
{
GivenExistingFileSize(100);
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse();
GivenExistingFileDate(givenDate);
Subject.AlreadyExists(givenDate, "c:\\file.exe").Should().BeTrue();
}
}
}
}

@ -7,6 +7,7 @@ using Moq;
using NUnit.Framework;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Http;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Music;
@ -19,6 +20,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
{
Artist _artist;
Album _album;
private HttpResponse _httpResponse;
[SetUp]
public void Setup()
@ -34,6 +36,9 @@ namespace NzbDrone.Core.Test.MediaCoverTests
.With(v => v.Id = 4)
.With(v => v.Images = new List<MediaCover.MediaCover> { new MediaCover.MediaCover(MediaCoverTypes.Cover, "") })
.Build();
_httpResponse = new HttpResponse(null, new HttpHeader(), "");
Mocker.GetMock<IHttpClient>().Setup(c => c.Head(It.IsAny<HttpRequest>())).Returns(_httpResponse);
}
[Test]
@ -95,7 +100,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
public void should_resize_covers_if_main_downloaded()
{
Mocker.GetMock<ICoverExistsSpecification>()
.Setup(v => v.AlreadyExists(It.IsAny<string>(), It.IsAny<string>()))
.Setup(v => v.AlreadyExists(It.IsAny<DateTime>(), It.IsAny<string>()))
.Returns(false);
Mocker.GetMock<IDiskProvider>()
@ -112,7 +117,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
public void should_resize_covers_if_missing()
{
Mocker.GetMock<ICoverExistsSpecification>()
.Setup(v => v.AlreadyExists(It.IsAny<string>(), It.IsAny<string>()))
.Setup(v => v.AlreadyExists(It.IsAny<DateTime>(), It.IsAny<string>()))
.Returns(true);
Mocker.GetMock<IDiskProvider>()
@ -129,7 +134,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
public void should_not_resize_covers_if_exists()
{
Mocker.GetMock<ICoverExistsSpecification>()
.Setup(v => v.AlreadyExists(It.IsAny<string>(), It.IsAny<string>()))
.Setup(v => v.AlreadyExists(It.IsAny<DateTime>(), It.IsAny<string>()))
.Returns(true);
Mocker.GetMock<IDiskProvider>()
@ -150,7 +155,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
public void should_resize_covers_if_existing_is_empty()
{
Mocker.GetMock<ICoverExistsSpecification>()
.Setup(v => v.AlreadyExists(It.IsAny<string>(), It.IsAny<string>()))
.Setup(v => v.AlreadyExists(It.IsAny<DateTime>(), It.IsAny<string>()))
.Returns(true);
Mocker.GetMock<IDiskProvider>()
@ -171,7 +176,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
public void should_log_error_if_resize_failed()
{
Mocker.GetMock<ICoverExistsSpecification>()
.Setup(v => v.AlreadyExists(It.IsAny<string>(), It.IsAny<string>()))
.Setup(v => v.AlreadyExists(It.IsAny<DateTime>(), It.IsAny<string>()))
.Returns(true);
Mocker.GetMock<IDiskProvider>()

@ -1,34 +1,32 @@
using NzbDrone.Common.Disk;
using NzbDrone.Common.Http;
using System;
using NzbDrone.Common.Disk;
namespace NzbDrone.Core.MediaCover
{
public interface ICoverExistsSpecification
{
bool AlreadyExists(string url, string path);
bool AlreadyExists(DateTime serverModifiedDate, string localPath);
}
public class CoverAlreadyExistsSpecification : ICoverExistsSpecification
{
private readonly IDiskProvider _diskProvider;
private readonly IHttpClient _httpClient;
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpClient httpClient)
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider)
{
_diskProvider = diskProvider;
_httpClient = httpClient;
}
public bool AlreadyExists(string url, string path)
public bool AlreadyExists(DateTime lastModifiedDateServer, string localPath)
{
if (!_diskProvider.FileExists(path))
if (!_diskProvider.FileExists(localPath))
{
return false;
}
var headers = _httpClient.Head(new HttpRequest(url)).Headers;
var fileSize = _diskProvider.GetFileSize(path);
return fileSize == headers.ContentLength;
DateTime? lastModifiedLocal = _diskProvider.FileGetLastWrite(localPath);
return lastModifiedLocal.Value.ToUniversalTime() == lastModifiedDateServer.ToUniversalTime();
}
}
}
}

@ -109,12 +109,16 @@ namespace NzbDrone.Core.MediaCover
{
var fileName = GetCoverPath(artist.Id, cover.CoverType);
var alreadyExists = false;
try
{
alreadyExists = _coverExistsSpecification.AlreadyExists(cover.Url, fileName);
var lastModifiedServer = GetCoverModifiedDate(cover.Url);
alreadyExists = _coverExistsSpecification.AlreadyExists(lastModifiedServer, fileName);
if (!alreadyExists)
{
DownloadCover(artist, cover);
DownloadCover(artist, cover, lastModifiedServer);
}
}
catch (WebException e)
@ -130,48 +134,58 @@ namespace NzbDrone.Core.MediaCover
}
}
private void EnsureAlbumCovers(Album album)
{
foreach (var cover in album.Images)
{
var fileName = GetCoverPath(album.ArtistId, cover.CoverType, null, album.Id);
var alreadyExists = false;
try
{
alreadyExists = _coverExistsSpecification.AlreadyExists(cover.Url, fileName);
if (!alreadyExists)
{
DownloadAlbumCover(album, cover);
}
}
catch (WebException e)
{
_logger.Warn("Couldn't download media cover for {0}. {1}", album, e.Message);
}
catch (Exception e)
{
_logger.Error(e, "Couldn't download media cover for {0}", album);
}
EnsureResizedCovers(album.Artist, cover, !alreadyExists, album);
}
}
private void DownloadCover(Artist artist, MediaCover cover)
//TODO Decide if we want to cache album art local
//private void EnsureAlbumCovers(Album album)
//{
// foreach (var cover in album.Images)
// {
// var fileName = GetCoverPath(album.ArtistId, cover.CoverType, null, album.Id);
// var alreadyExists = false;
// try
// {
// alreadyExists = _coverExistsSpecification.AlreadyExists(cover.Url, fileName);
// if (!alreadyExists)
// {
// DownloadAlbumCover(album, cover);
// }
// }
// catch (WebException e)
// {
// _logger.Warn("Couldn't download media cover for {0}. {1}", album, e.Message);
// }
// catch (Exception e)
// {
// _logger.Error(e, "Couldn't download media cover for {0}", album);
// }
// EnsureResizedCovers(album.Artist, cover, !alreadyExists, album);
// }
//}
private void DownloadCover(Artist artist, MediaCover cover, DateTime lastModified)
{
var fileName = GetCoverPath(artist.Id, cover.CoverType);
_logger.Info("Downloading {0} for {1} {2}", cover.CoverType, artist, cover.Url);
_httpClient.DownloadFile(cover.Url, fileName);
try
{
_diskProvider.FileSetLastWriteTime(fileName, lastModified);
}
catch (Exception ex)
{
_logger.Debug(ex, "Unable to set modified date for {0} image for artist {1}", cover.CoverType, artist);
}
}
private void DownloadAlbumCover(Album album, MediaCover cover)
{
var fileName = GetCoverPath(album.ArtistId, cover.CoverType, null, album.Id);
//private void DownloadAlbumCover(Album album, MediaCover cover)
//{
// var fileName = GetCoverPath(album.ArtistId, cover.CoverType, null, album.Id);
_logger.Info("Downloading {0} for {1} {2}", cover.CoverType, album, cover.Url);
_httpClient.DownloadFile(cover.Url, fileName);
}
// _logger.Info("Downloading {0} for {1} {2}", cover.CoverType, album, cover.Url);
// _httpClient.DownloadFile(cover.Url, fileName);
//}
private void EnsureResizedCovers(Artist artist, MediaCover cover, bool forceResize, Album album = null)
{
@ -270,5 +284,19 @@ namespace NzbDrone.Core.MediaCover
_diskProvider.DeleteFolder(path, true);
}
}
private DateTime GetCoverModifiedDate(string url)
{
var lastModifiedServer = DateTime.Now;
var headers = _httpClient.Head(new HttpRequest(url)).Headers;
if (headers.LastModified.HasValue)
{
lastModifiedServer = headers.LastModified.Value;
}
return lastModifiedServer;
}
}
}

Loading…
Cancel
Save