Fixed: Refreshing anime series won't cause an error

pull/4/head
Mark McDowall 10 years ago
parent c8993db2ad
commit 4f0ca20808

@ -1,41 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.MetadataSource.Tvdb;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Test.Common.Categories;
namespace NzbDrone.Core.Test.MetadataSourceTests
{
[TestFixture]
[IntegrationTest]
public class TvdbProxyFixture : CoreTest<TvdbProxy>
{
[TestCase(88031)]
[TestCase(179321)]
public void should_be_able_to_get_series_detail(int tvdbId)
{
UseRealHttp();
var episodes = Subject.GetEpisodeInfo(tvdbId);
ValidateEpisodes(episodes);
}
private void ValidateEpisodes(List<Episode> episodes)
{
episodes.Should().NotBeEmpty();
episodes.GroupBy(e => e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000"))
.Max(e => e.Count()).Should().Be(1);
episodes.Should().Contain(c => c.SeasonNumber > 0);
episodes.Should().OnlyContain(c => c.SeasonNumber > 0 || c.EpisodeNumber > 0);
}
}
}

@ -249,7 +249,6 @@
<Compile Include="Messaging\Events\EventAggregatorFixture.cs" /> <Compile Include="Messaging\Events\EventAggregatorFixture.cs" />
<Compile Include="Metadata\Consumers\Roksbox\FindMetadataFileFixture.cs" /> <Compile Include="Metadata\Consumers\Roksbox\FindMetadataFileFixture.cs" />
<Compile Include="Metadata\Consumers\Wdtv\FindMetadataFileFixture.cs" /> <Compile Include="Metadata\Consumers\Wdtv\FindMetadataFileFixture.cs" />
<Compile Include="MetadataSourceTests\TvdbProxyFixture.cs" />
<Compile Include="NotificationTests\PlexProviderTest.cs" /> <Compile Include="NotificationTests\PlexProviderTest.cs" />
<Compile Include="NotificationTests\ProwlProviderTest.cs" /> <Compile Include="NotificationTests\ProwlProviderTest.cs" />
<Compile Include="NotificationTests\Xbmc\Http\ActivePlayersFixture.cs" /> <Compile Include="NotificationTests\Xbmc\Http\ActivePlayersFixture.cs" />

@ -6,7 +6,6 @@ using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.MetadataSource; using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.MetadataSource.Tvdb;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
@ -73,13 +72,6 @@ namespace NzbDrone.Core.Test.TvTests
.Callback<List<Episode>>(e => _deletedEpisodes = e); .Callback<List<Episode>>(e => _deletedEpisodes = e);
} }
private void GivenAnimeEpisodes(List<Episode> episodes)
{
Mocker.GetMock<ITvdbProxy>()
.Setup(s => s.GetEpisodeInfo(It.IsAny<Int32>()))
.Returns(episodes);
}
[Test] [Test]
public void should_create_all_when_no_existing_episodes() public void should_create_all_when_no_existing_episodes()
{ {
@ -175,22 +167,10 @@ namespace NzbDrone.Core.Test.TvTests
_deletedEpisodes.Should().BeEmpty(); _deletedEpisodes.Should().BeEmpty();
} }
[Test]
public void should_not_set_absolute_episode_number_for_non_anime()
{
Mocker.GetMock<IEpisodeService>().Setup(c => c.GetEpisodeBySeries(It.IsAny<Int32>()))
.Returns(new List<Episode>());
Subject.RefreshEpisodeInfo(GetSeries(), GetEpisodes());
_insertedEpisodes.All(e => !e.AbsoluteEpisodeNumber.HasValue).Should().BeTrue();
}
[Test] [Test]
public void should_set_absolute_episode_number_for_anime() public void should_set_absolute_episode_number_for_anime()
{ {
var episodes = Builder<Episode>.CreateListOfSize(3).Build().ToList(); var episodes = Builder<Episode>.CreateListOfSize(3).Build().ToList();
GivenAnimeEpisodes(episodes);
Mocker.GetMock<IEpisodeService>().Setup(c => c.GetEpisodeBySeries(It.IsAny<Int32>())) Mocker.GetMock<IEpisodeService>().Setup(c => c.GetEpisodeBySeries(It.IsAny<Int32>()))
.Returns(new List<Episode>()); .Returns(new List<Episode>());
@ -206,7 +186,6 @@ namespace NzbDrone.Core.Test.TvTests
public void should_set_absolute_episode_number_even_if_not_previously_set_for_anime() public void should_set_absolute_episode_number_even_if_not_previously_set_for_anime()
{ {
var episodes = Builder<Episode>.CreateListOfSize(3).Build().ToList(); var episodes = Builder<Episode>.CreateListOfSize(3).Build().ToList();
GivenAnimeEpisodes(episodes);
var existingEpisodes = episodes.JsonClone(); var existingEpisodes = episodes.JsonClone();
existingEpisodes.ForEach(e => e.AbsoluteEpisodeNumber = null); existingEpisodes.ForEach(e => e.AbsoluteEpisodeNumber = null);
@ -234,8 +213,6 @@ namespace NzbDrone.Core.Test.TvTests
.With(e => e.AbsoluteEpisodeNumber = expectedAbsoluteNumber) .With(e => e.AbsoluteEpisodeNumber = expectedAbsoluteNumber)
.Build(); .Build();
GivenAnimeEpisodes(new List<Episode> { episode });
var existingEpisode = episode.JsonClone(); var existingEpisode = episode.JsonClone();
existingEpisode.SeasonNumber = 1; existingEpisode.SeasonNumber = 1;
existingEpisode.EpisodeNumber = 1; existingEpisode.EpisodeNumber = 1;
@ -265,8 +242,6 @@ namespace NzbDrone.Core.Test.TvTests
episodes[0].SeasonNumber.Should().NotBe(episodes[1].SeasonNumber); episodes[0].SeasonNumber.Should().NotBe(episodes[1].SeasonNumber);
episodes[0].EpisodeNumber.Should().NotBe(episodes[1].EpisodeNumber); episodes[0].EpisodeNumber.Should().NotBe(episodes[1].EpisodeNumber);
GivenAnimeEpisodes(episodes);
var existingEpisode = new Episode var existingEpisode = new Episode
{ {
SeasonNumber = episodes[0].SeasonNumber, SeasonNumber = episodes[0].SeasonNumber,
@ -297,8 +272,6 @@ namespace NzbDrone.Core.Test.TvTests
episodes[3].AbsoluteEpisodeNumber = null; episodes[3].AbsoluteEpisodeNumber = null;
episodes[4].AbsoluteEpisodeNumber = null; episodes[4].AbsoluteEpisodeNumber = null;
GivenAnimeEpisodes(episodes);
Mocker.GetMock<IEpisodeService>().Setup(c => c.GetEpisodeBySeries(It.IsAny<Int32>())) Mocker.GetMock<IEpisodeService>().Setup(c => c.GetEpisodeBySeries(It.IsAny<Int32>()))
.Returns(new List<Episode>()); .Returns(new List<Episode>());

@ -160,12 +160,13 @@ namespace NzbDrone.Core.MetadataSource
return series; return series;
} }
private static Tv.Episode MapEpisode(TVDBSharp.Models.Episode traktEpisode) private static Episode MapEpisode(TVDBSharp.Models.Episode traktEpisode)
{ {
var episode = new Tv.Episode(); var episode = new Episode();
episode.Overview = traktEpisode.Description; episode.Overview = traktEpisode.Description;
episode.SeasonNumber = traktEpisode.SeasonNumber; episode.SeasonNumber = traktEpisode.SeasonNumber;
episode.EpisodeNumber = traktEpisode.EpisodeNumber; episode.EpisodeNumber = traktEpisode.EpisodeNumber;
episode.AbsoluteEpisodeNumber = traktEpisode.AbsoluteEpisodeNumber;
episode.Title = traktEpisode.Title; episode.Title = traktEpisode.Title;
if (traktEpisode.FirstAired != null) if (traktEpisode.FirstAired != null)

@ -1,52 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.MetadataSource.Tvdb
{
public interface ITvdbProxy
{
List<Episode> GetEpisodeInfo(int tvdbSeriesId);
}
public class TvdbProxy : ITvdbProxy
{
private readonly IHttpClient _httpClient;
public TvdbProxy(IHttpClient httpClient)
{
_httpClient = httpClient;
}
public List<Episode> GetEpisodeInfo(int tvdbSeriesId)
{
var httpRequest = new HttpRequest("http://thetvdb.com/data/series/{tvdbId}/all/");
httpRequest.AddSegment("tvdbId", tvdbSeriesId.ToString());
var response = _httpClient.Get(httpRequest);
var xml = XDocument.Load(new StringReader(response.Content));
var episodes = xml.Descendants("Episode").Select(MapEpisode).ToList();
return episodes;
}
private static Episode MapEpisode(XElement item)
{
//TODO: We should map all the data incase we want to actually use it
var episode = new Episode();
episode.SeasonNumber = item.TryGetValue("SeasonNumber", 0);
episode.EpisodeNumber = item.TryGetValue("EpisodeNumber", 0);
if (item.TryGetValue("absolute_number").IsNotNullOrWhiteSpace())
{
episode.AbsoluteEpisodeNumber = item.TryGetValue("absolute_number", 0);
}
return episode;
}
}
}

@ -598,6 +598,7 @@
<Compile Include="Messaging\IProcessMessage.cs" /> <Compile Include="Messaging\IProcessMessage.cs" />
<Compile Include="MetadataSource\TvDbProxy.cs" /> <Compile Include="MetadataSource\TvDbProxy.cs" />
<Compile Include="MetadataSource\SearchSeriesComparer.cs" /> <Compile Include="MetadataSource\SearchSeriesComparer.cs" />
<Compile Include="MetadataSource\Tvdb\TvdbException.cs" />
<Compile Include="Metadata\Consumers\MediaBrowser\MediaBrowserMetadata.cs" /> <Compile Include="Metadata\Consumers\MediaBrowser\MediaBrowserMetadata.cs" />
<Compile Include="Metadata\Consumers\MediaBrowser\MediaBrowserMetadataSettings.cs" /> <Compile Include="Metadata\Consumers\MediaBrowser\MediaBrowserMetadataSettings.cs" />
<Compile Include="Metadata\Consumers\Roksbox\RoksboxMetadata.cs" /> <Compile Include="Metadata\Consumers\Roksbox\RoksboxMetadata.cs" />
@ -623,8 +624,6 @@
<Compile Include="Metadata\MetadataType.cs" /> <Compile Include="Metadata\MetadataType.cs" />
<Compile Include="MetadataSource\IProvideSeriesInfo.cs" /> <Compile Include="MetadataSource\IProvideSeriesInfo.cs" />
<Compile Include="MetadataSource\ISearchForNewSeries.cs" /> <Compile Include="MetadataSource\ISearchForNewSeries.cs" />
<Compile Include="MetadataSource\Tvdb\TvdbException.cs" />
<Compile Include="MetadataSource\Tvdb\TvdbProxy.cs" />
<Compile Include="Profiles\Delay\DelayProfile.cs" /> <Compile Include="Profiles\Delay\DelayProfile.cs" />
<Compile Include="Profiles\Delay\DelayProfileService.cs" /> <Compile Include="Profiles\Delay\DelayProfileService.cs" />
<Compile Include="Profiles\Delay\DelayProfileTagInUseValidator.cs" /> <Compile Include="Profiles\Delay\DelayProfileTagInUseValidator.cs" />

@ -4,7 +4,6 @@ using System.Linq;
using NLog; using NLog;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.MetadataSource.Tvdb;
using NzbDrone.Core.Tv.Events; using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Core.Tv namespace NzbDrone.Core.Tv
@ -17,14 +16,12 @@ namespace NzbDrone.Core.Tv
public class RefreshEpisodeService : IRefreshEpisodeService public class RefreshEpisodeService : IRefreshEpisodeService
{ {
private readonly IEpisodeService _episodeService; private readonly IEpisodeService _episodeService;
private readonly ITvdbProxy _tvdbProxy;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly Logger _logger; private readonly Logger _logger;
public RefreshEpisodeService(IEpisodeService episodeService, ITvdbProxy tvdbProxy, IEventAggregator eventAggregator, Logger logger) public RefreshEpisodeService(IEpisodeService episodeService, IEventAggregator eventAggregator, Logger logger)
{ {
_episodeService = episodeService; _episodeService = episodeService;
_tvdbProxy = tvdbProxy;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_logger = logger; _logger = logger;
} }
@ -153,23 +150,6 @@ namespace NzbDrone.Core.Tv
private List<Episode> MapAbsoluteEpisodeNumbers(Series series, List<Episode> traktEpisodes) private List<Episode> MapAbsoluteEpisodeNumbers(Series series, List<Episode> traktEpisodes)
{ {
var tvdbEpisodes = _tvdbProxy.GetEpisodeInfo(series.TvdbId);
foreach (var episode in traktEpisodes)
{
//I'd use single, but then I'd have to trust the tvdb data... and I don't
var tvdbEpisode = tvdbEpisodes.FirstOrDefault(e => e.SeasonNumber == episode.SeasonNumber &&
e.EpisodeNumber == episode.EpisodeNumber);
if (tvdbEpisode == null)
{
_logger.Debug("Cannot find matching episode from the tvdb: {0}x{1:00}", episode.SeasonNumber, episode.EpisodeNumber);
continue;
}
episode.AbsoluteEpisodeNumber = tvdbEpisode.AbsoluteEpisodeNumber;
}
//Return all episodes with no abs number, but distinct for those with abs number //Return all episodes with no abs number, but distinct for those with abs number
return traktEpisodes.Where(e => e.AbsoluteEpisodeNumber.HasValue) return traktEpisodes.Where(e => e.AbsoluteEpisodeNumber.HasValue)
.DistinctBy(e => e.AbsoluteEpisodeNumber.Value) .DistinctBy(e => e.AbsoluteEpisodeNumber.Value)

@ -160,6 +160,10 @@ namespace TVDBSharp.Models
Id = int.Parse(episodeNode.GetXmlData("id")), Id = int.Parse(episodeNode.GetXmlData("id")),
Title = episodeNode.GetXmlData("EpisodeName"), Title = episodeNode.GetXmlData("EpisodeName"),
Description = episodeNode.GetXmlData("Overview"), Description = episodeNode.GetXmlData("Overview"),
AbsoluteEpisodeNumber =
string.IsNullOrWhiteSpace(episodeNode.GetXmlData("absolute_number"))
? (int?)null
: int.Parse(episodeNode.GetXmlData("absolute_number")),
EpisodeNumber = int.Parse(episodeNode.GetXmlData("EpisodeNumber")), EpisodeNumber = int.Parse(episodeNode.GetXmlData("EpisodeNumber")),
Director = episodeNode.GetXmlData("Director"), Director = episodeNode.GetXmlData("Director"),
EpisodeImage = GetBannerUri(episodeNode.GetXmlData("filename")), EpisodeImage = GetBannerUri(episodeNode.GetXmlData("filename")),

@ -23,6 +23,11 @@ namespace TVDBSharp.Models
/// </summary> /// </summary>
public string Title { get; set; } public string Title { get; set; }
/// <summary>
/// This episode's absolute number
/// </summary>
public int? AbsoluteEpisodeNumber { get; set; }
/// <summary> /// <summary>
/// This episode's number in the appropriate season. /// This episode's number in the appropriate season.
/// </summary> /// </summary>

Loading…
Cancel
Save