commit
879035b28a
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
namespace NzbDrone.Common.Http
|
||||||
|
{
|
||||||
|
public enum HttpMethod
|
||||||
|
{
|
||||||
|
GET,
|
||||||
|
PUT,
|
||||||
|
POST,
|
||||||
|
HEAD,
|
||||||
|
DELETE,
|
||||||
|
PATCH,
|
||||||
|
OPTIONS
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,53 +1,33 @@
|
|||||||
using System;
|
|
||||||
using System.Net;
|
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
using NzbDrone.Core.DataAugmentation.Scene;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common.Categories;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
|
namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[IntegrationTest]
|
||||||
public class SceneMappingProxyFixture : CoreTest<SceneMappingProxy>
|
public class SceneMappingProxyFixture : CoreTest<SceneMappingProxy>
|
||||||
{
|
{
|
||||||
private const string SCENE_MAPPING_URL = "http://services.nzbdrone.com/v1/SceneMapping";
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
UseRealHttp();
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void fetch_should_return_list_of_mappings()
|
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();
|
var mappings = Subject.Fetch();
|
||||||
|
|
||||||
mappings.Should().NotBeEmpty();
|
mappings.Should().NotBeEmpty();
|
||||||
|
|
||||||
mappings.Should().NotContain(c => String.IsNullOrWhiteSpace(c.SearchTerm));
|
mappings.Should().NotContain(c => c.SearchTerm.IsNullOrWhiteSpace());
|
||||||
mappings.Should().NotContain(c => String.IsNullOrWhiteSpace(c.Title));
|
mappings.Should().NotContain(c => c.Title.IsNullOrWhiteSpace());
|
||||||
mappings.Should().NotContain(c => c.TvdbId == 0);
|
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
]
|
|
@ -0,0 +1,7 @@
|
|||||||
|
namespace NzbDrone.Core.DataAugmentation.DailySeries
|
||||||
|
{
|
||||||
|
public class DailySeries
|
||||||
|
{
|
||||||
|
public int TvdbId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
namespace NzbDrone.Core.DataAugmentation.DailySeries
|
||||||
{
|
{
|
||||||
public interface IDailySeriesService
|
public interface IDailySeriesService
|
||||||
{
|
{
|
||||||
void UpdateDailySeries();
|
|
||||||
bool IsDailySeries(int tvdbid);
|
bool IsDailySeries(int tvdbid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DailySeriesService : IDailySeriesService
|
public class DailySeriesService : IDailySeriesService
|
||||||
{
|
{
|
||||||
//TODO: add timer command
|
|
||||||
|
|
||||||
private readonly IDailySeriesDataProxy _proxy;
|
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;
|
_proxy = proxy;
|
||||||
_seriesService = seriesService;
|
_cache = cacheManager.GetCache<List<int>>(GetType());
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDailySeries(int tvdbid)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in new issue