diff --git a/NzbDrone.Core.Test/EpisodeStatusTest.cs b/NzbDrone.Core.Test/EpisodeStatusTest.cs new file mode 100644 index 000000000..ff162c9f4 --- /dev/null +++ b/NzbDrone.Core.Test/EpisodeStatusTest.cs @@ -0,0 +1,119 @@ +// ReSharper disable RedundantUsingDirective +// ReSharper disable RedundantUsingDirective +using System; +using FizzWare.NBuilder; +using MbUnit.Framework; +using NzbDrone.Core.Model; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test +{ + [TestFixture] + // ReSharper disable InconsistentNaming + public class EpisodeStatusTest : TestBase + { + [Test] + [Row(1, false, false, EpisodeStatusType.NotAired)] + [Row(-2, false, false, EpisodeStatusType.Missing)] + [Row(1, true, false, EpisodeStatusType.Ready)] + [Row(1, true, true, EpisodeStatusType.Ignored)] + [Row(1, false, true, EpisodeStatusType.Ignored)] + public void no_grab_date(int offsetDays, bool hasEpisodes, bool ignored, EpisodeStatusType status) + { + Episode episode = Builder.CreateNew() + .With(e => e.Season = Builder.CreateNew() + .With(s => s.Monitored = true).Build()) + .With(e => e.AirDate = DateTime.Now.AddDays(offsetDays)) + .With(e => e.Ignored = ignored) + .With(e => e.EpisodeFileId = 0) + .With(e => e.GrabDate = null) + .Build(); + + if (hasEpisodes) + { + episode.EpisodeFileId = 12; + } + + Assert.AreEqual(status, episode.Status); + } + + + [Test] + [Row(1, false, false, EpisodeStatusType.NotAired)] + [Row(-2, false, false, EpisodeStatusType.Missing)] + [Row(1, true, false, EpisodeStatusType.Ready)] + [Row(1, true, true, EpisodeStatusType.Ignored)] + [Row(1, false, true, EpisodeStatusType.Ignored)] + public void old_grab_date(int offsetDays, bool hasEpisodes, bool ignored, + EpisodeStatusType status) + { + Episode episode = Builder.CreateNew() + .With(e => e.Season = Builder.CreateNew() + .With(s => s.Monitored = true).Build()).With( + e => e.AirDate = DateTime.Now.AddDays(offsetDays)) + .With(e => e.Ignored = ignored) + .With(e => e.EpisodeFileId = 0) + .With(e => e.GrabDate = DateTime.Now.AddDays(-1).AddHours(-1)) + .Build(); + + if (hasEpisodes) + { + episode.EpisodeFileId = 12; + } + + Assert.AreEqual(status, episode.Status); + } + + + [Test] + [Row(1, false, false, EpisodeStatusType.Downloading)] + [Row(-2, false, false, EpisodeStatusType.Downloading)] + [Row(1, true, false, EpisodeStatusType.Downloading)] + [Row(1, true, true, EpisodeStatusType.Ignored)] + [Row(1, false, true, EpisodeStatusType.Ignored)] + public void recent_grab_date(int offsetDays, bool hasEpisodes, bool ignored, + EpisodeStatusType status) + { + Episode episode = Builder.CreateNew() + .With(e => e.Season = Builder.CreateNew() + .With(s => s.Monitored = true).Build()) + .With(e => e.AirDate = DateTime.Now.AddDays(offsetDays)) + .With(e => e.Ignored = ignored) + .With(e => e.EpisodeFileId = 0) + .With(e => e.GrabDate = DateTime.Now.AddDays(-1)) + .Build(); + + if (hasEpisodes) + { + episode.EpisodeFileId = 12; + } + + Assert.AreEqual(status, episode.Status); + } + + [Test] + [Row(1, false, false, EpisodeStatusType.Ignored)] + [Row(-2, false, false, EpisodeStatusType.Ignored)] + [Row(1, true, false, EpisodeStatusType.Ignored)] + [Row(1, true, true, EpisodeStatusType.Ignored)] + [Row(1, false, true, EpisodeStatusType.Ignored)] + public void skipped_season(int offsetDays, bool hasEpisodes, bool ignored, EpisodeStatusType status) + { + Episode episode = Builder.CreateNew() + .With(e => e.AirDate = DateTime.Now.AddDays(offsetDays)) + .With(e => e.Ignored = ignored) + .With(e => e.EpisodeFileId = 0) + .With(e => e.Season = Builder.CreateNew() + .With(s => s.Monitored == false).Build()) + .Build(); + + if (hasEpisodes) + { + episode.EpisodeFileId = 12; + } + + Assert.AreEqual(status, episode.Status); + } + } +} \ 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 9431fb56f..aad12a791 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -85,6 +85,7 @@ + @@ -99,7 +100,6 @@ - diff --git a/NzbDrone.Core.Test/SyncProviderTest.cs b/NzbDrone.Core.Test/SyncProviderTest.cs deleted file mode 100644 index 9df079751..000000000 --- a/NzbDrone.Core.Test/SyncProviderTest.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using AutoMoq; -using MbUnit.Framework; -using Moq; -using NzbDrone.Core.Providers; -using NzbDrone.Core.Providers.Core; -using NzbDrone.Core.Test.Framework; - -namespace NzbDrone.Core.Test -{ - [TestFixture] - // ReSharper disable InconsistentNaming - public class SyncProviderTest : TestBase - { - - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Model/EpisodeStatusType.cs b/NzbDrone.Core/Model/EpisodeStatusType.cs index d1addd0e3..345706da6 100644 --- a/NzbDrone.Core/Model/EpisodeStatusType.cs +++ b/NzbDrone.Core/Model/EpisodeStatusType.cs @@ -2,8 +2,30 @@ { public enum EpisodeStatusType { - Missing = 0, - Grabbed = 1, - Downloaded = 2 + /// + /// Episode has not aired yet + /// + NotAired , + + /// + /// Episode is ignored + /// + Ignored, + + /// + /// Episode has aired but no episode + /// files have avilable + /// + Missing , + + /// + /// Episode is being downloaded + /// + Downloading , + + /// + /// Episode is present in disk + /// + Ready } } \ No newline at end of file diff --git a/NzbDrone.Core/Providers/EpisodeProvider.cs b/NzbDrone.Core/Providers/EpisodeProvider.cs index ee2be5abe..bcb2a8968 100644 --- a/NzbDrone.Core/Providers/EpisodeProvider.cs +++ b/NzbDrone.Core/Providers/EpisodeProvider.cs @@ -144,14 +144,11 @@ public virtual void RefreshEpisodeInfo(int seriesId) AirDate = episode.FirstAired.Date, TvDbEpisodeId = episode.Id, EpisodeNumber = episode.EpisodeNumber, - Language = episode.Language.Abbriviation, Overview = episode.Overview, SeasonId = episode.SeasonId, SeasonNumber = episode.SeasonNumber, SeriesId = seriesId, Title = episode.EpisodeName, - LastInfoSync = DateTime.Now - }; var existingEpisode = GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber); @@ -161,8 +158,6 @@ public virtual void RefreshEpisodeInfo(int seriesId) //TODO: Write test for this, possibly make it future proof, we should only copy fields that come from tvdb newEpisode.EpisodeId = existingEpisode.EpisodeId; newEpisode.EpisodeFileId = existingEpisode.EpisodeFileId; - newEpisode.LastDiskSync = existingEpisode.LastDiskSync; - newEpisode.Status = existingEpisode.Status; updateList.Add(newEpisode); } else diff --git a/NzbDrone.Core/Providers/Indexer/InventoryProvider.cs b/NzbDrone.Core/Providers/Indexer/InventoryProvider.cs index 191c4b5f6..70e462a68 100644 --- a/NzbDrone.Core/Providers/Indexer/InventoryProvider.cs +++ b/NzbDrone.Core/Providers/Indexer/InventoryProvider.cs @@ -79,7 +79,6 @@ internal bool IsNeeded(EpisodeParseResult parseResult) SeasonNumber = parseResult.SeasonNumber, Title = parseResult.EpisodeTitle, Overview = String.Empty, - Language = "en" }; _episodeProvider.AddEpisode(episodeInfo); diff --git a/NzbDrone.Core/Repository/Episode.cs b/NzbDrone.Core/Repository/Episode.cs index 197ae6ec1..811945769 100644 --- a/NzbDrone.Core/Repository/Episode.cs +++ b/NzbDrone.Core/Repository/Episode.cs @@ -23,12 +23,40 @@ public class Episode [SubSonicLongString] public string Overview { get; set; } - public string Language { get; set; } - public EpisodeStatusType Status { get; set; } + public Boolean Ignored { get; set; } - public DateTime? LastInfoSync { get; set; } - public DateTime? LastDiskSync { get; set; } + /// + /// Gets or sets the grab date. + /// + /// + /// Used to specify when the episode was grapped. + /// this filed is used by status as an expirable "Grabbed" status. + /// + public DateTime? GrabDate { get; set; } + + [SubSonicIgnore] + public EpisodeStatusType Status + { + get + { + if (Ignored || (Season != null && !Season.Monitored)) return EpisodeStatusType.Ignored; + + if (GrabDate != null && GrabDate.Value.AddDays(1) >= DateTime.Now) + { + return EpisodeStatusType.Downloading; + } + + if (EpisodeFileId != 0) return EpisodeStatusType.Ready; + + if (DateTime.Now.Date >= AirDate.Date) + { + return EpisodeStatusType.Missing; + } + + return EpisodeStatusType.NotAired; + } + } [SubSonicToOneRelation(ThisClassContainsJoinKey = true)] public virtual Season Season { get; set; }