From a6e8ec6123d3095652c8c30539f2822676e682fb Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 12 Oct 2012 20:49:59 -0700 Subject: [PATCH] XemClient added New: Now using the thexem.de for episode information --- Libraries/XemLib/XemLib.dll | Bin 0 -> 33280 bytes Libraries/XemLib/XemLib.pdb | Bin 0 -> 60928 bytes NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 7 +- .../ProviderTests/EpisodeProviderTest.cs | 52 +++++++------- ...isodeProviderTest_DeleteInvalidEpisodes.cs | 12 ++-- .../Metadata/Xbmc_ForEpisodeFile_Fixture.cs | 24 +++---- .../Metadata/Xbmc_ForSeries_Fixture.cs | 36 +++++----- .../RecycleBinProviderTests/CleanupFixture.cs | 1 - .../DeleteDirectoryFixture.cs | 1 - .../DeleteFileFixture.cs | 1 - .../RecycleBinProviderTests/EmptyFixture.cs | 1 - .../ProviderTests/SeasonProviderTest.cs | 1 - .../ProviderTests/TvDbProviderTest.cs | 59 +--------------- NzbDrone.Core/NzbDrone.Core.csproj | 7 +- NzbDrone.Core/Providers/EpisodeProvider.cs | 2 +- .../Providers/Metadata/MetadataBase.cs | 2 +- NzbDrone.Core/Providers/Metadata/Xbmc.cs | 34 ++++----- NzbDrone.Core/Providers/MetadataProvider.cs | 8 +-- NzbDrone.Core/Providers/SeriesProvider.cs | 4 +- NzbDrone.Core/Providers/TvDbProvider.cs | 65 +++++------------- .../Controllers/AddSeriesController.cs | 6 +- NzbDrone.Web/NzbDrone.Web.csproj | 8 +-- 22 files changed, 121 insertions(+), 210 deletions(-) create mode 100644 Libraries/XemLib/XemLib.dll create mode 100644 Libraries/XemLib/XemLib.pdb diff --git a/Libraries/XemLib/XemLib.dll b/Libraries/XemLib/XemLib.dll new file mode 100644 index 0000000000000000000000000000000000000000..b32ae3128c86729098a1e21c4de42858d6bfd870 GIT binary patch literal 33280 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
  • P{IH@^pw~_x8F7G*`y|mDFfHrFF+|nxB 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 Nq3(ZMK)d#&Gk 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 Y-jaaUmmTk|D)rT-PXc`s$WsFU2U=Q)+W-In literal 0 HcmV?d00001 diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 42e947a8a..91bf04d2c 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -128,14 +128,13 @@ - - False - ..\Libraries\TvdbLib.dll - False ..\packages\WebActivator.1.5\lib\net40\WebActivator.dll + + ..\Libraries\XemLib\XemLib.dll + diff --git a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs index 9870924f1..d17aa670a 100644 --- a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs @@ -17,7 +17,7 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; using PetaPoco; -using TvdbLib.Data; +using XemLib.Data; namespace NzbDrone.Core.Test.ProviderTests { @@ -161,7 +161,7 @@ namespace NzbDrone.Core.Test.ProviderTests c => c.Episodes = new List(Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .Build()) ).With(c => c.Id = seriesId).Build(); @@ -172,7 +172,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeEpisodes); //Act @@ -195,7 +195,7 @@ namespace NzbDrone.Core.Test.ProviderTests c => c.Episodes = new List(Builder.CreateListOfSize(10). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")).And(e => e.FirstAired = DateTime.Now) + .With(l => l.Language = "en").And(e => e.FirstAired = DateTime.Now) .TheFirst(7).With(e => e.FirstAired = new DateTime(1800, 1, 1)) .Build()) ).With(c => c.Id = seriesId).Build(); @@ -207,7 +207,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeEpisodes); @@ -236,7 +236,7 @@ namespace NzbDrone.Core.Test.ProviderTests c => c.Episodes = new List(Builder.CreateListOfSize(1) .All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")).And(e => e.FirstAired = DateTime.Now) + .With(l => l.Language = "en").And(e => e.FirstAired = DateTime.Now) .TheFirst(1).With(e => e.FirstAired = new DateTime(1800, 1, 1)) .Build()) ).With(c => c.Id = seriesId).Build(); @@ -248,7 +248,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeEpisode); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeTvDbEpisodes); //Act @@ -271,7 +271,7 @@ namespace NzbDrone.Core.Test.ProviderTests c => c.Episodes = new List(Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .TheFirst(1) .With(e => e.EpisodeNumber = 0) .With(e => e.SeasonNumber = 15) @@ -285,7 +285,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeEpisodes); @@ -324,7 +324,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeEpisodes); @@ -362,7 +362,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeEpisodes); @@ -395,7 +395,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeEpisodes); @@ -428,7 +428,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeEpisodes); @@ -451,7 +451,7 @@ namespace NzbDrone.Core.Test.ProviderTests c => c.Episodes = new List(Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .With(e => e.SeasonNumber = 0) .Build()) ).With(c => c.Id = seriesId).Build(); @@ -463,7 +463,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeEpisodes); Mocker.GetMock() @@ -493,7 +493,7 @@ namespace NzbDrone.Core.Test.ProviderTests var currentEpisodes = new List(); Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(tvdbSeries); Mocker.GetMock() @@ -528,7 +528,7 @@ namespace NzbDrone.Core.Test.ProviderTests } Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(tvdbSeries); Mocker.GetMock() @@ -565,7 +565,7 @@ namespace NzbDrone.Core.Test.ProviderTests .Returns(fakeEpisodeList); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(fakeTvDbResult); //Act @@ -602,7 +602,7 @@ namespace NzbDrone.Core.Test.ProviderTests var fakeSeries = Builder.CreateNew().With(c => c.SeriesId = seriesId).Build(); Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(tvdbSeries); Mocker.GetMock() @@ -643,7 +643,7 @@ namespace NzbDrone.Core.Test.ProviderTests } Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(tvdbSeries); var updatedEpisodes = new List(); @@ -692,7 +692,7 @@ namespace NzbDrone.Core.Test.ProviderTests } Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(tvdbSeries); var updatedEpisodes = new List(); @@ -738,7 +738,7 @@ namespace NzbDrone.Core.Test.ProviderTests } Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(tvdbSeries); var updatedEpisodes = new List(); @@ -777,7 +777,7 @@ namespace NzbDrone.Core.Test.ProviderTests c => c.Episodes = new List(Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .With(e => e.SeasonNumber = 5) .TheFirst(1) .With(e => e.EpisodeNumber = 1) @@ -796,7 +796,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeEpisode); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(tvdbSeries); Mocker.GetMock() @@ -1486,7 +1486,7 @@ namespace NzbDrone.Core.Test.ProviderTests c => c.Episodes = new List(Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .With(e => e.EpisodeNumber = 0) .TheFirst(1) .With(e => e.SeasonNumber = 1) @@ -1508,7 +1508,7 @@ namespace NzbDrone.Core.Test.ProviderTests Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true, false)) + .Setup(c => c.GetSeries(seriesId, true, false, false)) .Returns(tvdbSeries); //Act diff --git a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest_DeleteInvalidEpisodes.cs b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest_DeleteInvalidEpisodes.cs index c4f767a92..2d43a5c03 100644 --- a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest_DeleteInvalidEpisodes.cs +++ b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest_DeleteInvalidEpisodes.cs @@ -10,7 +10,7 @@ using NzbDrone.Core.Providers; using NzbDrone.Core.Repository; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; -using TvdbLib.Data; +using XemLib.Data; namespace NzbDrone.Core.Test.ProviderTests { @@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.ProviderTests var tvDbSeries = Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .Build(); @@ -65,7 +65,7 @@ namespace NzbDrone.Core.Test.ProviderTests var tvDbSeries = Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .Build(); var fakeSeries = Builder.CreateNew() @@ -102,7 +102,7 @@ namespace NzbDrone.Core.Test.ProviderTests var tvDbSeries = Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .Build(); var fakeSeries = Builder.CreateNew() @@ -139,7 +139,7 @@ namespace NzbDrone.Core.Test.ProviderTests var tvDbSeries = Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .Build(); var fakeSeries = Builder.CreateNew() @@ -179,7 +179,7 @@ namespace NzbDrone.Core.Test.ProviderTests var tvDbSeries = Builder.CreateListOfSize(episodeCount). All() - .With(l => l.Language = new TvdbLanguage(0, "eng", "a")) + .With(l => l.Language = "en") .Build(); var fakeSeries = Builder.CreateNew() diff --git a/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForEpisodeFile_Fixture.cs b/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForEpisodeFile_Fixture.cs index 48b8ed3fc..c4822c146 100644 --- a/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForEpisodeFile_Fixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForEpisodeFile_Fixture.cs @@ -17,8 +17,8 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; using NzbDrone.Test.Common; -using TvdbLib.Data; -using TvdbLib.Data.Banner; +using XemLib.Data; +using XemLib.Data.Banner; namespace NzbDrone.Core.Test.ProviderTests.Metadata { @@ -52,31 +52,30 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata .With(e => e.SeriesId = 79488) .With(e => e.SeasonNumber = 1) .With(e => e.Directors = new List{ "Fake Director" }) - .With(e => e.Writer = new List{ "Fake Writer" }) + .With(e => e.Writers = new List{ "Fake Writer" }) .With(e => e.GuestStars = new List { "Guest Star 1", "Guest Star 2", "Guest Star 3", "" }) .Build(); var seasonBanners = Builder .CreateListOfSize(4) .TheFirst(2) - .With(b => b.Season = 1) + .With(b => b.SeasonNumber = 1) .TheLast(2) - .With(b => b.Season = 2) + .With(b => b.SeasonNumber = 2) .TheFirst(1) - .With(b => b.BannerType = TvdbSeasonBanner.Type.season) + .With(b => b.BannerType = TvdbSeasonBanner.Type.Poster) .With(b => b.BannerPath = "seasons/79488-1-1.jpg") .TheNext(2) - .With(b => b.BannerType = TvdbSeasonBanner.Type.seasonwide) + .With(b => b.BannerType = TvdbSeasonBanner.Type.Banner) .With(b => b.BannerPath = "banners/seasons/79488-test.jpg") .TheLast(1) - .With(b => b.BannerType = TvdbSeasonBanner.Type.season) + .With(b => b.BannerType = TvdbSeasonBanner.Type.Poster) .With(b => b.BannerPath = "seasons/79488-2-1.jpg") .Build(); var seriesActors = Builder .CreateListOfSize(5) .All() - .With(a => a.ActorImage = Builder.CreateNew().Build()) .Build(); tvdbSeries = Builder @@ -85,9 +84,10 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata .With(s => s.SeriesName = "30 Rock") .With(s => s.TvdbActors = seriesActors.ToList()) .With(s => s.Episodes = tvdbEpisodes.ToList()) + .With(s => s.Banners = new TvdbBanners()) .Build(); - tvdbSeries.Banners.AddRange(seasonBanners); + tvdbSeries.Banners.SeasonBanners.AddRange(seasonBanners); } private void WithUseBanners() @@ -128,7 +128,7 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata private void WithNoWriters() { - tvdbSeries.Episodes.ForEach(e => e.Writer = new List()); + tvdbSeries.Episodes.ForEach(e => e.Writers = new List()); } [Test] @@ -159,7 +159,7 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata { WithSingleEpisodeFile(); Mocker.Resolve().CreateForEpisodeFile(episodeFile, tvdbSeries); - Mocker.GetMock().Verify(v => v.Download(tvdbSeries.Episodes.First().BannerPath, episodeFile.Path.Replace("avi", "tbn")), Times.Once()); + Mocker.GetMock().Verify(v => v.Download(tvdbSeries.Episodes.First().Banner, episodeFile.Path.Replace("avi", "tbn")), Times.Once()); } [Test] diff --git a/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForSeries_Fixture.cs b/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForSeries_Fixture.cs index 1a55c0eb7..6151bfc11 100644 --- a/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForSeries_Fixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForSeries_Fixture.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; @@ -16,8 +17,8 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; using NzbDrone.Test.Common; -using TvdbLib.Data; -using TvdbLib.Data.Banner; +using XemLib.Data; +using XemLib.Data.Banner; namespace NzbDrone.Core.Test.ProviderTests.Metadata { @@ -42,24 +43,23 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata var seasonBanners = Builder .CreateListOfSize(4) .TheFirst(2) - .With(b => b.Season = 1) + .With(b => b.SeasonNumber = 1) .TheLast(2) - .With(b => b.Season = 2) + .With(b => b.SeasonNumber = 2) .TheFirst(1) - .With(b => b.BannerType = TvdbSeasonBanner.Type.season) + .With(b => b.BannerType = TvdbSeasonBanner.Type.Poster) .With(b => b.BannerPath = "seasons/79488-1-1.jpg") .TheNext(2) - .With(b => b.BannerType = TvdbSeasonBanner.Type.seasonwide) + .With(b => b.BannerType = TvdbSeasonBanner.Type.Banner) .With(b => b.BannerPath = "banners/seasons/79488-test.jpg") .TheLast(1) - .With(b => b.BannerType = TvdbSeasonBanner.Type.season) + .With(b => b.BannerType = TvdbSeasonBanner.Type.Poster) .With(b => b.BannerPath = "seasons/79488-2-1.jpg") .Build(); var seriesActors = Builder .CreateListOfSize(5) .All() - .With(a => a.ActorImage = Builder.CreateNew().Build()) .Build(); tvdbSeries = Builder @@ -67,9 +67,10 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata .With(s => s.Id = 79488) .With(s => s.SeriesName = "30 Rock") .With(s => s.TvdbActors = seriesActors.ToList()) + .With(s => s.Banners = new TvdbBanners()) .Build(); - tvdbSeries.Banners.AddRange(seasonBanners); + tvdbSeries.Banners.SeasonBanners.AddRange(seasonBanners); } private void WithUseBanners() @@ -82,19 +83,18 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata var seasonBanners = Builder .CreateListOfSize(2) .All() - .With(b => b.Season = 0) + .With(b => b.SeasonNumber = 0) .TheFirst(1) - .With(b => b.BannerType = TvdbSeasonBanner.Type.season) + .With(b => b.BannerType = TvdbSeasonBanner.Type.Poster) .With(b => b.BannerPath = "seasons/79488-0-1.jpg") .TheLast(1) - .With(b => b.BannerType = TvdbSeasonBanner.Type.seasonwide) + .With(b => b.BannerType = TvdbSeasonBanner.Type.Banner) .With(b => b.BannerPath = "banners/seasons/79488-0-1.jpg") .Build(); var seriesActors = Builder .CreateListOfSize(5) .All() - .With(a => a.ActorImage = Builder.CreateNew().Build()) .Build(); tvdbSeries = Builder @@ -102,9 +102,11 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata .With(s => s.Id = 79488) .With(s => s.SeriesName = "30 Rock") .With(s => s.TvdbActors = seriesActors.ToList()) + .With(s => s.Banners = new TvdbBanners()) + .With(s => s.Genres = new List { "Comedy" }) .Build(); - tvdbSeries.Banners.AddRange(seasonBanners); + tvdbSeries.Banners.SeasonBanners.AddRange(seasonBanners); } [Test] @@ -124,14 +126,14 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata public void should_download_fanart() { Mocker.Resolve().CreateForSeries(series, tvdbSeries); - Mocker.GetMock().Verify(v => v.Download(tvdbSeries.FanartPath, Path.Combine(series.Path, "fanart.jpg")), Times.Once()); + Mocker.GetMock().Verify(v => v.Download(tvdbSeries.Fanart, Path.Combine(series.Path, "fanart.jpg")), Times.Once()); } [Test] public void should_download_poster_when_useBanners_is_false() { Mocker.Resolve().CreateForSeries(series, tvdbSeries); - Mocker.GetMock().Verify(v => v.Download(tvdbSeries.PosterPath, Path.Combine(series.Path, "folder.jpg")), Times.Once()); + Mocker.GetMock().Verify(v => v.Download(tvdbSeries.Poster, Path.Combine(series.Path, "folder.jpg")), Times.Once()); } [Test] @@ -139,7 +141,7 @@ namespace NzbDrone.Core.Test.ProviderTests.Metadata { WithUseBanners(); Mocker.Resolve().CreateForSeries(series, tvdbSeries); - Mocker.GetMock().Verify(v => v.Download(tvdbSeries.BannerPath, Path.Combine(series.Path, "folder.jpg")), Times.Once()); + Mocker.GetMock().Verify(v => v.Download(tvdbSeries.Banner, Path.Combine(series.Path, "folder.jpg")), Times.Once()); } [Test] diff --git a/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs b/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs index dd4255406..26e367da3 100644 --- a/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs @@ -18,7 +18,6 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; using PetaPoco; -using TvdbLib.Data; namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests { diff --git a/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/DeleteDirectoryFixture.cs b/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/DeleteDirectoryFixture.cs index e4cd1fd3b..162baf1e8 100644 --- a/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/DeleteDirectoryFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/DeleteDirectoryFixture.cs @@ -18,7 +18,6 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; using PetaPoco; -using TvdbLib.Data; namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests { diff --git a/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/DeleteFileFixture.cs b/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/DeleteFileFixture.cs index 5ac5c3378..3f4310402 100644 --- a/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/DeleteFileFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/DeleteFileFixture.cs @@ -18,7 +18,6 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; using PetaPoco; -using TvdbLib.Data; namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests { diff --git a/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/EmptyFixture.cs b/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/EmptyFixture.cs index 1835dda2a..4b7853392 100644 --- a/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/EmptyFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/EmptyFixture.cs @@ -18,7 +18,6 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; using PetaPoco; -using TvdbLib.Data; namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests { diff --git a/NzbDrone.Core.Test/ProviderTests/SeasonProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/SeasonProviderTest.cs index fa400ab90..248fb82dc 100644 --- a/NzbDrone.Core.Test/ProviderTests/SeasonProviderTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/SeasonProviderTest.cs @@ -16,7 +16,6 @@ using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; using PetaPoco; -using TvdbLib.Data; namespace NzbDrone.Core.Test.ProviderTests { diff --git a/NzbDrone.Core.Test/ProviderTests/TvDbProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/TvDbProviderTest.cs index 2dd003ace..42232678e 100644 --- a/NzbDrone.Core.Test/ProviderTests/TvDbProviderTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/TvDbProviderTest.cs @@ -10,8 +10,8 @@ using NzbDrone.Common; using NzbDrone.Core.Providers; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common; -using TvdbLib.Data; -using TvdbLib.Exceptions; +using XemLib.Data; +using XemLib.Exceptions; namespace NzbDrone.Core.Test.ProviderTests { @@ -30,7 +30,7 @@ namespace NzbDrone.Core.Test.ProviderTests [TearDown] public void TearDown() { - ExceptionVerification.MarkInconclusive(typeof(TvdbNotAvailableException)); + ExceptionVerification.MarkInconclusive(typeof(TheTvbdbUnavailableException)); } [TestCase("The Simpsons")] @@ -68,58 +68,5 @@ namespace NzbDrone.Core.Test.ProviderTests .Max(e => e.Count()).Should().Be(1); } - - [Test] - public void American_dad_fix() - { - //act - var result = tvDbProvider.GetSeries(73141, true); - - var seasonsNumbers = result.Episodes.Select(e => e.SeasonNumber) - .Distinct().ToList(); - - var seasons = new Dictionary>(seasonsNumbers.Count); - - foreach (var season in seasonsNumbers) - { - seasons.Add(season, result.Episodes.Where(e => e.SeasonNumber == season).ToList()); - } - - foreach (var episode in result.Episodes) - { - Console.WriteLine(episode); - } - - //assert - seasonsNumbers.Should().HaveCount(9); - seasons[1].Should().HaveCount(23); - seasons[2].Should().HaveCount(19); - seasons[3].Should().HaveCount(16); - seasons[4].Should().HaveCount(20); - seasons[5].Should().HaveCount(18); - seasons[6].Should().HaveCount(19); - seasons[7].Should().HaveCount(18); - - foreach (var season in seasons) - { - season.Value.Should().OnlyHaveUniqueItems("Season {0}", season.Key); - } - - //Make sure no episode number is skipped - foreach (var season in seasons) - { - for (int i = 1; i < season.Value.Count; i++) - { - //Skip specials, because someone decided 1,3,4,6,7,21 is how you count... - if (season.Key == 0) - continue; - - season.Value.Should().Contain(c => c.EpisodeNumber == i, "Can't find Episode S{0:00}E{1:00}", - season.Value[0].SeasonNumber, i); - } - } - - - } } } \ No newline at end of file diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 8cc7feb5b..cf3932439 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -206,10 +206,6 @@ - - False - ..\Libraries\TvdbLib.dll - ..\packages\twitterizer.2.4.0.26532\lib\net40\Twitterizer2.dll @@ -217,6 +213,9 @@ False ..\packages\WebActivator.1.5\lib\net40\WebActivator.dll + + ..\Libraries\XemLib\XemLib.dll + diff --git a/NzbDrone.Core/Providers/EpisodeProvider.cs b/NzbDrone.Core/Providers/EpisodeProvider.cs index 78e23961d..29bdd62d9 100644 --- a/NzbDrone.Core/Providers/EpisodeProvider.cs +++ b/NzbDrone.Core/Providers/EpisodeProvider.cs @@ -7,7 +7,7 @@ using NLog; using NzbDrone.Core.Model; using NzbDrone.Core.Repository; using PetaPoco; -using TvdbLib.Data; +using XemLib.Data; namespace NzbDrone.Core.Providers { diff --git a/NzbDrone.Core/Providers/Metadata/MetadataBase.cs b/NzbDrone.Core/Providers/Metadata/MetadataBase.cs index 740785acc..ee9de7e06 100644 --- a/NzbDrone.Core/Providers/Metadata/MetadataBase.cs +++ b/NzbDrone.Core/Providers/Metadata/MetadataBase.cs @@ -4,7 +4,7 @@ using NzbDrone.Common; using NzbDrone.Core.Model; using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Repository; -using TvdbLib.Data; +using XemLib.Data; namespace NzbDrone.Core.Providers.Metadata { diff --git a/NzbDrone.Core/Providers/Metadata/Xbmc.cs b/NzbDrone.Core/Providers/Metadata/Xbmc.cs index 8182cc235..44f9c9e5e 100644 --- a/NzbDrone.Core/Providers/Metadata/Xbmc.cs +++ b/NzbDrone.Core/Providers/Metadata/Xbmc.cs @@ -8,8 +8,8 @@ using NzbDrone.Common; using NzbDrone.Core.Model; using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Repository; -using TvdbLib.Data; -using TvdbLib.Data.Banner; +using XemLib.Data; +using XemLib.Data.Banner; namespace NzbDrone.Core.Providers.Metadata { @@ -48,16 +48,16 @@ namespace NzbDrone.Core.Providers.Metadata tvShow.Add(new XElement("episodeguideurl", episodeGuideUrl)); tvShow.Add(new XElement("mpaa", tvDbSeries.ContentRating)); tvShow.Add(new XElement("id", tvDbSeries.Id)); - tvShow.Add(new XElement("genre", tvDbSeries.GenreString.Trim('|').Split('|')[0])); + tvShow.Add(new XElement("genre", tvDbSeries.Genres.FirstOrDefault())); tvShow.Add(new XElement("premiered", tvDbSeries.FirstAired.ToString("yyyy-MM-dd"))); - tvShow.Add(new XElement("studio", tvDbSeries.Network)); + tvShow.Add(new XElement("studio", tvDbSeries.Network)); foreach(var actor in tvDbSeries.TvdbActors) { tvShow.Add(new XElement("actor", new XElement("name", actor.Name), new XElement("role", actor.Role), - new XElement("thumb", "http://www.thetvdb.com/banners/" + actor.ActorImage.BannerPath) + new XElement("thumb", "http://www.thetvdb.com/banners/" + actor.Image) )); } @@ -71,7 +71,7 @@ namespace NzbDrone.Core.Providers.Metadata if (!_diskProvider.FileExists(Path.Combine(series.Path, "fanart.jpg"))) { _logger.Debug("Downloading fanart for: {0}", series.Title); - _bannerProvider.Download(tvDbSeries.FanartPath, Path.Combine(series.Path, "fanart.jpg")); + _bannerProvider.Download(tvDbSeries.Fanart, Path.Combine(series.Path, "fanart.jpg")); } if (!_diskProvider.FileExists(Path.Combine(series.Path, "folder.jpg"))) @@ -79,19 +79,19 @@ namespace NzbDrone.Core.Providers.Metadata if(_configProvider.MetadataUseBanners) { _logger.Debug("Downloading series banner for: {0}", series.Title); - _bannerProvider.Download(tvDbSeries.BannerPath, Path.Combine(series.Path, "folder.jpg")); + _bannerProvider.Download(tvDbSeries.Banner, Path.Combine(series.Path, "folder.jpg")); _logger.Debug("Downloading Season banners for {0}", series.Title); - DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.seasonwide); + DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.Banner); } else { _logger.Debug("Downloading series thumbnail for: {0}", series.Title); - _bannerProvider.Download(tvDbSeries.PosterPath, Path.Combine(series.Path, "folder.jpg")); + _bannerProvider.Download(tvDbSeries.Poster, Path.Combine(series.Path, "folder.jpg")); _logger.Debug("Downloading Season posters for {0}", series.Title); - DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.season); + DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.Poster); } } } @@ -112,7 +112,7 @@ namespace NzbDrone.Core.Providers.Metadata e.SeasonNumber == episodeFile.SeasonNumber && e.EpisodeNumber == episodes.First().EpisodeNumber); - if (episodeFileThumbnail == null || String.IsNullOrWhiteSpace(episodeFileThumbnail.BannerPath)) + if (episodeFileThumbnail == null || String.IsNullOrWhiteSpace(episodeFileThumbnail.Banner)) { _logger.Debug("No thumbnail is available for this episode"); return; @@ -121,7 +121,7 @@ namespace NzbDrone.Core.Providers.Metadata if (!_diskProvider.FileExists(episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".tbn"))) { _logger.Debug("Downloading episode thumbnail for: {0}", episodeFile.EpisodeFileId); - _bannerProvider.Download(episodeFileThumbnail.BannerPath, + _bannerProvider.Download(episodeFileThumbnail.Banner, episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".tbn")); } @@ -165,9 +165,9 @@ namespace NzbDrone.Core.Providers.Metadata details.Add(new XElement("plot", tvdbEpisode.Overview)); details.Add(new XElement("displayseason")); details.Add(new XElement("displayepisode")); - details.Add(new XElement("thumb", "http://www.thetvdb.com/banners/" + tvdbEpisode.BannerPath)); + details.Add(new XElement("thumb", "http://www.thetvdb.com/banners/" + tvdbEpisode.Banner)); details.Add(new XElement("watched", "false")); - details.Add(new XElement("credits", tvdbEpisode.Writer.FirstOrDefault())); + details.Add(new XElement("credits", tvdbEpisode.Writers.FirstOrDefault())); details.Add(new XElement("director", tvdbEpisode.Directors.FirstOrDefault())); details.Add(new XElement("rating", tvdbEpisode.Rating)); @@ -186,7 +186,7 @@ namespace NzbDrone.Core.Providers.Metadata details.Add(new XElement("actor", new XElement("name", actor.Name), new XElement("role", actor.Role), - new XElement("thumb", "http://www.thetvdb.com/banners/" + actor.ActorImage.BannerPath) + new XElement("thumb", "http://www.thetvdb.com/banners/" + actor.Image) )); } @@ -235,11 +235,11 @@ namespace NzbDrone.Core.Providers.Metadata private void DownloadSeasonThumbnails(Series series, TvdbSeries tvDbSeries, TvdbSeasonBanner.Type bannerType) { - var seasons = tvDbSeries.SeasonBanners.Where(s => s.BannerType == bannerType).Select(s => s.Season); + var seasons = tvDbSeries.Banners.SeasonBanners.Where(s => s.BannerType == bannerType).Select(s => s.SeasonNumber); foreach (var season in seasons) { - var banner = tvDbSeries.SeasonBanners.FirstOrDefault(b => b.BannerType == bannerType && b.Season == season); + var banner = tvDbSeries.Banners.SeasonBanners.FirstOrDefault(b => b.BannerType == bannerType && b.SeasonNumber == season); _logger.Debug("Downloading banner for Season: {0} Series: {1}", season, series.Title); if (season == 0) diff --git a/NzbDrone.Core/Providers/MetadataProvider.cs b/NzbDrone.Core/Providers/MetadataProvider.cs index caad52dba..d6d27ac08 100644 --- a/NzbDrone.Core/Providers/MetadataProvider.cs +++ b/NzbDrone.Core/Providers/MetadataProvider.cs @@ -8,7 +8,7 @@ using NzbDrone.Core.Providers.ExternalNotification; using NzbDrone.Core.Providers.Metadata; using NzbDrone.Core.Repository; using PetaPoco; -using TvdbLib.Data; +using XemLib.Data; namespace NzbDrone.Core.Providers { @@ -92,7 +92,7 @@ namespace NzbDrone.Core.Providers public virtual void CreateForSeries(Series series) { - var tvDbSeries = _tvDbProvider.GetSeries(series.SeriesId, false, true); + var tvDbSeries = _tvDbProvider.GetSeries(series.SeriesId, false, true, true); CreateForSeries(series, tvDbSeries); } @@ -107,7 +107,7 @@ namespace NzbDrone.Core.Providers public virtual void CreateForEpisodeFile(EpisodeFile episodeFile) { - var tvDbSeries = _tvDbProvider.GetSeries(episodeFile.SeriesId, true, true); + var tvDbSeries = _tvDbProvider.GetSeries(episodeFile.SeriesId, true, true, true); CreateForEpisodeFile(episodeFile, tvDbSeries); } @@ -130,7 +130,7 @@ namespace NzbDrone.Core.Providers Logger.Trace("Creating metadata for {0} files.", episodeFiles.Count); - var tvDbSeries = _tvDbProvider.GetSeries(episodeFiles.First().SeriesId, true, true); + var tvDbSeries = _tvDbProvider.GetSeries(episodeFiles.First().SeriesId, true, true, true); foreach(var episodeFile in episodeFiles) { diff --git a/NzbDrone.Core/Providers/SeriesProvider.cs b/NzbDrone.Core/Providers/SeriesProvider.cs index ecbded829..9c6d61242 100644 --- a/NzbDrone.Core/Providers/SeriesProvider.cs +++ b/NzbDrone.Core/Providers/SeriesProvider.cs @@ -97,11 +97,11 @@ namespace NzbDrone.Core.Providers series.AirsDayOfWeek = tvDbSeries.AirsDayOfWeek; series.Overview = tvDbSeries.Overview; series.Status = tvDbSeries.Status; - series.Language = tvDbSeries.Language != null ? tvDbSeries.Language.Abbriviation : string.Empty; + series.Language = tvDbSeries.Language != null ? tvDbSeries.Language : string.Empty; series.CleanTitle = Parser.NormalizeTitle(tvDbSeries.SeriesName); series.LastInfoSync = DateTime.Now; series.Runtime = (int)tvDbSeries.Runtime; - series.BannerUrl = tvDbSeries.BannerPath; + series.BannerUrl = tvDbSeries.Banner; series.Network = tvDbSeries.Network; UpdateSeries(series); diff --git a/NzbDrone.Core/Providers/TvDbProvider.cs b/NzbDrone.Core/Providers/TvDbProvider.cs index 0bbd29b69..aca384bbc 100644 --- a/NzbDrone.Core/Providers/TvDbProvider.cs +++ b/NzbDrone.Core/Providers/TvDbProvider.cs @@ -5,9 +5,8 @@ using System.Text.RegularExpressions; using NLog; using Ninject; using NzbDrone.Common; -using TvdbLib; -using TvdbLib.Cache; -using TvdbLib.Data; +using XemLib; +using XemLib.Data; namespace NzbDrone.Core.Providers { @@ -17,13 +16,13 @@ namespace NzbDrone.Core.Providers public const string TVDB_APIKEY = "5D2D188E86E07F4F"; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - private readonly TvdbHandler _handler; + private readonly XemClient _xemClient; [Inject] public TvDbProvider(EnvironmentProvider environmentProvider) { _environmentProvider = environmentProvider; - _handler = new TvdbHandler(new XmlCacheProvider(_environmentProvider.GetCacheFolder()), TVDB_APIKEY); + _xemClient = new XemClient(TVDB_APIKEY); } public TvDbProvider() @@ -33,57 +32,27 @@ namespace NzbDrone.Core.Providers public virtual IList SearchSeries(string title) { - lock (_handler) - { - Logger.Debug("Searching TVDB for '{0}'", title); + Logger.Debug("Searching TVDB for '{0}'", title); - var result = _handler.SearchSeries(title); + var result = _xemClient.SearchSeries(title); - Logger.Debug("Search for '{0}' returned {1} possible results", title, result.Count); - return result; - } + Logger.Debug("Search for '{0}' returned {1} possible results", title, result.Count); + return result; } - public virtual TvdbSeries GetSeries(int id, bool loadEpisodes, bool loadActors = false) + public virtual TvdbSeries GetSeries(int id, bool loadEpisodes, bool loadActors = false, bool loadBanners = false) { - lock (_handler) - { - Logger.Debug("Fetching SeriesId'{0}' from tvdb", id); - var result = _handler.GetSeries(id, TvdbLanguage.DefaultLanguage, loadEpisodes, loadActors, true, true); + Logger.Debug("Fetching SeriesId'{0}' from tvdb", id); + var result = _xemClient.GetSeries(id, loadEpisodes, loadActors, true, TvdbLanguage.Default); - //Fix American Dad's scene gongshow - if (result != null && result.Id == 73141) - { - result.Episodes = result.Episodes.Where(e => e.SeasonNumber == 0 || e.EpisodeNumber > 0).ToList(); + //Remove duplicated episodes + var episodes = result.Episodes.OrderByDescending(e => e.FirstAired).ThenByDescending(e => e.EpisodeName) + .GroupBy(e => e.SeriesId.ToString("000000") + e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000")) + .Select(e => e.First()); - var seasonOneEpisodeCount = result.Episodes.Where(e => e.SeasonNumber == 1).Count(); - var seasonOneId = result.Episodes.Where(e => e.SeasonNumber == 1).First().SeasonId; + result.Episodes = episodes.ToList(); - foreach (var episode in result.Episodes) - { - if (episode.SeasonNumber > 1) - { - if (episode.SeasonNumber == 2) - { - episode.EpisodeNumber = episode.EpisodeNumber + seasonOneEpisodeCount; - episode.SeasonId = seasonOneId; - } - - episode.SeasonNumber = episode.SeasonNumber - 1; - } - - } - } - - //Remove duplicated episodes - var episodes = result.Episodes.OrderByDescending(e => e.FirstAired).ThenByDescending(e => e.EpisodeName) - .GroupBy(e => e.SeriesId.ToString("000000") + e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000")) - .Select(e => e.First()); - - result.Episodes = episodes.ToList(); - - return result; - } + return result; } } } \ No newline at end of file diff --git a/NzbDrone.Web/Controllers/AddSeriesController.cs b/NzbDrone.Web/Controllers/AddSeriesController.cs index 96adab086..541dcea23 100644 --- a/NzbDrone.Web/Controllers/AddSeriesController.cs +++ b/NzbDrone.Web/Controllers/AddSeriesController.cs @@ -12,7 +12,7 @@ using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Repository; using NzbDrone.Web.Filters; using NzbDrone.Web.Models; -using TvdbLib.Exceptions; +using XemLib.Exceptions; namespace NzbDrone.Web.Controllers { @@ -156,14 +156,14 @@ namespace NzbDrone.Web.Controllers DisplayedTitle = r.FirstAired.Year > 1900 && !r.SeriesName.EndsWith("(" + r.FirstAired.Year + ")") ? string.Format("{0} ({1})", r.SeriesName, r.FirstAired.Year) : r.SeriesName, - Banner = r.Banner.BannerPath, + Banner = r.Banner, Url = String.Format("http://www.thetvdb.com/?tab=series&id={0}", r.Id) }).ToList(); return Json(tvDbResults, JsonRequestBehavior.AllowGet); } - catch(TvdbNotAvailableException ex) + catch (TheTvbdbUnavailableException ex) { logger.WarnException("Unable to lookup series on TheTVDB", ex); return JsonNotificationResult.Info("Lookup Failed", "TheTVDB is not available at this time."); diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index 56305e711..0bb0c2722 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -138,14 +138,14 @@ True - - False - ..\Libraries\TvdbLib.dll - False ..\packages\WebActivator.1.5.1\lib\net40\WebActivator.dll + + False + ..\Libraries\XemLib\XemLib.dll +