1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-12-16 11:37:58 +02: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:
Taloth Saldono 2015-08-12 20:45:44 +02:00
parent 2627072aab
commit 9bcb6ff19a
9 changed files with 124 additions and 20 deletions

View File

@ -83,16 +83,27 @@ public void should_throw_on_unsuccessful_status_codes(int statusCode)
ExceptionVerification.IgnoreWarns();
}
[TestCase(HttpStatusCode.MovedPermanently)]
public void should_not_follow_redirects_when_not_in_production(HttpStatusCode statusCode)
[Test]
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);
}
[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]
public void should_send_user_agent()
{

View File

@ -61,11 +61,6 @@ public HttpResponse Execute(HttpRequest request)
webRequest.AllowAutoRedirect = request.AllowAutoRedirect;
webRequest.ContentLength = 0;
if (!RuntimeInfoBase.IsProduction)
{
webRequest.AllowAutoRedirect = false;
}
var stopWatch = Stopwatch.StartNew();
if (request.Headers != null)
@ -83,7 +78,7 @@ public HttpResponse Execute(HttpRequest request)
_logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds);
if (request.AllowAutoRedirect && !RuntimeInfoBase.IsProduction &&
if (!RuntimeInfoBase.IsProduction &&
(response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.MovedPermanently ||
response.StatusCode == HttpStatusCode.Found))

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Net;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Common.Http
{
@ -16,6 +17,11 @@ public HttpRequest(string url, HttpAccept httpAccept = null)
AllowAutoRedirect = true;
Cookies = new Dictionary<string, string>();
if (!RuntimeInfoBase.IsProduction)
{
AllowAutoRedirect = false;
}
if (httpAccept != null)
{
Headers.Accept = httpAccept.Value;

View File

@ -3,6 +3,7 @@
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MetadataSource.SkyHook;
using NzbDrone.Core.Test.Framework;
@ -38,9 +39,7 @@ public void should_be_able_to_get_series_detail(int tvdbId, string title)
[Test]
public void getting_details_of_invalid_series()
{
Assert.Throws<Common.Http.HttpException>(() => Subject.GetSeriesInfo(Int32.MaxValue));
ExceptionVerification.ExpectedWarns(1);
Assert.Throws<SeriesNotFoundException>(() => Subject.GetSeriesInfo(Int32.MaxValue));
}
[Test]

View File

@ -5,10 +5,12 @@
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Commands;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.TvTests
{
@ -34,14 +36,16 @@ public void Setup()
Mocker.GetMock<ISeriesService>()
.Setup(s => s.GetSeries(_series.Id))
.Returns(_series);
Mocker.GetMock<IProvideSeriesInfo>()
.Setup(s => s.GetSeriesInfo(It.IsAny<int>()))
.Callback<int>(p => { throw new SeriesNotFoundException(p); });
}
private void GivenNewSeriesInfo(Series series)
{
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>()));
}
@ -90,5 +94,32 @@ public void should_update_tvrage_id_if_changed()
Mocker.GetMock<ISeriesService>()
.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);
}
}
}

View 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;
}
}
}

View File

@ -2,11 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
using NzbDrone.Core.Tv;
@ -31,8 +30,23 @@ public Tuple<Series, List<Episode>> GetSeriesInfo(int tvdbSeriesId)
{
var httpRequest = _requestBuilder.Build(tvdbSeriesId.ToString());
httpRequest.AddSegment("route", "shows");
httpRequest.AllowAutoRedirect = true;
httpRequest.SuppressHttpError = true;
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 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}");
httpRequest.AddSegment("route", "search");
httpRequest.AddSegment("term", term);
@ -80,7 +94,7 @@ public List<Series> SearchForNewSeries(string title)
return httpResponse.Resource.SelectList(MapSeries);
}
catch (Common.Http.HttpException)
catch (HttpException)
{
throw new SkyHookException("Search for '{0}' failed. Unable to communicate with SkyHook.", title);
}

View File

@ -431,6 +431,7 @@
<Compile Include="Exceptions\BadRequestException.cs" />
<Compile Include="Exceptions\DownstreamException.cs" />
<Compile Include="Exceptions\NzbDroneClientException.cs" />
<Compile Include="Exceptions\SeriesNotFoundException.cs" />
<Compile Include="Exceptions\ReleaseDownloadException.cs" />
<Compile Include="Exceptions\StatusCodeToExceptions.cs" />
<Compile Include="Fluent.cs" />

View File

@ -6,6 +6,7 @@
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Core.DataAugmentation.DailySeries;
using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
@ -48,10 +49,27 @@ public RefreshSeriesService(IProvideSeriesInfo seriesInfo,
private void RefreshSeriesInfo(Series series)
{
_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;
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.TitleSlug = seriesInfo.TitleSlug;
series.TvRageId = seriesInfo.TvRageId;