diff --git a/NzbDrone.App.Test/NzbDrone.App.Test.ncrunchproject b/NzbDrone.App.Test/NzbDrone.App.Test.ncrunchproject new file mode 100644 index 000000000..8641d3614 --- /dev/null +++ b/NzbDrone.App.Test/NzbDrone.App.Test.ncrunchproject @@ -0,0 +1,19 @@ + + false + false + false + true + false + false + false + false + true + true + false + true + true + 60000 + + + AutoDetect + \ No newline at end of file diff --git a/NzbDrone.Common.Test/NzbDrone.Common.Test.ncrunchproject b/NzbDrone.Common.Test/NzbDrone.Common.Test.ncrunchproject new file mode 100644 index 000000000..8641d3614 --- /dev/null +++ b/NzbDrone.Common.Test/NzbDrone.Common.Test.ncrunchproject @@ -0,0 +1,19 @@ + + false + false + false + true + false + false + false + false + true + true + false + true + true + 60000 + + + AutoDetect + \ No newline at end of file diff --git a/NzbDrone.Common/NzbDrone.Common.ncrunchproject b/NzbDrone.Common/NzbDrone.Common.ncrunchproject new file mode 100644 index 000000000..8641d3614 --- /dev/null +++ b/NzbDrone.Common/NzbDrone.Common.ncrunchproject @@ -0,0 +1,19 @@ + + false + false + false + true + false + false + false + false + true + true + false + true + true + 60000 + + + AutoDetect + \ No newline at end of file diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index c4938453d..cfaef9e0f 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -114,6 +114,8 @@ + + diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.ncrunchproject b/NzbDrone.Core.Test/NzbDrone.Core.Test.ncrunchproject new file mode 100644 index 000000000..8641d3614 --- /dev/null +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.ncrunchproject @@ -0,0 +1,19 @@ + + false + false + false + true + false + false + false + false + true + true + false + true + true + 60000 + + + AutoDetect + \ No newline at end of file diff --git a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs index 7798d6695..28229bb67 100644 --- a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs @@ -172,7 +172,7 @@ public void RefreshEpisodeInfo_emptyRepo() Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeEpisodes); //Act @@ -207,7 +207,7 @@ public void RefreshEpisodeInfo_should_set_older_than_1900_to_null() Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeEpisodes); @@ -248,7 +248,7 @@ public void RefreshEpisodeInfo_should_set_older_than_1900_to_null_for_existing_e Db.Insert(fakeEpisode); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeTvDbEpisodes); //Act @@ -285,7 +285,7 @@ public void RefreshEpisodeInfo_ignore_episode_zero() Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeEpisodes); @@ -324,7 +324,7 @@ public void RefreshEpisodeInfo_should_skip_future_episodes_with_no_title() Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeEpisodes); @@ -362,7 +362,7 @@ public void RefreshEpisodeInfo_should_skip_older_than_1900_year_episodes_with_no Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeEpisodes); @@ -395,7 +395,7 @@ public void RefreshEpisodeInfo_should_add_future_episodes_with_title() Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeEpisodes); @@ -428,7 +428,7 @@ public void RefreshEpisodeInfo_should_add_old_episodes_with_no_title() Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeEpisodes); @@ -463,7 +463,7 @@ public void RefreshEpisodeInfo_ignore_season_zero() Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeEpisodes); Mocker.GetMock() @@ -493,7 +493,7 @@ public void new_episodes_only_calls_Insert() var currentEpisodes = new List(); Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(tvdbSeries); Mocker.GetMock() @@ -528,7 +528,7 @@ public void existing_episodes_only_calls_Update() } Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(tvdbSeries); Mocker.GetMock() @@ -565,7 +565,7 @@ public void should_try_to_get_existing_episode_using_tvdbid_first() .Returns(fakeEpisodeList); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(fakeTvDbResult); //Act @@ -602,7 +602,7 @@ public void should_try_to_get_existing_episode_using_tvdbid_first_then_season_ep var fakeSeries = Builder.CreateNew().With(c => c.SeriesId = seriesId).Build(); Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(tvdbSeries); Mocker.GetMock() @@ -634,7 +634,7 @@ public void existing_episodes_keep_their_episodeId_file_id() } Mocker.GetMock(MockBehavior.Strict) - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(tvdbSeries); var updatedEpisodes = new List(); @@ -695,7 +695,7 @@ public void RefreshEpisodeInfo_should_ignore_new_episode_for_ignored_season() Db.Insert(fakeEpisode); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(tvdbSeries); Mocker.GetMock() @@ -1407,7 +1407,7 @@ public void RefreshEpisodeInfo_should_ignore_episode_zero_except_if_season_one() Db.Insert(fakeSeries); Mocker.GetMock() - .Setup(c => c.GetSeries(seriesId, true)) + .Setup(c => c.GetSeries(seriesId, true, false)) .Returns(tvdbSeries); //Act diff --git a/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForEpisodeFile_Fixture.cs b/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForEpisodeFile_Fixture.cs new file mode 100644 index 000000000..53f3df7f4 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForEpisodeFile_Fixture.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.Model.Notification; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Providers.Metadata; +using NzbDrone.Core.Repository; +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; + +namespace NzbDrone.Core.Test.ProviderTests.Metadata +{ + [TestFixture] + // ReSharper disable InconsistentNaming + public class Xbmc_ForEpisoddeFile_Fixture : CoreTest + { + private Series series; + private EpisodeFile episodeFile; + private TvdbSeries tvdbSeries; + + [SetUp] + public void Setup() + { + WithTempAsAppPath(); + + series = Builder + .CreateNew() + .With(s => s.SeriesId == 79488) + .With(s => s.Title == "30 Rock") + .Build(); + + episodeFile = Builder.CreateNew() + .With(f => f.SeriesId = 79488) + .With(f => f.SeasonNumber = 1) + .With(f => f.Path = @"C:\Test\30 Rock\Season 01\30 Rock - S01E01 - Pilot.avi") + .Build(); + + var tvdbEpisodes = Builder.CreateListOfSize(2) + .All() + .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.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) + .TheLast(2) + .With(b => b.Season = 2) + .TheFirst(1) + .With(b => b.BannerType = TvdbSeasonBanner.Type.season) + .With(b => b.BannerPath = "seasons/79488-1-1.jpg") + .TheNext(2) + .With(b => b.BannerType = TvdbSeasonBanner.Type.seasonwide) + .With(b => b.BannerPath = "banners/seasons/79488-test.jpg") + .TheLast(1) + .With(b => b.BannerType = TvdbSeasonBanner.Type.season) + .With(b => b.BannerPath = "seasons/79488-2-1.jpg") + .Build(); + + var seriesActors = Builder + .CreateListOfSize(5) + .Build(); + + tvdbSeries = Builder + .CreateNew() + .With(s => s.Id = 79488) + .With(s => s.SeriesName = "30 Rock") + .With(s => s.TvdbActors = seriesActors.ToList()) + .With(s => s.Episodes = tvdbEpisodes.ToList()) + .Build(); + + tvdbSeries.Banners.AddRange(seasonBanners); + } + + private void WithUseBanners() + { + Mocker.GetMock().SetupGet(s => s.MetadataUseBanners).Returns(true); + } + + private void WithSingleEpisodeFile() + { + var episode = Builder.CreateNew() + .With(e => e.SeasonNumber = 1) + .With(e => e.SeriesId = 79488) + .With(e => e.EpisodeNumber = 1) + .Build(); + + Mocker.GetMock() + .Setup(s => s.GetEpisodesByFileId(episodeFile.EpisodeFileId)) + .Returns(new List { episode }); + } + + private void WithMultiEpisodeFile() + { + var episodes = Builder.CreateListOfSize(2) + .All() + .With(e => e.SeriesId = 79488) + .With(e => e.SeasonNumber = 1) + .Build(); + + Mocker.GetMock() + .Setup(s => s.GetEpisodesByFileId(episodeFile.EpisodeFileId)) + .Returns(episodes.ToList()); + } + + [Test] + public void should_not_blowup() + { + WithSingleEpisodeFile(); + Mocker.Resolve().ForEpisodeFile(episodeFile, tvdbSeries); + } + + [Test] + public void should_call_diskprovider_writeAllText_once_for_single_episode() + { + WithSingleEpisodeFile(); + Mocker.Resolve().ForEpisodeFile(episodeFile, tvdbSeries); + Mocker.GetMock().Verify(v => v.WriteAllText(episodeFile.Path.Replace("avi", "nfo"), It.IsAny()), Times.Once()); + } + + [Test] + public void should_call_diskprovider_writeAllText_once_for_multi_episode() + { + WithMultiEpisodeFile(); + Mocker.Resolve().ForEpisodeFile(episodeFile, tvdbSeries); + Mocker.GetMock().Verify(v => v.WriteAllText(episodeFile.Path.Replace("avi", "nfo"), It.IsAny()), Times.Once()); + } + + [Test] + public void should_download_thumbnail_when_thumbnail_path_is_not_null() + { + WithSingleEpisodeFile(); + Mocker.Resolve().ForEpisodeFile(episodeFile, tvdbSeries); + Mocker.GetMock().Verify(v => v.Download(tvdbSeries.Episodes.First().BannerPath, episodeFile.Path.Replace("avi", "tbn")), Times.Once()); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForSeries_Fixture.cs b/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForSeries_Fixture.cs new file mode 100644 index 000000000..4e468b501 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/Metadata/Xbmc_ForSeries_Fixture.cs @@ -0,0 +1,128 @@ +using System; +using System.IO; +using System.Linq; +using System.Net; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Common; +using NzbDrone.Core.Model.Notification; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Providers.Metadata; +using NzbDrone.Core.Repository; +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; + +namespace NzbDrone.Core.Test.ProviderTests.Metadata +{ + [TestFixture] + // ReSharper disable InconsistentNaming + public class Xbmc_ForSeries_Fixture : CoreTest + { + private Series series; + private TvdbSeries tvdbSeries; + + [SetUp] + public void Setup() + { + WithTempAsAppPath(); + + series = Builder + .CreateNew() + .With(s => s.SeriesId == 79488) + .With(s => s.Title == "30 Rock") + .Build(); + + var seasonBanners = Builder + .CreateListOfSize(4) + .TheFirst(2) + .With(b => b.Season = 1) + .TheLast(2) + .With(b => b.Season = 2) + .TheFirst(1) + .With(b => b.BannerType = TvdbSeasonBanner.Type.season) + .With(b => b.BannerPath = "seasons/79488-1-1.jpg") + .TheNext(2) + .With(b => b.BannerType = TvdbSeasonBanner.Type.seasonwide) + .With(b => b.BannerPath = "banners/seasons/79488-test.jpg") + .TheLast(1) + .With(b => b.BannerType = TvdbSeasonBanner.Type.season) + .With(b => b.BannerPath = "seasons/79488-2-1.jpg") + .Build(); + + var seriesActors = Builder + .CreateListOfSize(5) + .Build(); + + tvdbSeries = Builder + .CreateNew() + .With(s => s.Id = 79488) + .With(s => s.SeriesName = "30 Rock") + .With(s => s.TvdbActors = seriesActors.ToList()) + .Build(); + + tvdbSeries.Banners.AddRange(seasonBanners); + } + + private void WithUseBanners() + { + Mocker.GetMock().SetupGet(s => s.MetadataUseBanners).Returns(true); + } + + [Test] + public void should_not_blowup() + { + Mocker.Resolve().ForSeries(series, tvdbSeries); + } + + [Test] + public void should_call_diskprovider_writeAllText() + { + Mocker.Resolve().ForSeries(series, tvdbSeries); + Mocker.GetMock().Verify(v => v.WriteAllText(Path.Combine(series.Path, "tvshow.nfo"), It.IsAny()), Times.Once()); + } + + [Test] + public void should_download_fanart() + { + Mocker.Resolve().ForSeries(series, tvdbSeries); + Mocker.GetMock().Verify(v => v.Download(tvdbSeries.FanartPath, Path.Combine(series.Path, "fanart.jpg")), Times.Once()); + } + + [Test] + public void should_download_poster_when_useBanners_is_false() + { + Mocker.Resolve().ForSeries(series, tvdbSeries); + Mocker.GetMock().Verify(v => v.Download(tvdbSeries.PosterPath, Path.Combine(series.Path, "folder.jpg")), Times.Once()); + } + + [Test] + public void should_download_banner_when_useBanners_is_true() + { + WithUseBanners(); + Mocker.Resolve().ForSeries(series, tvdbSeries); + Mocker.GetMock().Verify(v => v.Download(tvdbSeries.BannerPath, Path.Combine(series.Path, "folder.jpg")), Times.Once()); + } + + [Test] + public void should_download_season_poster_when_useBanners_is_false() + { + Mocker.Resolve().ForSeries(series, tvdbSeries); + Mocker.GetMock().Verify(v => v.Download(It.Is(s => !s.Contains("banners")), It.IsRegex(@"season\d{2}\.tbn")), Times.Exactly(2)); + } + + [Test] + public void should_download_season_banner_when_useBanners_is_true() + { + WithUseBanners(); + Mocker.Resolve().ForSeries(series, tvdbSeries); + Mocker.GetMock().Verify(v => v.Download(It.Is(s => s.Contains("banners")), It.IsRegex(@"season\d{2}\.tbn")), Times.Exactly(2)); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Model/MisnamedEpisodeModel.cs b/NzbDrone.Core/Model/MisnamedEpisodeModel.cs index a7445d609..8697f6754 100644 --- a/NzbDrone.Core/Model/MisnamedEpisodeModel.cs +++ b/NzbDrone.Core/Model/MisnamedEpisodeModel.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace NzbDrone.Core.Model.Metadata +namespace NzbDrone.Core.Model { public class MisnamedEpisodeModel { diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index b51d80ed1..1e69555c1 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -239,6 +239,7 @@ + @@ -284,6 +285,9 @@ + + + @@ -313,6 +317,7 @@ Code + diff --git a/NzbDrone.Core/NzbDrone.Core.ncrunchproject b/NzbDrone.Core/NzbDrone.Core.ncrunchproject new file mode 100644 index 000000000..8641d3614 --- /dev/null +++ b/NzbDrone.Core/NzbDrone.Core.ncrunchproject @@ -0,0 +1,19 @@ + + false + false + false + true + false + false + false + false + true + true + false + true + true + 60000 + + + AutoDetect + \ No newline at end of file diff --git a/NzbDrone.Core/Providers/Metadata/Xbmc.cs b/NzbDrone.Core/Providers/Metadata/Xbmc.cs index 46b9f6f01..fe2e16d89 100644 --- a/NzbDrone.Core/Providers/Metadata/Xbmc.cs +++ b/NzbDrone.Core/Providers/Metadata/Xbmc.cs @@ -14,9 +14,9 @@ namespace NzbDrone.Core.Providers.Metadata { - public abstract class Xbmc : MetadataBase + public class Xbmc : MetadataBase { - protected readonly Logger _logger; + protected readonly Logger _logger = LogManager.GetCurrentClassLogger(); public Xbmc(ConfigProvider configProvider, DiskProvider diskProvider, BannerProvider bannerProvider, EpisodeProvider episodeProvider) : base(configProvider, diskProvider, bannerProvider, episodeProvider) @@ -71,22 +71,22 @@ public override void ForSeries(Series series, TvdbSeries tvDbSeries) _logger.Debug("Downloading fanart for: {0}", series.Title); _bannerProvider.Download(tvDbSeries.FanartPath, Path.Combine(series.Path, "fanart.jpg")); - if (!_configProvider.MetadataUseBanners) + if (_configProvider.MetadataUseBanners) { - _logger.Debug("Downloading series thumbnail for: {0}", series.Title); - _bannerProvider.Download(tvDbSeries.PosterPath, "folder.jpg"); + _logger.Debug("Downloading series banner for: {0}", series.Title); + _bannerProvider.Download(tvDbSeries.BannerPath, Path.Combine(series.Path, "folder.jpg")); - _logger.Debug("Downloading Season posters for {0}", series.Title); - DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.season); + _logger.Debug("Downloading Season banners for {0}", series.Title); + DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.seasonwide); } else { - _logger.Debug("Downloading series banner for: {0}", series.Title); - _bannerProvider.Download(tvDbSeries.BannerPath, "folder.jpg"); + _logger.Debug("Downloading series thumbnail for: {0}", series.Title); + _bannerProvider.Download(tvDbSeries.PosterPath, Path.Combine(series.Path, "folder.jpg")); - _logger.Debug("Downloading Season banners for {0}", series.Title); - DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.seasonwide); + _logger.Debug("Downloading Season posters for {0}", series.Title); + DownloadSeasonThumbnails(series, tvDbSeries, TvdbSeasonBanner.Type.season); } } @@ -114,25 +114,33 @@ public override void ForEpisodeFile(EpisodeFile episodeFile, TvdbSeries tvDbSeri } _logger.Debug("Downloading episode thumbnail for: {0}", episodeFile.EpisodeFileId); - _bannerProvider.Download(episodeFileThumbnail.BannerPath, "folder.jpg"); + _bannerProvider.Download(episodeFileThumbnail.BannerPath, episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".tbn")); _logger.Debug("Generating filename.nfo for: {0}", episodeFile.EpisodeFileId); - var sb = new StringBuilder(); - var xws = new XmlWriterSettings(); - xws.OmitXmlDeclaration = false; - xws.Indent = false; - using (var xw = XmlWriter.Create(sb, xws)) + var xmlResult = String.Empty; + foreach (var episode in episodes) { - var doc = new XDocument(); + var sb = new StringBuilder(); + var xws = new XmlWriterSettings(); + xws.OmitXmlDeclaration = false; + xws.Indent = false; - foreach (var episode in episodes) + using (var xw = XmlWriter.Create(sb, xws)) { - var tvdbEpisode = - tvDbSeries.Episodes.FirstOrDefault( - e => - e.SeasonNumber == episode.SeasonNumber && - e.EpisodeNumber == episode.EpisodeNumber); + var doc = new XDocument(); + var tvdbEpisode = tvDbSeries.Episodes.FirstOrDefault( + e => + e.Id == episode.TvDbEpisodeId); + + if (tvdbEpisode == null) + { + _logger.Debug("Looking up by TvDbEpisodeId failed, trying to match via season/episode number combination"); + tvdbEpisode = tvDbSeries.Episodes.FirstOrDefault( + e => + e.SeasonNumber == episode.SeasonNumber && + e.EpisodeNumber == episode.EpisodeNumber); + } if (tvdbEpisode == null) { @@ -161,7 +169,7 @@ public override void ForEpisodeFile(EpisodeFile episodeFile, TvdbSeries tvDbSeri details.Add(new XElement("actor", new XElement("name", actor) - )); + )); } foreach(var actor in tvDbSeries.TvdbActors) @@ -170,17 +178,17 @@ public override void ForEpisodeFile(EpisodeFile episodeFile, TvdbSeries tvDbSeri new XElement("name", actor.Name), new XElement("role", actor.Role), new XElement("thumb", actor.ActorImage) - )); + )); } doc.Add(details); doc.Save(xw); } + xmlResult += sb.ToString(); } - - var filename = Path.GetFileNameWithoutExtension(episodeFile.Path) + ".nfo"; + var filename = episodeFile.Path.Replace(Path.GetExtension(episodeFile.Path), ".nfo"); _logger.Debug("Saving episodedetails to: {0}", filename); - _diskProvider.WriteAllText(filename, sb.ToString()); + _diskProvider.WriteAllText(filename, xmlResult); } private void DownloadSeasonThumbnails(Series series, TvdbSeries tvDbSeries, TvdbSeasonBanner.Type bannerType) diff --git a/NzbDrone.Core/Providers/MetadataProvider.cs b/NzbDrone.Core/Providers/MetadataProvider.cs index eb0f11d5e..91084d974 100644 --- a/NzbDrone.Core/Providers/MetadataProvider.cs +++ b/NzbDrone.Core/Providers/MetadataProvider.cs @@ -8,6 +8,7 @@ using NzbDrone.Core.Providers.Metadata; using NzbDrone.Core.Repository; using PetaPoco; +using TvdbLib.Data; namespace NzbDrone.Core.Providers { @@ -92,6 +93,11 @@ public virtual void CreateForSeries(Series series) { var tvDbSeries = _tvDbProvider.GetSeries(series.SeriesId, false, true); + CreateForSeries(series, tvDbSeries); + } + + public virtual void CreateForSeries(Series series, TvdbSeries tvDbSeries) + { foreach (var provider in _metadataProviders.Where(i => GetSettings(i.GetType()).Enable)) { provider.ForSeries(series, tvDbSeries); diff --git a/NzbDrone.Core/Providers/SeriesProvider.cs b/NzbDrone.Core/Providers/SeriesProvider.cs index 0a5efdbac..aee5b150d 100644 --- a/NzbDrone.Core/Providers/SeriesProvider.cs +++ b/NzbDrone.Core/Providers/SeriesProvider.cs @@ -20,17 +20,19 @@ public class SeriesProvider private readonly IDatabase _database; private readonly SceneMappingProvider _sceneNameMappingProvider; private readonly BannerProvider _bannerProvider; + private readonly MetadataProvider _metadataProvider; private static readonly Regex TimeRegex = new Regex(@"^(?