mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-10-30 15:32:31 +01:00
HttpClient
This commit is contained in:
parent
3a287bf7e7
commit
2c1d3339d0
@ -9,13 +9,10 @@ namespace NzbDrone.Api.Update
|
||||
public class UpdateModule : NzbDroneRestModule<UpdateResource>
|
||||
{
|
||||
private readonly IRecentUpdateProvider _recentUpdateProvider;
|
||||
private readonly IInstallUpdates _installUpdateService;
|
||||
|
||||
public UpdateModule(IRecentUpdateProvider recentUpdateProvider,
|
||||
IInstallUpdates installUpdateService)
|
||||
public UpdateModule(IRecentUpdateProvider recentUpdateProvider)
|
||||
{
|
||||
_recentUpdateProvider = recentUpdateProvider;
|
||||
_installUpdateService = installUpdateService;
|
||||
GetResourceAll = GetRecentUpdates;
|
||||
}
|
||||
|
||||
|
85
src/NzbDrone.Common.Test/Http/HttpClientFixture.cs
Normal file
85
src/NzbDrone.Common.Test/Http/HttpClientFixture.cs
Normal file
@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Test.Common.Categories;
|
||||
|
||||
namespace NzbDrone.Common.Test.Http
|
||||
{
|
||||
[TestFixture]
|
||||
[IntegrationTest]
|
||||
public class RestClientFixture : TestBase<HttpClient>
|
||||
{
|
||||
[Test]
|
||||
public void should_execute_simple_get()
|
||||
{
|
||||
var request = new HttpRequest("http://eu.httpbin.org/get");
|
||||
|
||||
var response = Subject.Execute(request);
|
||||
|
||||
response.Content.Should().NotBeNullOrWhiteSpace();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_execute_typed_get()
|
||||
{
|
||||
var request = new HttpRequest("http://eu.httpbin.org/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Url.Should().Be(request.Url.ToString());
|
||||
}
|
||||
|
||||
[TestCase("gzip")]
|
||||
public void should_execute_get_using_gzip(string compression)
|
||||
{
|
||||
var request = new HttpRequest("http://eu.httpbin.org/" + compression);
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers["Accept-Encoding"].ToString().Should().Be(compression);
|
||||
response.Headers.ContentLength.Should().BeLessOrEqualTo(response.Content.Length);
|
||||
}
|
||||
|
||||
[TestCase(HttpStatusCode.Unauthorized)]
|
||||
[TestCase(HttpStatusCode.Forbidden)]
|
||||
[TestCase(HttpStatusCode.NotFound)]
|
||||
[TestCase(HttpStatusCode.InternalServerError)]
|
||||
[TestCase(HttpStatusCode.ServiceUnavailable)]
|
||||
[TestCase(HttpStatusCode.BadGateway)]
|
||||
public void should_throw_on_unsuccessful_status_codes(HttpStatusCode statusCode)
|
||||
{
|
||||
var request = new HttpRequest("http://eu.httpbin.org/status/" + (int)statusCode);
|
||||
|
||||
var exception = Assert.Throws<HttpException>(() => Subject.Get<HttpBinResource>(request));
|
||||
|
||||
exception.Response.StatusCode.Should().Be(statusCode);
|
||||
}
|
||||
|
||||
|
||||
[TestCase(HttpStatusCode.Moved)]
|
||||
[TestCase(HttpStatusCode.MovedPermanently)]
|
||||
public void should_not_follow_redirects_when_not_in_production(HttpStatusCode statusCode)
|
||||
{
|
||||
var request = new HttpRequest("http://eu.httpbin.org/status/" + (int)statusCode);
|
||||
|
||||
Assert.Throws<Exception>(() => Subject.Get<HttpBinResource>(request));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class HttpBinResource
|
||||
{
|
||||
public Dictionary<string, object> Headers { get; set; }
|
||||
public string Origin { get; set; }
|
||||
public string Url { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
22
src/NzbDrone.Common.Test/Http/HttpRequestBuilderFixture.cs
Normal file
22
src/NzbDrone.Common.Test/Http/HttpRequestBuilderFixture.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Common.Test.Http
|
||||
{
|
||||
[TestFixture]
|
||||
public class HttpRequestBuilderFixture : TestBase
|
||||
{
|
||||
[Test]
|
||||
public void should_remove_duplicated_slashes()
|
||||
{
|
||||
var builder = new HttpRequestBuilder("http://domain/");
|
||||
|
||||
var request = builder.Build("/v1/");
|
||||
|
||||
request.Url.ToString().Should().Be("http://domain/v1/");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
29
src/NzbDrone.Common.Test/Http/HttpRequestFixture.cs
Normal file
29
src/NzbDrone.Common.Test/Http/HttpRequestFixture.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
|
||||
namespace NzbDrone.Common.Test.Http
|
||||
{
|
||||
[TestFixture]
|
||||
public class HttpRequestFixture
|
||||
{
|
||||
[TestCase("http://host/{seg}/some", "http://host/dir/some")]
|
||||
[TestCase("http://host/some/{seg}", "http://host/some/dir")]
|
||||
public void should_add_single_segment_url_segments(string url, string result)
|
||||
{
|
||||
var request = new HttpRequest(url);
|
||||
|
||||
request.AddSegment("seg", "dir");
|
||||
|
||||
request.Url.Should().Be(result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void shouldnt_add_value_for_nonexisting_segment()
|
||||
{
|
||||
var request = new HttpRequest("http://host/{seg}/some");
|
||||
Assert.Throws<InvalidOperationException>(() => request.AddSegment("seg2", "dir"));
|
||||
}
|
||||
}
|
||||
}
|
@ -73,6 +73,9 @@
|
||||
<Compile Include="EnvironmentProviderTest.cs" />
|
||||
<Compile Include="EnvironmentTests\EnvironmentProviderTest.cs" />
|
||||
<Compile Include="EnvironmentTests\StartupArgumentsFixture.cs" />
|
||||
<Compile Include="Http\HttpClientFixture.cs" />
|
||||
<Compile Include="Http\HttpRequestBuilderFixture.cs" />
|
||||
<Compile Include="Http\HttpRequestFixture.cs" />
|
||||
<Compile Include="InstrumentationTests\CleanseLogMessageFixture.cs" />
|
||||
<Compile Include="LevenshteinDistanceFixture.cs" />
|
||||
<Compile Include="PathExtensionFixture.cs" />
|
||||
|
@ -26,13 +26,5 @@ namespace NzbDrone.Common.Test
|
||||
Assert.Throws<ArgumentException>(() => Subject.DownloadString(url));
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_get_headers()
|
||||
{
|
||||
Subject.GetHeader("http://www.google.com").Should().NotBeEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
19
src/NzbDrone.Common/Cloud/CloudClient.cs
Normal file
19
src/NzbDrone.Common/Cloud/CloudClient.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using NzbDrone.Common.Http;
|
||||
|
||||
namespace NzbDrone.Common.Cloud
|
||||
{
|
||||
public interface IDroneServicesRequestBuilder
|
||||
{
|
||||
HttpRequest Build(string path);
|
||||
}
|
||||
|
||||
public class DroneServicesHttpRequestBuilder : HttpRequestBuilder, IDroneServicesRequestBuilder
|
||||
{
|
||||
private const string ROOT_URL = "http://services.nzbdrone.com/v1/";
|
||||
|
||||
public DroneServicesHttpRequestBuilder()
|
||||
: base(ROOT_URL)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
15
src/NzbDrone.Common/Http/GZipWebClient.cs
Normal file
15
src/NzbDrone.Common/Http/GZipWebClient.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class GZipWebClient : WebClient
|
||||
{
|
||||
protected override WebRequest GetWebRequest(Uri address)
|
||||
{
|
||||
var request = (HttpWebRequest)base.GetWebRequest(address);
|
||||
request.AutomaticDecompression = DecompressionMethods.GZip;
|
||||
return request;
|
||||
}
|
||||
}
|
||||
}
|
160
src/NzbDrone.Common/Http/HttpClient.cs
Normal file
160
src/NzbDrone.Common/Http/HttpClient.cs
Normal file
@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public interface IHttpClient
|
||||
{
|
||||
HttpResponse Execute(HttpRequest request);
|
||||
void DownloadFile(string url, string fileName);
|
||||
HttpResponse Get(HttpRequest request);
|
||||
HttpResponse<T> Get<T>(HttpRequest request) where T : new();
|
||||
HttpResponse Head(HttpRequest request);
|
||||
}
|
||||
|
||||
public class HttpClient : IHttpClient
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
private readonly string _userAgent;
|
||||
|
||||
public HttpClient(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_userAgent = String.Format("NzbDrone {0}", BuildInfo.Version);
|
||||
ServicePointManager.DefaultConnectionLimit = 12;
|
||||
}
|
||||
|
||||
public HttpResponse Execute(HttpRequest request)
|
||||
{
|
||||
_logger.Trace(request);
|
||||
|
||||
var webRequest = (HttpWebRequest)WebRequest.Create(request.Url);
|
||||
|
||||
// Deflate is not a standard and could break depending on implementation.
|
||||
// we should just stick with the more compatible Gzip
|
||||
//http://stackoverflow.com/questions/8490718/how-to-decompress-stream-deflated-with-java-util-zip-deflater-in-net
|
||||
webRequest.AutomaticDecompression = DecompressionMethods.GZip;
|
||||
|
||||
webRequest.Credentials = request.NetworkCredential;
|
||||
webRequest.Method = request.Method.ToString();
|
||||
webRequest.KeepAlive = false;
|
||||
|
||||
if (!RuntimeInfoBase.IsProduction)
|
||||
{
|
||||
webRequest.AllowAutoRedirect = false;
|
||||
}
|
||||
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
|
||||
if (!request.Body.IsNullOrWhiteSpace())
|
||||
{
|
||||
var bytes = new byte[request.Body.Length * sizeof(char)];
|
||||
Buffer.BlockCopy(request.Body.ToCharArray(), 0, bytes, 0, bytes.Length);
|
||||
|
||||
webRequest.ContentLength = bytes.Length;
|
||||
using (var writeStream = webRequest.GetRequestStream())
|
||||
{
|
||||
writeStream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
}
|
||||
|
||||
HttpWebResponse httpWebResponse;
|
||||
|
||||
try
|
||||
{
|
||||
httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
httpWebResponse = (HttpWebResponse)e.Response;
|
||||
}
|
||||
|
||||
string content = null;
|
||||
|
||||
using (var responseStream = httpWebResponse.GetResponseStream())
|
||||
{
|
||||
if (responseStream != null)
|
||||
{
|
||||
using (var reader = new StreamReader(responseStream))
|
||||
{
|
||||
content = reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopWatch.Stop();
|
||||
|
||||
var response = new HttpResponse(request, new HttpHeader(httpWebResponse.Headers), content, httpWebResponse.StatusCode);
|
||||
_logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds);
|
||||
|
||||
if (!RuntimeInfoBase.IsProduction &&
|
||||
(response.StatusCode == HttpStatusCode.Moved ||
|
||||
response.StatusCode == HttpStatusCode.MovedPermanently))
|
||||
{
|
||||
throw new Exception("Server requested a redirect to [" + response.Headers["Location"] + "]. Update the request URL to avoid this redirect.");
|
||||
}
|
||||
|
||||
if (!request.SuppressHttpError && response.HasHttpError)
|
||||
{
|
||||
_logger.Warn("HTTP Error - {0}", response);
|
||||
throw new HttpException(request, response);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public void DownloadFile(string url, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(fileName);
|
||||
if (fileInfo.Directory != null && !fileInfo.Directory.Exists)
|
||||
{
|
||||
fileInfo.Directory.Create();
|
||||
}
|
||||
|
||||
_logger.Debug("Downloading [{0}] to [{1}]", url, fileName);
|
||||
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
var webClient = new GZipWebClient();
|
||||
webClient.Headers.Add(HttpRequestHeader.UserAgent, _userAgent);
|
||||
webClient.DownloadFile(url, fileName);
|
||||
stopWatch.Stop();
|
||||
_logger.Debug("Downloading Completed. took {0:0}s", stopWatch.Elapsed.Seconds);
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
_logger.Warn("Failed to get response from: {0} {1}", url, e.Message);
|
||||
throw;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.WarnException("Failed to get response from: " + url, e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public HttpResponse Get(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.GET;
|
||||
return Execute(request);
|
||||
}
|
||||
|
||||
public HttpResponse<T> Get<T>(HttpRequest request) where T : new()
|
||||
{
|
||||
var response = Get(request);
|
||||
return new HttpResponse<T>(response);
|
||||
}
|
||||
|
||||
public HttpResponse Head(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.HEAD;
|
||||
return Execute(request);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
27
src/NzbDrone.Common/Http/HttpException.cs
Normal file
27
src/NzbDrone.Common/Http/HttpException.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class HttpException : Exception
|
||||
{
|
||||
public HttpRequest Request { get; private set; }
|
||||
public HttpResponse Response { get; private set; }
|
||||
|
||||
public HttpException(HttpRequest request, HttpResponse response)
|
||||
: base(string.Format("HTTP request failed: [{0}] [{1}] at [{2}]", (int)response.StatusCode, request.Method, request.Url.ToString()))
|
||||
{
|
||||
Request = request;
|
||||
Response = response;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Response != null)
|
||||
{
|
||||
return base.ToString() + Environment.NewLine + Response.Content;
|
||||
}
|
||||
|
||||
return base.ToString();
|
||||
}
|
||||
}
|
||||
}
|
70
src/NzbDrone.Common/Http/HttpHeader.cs
Normal file
70
src/NzbDrone.Common/Http/HttpHeader.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class HttpHeader : Dictionary<string, object>
|
||||
{
|
||||
public HttpHeader(NameValueCollection headers)
|
||||
{
|
||||
foreach (var key in headers.AllKeys)
|
||||
{
|
||||
this[key] = headers[key];
|
||||
}
|
||||
}
|
||||
|
||||
public HttpHeader()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public long? ContentLength
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ContainsKey("Content-Length"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return Convert.ToInt64(this["Content-Length"]);
|
||||
}
|
||||
set
|
||||
{
|
||||
this["Content-Length"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string ContentType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ContainsKey("Content-Type"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this["Content-Type"].ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
this["Content-Type"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Accept
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!ContainsKey("Accept"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this["Accept"].ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
this["Accept"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
src/NzbDrone.Common/Http/HttpMethod.cs
Normal file
13
src/NzbDrone.Common/Http/HttpMethod.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public enum HttpMethod
|
||||
{
|
||||
GET,
|
||||
PUT,
|
||||
POST,
|
||||
HEAD,
|
||||
DELETE,
|
||||
PATCH,
|
||||
OPTIONS
|
||||
}
|
||||
}
|
@ -1,40 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
[Obsolete("Use IHttpClient")]
|
||||
public interface IHttpProvider
|
||||
{
|
||||
string DownloadString(string url);
|
||||
string DownloadString(string url, string username, string password);
|
||||
string DownloadString(string url, ICredentials credentials);
|
||||
Dictionary<string, string> GetHeader(string url);
|
||||
Stream DownloadStream(string url, NetworkCredential credential = null);
|
||||
void DownloadFile(string url, string fileName);
|
||||
string PostCommand(string address, string username, string password, string command);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use HttpProvider")]
|
||||
public class HttpProvider : IHttpProvider
|
||||
{
|
||||
private class GZipWebClient : WebClient
|
||||
{
|
||||
protected override WebRequest GetWebRequest(Uri address)
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
|
||||
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Logger _logger;
|
||||
|
||||
public const string CONTENT_LENGTH_HEADER = "Content-Length";
|
||||
|
||||
private readonly string _userAgent;
|
||||
|
||||
@ -55,7 +38,7 @@ namespace NzbDrone.Common.Http
|
||||
return DownloadString(url, new NetworkCredential(username, password));
|
||||
}
|
||||
|
||||
public string DownloadString(string url, ICredentials identity)
|
||||
private string DownloadString(string url, ICredentials identity)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -75,81 +58,6 @@ namespace NzbDrone.Common.Http
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetHeader(string url)
|
||||
{
|
||||
var headers = new Dictionary<string, string>();
|
||||
var request = WebRequest.Create(url);
|
||||
request.Method = "HEAD";
|
||||
|
||||
var response = request.GetResponse();
|
||||
|
||||
foreach (var key in response.Headers.AllKeys)
|
||||
{
|
||||
headers.Add(key, response.Headers[key]);
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
public Stream DownloadStream(string url, NetworkCredential credential = null)
|
||||
{
|
||||
var request = (HttpWebRequest)WebRequest.Create(url);
|
||||
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
|
||||
request.UserAgent = _userAgent;
|
||||
request.Timeout = 20 * 1000;
|
||||
|
||||
request.Credentials = credential;
|
||||
var response = request.GetResponse();
|
||||
|
||||
return response.GetResponseStream();
|
||||
}
|
||||
|
||||
public void DownloadFile(string url, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(fileName);
|
||||
if (fileInfo.Directory != null && !fileInfo.Directory.Exists)
|
||||
{
|
||||
fileInfo.Directory.Create();
|
||||
}
|
||||
|
||||
_logger.Debug("Downloading [{0}] to [{1}]", url, fileName);
|
||||
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
var webClient = new GZipWebClient();
|
||||
webClient.Headers.Add(HttpRequestHeader.UserAgent, _userAgent);
|
||||
webClient.DownloadFile(url, fileName);
|
||||
stopWatch.Stop();
|
||||
_logger.Debug("Downloading Completed. took {0:0}s", stopWatch.Elapsed.Seconds);
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
_logger.Warn("Failed to get response from: {0} {1}", url, e.Message);
|
||||
throw;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.WarnException("Failed to get response from: " + url, e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public string PostCommand(string address, string username, string password, string command)
|
||||
{
|
||||
address = String.Format("http://{0}/jsonrpc", address);
|
||||
|
||||
_logger.Debug("Posting command: {0}, to {1}", command, address);
|
||||
|
||||
byte[] byteArray = Encoding.ASCII.GetBytes(command);
|
||||
|
||||
var wc = new NzbDroneWebClient();
|
||||
wc.Credentials = new NetworkCredential(username, password);
|
||||
|
||||
var response = wc.UploadData(address, "POST", byteArray);
|
||||
var text = Encoding.ASCII.GetString(response);
|
||||
|
||||
return text.Replace(" ", " ");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
66
src/NzbDrone.Common/Http/HttpRequest.cs
Normal file
66
src/NzbDrone.Common/Http/HttpRequest.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class HttpRequest
|
||||
{
|
||||
|
||||
private readonly Dictionary<string, string> _segments;
|
||||
|
||||
public HttpRequest(string url)
|
||||
{
|
||||
UriBuilder = new UriBuilder(url);
|
||||
Headers = new HttpHeader();
|
||||
_segments = new Dictionary<string, string>();
|
||||
|
||||
Headers.Accept = "application/json";
|
||||
}
|
||||
|
||||
public UriBuilder UriBuilder { get; private set; }
|
||||
|
||||
public Uri Url
|
||||
{
|
||||
get
|
||||
{
|
||||
var uri = UriBuilder.Uri.ToString();
|
||||
|
||||
foreach (var segment in _segments)
|
||||
{
|
||||
uri = uri.Replace(segment.Key, segment.Value);
|
||||
}
|
||||
|
||||
return new Uri(uri);
|
||||
}
|
||||
}
|
||||
|
||||
public HttpMethod Method { get; set; }
|
||||
public HttpHeader Headers { get; set; }
|
||||
public string Body { get; set; }
|
||||
public NetworkCredential NetworkCredential { get; set; }
|
||||
public bool SuppressHttpError { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Body == null)
|
||||
{
|
||||
return string.Format("Req: [{0}] {1}", Method, Url);
|
||||
}
|
||||
|
||||
return string.Format("Req: [{0}] {1} {2} {3}", Method, Url, Environment.NewLine, Body);
|
||||
}
|
||||
|
||||
public void AddSegment(string segment, string value)
|
||||
{
|
||||
var key = "{" + segment + "}";
|
||||
|
||||
if (!UriBuilder.Uri.ToString().Contains(key))
|
||||
{
|
||||
throw new InvalidOperationException("Segment " + key +" is not defined in Uri");
|
||||
}
|
||||
|
||||
_segments.Add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
40
src/NzbDrone.Common/Http/HttpRequestBuilder.cs
Normal file
40
src/NzbDrone.Common/Http/HttpRequestBuilder.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class HttpRequestBuilder
|
||||
{
|
||||
public Uri BaseUri { get; private set; }
|
||||
public bool SupressHttpError { get; set; }
|
||||
public NetworkCredential NetworkCredential { get; set; }
|
||||
|
||||
public Action<HttpRequest> PostProcess { get; set; }
|
||||
|
||||
public HttpRequestBuilder(string baseUri)
|
||||
{
|
||||
BaseUri = new Uri(baseUri);
|
||||
}
|
||||
|
||||
public virtual HttpRequest Build(string path)
|
||||
{
|
||||
if (BaseUri.ToString().EndsWith("/"))
|
||||
{
|
||||
path = path.TrimStart('/');
|
||||
}
|
||||
|
||||
var request = new HttpRequest(BaseUri + path)
|
||||
{
|
||||
SuppressHttpError = SupressHttpError,
|
||||
NetworkCredential = NetworkCredential
|
||||
};
|
||||
|
||||
if (PostProcess != null)
|
||||
{
|
||||
PostProcess(request);
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
}
|
65
src/NzbDrone.Common/Http/HttpResponse.cs
Normal file
65
src/NzbDrone.Common/Http/HttpResponse.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using NzbDrone.Common.Serializer;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class HttpResponse
|
||||
{
|
||||
public HttpResponse(HttpRequest request, HttpHeader headers, string content, HttpStatusCode statusCode)
|
||||
{
|
||||
Request = request;
|
||||
Headers = headers;
|
||||
Content = content;
|
||||
StatusCode = statusCode;
|
||||
}
|
||||
|
||||
public HttpRequest Request { get; private set; }
|
||||
public HttpHeader Headers { get; private set; }
|
||||
public HttpStatusCode StatusCode { get; private set; }
|
||||
public string Content { get; private set; }
|
||||
|
||||
public bool HasHttpError
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)StatusCode >= 400;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var result = string.Format("Res: [{0}] {1} : {2}.{3}", Request.Method, Request.Url, (int)StatusCode, StatusCode);
|
||||
|
||||
if (HasHttpError)
|
||||
{
|
||||
result += Environment.NewLine + Content;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Stream GetStream()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var writer = new StreamWriter(stream);
|
||||
writer.Write(Content);
|
||||
writer.Flush();
|
||||
stream.Position = 0;
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class HttpResponse<T> : HttpResponse where T : new()
|
||||
{
|
||||
public HttpResponse(HttpResponse response)
|
||||
: base(response.Request, response.Headers, response.Content, response.StatusCode)
|
||||
{
|
||||
Resource = Json.Deserialize<T>(response.Content);
|
||||
}
|
||||
|
||||
public T Resource { get; private set; }
|
||||
}
|
||||
}
|
21
src/NzbDrone.Common/Http/UriExtensions.cs
Normal file
21
src/NzbDrone.Common/Http/UriExtensions.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public static class UriExtensions
|
||||
{
|
||||
public static void SetQueryParam(this UriBuilder uriBuilder, string key, object value)
|
||||
{
|
||||
var query = uriBuilder.Query;
|
||||
|
||||
if (query.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
query += "&";
|
||||
}
|
||||
|
||||
uriBuilder.Query = query.Trim('?') + (key + "=" + value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -58,16 +58,13 @@
|
||||
<Reference Include="NLog">
|
||||
<HintPath>..\packages\NLog.2.1.0\lib\net40\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RestSharp, Version=104.4.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\RestSharp.104.4.0\lib\net4\RestSharp.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ArchiveService.cs" />
|
||||
<Compile Include="Cache\Cached.cs" />
|
||||
<Compile Include="Cache\CacheManager.cs" />
|
||||
<Compile Include="Cache\ICached.cs" />
|
||||
<Compile Include="Cloud\CloudClient.cs" />
|
||||
<Compile Include="Composition\Container.cs" />
|
||||
<Compile Include="Composition\ContainerBuilderBase.cs" />
|
||||
<Compile Include="Composition\IContainer.cs" />
|
||||
@ -114,10 +111,21 @@
|
||||
<Compile Include="Extensions\Base64Extentions.cs" />
|
||||
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||
<Compile Include="HashUtil.cs" />
|
||||
<Compile Include="Http\GZipWebClient.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Http\HttpClient.cs" />
|
||||
<Compile Include="Http\HttpException.cs" />
|
||||
<Compile Include="Http\HttpHeader.cs" />
|
||||
<Compile Include="Http\HttpMethod.cs" />
|
||||
<Compile Include="Http\HttpProvider.cs" />
|
||||
<Compile Include="Http\HttpRequest.cs" />
|
||||
<Compile Include="Http\HttpResponse.cs" />
|
||||
<Compile Include="Http\NzbDroneWebClient.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Http\HttpRequestBuilder.cs" />
|
||||
<Compile Include="Http\UriExtensions.cs" />
|
||||
<Compile Include="IEnumerableExtensions.cs" />
|
||||
<Compile Include="Instrumentation\CleanseLogMessage.cs" />
|
||||
<Compile Include="Instrumentation\ExceptronTarget.cs" />
|
||||
|
@ -74,6 +74,11 @@ namespace NzbDrone.Common
|
||||
return String.IsNullOrWhiteSpace(text);
|
||||
}
|
||||
|
||||
public static bool IsNotNullOrWhiteSpace(this string text)
|
||||
{
|
||||
return !String.IsNullOrWhiteSpace(text);
|
||||
}
|
||||
|
||||
public static bool ContainsIgnoreCase(this string text, string contains)
|
||||
{
|
||||
return text.IndexOf(contains, StringComparison.InvariantCultureIgnoreCase) > -1;
|
||||
|
@ -3,6 +3,5 @@
|
||||
<package id="loggly-csharp" version="2.3" targetFramework="net40" />
|
||||
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net40" />
|
||||
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||
<package id="RestSharp" version="104.4.0" targetFramework="net40" />
|
||||
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
|
||||
</packages>
|
@ -0,0 +1,28 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DataAugmentation.DailySeries;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Test.Common.Categories;
|
||||
|
||||
namespace NzbDrone.Core.Test.DataAugmentation.DailySeries
|
||||
{
|
||||
[TestFixture]
|
||||
[IntegrationTest]
|
||||
public class DailySeriesDataProxyFixture : CoreTest<DailySeriesDataProxy>
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
UseRealHttp();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_get_list_of_daily_series()
|
||||
{
|
||||
var list = Subject.GetDailySeriesIds();
|
||||
list.Should().NotBeEmpty();
|
||||
list.Should().OnlyHaveUniqueItems();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,53 +1,33 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common.Categories;
|
||||
|
||||
namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
|
||||
{
|
||||
[TestFixture]
|
||||
|
||||
[IntegrationTest]
|
||||
public class SceneMappingProxyFixture : CoreTest<SceneMappingProxy>
|
||||
{
|
||||
private const string SCENE_MAPPING_URL = "http://services.nzbdrone.com/v1/SceneMapping";
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
UseRealHttp();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void fetch_should_return_list_of_mappings()
|
||||
{
|
||||
Mocker.GetMock<IHttpProvider>()
|
||||
.Setup(s => s.DownloadString(SCENE_MAPPING_URL))
|
||||
.Returns(ReadAllText("Files", "SceneMappings.json"));
|
||||
|
||||
var mappings = Subject.Fetch();
|
||||
|
||||
mappings.Should().NotBeEmpty();
|
||||
|
||||
mappings.Should().NotContain(c => String.IsNullOrWhiteSpace(c.SearchTerm));
|
||||
mappings.Should().NotContain(c => String.IsNullOrWhiteSpace(c.Title));
|
||||
mappings.Should().NotContain(c => c.TvdbId == 0);
|
||||
mappings.Should().NotContain(c => c.SearchTerm.IsNullOrWhiteSpace());
|
||||
mappings.Should().NotContain(c => c.Title.IsNullOrWhiteSpace());
|
||||
mappings.Should().Contain(c => c.SeasonNumber > 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_on_server_error()
|
||||
{
|
||||
Mocker.GetMock<IHttpProvider>()
|
||||
.Setup(s => s.DownloadString(SCENE_MAPPING_URL))
|
||||
.Throws(new WebException());
|
||||
Assert.Throws<WebException>(() => Subject.Fetch());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_on_bad_json()
|
||||
{
|
||||
Mocker.GetMock<IHttpProvider>()
|
||||
.Setup(s => s.DownloadString(SCENE_MAPPING_URL))
|
||||
.Returns("bad json");
|
||||
Assert.Throws<JsonReaderException>(() => Subject.Fetch());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,9 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using FluentAssertions;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients;
|
||||
using NzbDrone.Core.Download.Clients.UsenetBlackhole;
|
||||
|
||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
@ -46,7 +42,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
|
||||
protected void WithFailedDownload()
|
||||
{
|
||||
Mocker.GetMock<IHttpProvider>()
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Throws(new WebException());
|
||||
}
|
||||
@ -84,7 +80,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
|
||||
Subject.Download(remoteEpisode);
|
||||
|
||||
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(_downloadUrl, _filePath), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(_downloadUrl, _filePath), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -98,7 +94,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
|
||||
Subject.Download(remoteEpisode);
|
||||
|
||||
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using FluentAssertions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Parser;
|
||||
@ -30,6 +30,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), null))
|
||||
.Returns(CreateRemoteEpisode());
|
||||
|
||||
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(c => c.Get(It.IsAny<HttpRequest>()))
|
||||
.Returns(new HttpResponse(null, null, "", HttpStatusCode.OK));
|
||||
|
||||
}
|
||||
|
||||
protected virtual RemoteEpisode CreateRemoteEpisode()
|
||||
|
@ -51,14 +51,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
};
|
||||
}
|
||||
|
||||
private void WithExistingFile()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.FileExists(_nzbPath)).Returns(true);
|
||||
}
|
||||
|
||||
private void WithFailedDownload()
|
||||
{
|
||||
Mocker.GetMock<IHttpProvider>().Setup(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>())).Throws(new WebException());
|
||||
Mocker.GetMock<IHttpClient>().Setup(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>())).Throws(new WebException());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -66,7 +61,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
{
|
||||
Subject.Download(_remoteEpisode);
|
||||
|
||||
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(_nzbUrl, _nzbPath), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(_nzbUrl, _nzbPath), Times.Once());
|
||||
}
|
||||
|
||||
|
||||
@ -102,7 +97,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
||||
|
||||
Subject.Download(_remoteEpisode);
|
||||
|
||||
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
[
|
||||
{
|
||||
"title": "Adventure Time",
|
||||
"searchTitle": "Adventure Time",
|
||||
"season": -1,
|
||||
"tvdbId": 152831
|
||||
},
|
||||
{
|
||||
"title": "Americas Funniest Home Videos",
|
||||
"searchTitle": "Americas Funniest Home Videos",
|
||||
"season": -1,
|
||||
"tvdbId": 76235
|
||||
},
|
||||
{
|
||||
"title": "Antiques Roadshow UK",
|
||||
"searchTitle": "Antiques Roadshow UK",
|
||||
"season": -1,
|
||||
"tvdbId": 83774
|
||||
},
|
||||
{
|
||||
"title": "Aqua Something You Know Whatever",
|
||||
"searchTitle": "Aqua Something You Know Whatever",
|
||||
"season": 9,
|
||||
"tvdbId": 77120
|
||||
},
|
||||
{
|
||||
"title": "Aqua Teen Hunger Force",
|
||||
"searchTitle": "Aqua Teen Hunger Force",
|
||||
"season": -1,
|
||||
"tvdbId": 77120
|
||||
}
|
||||
]
|
@ -1,5 +1,6 @@
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Cloud;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
@ -15,6 +16,8 @@ namespace NzbDrone.Core.Test.Framework
|
||||
protected void UseRealHttp()
|
||||
{
|
||||
Mocker.SetConstant<IHttpProvider>(new HttpProvider(TestLogger));
|
||||
Mocker.SetConstant<IHttpClient>(new HttpClient(TestLogger));
|
||||
Mocker.SetConstant<IDroneServicesRequestBuilder>(new DroneServicesHttpRequestBuilder());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@ -14,14 +15,14 @@ namespace NzbDrone.Core.Test.MediaCoverTests
|
||||
[TestFixture]
|
||||
public class CoverAlreadyExistsSpecificationFixture : CoreTest<CoverAlreadyExistsSpecification>
|
||||
{
|
||||
private Dictionary<string, string> _headers;
|
||||
private HttpResponse _httpResponse;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_headers = new Dictionary<string, string>();
|
||||
_httpResponse = new HttpResponse(null, new HttpHeader(), null, HttpStatusCode.OK);
|
||||
Mocker.GetMock<IDiskProvider>().Setup(c => c.GetFileSize(It.IsAny<string>())).Returns(100);
|
||||
Mocker.GetMock<IHttpProvider>().Setup(c => c.GetHeader(It.IsAny<string>())).Returns(_headers);
|
||||
Mocker.GetMock<IHttpClient>().Setup(c => c.Head(It.IsAny<HttpRequest>())).Returns(_httpResponse);
|
||||
|
||||
}
|
||||
|
||||
@ -50,7 +51,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
|
||||
public void should_return_false_if_file_exists_but_diffrent_size()
|
||||
{
|
||||
GivenExistingFileSize(100);
|
||||
_headers.Add(HttpProvider.CONTENT_LENGTH_HEADER, "200");
|
||||
_httpResponse.Headers.ContentLength = 200;
|
||||
|
||||
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse();
|
||||
}
|
||||
@ -60,8 +61,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
|
||||
public void should_return_ture_if_file_exists_and_same_size()
|
||||
{
|
||||
GivenExistingFileSize(100);
|
||||
_headers.Add(HttpProvider.CONTENT_LENGTH_HEADER, "100");
|
||||
|
||||
_httpResponse.Headers.ContentLength = 100;
|
||||
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeTrue();
|
||||
}
|
||||
|
||||
@ -70,8 +70,6 @@ namespace NzbDrone.Core.Test.MediaCoverTests
|
||||
{
|
||||
GivenExistingFileSize(100);
|
||||
Subject.AlreadyExists("http://url", "c:\\file.exe").Should().BeFalse();
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using NzbDrone.Core.Rest;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
@ -16,12 +16,27 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||
[IntegrationTest]
|
||||
public class TraktProxyFixture : CoreTest<TraktProxy>
|
||||
{
|
||||
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
UseRealHttp();
|
||||
}
|
||||
|
||||
[TestCase("The Simpsons", "The Simpsons")]
|
||||
[TestCase("South Park", "South Park")]
|
||||
[TestCase("Franklin & Bash", "Franklin & Bash")]
|
||||
[TestCase("Mr. D", "Mr. D")]
|
||||
[TestCase("Rob & Big", "Rob and Big")]
|
||||
[TestCase("M*A*S*H", "M*A*S*H")]
|
||||
[TestCase("imdb:tt0436992", "Doctor Who (2005)")]
|
||||
[TestCase("imdb:0436992", "Doctor Who (2005)")]
|
||||
[TestCase("IMDB:0436992", "Doctor Who (2005)")]
|
||||
[TestCase("IMDB: 0436992 ", "Doctor Who (2005)")]
|
||||
[TestCase("tvdb:78804", "Doctor Who (2005)")]
|
||||
[TestCase("TVDB:78804", "Doctor Who (2005)")]
|
||||
[TestCase("TVDB: 78804 ", "Doctor Who (2005)")]
|
||||
public void successful_search(string title, string expected)
|
||||
{
|
||||
var result = Subject.SearchForNewSeries(title);
|
||||
@ -52,7 +67,7 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||
[Test]
|
||||
public void getting_details_of_invalid_series()
|
||||
{
|
||||
Assert.Throws<RestException>(() => Subject.GetSeriesInfo(Int32.MaxValue));
|
||||
Assert.Throws<HttpException>(() => Subject.GetSeriesInfo(Int32.MaxValue));
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.MetadataSource;
|
||||
using NzbDrone.Core.MetadataSource.Tvdb;
|
||||
using NzbDrone.Core.Rest;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Test.Common.Categories;
|
||||
|
||||
namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||
@ -17,70 +13,15 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||
[IntegrationTest]
|
||||
public class TvdbProxyFixture : CoreTest<TvdbProxy>
|
||||
{
|
||||
// [TestCase("The Simpsons", "The Simpsons")]
|
||||
// [TestCase("South Park", "South Park")]
|
||||
// [TestCase("Franklin & Bash", "Franklin & Bash")]
|
||||
// [TestCase("Mr. D", "Mr. D")]
|
||||
// [TestCase("Rob & Big", "Rob and Big")]
|
||||
// [TestCase("M*A*S*H", "M*A*S*H")]
|
||||
// public void successful_search(string title, string expected)
|
||||
// {
|
||||
// var result = Subject.SearchForNewSeries(title);
|
||||
//
|
||||
// result.Should().NotBeEmpty();
|
||||
//
|
||||
// result[0].Title.Should().Be(expected);
|
||||
// }
|
||||
//
|
||||
// [Test]
|
||||
// public void no_search_result()
|
||||
// {
|
||||
// var result = Subject.SearchForNewSeries(Guid.NewGuid().ToString());
|
||||
// result.Should().BeEmpty();
|
||||
// }
|
||||
|
||||
[TestCase(88031)]
|
||||
[TestCase(179321)]
|
||||
public void should_be_able_to_get_series_detail(int tvdbId)
|
||||
{
|
||||
var details = Subject.GetSeriesInfo(tvdbId);
|
||||
UseRealHttp();
|
||||
|
||||
//ValidateSeries(details.Item1);
|
||||
ValidateEpisodes(details.Item2);
|
||||
}
|
||||
var episodes = Subject.GetEpisodeInfo(tvdbId);
|
||||
|
||||
// [Test]
|
||||
// public void getting_details_of_invalid_series()
|
||||
// {
|
||||
// Assert.Throws<RestException>(() => Subject.GetSeriesInfo(Int32.MaxValue));
|
||||
//
|
||||
// ExceptionVerification.ExpectedWarns(1);
|
||||
// }
|
||||
//
|
||||
// [Test]
|
||||
// public void should_not_have_period_at_start_of_title_slug()
|
||||
// {
|
||||
// var details = Subject.GetSeriesInfo(79099);
|
||||
//
|
||||
// details.Item1.TitleSlug.Should().Be("dothack");
|
||||
// }
|
||||
|
||||
private void ValidateSeries(Series series)
|
||||
{
|
||||
series.Should().NotBeNull();
|
||||
series.Title.Should().NotBeNullOrWhiteSpace();
|
||||
series.CleanTitle.Should().Be(Parser.Parser.CleanSeriesTitle(series.Title));
|
||||
series.Overview.Should().NotBeNullOrWhiteSpace();
|
||||
series.AirTime.Should().NotBeNullOrWhiteSpace();
|
||||
series.FirstAired.Should().HaveValue();
|
||||
series.FirstAired.Value.Kind.Should().Be(DateTimeKind.Utc);
|
||||
series.Images.Should().NotBeEmpty();
|
||||
series.ImdbId.Should().NotBeNullOrWhiteSpace();
|
||||
series.Network.Should().NotBeNullOrWhiteSpace();
|
||||
series.Runtime.Should().BeGreaterThan(0);
|
||||
series.TitleSlug.Should().NotBeNullOrWhiteSpace();
|
||||
series.TvRageId.Should().BeGreaterThan(0);
|
||||
series.TvdbId.Should().BeGreaterThan(0);
|
||||
ValidateEpisodes(episodes);
|
||||
}
|
||||
|
||||
private void ValidateEpisodes(List<Episode> episodes)
|
||||
@ -91,30 +32,10 @@ namespace NzbDrone.Core.Test.MetadataSourceTests
|
||||
.Max(e => e.Count()).Should().Be(1);
|
||||
|
||||
episodes.Should().Contain(c => c.SeasonNumber > 0);
|
||||
// episodes.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Overview));
|
||||
|
||||
foreach (var episode in episodes)
|
||||
{
|
||||
ValidateEpisode(episode);
|
||||
|
||||
//if atleast one episdoe has title it means parse it working.
|
||||
// episodes.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Title));
|
||||
}
|
||||
episodes.Should().OnlyContain(c => c.SeasonNumber > 0 || c.EpisodeNumber > 0);
|
||||
}
|
||||
|
||||
private void ValidateEpisode(Episode episode)
|
||||
{
|
||||
episode.Should().NotBeNull();
|
||||
|
||||
//TODO: Is there a better way to validate that episode number or season number is greater than zero?
|
||||
(episode.EpisodeNumber + episode.SeasonNumber).Should().NotBe(0);
|
||||
|
||||
episode.Should().NotBeNull();
|
||||
|
||||
// if (episode.AirDateUtc.HasValue)
|
||||
// {
|
||||
// episode.AirDateUtc.Value.Kind.Should().Be(DateTimeKind.Utc);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,7 @@
|
||||
<Compile Include="Configuration\ConfigServiceFixture.cs" />
|
||||
<Compile Include="DataAugmentationFixture\Scene\SceneMappingProxyFixture.cs" />
|
||||
<Compile Include="DataAugmentationFixture\Scene\SceneMappingServiceFixture.cs" />
|
||||
<Compile Include="DataAugmentation\DailySeries\DailySeriesDataProxyFixture.cs" />
|
||||
<Compile Include="Datastore\BasicRepositoryFixture.cs" />
|
||||
<Compile Include="Datastore\Converters\ProviderSettingConverterFixture.cs" />
|
||||
<Compile Include="Datastore\DatabaseFixture.cs" />
|
||||
@ -380,9 +381,6 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Files\SceneMappings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Files\TestArchive.tar.gz">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
@ -24,6 +24,8 @@ namespace NzbDrone.Core.Test.TvTests
|
||||
[TestFixtureSetUp]
|
||||
public void TestFixture()
|
||||
{
|
||||
UseRealHttp();
|
||||
|
||||
_gameOfThrones = Mocker.Resolve<TraktProxy>().GetSeriesInfo(121361);//Game of thrones
|
||||
|
||||
// Remove specials.
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Update;
|
||||
|
||||
@ -12,7 +13,7 @@ namespace NzbDrone.Core.Test.UpdateTests
|
||||
public void no_update_when_version_higher()
|
||||
{
|
||||
UseRealHttp();
|
||||
Subject.GetLatestUpdate("master", new Version(10,0)).Should().BeNull();
|
||||
Subject.GetLatestUpdate("master", new Version(10, 0)).Should().BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -21,5 +22,21 @@ namespace NzbDrone.Core.Test.UpdateTests
|
||||
UseRealHttp();
|
||||
Subject.GetLatestUpdate("master", new Version(2, 0)).Should().NotBeNull();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_get_recent_updates()
|
||||
{
|
||||
const string branch = "master";
|
||||
UseRealHttp();
|
||||
var recent = Subject.GetRecentUpdates(branch, 2);
|
||||
|
||||
recent.Should().NotBeEmpty();
|
||||
recent.Should().OnlyContain(c => c.Hash.IsNotNullOrWhiteSpace());
|
||||
recent.Should().OnlyContain(c => c.FileName.Contains("Drone.master.2"));
|
||||
recent.Should().OnlyContain(c => c.ReleaseDate.Year == 2014);
|
||||
recent.Should().OnlyContain(c => c.Changes.New != null);
|
||||
recent.Should().OnlyContain(c => c.Changes.Fixed != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ namespace NzbDrone.Core.Test.UpdateTests
|
||||
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(_updatePackage.Url, updateArchive));
|
||||
Mocker.GetMock<IHttpClient>().Verify(c => c.DownloadFile(_updatePackage.Url, updateArchive));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -124,8 +124,6 @@ namespace NzbDrone.Core.Test.UpdateTests
|
||||
|
||||
Subject.Execute(new ApplicationUpdateCommand());
|
||||
|
||||
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Verify(c => c.MoveFolder(updateClientFolder, _sandboxFolder));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
namespace NzbDrone.Core.DataAugmentation.DailySeries
|
||||
{
|
||||
public class DailySeries
|
||||
{
|
||||
public int TvdbId { get; set; }
|
||||
}
|
||||
}
|
@ -1,27 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Cloud;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
|
||||
namespace NzbDrone.Core.DataAugmentation.DailySeries
|
||||
{
|
||||
|
||||
public interface IDailySeriesDataProxy
|
||||
{
|
||||
IEnumerable<int> GetDailySeriesIds();
|
||||
bool IsDailySeries(int tvdbid);
|
||||
}
|
||||
|
||||
public class DailySeriesDataProxy : IDailySeriesDataProxy
|
||||
{
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IDroneServicesRequestBuilder _requestBuilder;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public DailySeriesDataProxy(IHttpProvider httpProvider, Logger logger)
|
||||
public DailySeriesDataProxy(IHttpClient httpClient, IDroneServicesRequestBuilder requestBuilder, Logger logger)
|
||||
{
|
||||
_httpProvider = httpProvider;
|
||||
_httpClient = httpClient;
|
||||
_requestBuilder = requestBuilder;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@ -29,32 +29,15 @@ namespace NzbDrone.Core.DataAugmentation.DailySeries
|
||||
{
|
||||
try
|
||||
{
|
||||
var dailySeriesIds = _httpProvider.DownloadString(Services.RootUrl + "/v1/DailySeries");
|
||||
|
||||
var seriesIds = Json.Deserialize<List<int>>(dailySeriesIds);
|
||||
|
||||
return seriesIds;
|
||||
var dailySeriesRequest = _requestBuilder.Build("dailyseries");
|
||||
var response = _httpClient.Get<List<DailySeries>>(dailySeriesRequest);
|
||||
return response.Resource.Select(c => c.TvdbId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.WarnException("Failed to get Daily Series", ex);
|
||||
return new List<int>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool IsDailySeries(int tvdbid)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = _httpProvider.DownloadString(Services.RootUrl + "/v1/DailySeries?seriesId=" + tvdbid);
|
||||
return Convert.ToBoolean(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.WarnException("Failed to check Daily Series status for: " + tvdbid, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,44 +1,30 @@
|
||||
using NzbDrone.Core.Tv;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Common.Cache;
|
||||
|
||||
namespace NzbDrone.Core.DataAugmentation.DailySeries
|
||||
{
|
||||
public interface IDailySeriesService
|
||||
{
|
||||
void UpdateDailySeries();
|
||||
bool IsDailySeries(int tvdbid);
|
||||
}
|
||||
|
||||
public class DailySeriesService : IDailySeriesService
|
||||
{
|
||||
//TODO: add timer command
|
||||
|
||||
private readonly IDailySeriesDataProxy _proxy;
|
||||
private readonly ISeriesService _seriesService;
|
||||
private readonly ICached<List<int>> _cache;
|
||||
|
||||
public DailySeriesService(IDailySeriesDataProxy proxy, ISeriesService seriesService)
|
||||
public DailySeriesService(IDailySeriesDataProxy proxy, ICacheManager cacheManager)
|
||||
{
|
||||
_proxy = proxy;
|
||||
_seriesService = seriesService;
|
||||
}
|
||||
|
||||
public void UpdateDailySeries()
|
||||
{
|
||||
var dailySeries = _proxy.GetDailySeriesIds();
|
||||
|
||||
foreach (var tvdbId in dailySeries)
|
||||
{
|
||||
var series = _seriesService.FindByTvdbId(tvdbId);
|
||||
|
||||
if (series != null)
|
||||
{
|
||||
_seriesService.SetSeriesType(series.Id, SeriesTypes.Daily);
|
||||
}
|
||||
}
|
||||
_cache = cacheManager.GetCache<List<int>>(GetType());
|
||||
}
|
||||
|
||||
public bool IsDailySeries(int tvdbid)
|
||||
{
|
||||
return _proxy.IsDailySeries(tvdbid);
|
||||
var dailySeries = _cache.Get("all", () => _proxy.GetDailySeriesIds().ToList(), TimeSpan.FromHours(1));
|
||||
return dailySeries.Any(i => i == tvdbid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Cloud;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
|
||||
namespace NzbDrone.Core.DataAugmentation.Scene
|
||||
{
|
||||
@ -12,17 +11,19 @@ namespace NzbDrone.Core.DataAugmentation.Scene
|
||||
|
||||
public class SceneMappingProxy : ISceneMappingProxy
|
||||
{
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IDroneServicesRequestBuilder _requestBuilder;
|
||||
|
||||
public SceneMappingProxy(IHttpProvider httpProvider)
|
||||
public SceneMappingProxy(IHttpClient httpClient, IDroneServicesRequestBuilder requestBuilder)
|
||||
{
|
||||
_httpProvider = httpProvider;
|
||||
_httpClient = httpClient;
|
||||
_requestBuilder = requestBuilder;
|
||||
}
|
||||
|
||||
public List<SceneMapping> Fetch()
|
||||
{
|
||||
var mappingsJson = _httpProvider.DownloadString(Services.RootUrl + "/v1/SceneMapping");
|
||||
return Json.Deserialize<List<SceneMapping>>(mappingsJson);
|
||||
var request = _requestBuilder.Build("/scenemapping");
|
||||
return _httpClient.Get<List<SceneMapping>>(request).Resource;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,10 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.DataAugmentation.Xem.Model;
|
||||
using NzbDrone.Core.Rest;
|
||||
using RestSharp;
|
||||
|
||||
namespace NzbDrone.Core.DataAugmentation.Xem
|
||||
{
|
||||
@ -20,34 +19,32 @@ namespace NzbDrone.Core.DataAugmentation.Xem
|
||||
public class XemProxy : IXemProxy
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
private const string XEM_BASE_URL = "http://thexem.de/map/";
|
||||
|
||||
private static readonly string[] IgnoredErrors = { "no single connection", "no show with the tvdb_id" };
|
||||
private HttpRequestBuilder _xemRequestBuilder;
|
||||
|
||||
|
||||
public XemProxy(Logger logger)
|
||||
public XemProxy(Logger logger, IHttpClient httpClient)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
|
||||
_xemRequestBuilder = new HttpRequestBuilder(XEM_BASE_URL)
|
||||
{
|
||||
PostProcess = r => r.UriBuilder.SetQueryParam("origin", "tvdb")
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static RestRequest BuildRequest(string resource)
|
||||
{
|
||||
var req = new RestRequest(resource, Method.GET);
|
||||
req.AddParameter("origin", "tvdb");
|
||||
return req;
|
||||
}
|
||||
|
||||
public List<int> GetXemSeriesIds()
|
||||
{
|
||||
_logger.Debug("Fetching Series IDs from");
|
||||
|
||||
var restClient = RestClientFactory.BuildClient(XEM_BASE_URL);
|
||||
|
||||
var request = BuildRequest("havemap");
|
||||
|
||||
var response = restClient.ExecuteAndValidate<XemResult<List<int>>>(request);
|
||||
var request = _xemRequestBuilder.Build("/havemap");
|
||||
var response = _httpClient.Get<XemResult<List<int>>>(request).Resource;
|
||||
CheckForFailureResult(response);
|
||||
|
||||
return response.Data.ToList();
|
||||
@ -57,13 +54,11 @@ namespace NzbDrone.Core.DataAugmentation.Xem
|
||||
{
|
||||
_logger.Debug("Fetching Mappings for: {0}", id);
|
||||
|
||||
var restClient = RestClientFactory.BuildClient(XEM_BASE_URL);
|
||||
|
||||
var request = BuildRequest("all");
|
||||
request.AddParameter("id", id);
|
||||
var request = _xemRequestBuilder.Build("/all");
|
||||
request.UriBuilder.SetQueryParam("id", id);
|
||||
|
||||
var response = restClient.ExecuteAndValidate<XemResult<List<XemSceneTvdbMapping>>>(request);
|
||||
CheckForFailureResult(response);
|
||||
var response = _httpClient.Get<XemResult<List<XemSceneTvdbMapping>>>(request).Resource;
|
||||
|
||||
return response.Data.Where(c => c.Scene != null).ToList();
|
||||
}
|
||||
@ -71,14 +66,11 @@ namespace NzbDrone.Core.DataAugmentation.Xem
|
||||
public List<SceneMapping> GetSceneTvdbNames()
|
||||
{
|
||||
_logger.Debug("Fetching alternate names");
|
||||
var restClient = RestClientFactory.BuildClient(XEM_BASE_URL);
|
||||
|
||||
var request = BuildRequest("allNames");
|
||||
request.AddParameter("origin", "tvdb");
|
||||
request.AddParameter("seasonNumbers", true);
|
||||
var request = _xemRequestBuilder.Build("/allNames");
|
||||
request.UriBuilder.SetQueryParam("seasonNumbers", true);
|
||||
|
||||
var response = restClient.ExecuteAndValidate<XemResult<Dictionary<Int32, List<JObject>>>>(request);
|
||||
CheckForFailureResult(response);
|
||||
var response = _httpClient.Get<XemResult<Dictionary<Int32, List<JObject>>>>(request).Resource;
|
||||
|
||||
var result = new List<SceneMapping>();
|
||||
|
||||
|
@ -18,10 +18,10 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
public class Nzbget : DownloadClientBase<NzbgetSettings>
|
||||
{
|
||||
private readonly INzbgetProxy _proxy;
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public Nzbget(INzbgetProxy proxy,
|
||||
IHttpProvider httpProvider,
|
||||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IParsingService parsingService,
|
||||
@ -29,7 +29,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
: base(configService, diskProvider, parsingService, logger)
|
||||
{
|
||||
_proxy = proxy;
|
||||
_httpProvider = httpProvider;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public override DownloadProtocol Protocol
|
||||
@ -49,7 +49,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
|
||||
_logger.Info("Adding report [{0}] to the queue.", title);
|
||||
|
||||
using (var nzb = _httpProvider.DownloadStream(url))
|
||||
using (var nzb = _httpClient.Get(new HttpRequest(url)).GetStream())
|
||||
{
|
||||
_logger.Info("Adding report [{0}] to the queue.", title);
|
||||
var response = _proxy.DownloadNzb(nzb, title, category, priority, Settings);
|
||||
@ -87,7 +87,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
var totalSize = MakeInt64(item.FileSizeHi, item.FileSizeLo);
|
||||
var pausedSize = MakeInt64(item.PausedSizeHi, item.PausedSizeLo);
|
||||
var remainingSize = MakeInt64(item.RemainingSizeHi, item.RemainingSizeLo);
|
||||
|
||||
|
||||
var droneParameter = item.Parameters.SingleOrDefault(p => p.Name == "drone");
|
||||
|
||||
var queueItem = new DownloadClientItem();
|
||||
@ -152,7 +152,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
}
|
||||
|
||||
var historyItems = new List<DownloadClientItem>();
|
||||
var successStatus = new[] {"SUCCESS", "NONE"};
|
||||
var successStatus = new[] { "SUCCESS", "NONE" };
|
||||
|
||||
foreach (var item in history)
|
||||
{
|
||||
@ -190,7 +190,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
|
||||
public override IEnumerable<DownloadClientItem> GetItems()
|
||||
{
|
||||
Dictionary<String,String> config = null;
|
||||
Dictionary<String, String> config = null;
|
||||
NzbgetCategory category = null;
|
||||
try
|
||||
{
|
||||
@ -270,7 +270,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||
if (name == null) yield break;
|
||||
|
||||
var destDir = config.GetValueOrDefault("Category" + i + ".DestDir");
|
||||
|
||||
|
||||
if (destDir.IsNullOrWhiteSpace())
|
||||
{
|
||||
var mainDir = config.GetValueOrDefault("MainDir");
|
||||
|
@ -16,16 +16,16 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||
{
|
||||
public class Pneumatic : DownloadClientBase<PneumaticSettings>
|
||||
{
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public Pneumatic(IHttpProvider httpProvider,
|
||||
public Pneumatic(IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IParsingService parsingService,
|
||||
Logger logger)
|
||||
: base(configService, diskProvider, parsingService, logger)
|
||||
{
|
||||
_httpProvider = httpProvider;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public override DownloadProtocol Protocol
|
||||
@ -52,7 +52,7 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||
var nzbFile = Path.Combine(Settings.NzbFolder, title + ".nzb");
|
||||
|
||||
_logger.Debug("Downloading NZB from: {0} to: {1}", url, nzbFile);
|
||||
_httpProvider.DownloadFile(url, nzbFile);
|
||||
_httpClient.DownloadFile(url, nzbFile);
|
||||
|
||||
_logger.Debug("NZB Download succeeded, saved to: {0}", nzbFile);
|
||||
|
||||
|
@ -18,11 +18,11 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
{
|
||||
public class Sabnzbd : DownloadClientBase<SabnzbdSettings>
|
||||
{
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly ISabnzbdProxy _proxy;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public Sabnzbd(ISabnzbdProxy proxy,
|
||||
IHttpProvider httpProvider,
|
||||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IParsingService parsingService,
|
||||
@ -30,7 +30,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
: base(configService, diskProvider, parsingService, logger)
|
||||
{
|
||||
_proxy = proxy;
|
||||
_httpProvider = httpProvider;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public override DownloadProtocol Protocol
|
||||
@ -48,7 +48,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
var category = Settings.TvCategory;
|
||||
var priority = remoteEpisode.IsRecentEpisode() ? Settings.RecentTvPriority : Settings.OlderTvPriority;
|
||||
|
||||
using (var nzb = _httpProvider.DownloadStream(url))
|
||||
using (var nzb = _httpClient.Get(new HttpRequest(url)).GetStream())
|
||||
{
|
||||
_logger.Info("Adding report [{0}] to the queue.", title);
|
||||
var response = _proxy.DownloadNzb(nzb, title, category, priority, Settings);
|
||||
@ -401,7 +401,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private ValidationFailure TestGlobalConfig()
|
||||
{
|
||||
var config = _proxy.GetConfig(Settings);
|
||||
|
@ -19,10 +19,10 @@ namespace NzbDrone.Core.Download.Clients.UsenetBlackhole
|
||||
public class UsenetBlackhole : DownloadClientBase<UsenetBlackholeSettings>
|
||||
{
|
||||
private readonly IDiskScanService _diskScanService;
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public UsenetBlackhole(IDiskScanService diskScanService,
|
||||
IHttpProvider httpProvider,
|
||||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IParsingService parsingService,
|
||||
@ -30,7 +30,7 @@ namespace NzbDrone.Core.Download.Clients.UsenetBlackhole
|
||||
: base(configService, diskProvider, parsingService, logger)
|
||||
{
|
||||
_diskScanService = diskScanService;
|
||||
_httpProvider = httpProvider;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public override DownloadProtocol Protocol
|
||||
@ -51,7 +51,7 @@ namespace NzbDrone.Core.Download.Clients.UsenetBlackhole
|
||||
var filename = Path.Combine(Settings.NzbFolder, title + ".nzb");
|
||||
|
||||
_logger.Debug("Downloading NZB from: {0} to: {1}", url, filename);
|
||||
_httpProvider.DownloadFile(url, filename);
|
||||
_httpClient.DownloadFile(url, filename);
|
||||
_logger.Debug("NZB Download succeeded, saved to: {0}", filename);
|
||||
|
||||
return null;
|
||||
|
@ -1,8 +1,5 @@
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
|
||||
namespace NzbDrone.Core.MediaCover
|
||||
{
|
||||
@ -14,14 +11,12 @@ namespace NzbDrone.Core.MediaCover
|
||||
public class CoverAlreadyExistsSpecification : ICoverExistsSpecification
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly Logger _logger;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpProvider httpProvider, Logger logger)
|
||||
public CoverAlreadyExistsSpecification(IDiskProvider diskProvider, IHttpClient httpClient)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_httpProvider = httpProvider;
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public bool AlreadyExists(string url, string path)
|
||||
@ -31,22 +26,9 @@ namespace NzbDrone.Core.MediaCover
|
||||
return false;
|
||||
}
|
||||
|
||||
var headers = _httpProvider.GetHeader(url);
|
||||
|
||||
string sizeString;
|
||||
|
||||
if (headers.TryGetValue(HttpProvider.CONTENT_LENGTH_HEADER, out sizeString))
|
||||
{
|
||||
int size;
|
||||
int.TryParse(sizeString, out size);
|
||||
var fileSize = _diskProvider.GetFileSize(path);
|
||||
|
||||
return fileSize == size;
|
||||
}
|
||||
|
||||
_logger.Warn("Couldn't find content-length header {0}", headers.ToJson());
|
||||
|
||||
return false;
|
||||
var headers = _httpClient.Head(new HttpRequest(url)).Headers;
|
||||
var fileSize = _diskProvider.GetFileSize(path);
|
||||
return fileSize == headers.ContentLength;
|
||||
}
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ namespace NzbDrone.Core.MediaCover
|
||||
IHandleAsync<SeriesDeletedEvent>,
|
||||
IMapCoversToLocal
|
||||
{
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly ICoverExistsSpecification _coverExistsSpecification;
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
@ -34,15 +34,15 @@ namespace NzbDrone.Core.MediaCover
|
||||
|
||||
private readonly string _coverRootFolder;
|
||||
|
||||
public MediaCoverService(IHttpProvider httpProvider,
|
||||
public MediaCoverService(IHttpClient httpClient,
|
||||
IDiskProvider diskProvider,
|
||||
IAppFolderInfo appFolderInfo,
|
||||
ICoverExistsSpecification coverExistsSpecification,
|
||||
IConfigFileProvider configFileProvider,
|
||||
ICoverExistsSpecification coverExistsSpecification,
|
||||
IConfigFileProvider configFileProvider,
|
||||
IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
{
|
||||
_httpProvider = httpProvider;
|
||||
_httpClient = httpClient;
|
||||
_diskProvider = diskProvider;
|
||||
_coverExistsSpecification = coverExistsSpecification;
|
||||
_configFileProvider = configFileProvider;
|
||||
@ -106,7 +106,7 @@ namespace NzbDrone.Core.MediaCover
|
||||
var fileName = GetCoverPath(series.Id, cover.CoverType);
|
||||
|
||||
_logger.Info("Downloading {0} for {1} {2}", cover.CoverType, series, cover.Url);
|
||||
_httpProvider.DownloadFile(cover.Url, fileName);
|
||||
_httpClient.DownloadFile(cover.Url, fileName);
|
||||
}
|
||||
|
||||
public void HandleAsync(SeriesUpdatedEvent message)
|
||||
|
@ -29,7 +29,7 @@ namespace NzbDrone.Core.Metadata
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly Logger _logger;
|
||||
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Metadata
|
||||
IMediaFileService mediaFileService,
|
||||
IEpisodeService episodeService,
|
||||
IDiskProvider diskProvider,
|
||||
IHttpProvider httpProvider,
|
||||
IHttpClient httpClient,
|
||||
IConfigService configService,
|
||||
IEventAggregator eventAggregator,
|
||||
Logger logger)
|
||||
@ -51,7 +51,7 @@ namespace NzbDrone.Core.Metadata
|
||||
_mediaFileService = mediaFileService;
|
||||
_episodeService = episodeService;
|
||||
_diskProvider = diskProvider;
|
||||
_httpProvider = httpProvider;
|
||||
_httpClient = httpClient;
|
||||
_configService = configService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_logger = logger;
|
||||
@ -336,7 +336,7 @@ namespace NzbDrone.Core.Metadata
|
||||
{
|
||||
try
|
||||
{
|
||||
_httpProvider.DownloadFile(url, path);
|
||||
_httpClient.DownloadFile(url, path);
|
||||
SetFilePermissions(path);
|
||||
}
|
||||
catch (WebException e)
|
||||
|
@ -2,86 +2,93 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MetadataSource.Trakt;
|
||||
using NzbDrone.Core.Tv;
|
||||
using RestSharp;
|
||||
using Episode = NzbDrone.Core.Tv.Episode;
|
||||
using NzbDrone.Core.Rest;
|
||||
|
||||
namespace NzbDrone.Core.MetadataSource
|
||||
{
|
||||
public class TraktProxy : ISearchForNewSeries, IProvideSeriesInfo
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
private readonly IHttpClient _httpClient;
|
||||
private static readonly Regex CollapseSpaceRegex = new Regex(@"\s+", RegexOptions.Compiled);
|
||||
private static readonly Regex InvalidSearchCharRegex = new Regex(@"(?:\*|\(|\)|'|!|@|\+)", RegexOptions.Compiled);
|
||||
|
||||
public TraktProxy(Logger logger)
|
||||
|
||||
private readonly HttpRequestBuilder _requestBuilder;
|
||||
|
||||
public TraktProxy(Logger logger, IHttpClient httpClient)
|
||||
{
|
||||
_requestBuilder = new HttpRequestBuilder("http://api.trakt.tv/{path}/{resource}.json/bc3c2c460f22cbb01c264022b540e191");
|
||||
_logger = logger;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
private IEnumerable<Show> SearchTrakt(string title)
|
||||
{
|
||||
|
||||
HttpRequest request;
|
||||
|
||||
var lowerTitle = title.ToLowerInvariant();
|
||||
|
||||
if (lowerTitle.StartsWith("tvdb:") || lowerTitle.StartsWith("tvdbid:") || lowerTitle.StartsWith("slug:"))
|
||||
{
|
||||
var slug = lowerTitle.Split(':')[1].Trim();
|
||||
|
||||
if (slug.IsNullOrWhiteSpace() || slug.Any(char.IsWhiteSpace))
|
||||
{
|
||||
return Enumerable.Empty<Show>();
|
||||
}
|
||||
|
||||
request = _requestBuilder.Build("/{slug}/extended");
|
||||
|
||||
request.AddSegment("path", "show");
|
||||
request.AddSegment("resource", "summary");
|
||||
request.AddSegment("slug", GetSearchTerm(slug));
|
||||
|
||||
return new List<Show> { _httpClient.Get<Show>(request).Resource };
|
||||
}
|
||||
|
||||
if (lowerTitle.StartsWith("imdb:") || lowerTitle.StartsWith("imdbid:"))
|
||||
{
|
||||
var slug = lowerTitle.Split(':')[1].TrimStart('t').Trim();
|
||||
|
||||
if (slug.IsNullOrWhiteSpace() || !slug.All(char.IsDigit) || slug.Length < 7)
|
||||
{
|
||||
return Enumerable.Empty<Show>();
|
||||
}
|
||||
|
||||
title = "tt" + slug;
|
||||
}
|
||||
|
||||
request = _requestBuilder.Build("");
|
||||
|
||||
request.AddSegment("path", "search");
|
||||
request.AddSegment("resource", "shows");
|
||||
request.UriBuilder.SetQueryParam("query", GetSearchTerm(title));
|
||||
request.UriBuilder.SetQueryParam("seasons", true);
|
||||
|
||||
return _httpClient.Get<List<Show>>(request).Resource;
|
||||
}
|
||||
|
||||
|
||||
public List<Series> SearchForNewSeries(string title)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (title.StartsWith("imdb:") || title.StartsWith("imdbid:"))
|
||||
{
|
||||
var slug = title.Split(':')[1].TrimStart('t');
|
||||
var series = SearchTrakt(title.Trim());
|
||||
|
||||
if (slug.IsNullOrWhiteSpace() || !slug.All(char.IsDigit) || slug.Length < 7)
|
||||
{
|
||||
return new List<Series>();
|
||||
}
|
||||
|
||||
title = "tt" + slug;
|
||||
}
|
||||
|
||||
if (title.StartsWith("tvdb:") || title.StartsWith("tvdbid:") || title.StartsWith("slug:"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var slug = title.Split(':')[1];
|
||||
|
||||
if (slug.IsNullOrWhiteSpace() || slug.Any(char.IsWhiteSpace))
|
||||
{
|
||||
return new List<Series>();
|
||||
}
|
||||
|
||||
var client = BuildClient("show", "summary");
|
||||
var restRequest = new RestRequest(GetSearchTerm(slug) + "/extended");
|
||||
var response = client.ExecuteAndValidate<Show>(restRequest);
|
||||
|
||||
return new List<Series> { MapSeries(response) };
|
||||
}
|
||||
catch (RestException ex)
|
||||
{
|
||||
if (ex.Response.StatusCode == HttpStatusCode.NotFound)
|
||||
{
|
||||
return new List<Series>();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var client = BuildClient("search", "shows");
|
||||
var restRequest = new RestRequest(GetSearchTerm(title) + "/30/seasons");
|
||||
var response = client.ExecuteAndValidate<List<Show>>(restRequest);
|
||||
|
||||
return response.Select(MapSeries)
|
||||
.OrderBy(v => title.LevenshteinDistanceClean(v.Title))
|
||||
.ToList();
|
||||
}
|
||||
return series.Select(MapSeries)
|
||||
.OrderBy(s => title.LevenshteinDistanceClean(s.Title))
|
||||
.ToList();
|
||||
}
|
||||
catch (WebException)
|
||||
catch (HttpException)
|
||||
{
|
||||
throw new TraktException("Search for '{0}' failed. Unable to communicate with Trakt.", title);
|
||||
}
|
||||
@ -94,20 +101,31 @@ namespace NzbDrone.Core.MetadataSource
|
||||
|
||||
public Tuple<Series, List<Episode>> GetSeriesInfo(int tvdbSeriesId)
|
||||
{
|
||||
var client = BuildClient("show", "summary");
|
||||
var restRequest = new RestRequest(tvdbSeriesId.ToString() + "/extended");
|
||||
var response = client.ExecuteAndValidate<Show>(restRequest);
|
||||
|
||||
var request = _requestBuilder.Build("/{tvdbId}/extended");
|
||||
|
||||
request.AddSegment("path", "show");
|
||||
request.AddSegment("resource", "summary");
|
||||
request.AddSegment("tvdbId", tvdbSeriesId.ToString());
|
||||
|
||||
var response = _httpClient.Get<Show>(request).Resource;
|
||||
|
||||
/*
|
||||
|
||||
var client = BuildClient("show", "summary");
|
||||
var restRequest = new RestRequest(tvdbSeriesId + "/extended");
|
||||
var response = client.ExecuteAndValidate<Show>(restRequest);*/
|
||||
|
||||
var episodes = response.seasons.SelectMany(c => c.episodes).Select(MapEpisode).ToList();
|
||||
var series = MapSeries(response);
|
||||
|
||||
return new Tuple<Series, List<Episode>>(series, episodes);
|
||||
}
|
||||
|
||||
private static IRestClient BuildClient(string resource, string method)
|
||||
{
|
||||
return RestClientFactory.BuildClient(string.Format("http://api.trakt.tv/{0}/{1}.json/bc3c2c460f22cbb01c264022b540e191", resource, method));
|
||||
}
|
||||
/*
|
||||
private static IRestClient BuildClient(string resource, string method)
|
||||
{
|
||||
return RestClientFactory.BuildClient(string.Format("http://api.trakt.tv/{0}/{1}.json/bc3c2c460f22cbb01c264022b540e191", resource, method));
|
||||
}*/
|
||||
|
||||
private static Series MapSeries(Show show)
|
||||
{
|
||||
@ -139,6 +157,18 @@ namespace NzbDrone.Core.MetadataSource
|
||||
return series;
|
||||
}
|
||||
|
||||
private static String GetTitleSlug(String url)
|
||||
{
|
||||
var slug = url.ToLower().Replace("http://trakt.tv/show/", "");
|
||||
|
||||
if (slug.StartsWith("."))
|
||||
{
|
||||
slug = "dot" + slug.Substring(1);
|
||||
}
|
||||
|
||||
return slug;
|
||||
}
|
||||
|
||||
private static Episode MapEpisode(Trakt.Episode traktEpisode)
|
||||
{
|
||||
var episode = new Episode();
|
||||
@ -179,13 +209,6 @@ namespace NzbDrone.Core.MetadataSource
|
||||
return SeriesStatusType.Continuing;
|
||||
}
|
||||
|
||||
private static DateTime? FromEpoch(long ticks)
|
||||
{
|
||||
if (ticks == 0) return null;
|
||||
|
||||
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified).AddSeconds(ticks);
|
||||
}
|
||||
|
||||
private static DateTime? FromIso(string iso)
|
||||
{
|
||||
DateTime result;
|
||||
@ -213,7 +236,7 @@ namespace NzbDrone.Core.MetadataSource
|
||||
phrase = InvalidSearchCharRegex.Replace(phrase, "");
|
||||
phrase = CollapseSpaceRegex.Replace(phrase, " ").Trim().ToLower();
|
||||
phrase = phrase.Trim('-');
|
||||
phrase = HttpUtility.UrlEncode(phrase);
|
||||
phrase = System.Web.HttpUtility.UrlEncode(phrase);
|
||||
|
||||
return phrase;
|
||||
}
|
||||
@ -279,23 +302,13 @@ namespace NzbDrone.Core.MetadataSource
|
||||
{
|
||||
season.Images.Add(new MediaCover.MediaCover(MediaCoverTypes.Poster, traktSeason.images.poster));
|
||||
}
|
||||
|
||||
|
||||
seasons.Add(season);
|
||||
}
|
||||
|
||||
return seasons;
|
||||
}
|
||||
|
||||
private static String GetTitleSlug(String url)
|
||||
{
|
||||
var slug = url.ToLower().Replace("http://trakt.tv/show/", "");
|
||||
|
||||
if (slug.StartsWith("."))
|
||||
{
|
||||
slug = "dot" + slug.Substring(1);
|
||||
}
|
||||
|
||||
return slug;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using NzbDrone.Core.Rest;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Tv;
|
||||
using RestSharp;
|
||||
|
||||
namespace NzbDrone.Core.MetadataSource.Tvdb
|
||||
{
|
||||
@ -17,37 +15,22 @@ namespace NzbDrone.Core.MetadataSource.Tvdb
|
||||
|
||||
public class TvdbProxy : ITvdbProxy
|
||||
{
|
||||
public Tuple<Series, List<Episode>> GetSeriesInfo(int tvdbSeriesId)
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public TvdbProxy(IHttpClient httpClient)
|
||||
{
|
||||
var client = BuildClient("series");
|
||||
var request = new RestRequest(tvdbSeriesId + "/all");
|
||||
|
||||
var response = client.Execute(request);
|
||||
|
||||
var xml = XDocument.Load(new StringReader(response.Content));
|
||||
|
||||
var episodes = xml.Descendants("Episode").Select(MapEpisode).ToList();
|
||||
var series = MapSeries(xml.Element("Series"));
|
||||
|
||||
return new Tuple<Series, List<Episode>>(series, episodes);
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public List<Episode> GetEpisodeInfo(int tvdbSeriesId)
|
||||
{
|
||||
return GetSeriesInfo(tvdbSeriesId).Item2;
|
||||
}
|
||||
var httpRequest = new HttpRequest("http://thetvdb.com/data/series/{tvdbId}/all/");
|
||||
httpRequest.AddSegment("tvdbId", tvdbSeriesId.ToString());
|
||||
var response = _httpClient.Get(httpRequest);
|
||||
|
||||
private static IRestClient BuildClient(string resource)
|
||||
{
|
||||
return RestClientFactory.BuildClient(String.Format("http://thetvdb.com/data/{0}", resource));
|
||||
}
|
||||
|
||||
private static Series MapSeries(XElement item)
|
||||
{
|
||||
//TODO: We should map all the data incase we want to actually use it
|
||||
var series = new Series();
|
||||
|
||||
return series;
|
||||
var xml = XDocument.Load(new StringReader(response.Content));
|
||||
var episodes = xml.Descendants("Episode").Select(MapEpisode).ToList();
|
||||
return episodes;
|
||||
}
|
||||
|
||||
private static Episode MapEpisode(XElement item)
|
||||
|
@ -128,6 +128,7 @@
|
||||
<Compile Include="Configuration\IConfigService.cs" />
|
||||
<Compile Include="Configuration\InvalidConfigFileException.cs" />
|
||||
<Compile Include="Configuration\ResetApiKeyCommand.cs" />
|
||||
<Compile Include="DataAugmentation\DailySeries\DailySeries.cs" />
|
||||
<Compile Include="DataAugmentation\DailySeries\DailySeriesDataProxy.cs" />
|
||||
<Compile Include="DataAugmentation\DailySeries\DailySeriesService.cs" />
|
||||
<Compile Include="DataAugmentation\Scene\ISceneMappingProvider.cs" />
|
||||
|
@ -26,7 +26,7 @@ namespace NzbDrone.Core.Update
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IHttpProvider _httpProvider;
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IArchiveService _archiveService;
|
||||
private readonly IProcessProvider _processProvider;
|
||||
private readonly IVerifyUpdates _updateVerifier;
|
||||
@ -36,7 +36,7 @@ namespace NzbDrone.Core.Update
|
||||
|
||||
|
||||
public InstallUpdateService(ICheckUpdateService checkUpdateService, IAppFolderInfo appFolderInfo,
|
||||
IDiskProvider diskProvider, IHttpProvider httpProvider,
|
||||
IDiskProvider diskProvider, IHttpClient httpClient,
|
||||
IArchiveService archiveService, IProcessProvider processProvider,
|
||||
IVerifyUpdates updateVerifier,
|
||||
IConfigFileProvider configFileProvider,
|
||||
@ -51,7 +51,7 @@ namespace NzbDrone.Core.Update
|
||||
_checkUpdateService = checkUpdateService;
|
||||
_appFolderInfo = appFolderInfo;
|
||||
_diskProvider = diskProvider;
|
||||
_httpProvider = httpProvider;
|
||||
_httpClient = httpClient;
|
||||
_archiveService = archiveService;
|
||||
_processProvider = processProvider;
|
||||
_updateVerifier = updateVerifier;
|
||||
@ -79,7 +79,7 @@ namespace NzbDrone.Core.Update
|
||||
|
||||
_logger.ProgressInfo("Downloading update {0}", updatePackage.Version);
|
||||
_logger.Debug("Downloading update package from [{0}] to [{1}]", updatePackage.Url, packageDestination);
|
||||
_httpProvider.DownloadFile(updatePackage.Url, packageDestination);
|
||||
_httpClient.DownloadFile(updatePackage.Url, packageDestination);
|
||||
|
||||
_logger.ProgressInfo("Verifying update package");
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
namespace NzbDrone.Core.Update
|
||||
@ -23,7 +24,7 @@ namespace NzbDrone.Core.Update
|
||||
public List<UpdatePackage> GetRecentUpdatePackages()
|
||||
{
|
||||
var branch = _configFileProvider.Branch;
|
||||
return _updatePackageProvider.GetRecentUpdates(branch);
|
||||
return _updatePackageProvider.GetRecentUpdates(branch, BuildInfo.Version.Major);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ namespace NzbDrone.Core.Update
|
||||
public class UpdatePackage
|
||||
{
|
||||
public Version Version { get; set; }
|
||||
public String Branch { get; set; }
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
public String FileName { get; set; }
|
||||
public String Url { get; set; }
|
||||
|
@ -1,50 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Cloud;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using RestSharp;
|
||||
using NzbDrone.Core.Rest;
|
||||
using NzbDrone.Common.Http;
|
||||
|
||||
namespace NzbDrone.Core.Update
|
||||
{
|
||||
public interface IUpdatePackageProvider
|
||||
{
|
||||
UpdatePackage GetLatestUpdate(string branch, Version currentVersion);
|
||||
List<UpdatePackage> GetRecentUpdates(string branch);
|
||||
List<UpdatePackage> GetRecentUpdates(string branch, int majorVersion);
|
||||
}
|
||||
|
||||
public class UpdatePackageProvider : IUpdatePackageProvider
|
||||
{
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IDroneServicesRequestBuilder _requestBuilder;
|
||||
|
||||
public UpdatePackageProvider(IHttpClient httpClient, IDroneServicesRequestBuilder requestBuilder)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_requestBuilder = requestBuilder;
|
||||
}
|
||||
|
||||
public UpdatePackage GetLatestUpdate(string branch, Version currentVersion)
|
||||
{
|
||||
var restClient = RestClientFactory.BuildClient(Services.RootUrl);
|
||||
var request = _requestBuilder.Build("/update/{branch}");
|
||||
request.UriBuilder.SetQueryParam("version", currentVersion);
|
||||
request.UriBuilder.SetQueryParam("os", OsInfo.Os.ToString().ToLowerInvariant());
|
||||
request.AddSegment("branch", branch);
|
||||
|
||||
var request = new RestRequest("/v1/update/{branch}");
|
||||
|
||||
request.AddParameter("version", currentVersion);
|
||||
request.AddParameter("os", OsInfo.Os.ToString().ToLowerInvariant());
|
||||
request.AddUrlSegment("branch", branch);
|
||||
|
||||
var update = restClient.ExecuteAndValidate<UpdatePackageAvailable>(request);
|
||||
var update = _httpClient.Get<UpdatePackageAvailable>(request).Resource;
|
||||
|
||||
if (!update.Available) return null;
|
||||
|
||||
return update.UpdatePackage;
|
||||
}
|
||||
|
||||
public List<UpdatePackage> GetRecentUpdates(string branch)
|
||||
public List<UpdatePackage> GetRecentUpdates(string branch, int majorVersion)
|
||||
{
|
||||
var restClient = RestClientFactory.BuildClient(Services.RootUrl);
|
||||
var request = _requestBuilder.Build("/update/{branch}/changes");
|
||||
request.UriBuilder.SetQueryParam("os", OsInfo.Os.ToString().ToLowerInvariant());
|
||||
request.AddSegment("branch", branch);
|
||||
|
||||
var request = new RestRequest("/v1/update/{branch}/changes");
|
||||
var updates = _httpClient.Get<List<UpdatePackage>>(request);
|
||||
|
||||
request.AddParameter("majorVersion", BuildInfo.Version.Major);
|
||||
request.AddParameter("os", OsInfo.Os.ToString().ToLowerInvariant());
|
||||
request.AddUrlSegment("branch", branch);
|
||||
|
||||
var updates = restClient.ExecuteAndValidate<List<UpdatePackage>>(request);
|
||||
|
||||
return updates;
|
||||
return updates.Resource;
|
||||
}
|
||||
}
|
||||
}
|
@ -8,14 +8,12 @@ namespace NzbDrone.Test.Common
|
||||
{
|
||||
public abstract class LoggingTest
|
||||
{
|
||||
protected static Logger TestLogger;
|
||||
protected static readonly Logger TestLogger = LogManager.GetLogger("TestLogger");
|
||||
|
||||
protected static void InitLogging()
|
||||
{
|
||||
new StartupContext();
|
||||
|
||||
TestLogger = LogManager.GetLogger("TestLogger");
|
||||
|
||||
if (LogManager.Configuration == null || LogManager.Configuration is XmlLoggingConfiguration)
|
||||
{
|
||||
LogManager.Configuration = new LoggingConfiguration();
|
||||
@ -44,8 +42,6 @@ namespace NzbDrone.Test.Common
|
||||
[TearDown]
|
||||
public void LoggingDownBase()
|
||||
{
|
||||
|
||||
|
||||
//can't use because of a bug in mono with 2.6.2,
|
||||
//https://bugs.launchpad.net/nunitv2/+bug/1076932
|
||||
if (BuildInfo.IsDebug && TestContext.CurrentContext.Result.State == TestState.Success)
|
||||
|
@ -54,6 +54,9 @@ namespace NzbDrone.Test.Common
|
||||
if (_mocker == null)
|
||||
{
|
||||
_mocker = new AutoMoqer();
|
||||
_mocker.SetConstant<ICacheManager>(new CacheManager());
|
||||
_mocker.SetConstant<IStartupContext>(new StartupContext(new string[0]));
|
||||
_mocker.SetConstant(TestLogger);
|
||||
}
|
||||
|
||||
return _mocker;
|
||||
@ -89,11 +92,7 @@ namespace NzbDrone.Test.Common
|
||||
|
||||
GetType().IsPublic.Should().BeTrue("All Test fixtures should be public to work in mono.");
|
||||
|
||||
Mocker.SetConstant<ICacheManager>(new CacheManager());
|
||||
|
||||
Mocker.SetConstant(LogManager.GetLogger("TestLogger"));
|
||||
|
||||
Mocker.SetConstant<IStartupContext>(new StartupContext(new string[0]));
|
||||
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
|
||||
@ -140,7 +139,7 @@ namespace NzbDrone.Test.Common
|
||||
{
|
||||
if (!OsInfo.IsMono)
|
||||
{
|
||||
throw new IgnoreException("linux specific test");
|
||||
throw new IgnoreException("mono specific test");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user