mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-09 04:22:30 +01:00
New: Sonarr can now update series to use another tvdbid in case when tvdb removes a duplicate and Skyhook detects it.
This commit is contained in:
parent
2627072aab
commit
9bcb6ff19a
@ -83,16 +83,27 @@ public void should_throw_on_unsuccessful_status_codes(int statusCode)
|
|||||||
ExceptionVerification.IgnoreWarns();
|
ExceptionVerification.IgnoreWarns();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(HttpStatusCode.MovedPermanently)]
|
[Test]
|
||||||
public void should_not_follow_redirects_when_not_in_production(HttpStatusCode statusCode)
|
public void should_not_follow_redirects_when_not_in_production()
|
||||||
{
|
{
|
||||||
var request = new HttpRequest("http://eu.httpbin.org/status/" + (int)statusCode);
|
var request = new HttpRequest("http://eu.httpbin.org/redirect/1");
|
||||||
|
|
||||||
Subject.Get<HttpBinResource>(request);
|
Subject.Get(request);
|
||||||
|
|
||||||
ExceptionVerification.ExpectedErrors(1);
|
ExceptionVerification.ExpectedErrors(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_follow_redirects()
|
||||||
|
{
|
||||||
|
var request = new HttpRequest("http://eu.httpbin.org/redirect/1");
|
||||||
|
request.AllowAutoRedirect = true;
|
||||||
|
|
||||||
|
Subject.Get(request);
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedErrors(0);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_send_user_agent()
|
public void should_send_user_agent()
|
||||||
{
|
{
|
||||||
|
@ -61,11 +61,6 @@ public HttpResponse Execute(HttpRequest request)
|
|||||||
webRequest.AllowAutoRedirect = request.AllowAutoRedirect;
|
webRequest.AllowAutoRedirect = request.AllowAutoRedirect;
|
||||||
webRequest.ContentLength = 0;
|
webRequest.ContentLength = 0;
|
||||||
|
|
||||||
if (!RuntimeInfoBase.IsProduction)
|
|
||||||
{
|
|
||||||
webRequest.AllowAutoRedirect = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var stopWatch = Stopwatch.StartNew();
|
var stopWatch = Stopwatch.StartNew();
|
||||||
|
|
||||||
if (request.Headers != null)
|
if (request.Headers != null)
|
||||||
@ -83,7 +78,7 @@ public HttpResponse Execute(HttpRequest request)
|
|||||||
|
|
||||||
_logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds);
|
_logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds);
|
||||||
|
|
||||||
if (request.AllowAutoRedirect && !RuntimeInfoBase.IsProduction &&
|
if (!RuntimeInfoBase.IsProduction &&
|
||||||
(response.StatusCode == HttpStatusCode.Moved ||
|
(response.StatusCode == HttpStatusCode.Moved ||
|
||||||
response.StatusCode == HttpStatusCode.MovedPermanently ||
|
response.StatusCode == HttpStatusCode.MovedPermanently ||
|
||||||
response.StatusCode == HttpStatusCode.Found))
|
response.StatusCode == HttpStatusCode.Found))
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
|
||||||
namespace NzbDrone.Common.Http
|
namespace NzbDrone.Common.Http
|
||||||
{
|
{
|
||||||
@ -16,6 +17,11 @@ public HttpRequest(string url, HttpAccept httpAccept = null)
|
|||||||
AllowAutoRedirect = true;
|
AllowAutoRedirect = true;
|
||||||
Cookies = new Dictionary<string, string>();
|
Cookies = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
if (!RuntimeInfoBase.IsProduction)
|
||||||
|
{
|
||||||
|
AllowAutoRedirect = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (httpAccept != null)
|
if (httpAccept != null)
|
||||||
{
|
{
|
||||||
Headers.Accept = httpAccept.Value;
|
Headers.Accept = httpAccept.Value;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.MetadataSource.SkyHook;
|
using NzbDrone.Core.MetadataSource.SkyHook;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
@ -38,9 +39,7 @@ public void should_be_able_to_get_series_detail(int tvdbId, string title)
|
|||||||
[Test]
|
[Test]
|
||||||
public void getting_details_of_invalid_series()
|
public void getting_details_of_invalid_series()
|
||||||
{
|
{
|
||||||
Assert.Throws<Common.Http.HttpException>(() => Subject.GetSeriesInfo(Int32.MaxValue));
|
Assert.Throws<SeriesNotFoundException>(() => Subject.GetSeriesInfo(Int32.MaxValue));
|
||||||
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.MetadataSource;
|
using NzbDrone.Core.MetadataSource;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Tv.Commands;
|
using NzbDrone.Core.Tv.Commands;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.TvTests
|
namespace NzbDrone.Core.Test.TvTests
|
||||||
{
|
{
|
||||||
@ -34,14 +36,16 @@ public void Setup()
|
|||||||
Mocker.GetMock<ISeriesService>()
|
Mocker.GetMock<ISeriesService>()
|
||||||
.Setup(s => s.GetSeries(_series.Id))
|
.Setup(s => s.GetSeries(_series.Id))
|
||||||
.Returns(_series);
|
.Returns(_series);
|
||||||
|
|
||||||
|
|
||||||
|
Mocker.GetMock<IProvideSeriesInfo>()
|
||||||
|
.Setup(s => s.GetSeriesInfo(It.IsAny<int>()))
|
||||||
|
.Callback<int>(p => { throw new SeriesNotFoundException(p); });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenNewSeriesInfo(Series series)
|
private void GivenNewSeriesInfo(Series series)
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IProvideSeriesInfo>()
|
Mocker.GetMock<IProvideSeriesInfo>()
|
||||||
.Setup(s => s.GetSeriesInfo(It.IsAny<Int32>()))
|
.Setup(s => s.GetSeriesInfo(_series.TvdbId))
|
||||||
.Returns(new Tuple<Series, List<Episode>>(series, new List<Episode>()));
|
.Returns(new Tuple<Series, List<Episode>>(series, new List<Episode>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,5 +94,32 @@ public void should_update_tvrage_id_if_changed()
|
|||||||
Mocker.GetMock<ISeriesService>()
|
Mocker.GetMock<ISeriesService>()
|
||||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.TvRageId == newSeriesInfo.TvRageId)));
|
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.TvRageId == newSeriesInfo.TvRageId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_log_error_if_tvdb_id_not_found()
|
||||||
|
{
|
||||||
|
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
||||||
|
|
||||||
|
Mocker.GetMock<ISeriesService>()
|
||||||
|
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedErrors(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_update_if_tvdb_id_changed()
|
||||||
|
{
|
||||||
|
var newSeriesInfo = _series.JsonClone();
|
||||||
|
newSeriesInfo.TvdbId = _series.TvdbId + 1;
|
||||||
|
|
||||||
|
GivenNewSeriesInfo(newSeriesInfo);
|
||||||
|
|
||||||
|
Subject.Execute(new RefreshSeriesCommand(_series.Id));
|
||||||
|
|
||||||
|
Mocker.GetMock<ISeriesService>()
|
||||||
|
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.TvdbId == newSeriesInfo.TvdbId)));
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
src/NzbDrone.Core/Exceptions/SeriesNotFoundException.cs
Normal file
29
src/NzbDrone.Core/Exceptions/SeriesNotFoundException.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using NzbDrone.Common.Exceptions;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Exceptions
|
||||||
|
{
|
||||||
|
public class SeriesNotFoundException : NzbDroneException
|
||||||
|
{
|
||||||
|
public int TvdbSeriesId { get; set; }
|
||||||
|
|
||||||
|
public SeriesNotFoundException(int tvdbSeriesId)
|
||||||
|
: base(string.Format("Series with tvdbid {0} was not found, it may have been removed from TheTVDB.", tvdbSeriesId))
|
||||||
|
{
|
||||||
|
TvdbSeriesId = tvdbSeriesId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SeriesNotFoundException(int tvdbSeriesId, string message, params object[] args)
|
||||||
|
: base(message, args)
|
||||||
|
{
|
||||||
|
TvdbSeriesId = tvdbSeriesId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SeriesNotFoundException(int tvdbSeriesId, string message)
|
||||||
|
: base(message)
|
||||||
|
{
|
||||||
|
TvdbSeriesId = tvdbSeriesId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Web;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
@ -31,8 +30,23 @@ public Tuple<Series, List<Episode>> GetSeriesInfo(int tvdbSeriesId)
|
|||||||
{
|
{
|
||||||
var httpRequest = _requestBuilder.Build(tvdbSeriesId.ToString());
|
var httpRequest = _requestBuilder.Build(tvdbSeriesId.ToString());
|
||||||
httpRequest.AddSegment("route", "shows");
|
httpRequest.AddSegment("route", "shows");
|
||||||
|
httpRequest.AllowAutoRedirect = true;
|
||||||
|
httpRequest.SuppressHttpError = true;
|
||||||
|
|
||||||
var httpResponse = _httpClient.Get<ShowResource>(httpRequest);
|
var httpResponse = _httpClient.Get<ShowResource>(httpRequest);
|
||||||
|
|
||||||
|
if (httpResponse.HasHttpError)
|
||||||
|
{
|
||||||
|
if (httpResponse.StatusCode == HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
throw new SeriesNotFoundException(tvdbSeriesId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new HttpException(httpRequest, httpResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var episodes = httpResponse.Resource.Episodes.Select(MapEpisode);
|
var episodes = httpResponse.Resource.Episodes.Select(MapEpisode);
|
||||||
var series = MapSeries(httpResponse.Resource);
|
var series = MapSeries(httpResponse.Resource);
|
||||||
|
|
||||||
@ -71,7 +85,7 @@ public List<Series> SearchForNewSeries(string title)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var term = HttpUtility.UrlEncode((title.ToLower().Trim()));
|
var term = System.Web.HttpUtility.UrlEncode((title.ToLower().Trim()));
|
||||||
var httpRequest = _requestBuilder.Build("?term={term}");
|
var httpRequest = _requestBuilder.Build("?term={term}");
|
||||||
httpRequest.AddSegment("route", "search");
|
httpRequest.AddSegment("route", "search");
|
||||||
httpRequest.AddSegment("term", term);
|
httpRequest.AddSegment("term", term);
|
||||||
@ -80,7 +94,7 @@ public List<Series> SearchForNewSeries(string title)
|
|||||||
|
|
||||||
return httpResponse.Resource.SelectList(MapSeries);
|
return httpResponse.Resource.SelectList(MapSeries);
|
||||||
}
|
}
|
||||||
catch (Common.Http.HttpException)
|
catch (HttpException)
|
||||||
{
|
{
|
||||||
throw new SkyHookException("Search for '{0}' failed. Unable to communicate with SkyHook.", title);
|
throw new SkyHookException("Search for '{0}' failed. Unable to communicate with SkyHook.", title);
|
||||||
}
|
}
|
||||||
|
@ -431,6 +431,7 @@
|
|||||||
<Compile Include="Exceptions\BadRequestException.cs" />
|
<Compile Include="Exceptions\BadRequestException.cs" />
|
||||||
<Compile Include="Exceptions\DownstreamException.cs" />
|
<Compile Include="Exceptions\DownstreamException.cs" />
|
||||||
<Compile Include="Exceptions\NzbDroneClientException.cs" />
|
<Compile Include="Exceptions\NzbDroneClientException.cs" />
|
||||||
|
<Compile Include="Exceptions\SeriesNotFoundException.cs" />
|
||||||
<Compile Include="Exceptions\ReleaseDownloadException.cs" />
|
<Compile Include="Exceptions\ReleaseDownloadException.cs" />
|
||||||
<Compile Include="Exceptions\StatusCodeToExceptions.cs" />
|
<Compile Include="Exceptions\StatusCodeToExceptions.cs" />
|
||||||
<Compile Include="Fluent.cs" />
|
<Compile Include="Fluent.cs" />
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.DataAugmentation.DailySeries;
|
using NzbDrone.Core.DataAugmentation.DailySeries;
|
||||||
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
@ -48,10 +49,27 @@ public RefreshSeriesService(IProvideSeriesInfo seriesInfo,
|
|||||||
private void RefreshSeriesInfo(Series series)
|
private void RefreshSeriesInfo(Series series)
|
||||||
{
|
{
|
||||||
_logger.ProgressInfo("Updating Info for {0}", series.Title);
|
_logger.ProgressInfo("Updating Info for {0}", series.Title);
|
||||||
var tuple = _seriesInfo.GetSeriesInfo(series.TvdbId);
|
|
||||||
|
Tuple<Series, List<Episode>> tuple;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tuple = _seriesInfo.GetSeriesInfo(series.TvdbId);
|
||||||
|
}
|
||||||
|
catch (SeriesNotFoundException)
|
||||||
|
{
|
||||||
|
_logger.Error("Series '{0}' (tvdbid {1}) was not found, it may have been removed from TheTVDB.", series.Title, series.TvdbId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var seriesInfo = tuple.Item1;
|
var seriesInfo = tuple.Item1;
|
||||||
|
|
||||||
|
if (series.TvdbId != seriesInfo.TvdbId)
|
||||||
|
{
|
||||||
|
_logger.Warn("Series '{0}' (tvdbid {1}) was replaced with '{2}' (tvdbid {3}), because the original was a duplicate.", series.Title, series.TvdbId, seriesInfo.Title, seriesInfo.TvdbId);
|
||||||
|
series.TvdbId = seriesInfo.TvdbId;
|
||||||
|
}
|
||||||
|
|
||||||
series.Title = seriesInfo.Title;
|
series.Title = seriesInfo.Title;
|
||||||
series.TitleSlug = seriesInfo.TitleSlug;
|
series.TitleSlug = seriesInfo.TitleSlug;
|
||||||
series.TvRageId = seriesInfo.TvRageId;
|
series.TvRageId = seriesInfo.TvRageId;
|
||||||
|
Loading…
Reference in New Issue
Block a user