covers are re-downloaded if remote size is different than
local size.
This commit is contained in:
parent
1d007be8fd
commit
e2d17ac109
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
@ -12,6 +13,8 @@ namespace NzbDrone.Common
|
||||||
string DownloadString(string address);
|
string DownloadString(string address);
|
||||||
string DownloadString(string address, string username, string password);
|
string DownloadString(string address, string username, string password);
|
||||||
string DownloadString(string address, ICredentials identity);
|
string DownloadString(string address, ICredentials identity);
|
||||||
|
Dictionary<string, string> DownloadHeader(string url);
|
||||||
|
|
||||||
Stream DownloadStream(string url, NetworkCredential credential = null);
|
Stream DownloadStream(string url, NetworkCredential credential = null);
|
||||||
void DownloadFile(string url, string fileName);
|
void DownloadFile(string url, string fileName);
|
||||||
string PostCommand(string address, string username, string password, string command);
|
string PostCommand(string address, string username, string password, string command);
|
||||||
|
@ -19,6 +22,9 @@ namespace NzbDrone.Common
|
||||||
|
|
||||||
public class HttpProvider : IHttpProvider
|
public class HttpProvider : IHttpProvider
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public const string ContentLenghtHeader = "Content-Length";
|
||||||
|
|
||||||
private readonly IEnvironmentProvider _environmentProvider;
|
private readonly IEnvironmentProvider _environmentProvider;
|
||||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
private readonly string _userAgent;
|
private readonly string _userAgent;
|
||||||
|
@ -54,6 +60,22 @@ namespace NzbDrone.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> DownloadHeader(string url)
|
||||||
|
{
|
||||||
|
var headers = new Dictionary<string, string>();
|
||||||
|
var request = WebRequest.Create(url);
|
||||||
|
request.Method = "HEAD";
|
||||||
|
|
||||||
|
var response = request.GetResponse();
|
||||||
|
|
||||||
|
foreach (var key in headers.Keys)
|
||||||
|
{
|
||||||
|
headers.Add(key, response.Headers[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
public Stream DownloadStream(string url, NetworkCredential credential = null)
|
public Stream DownloadStream(string url, NetworkCredential credential = null)
|
||||||
{
|
{
|
||||||
var request = (HttpWebRequest)WebRequest.Create(url);
|
var request = (HttpWebRequest)WebRequest.Create(url);
|
||||||
|
@ -70,7 +92,7 @@ namespace NzbDrone.Common
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var fileInfo = new FileInfo(fileName);
|
var fileInfo = new FileInfo(fileName);
|
||||||
if (!fileInfo.Directory.Exists)
|
if (fileInfo.Directory != null && !fileInfo.Directory.Exists)
|
||||||
{
|
{
|
||||||
fileInfo.Directory.Create();
|
fileInfo.Directory.Create();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace NzbDrone.Common
|
||||||
string[] GetDirectories(string path);
|
string[] GetDirectories(string path);
|
||||||
string[] GetFiles(string path, SearchOption searchOption);
|
string[] GetFiles(string path, SearchOption searchOption);
|
||||||
long GetDirectorySize(string path);
|
long GetDirectorySize(string path);
|
||||||
long GetSize(string path);
|
long GetFileSize(string path);
|
||||||
String CreateFolder(string path);
|
String CreateFolder(string path);
|
||||||
void CopyDirectory(string source, string target);
|
void CopyDirectory(string source, string target);
|
||||||
void MoveDirectory(string source, string destination);
|
void MoveDirectory(string source, string destination);
|
||||||
|
@ -131,7 +131,7 @@ namespace NzbDrone.Common
|
||||||
return GetFiles(path, SearchOption.AllDirectories).Sum(e => new FileInfo(e).Length);
|
return GetFiles(path, SearchOption.AllDirectories).Sum(e => new FileInfo(e).Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual long GetSize(string path)
|
public virtual long GetFileSize(string path)
|
||||||
{
|
{
|
||||||
Ensure.That(() => path).IsValidPath();
|
Ensure.That(() => path).IsValidPath();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.MediaCover;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.MediaCoverTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class CoverAlreadyExistsSpecificationFixture : CoreTest<CoverAlreadyExistsSpecification>
|
||||||
|
{
|
||||||
|
private Dictionary<string, string> _headers;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_headers = new Dictionary<string, string>();
|
||||||
|
Mocker.GetMock<IDiskProvider>().Setup(c => c.GetFileSize(It.IsAny<string>())).Returns(100);
|
||||||
|
Mocker.GetMock<IHttpProvider>().Setup(c => c.DownloadHeader(It.IsAny<string>())).Returns(_headers);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void GivenFileExistsOnDisk()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IDiskProvider>().Setup(c => c.FileExists(It.IsAny<string>())).Returns(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void GivenExistingFileSize(long bytes)
|
||||||
|
{
|
||||||
|
GivenFileExistsOnDisk();
|
||||||
|
Mocker.GetMock<IDiskProvider>().Setup(c => c.GetFileSize(It.IsAny<string>())).Returns(bytes);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_file_not_exists()
|
||||||
|
{
|
||||||
|
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_file_exists_but_diffrent_size()
|
||||||
|
{
|
||||||
|
GivenExistingFileSize(100);
|
||||||
|
_headers.Add(HttpProvider.ContentLenghtHeader, "200");
|
||||||
|
|
||||||
|
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_ture_if_file_exists_and_same_size()
|
||||||
|
{
|
||||||
|
GivenExistingFileSize(100);
|
||||||
|
_headers.Add(HttpProvider.ContentLenghtHeader, "100");
|
||||||
|
|
||||||
|
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[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().BeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -142,6 +142,7 @@
|
||||||
<Compile Include="JobTests\JobRepositoryFixture.cs" />
|
<Compile Include="JobTests\JobRepositoryFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\LanguageSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\LanguageSpecificationFixture.cs" />
|
||||||
<Compile Include="JobTests\TestJobs.cs" />
|
<Compile Include="JobTests\TestJobs.cs" />
|
||||||
|
<Compile Include="MediaCoverTests\CoverExistsSpecificationFixture.cs" />
|
||||||
<Compile Include="MediaCoverTests\MediaCoverServiceFixture.cs" />
|
<Compile Include="MediaCoverTests\MediaCoverServiceFixture.cs" />
|
||||||
<Compile Include="MediaFileTests\MediaFileTableCleanupServiceFixture.cs" />
|
<Compile Include="MediaFileTests\MediaFileTableCleanupServiceFixture.cs" />
|
||||||
<Compile Include="MediaFileTests\MediaFileRepositoryFixture.cs" />
|
<Compile Include="MediaFileTests\MediaFileRepositoryFixture.cs" />
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
_fileSize = size;
|
_fileSize = size;
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Setup(d => d.GetSize(It.IsAny<String>()))
|
.Setup(d => d.GetFileSize(It.IsAny<String>()))
|
||||||
.Returns(size);
|
.Returns(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
using NzbDrone.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaCover
|
||||||
|
{
|
||||||
|
public interface ICoverExistsSpecification
|
||||||
|
{
|
||||||
|
bool AlreadyExists(string url, string paht);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CoverAlreadyExistsSpecification : ICoverExistsSpecification
|
||||||
|
{
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly IHttpProvider _httpProvider;
|
||||||
|
|
||||||
|
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpProvider httpProvider)
|
||||||
|
{
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_httpProvider = httpProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AlreadyExists(string url, string path)
|
||||||
|
{
|
||||||
|
if (!_diskProvider.FileExists(path))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var headers = _httpProvider.DownloadHeader(url);
|
||||||
|
|
||||||
|
string sizeString = null;
|
||||||
|
|
||||||
|
if (headers.TryGetValue(HttpProvider.ContentLenghtHeader, out sizeString))
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
int.TryParse(sizeString, out size);
|
||||||
|
var fileSize = _diskProvider.GetFileSize(path);
|
||||||
|
|
||||||
|
if (fileSize != size)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,14 +14,17 @@ namespace NzbDrone.Core.MediaCover
|
||||||
{
|
{
|
||||||
private readonly IHttpProvider _httpProvider;
|
private readonly IHttpProvider _httpProvider;
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly ICoverExistsSpecification _coverExistsSpecification;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
private readonly string _coverRootFolder;
|
private readonly string _coverRootFolder;
|
||||||
|
|
||||||
public MediaCoverService(IHttpProvider httpProvider, IDiskProvider diskProvider, IEnvironmentProvider environmentProvider, Logger logger)
|
public MediaCoverService(IHttpProvider httpProvider, IDiskProvider diskProvider, IEnvironmentProvider environmentProvider,
|
||||||
|
ICoverExistsSpecification coverExistsSpecification, Logger logger)
|
||||||
{
|
{
|
||||||
_httpProvider = httpProvider;
|
_httpProvider = httpProvider;
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
|
_coverExistsSpecification = coverExistsSpecification;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
_coverRootFolder = environmentProvider.GetMediaCoverPath();
|
_coverRootFolder = environmentProvider.GetMediaCoverPath();
|
||||||
|
@ -37,7 +40,7 @@ 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);
|
||||||
if (!_diskProvider.FileExists(fileName))
|
if (!_coverExistsSpecification.AlreadyExists(cover.Url, fileName))
|
||||||
{
|
{
|
||||||
DownloadCover(series, cover);
|
DownloadCover(series, cover);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var size = _diskProvider.GetSize(filePath);
|
var size = _diskProvider.GetFileSize(filePath);
|
||||||
|
|
||||||
if (series.SeriesType == SeriesTypes.Daily || parsedEpisode.SeasonNumber > 0)
|
if (series.SeriesType == SeriesTypes.Daily || parsedEpisode.SeasonNumber > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace NzbDrone.Core.MetadataSource
|
||||||
|
|
||||||
var extension = Path.GetExtension(posterUrl);
|
var extension = Path.GetExtension(posterUrl);
|
||||||
var withoutExtension = posterUrl.Substring(0, posterUrl.Length - extension.Length);
|
var withoutExtension = posterUrl.Substring(0, posterUrl.Length - extension.Length);
|
||||||
return withoutExtension + "-138" + extension;
|
return withoutExtension + "-300" + extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SeriesStatusType GetSeriesStatus(string status)
|
private static SeriesStatusType GetSeriesStatus(string status)
|
||||||
|
|
|
@ -249,6 +249,7 @@
|
||||||
<Compile Include="Indexers\RssSyncCommand.cs" />
|
<Compile Include="Indexers\RssSyncCommand.cs" />
|
||||||
<Compile Include="Jobs\TaskManager.cs" />
|
<Compile Include="Jobs\TaskManager.cs" />
|
||||||
<Compile Include="Lifecycle\ApplicationShutdownRequested.cs" />
|
<Compile Include="Lifecycle\ApplicationShutdownRequested.cs" />
|
||||||
|
<Compile Include="MediaCover\CoverAlreadyExistsSpecification.cs" />
|
||||||
<Compile Include="MediaFiles\Commands\CleanMediaFileDb.cs" />
|
<Compile Include="MediaFiles\Commands\CleanMediaFileDb.cs" />
|
||||||
<Compile Include="MediaFiles\Commands\CleanUpRecycleBinCommand.cs" />
|
<Compile Include="MediaFiles\Commands\CleanUpRecycleBinCommand.cs" />
|
||||||
<Compile Include="MediaFiles\Commands\DownloadedEpisodesScanCommand.cs" />
|
<Compile Include="MediaFiles\Commands\DownloadedEpisodesScanCommand.cs" />
|
||||||
|
|
Loading…
Reference in New Issue