1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-10-27 06:02:33 +01:00

Fixed a bug where reports weren't being added to history

This commit is contained in:
kay.one 2011-05-23 21:12:54 -07:00
parent f3be5fa08e
commit 500e9af6c3
18 changed files with 344 additions and 225 deletions

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Text;
using AutoMoq;
using FizzWare.NBuilder;
using Gallio.Framework;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
using Moq;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;
// ReSharper disable InconsistentNaming
namespace NzbDrone.Core.Test
{
[TestFixture]
public class DownloadProviderTest
{
[Test]
public void Download_report_should_send_to_sab_and_add_to_history()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
var parseResult = Builder<EpisodeParseResult>.CreateNew()
.With(e => e.Episodes = Builder<Episode>.CreateListOfSize(2)
.WhereTheFirst(1).Has(s => s.EpisodeId = 12)
.AndTheNext(1).Has(s => s.EpisodeId = 99)
.Build())
.Build();
const string sabTitle = "My fake sab title";
mocker.GetMock<SabProvider>()
.Setup(s => s.IsInQueue(It.IsAny<String>()))
.Returns(false);
mocker.GetMock<SabProvider>()
.Setup(s => s.AddByUrl(parseResult.NzbUrl, sabTitle))
.Returns(true);
mocker.GetMock<SabProvider>()
.Setup(s => s.GetSabTitle(parseResult))
.Returns(sabTitle);
mocker.GetMock<HistoryProvider>()
.Setup(s => s.Add(It.Is<History>(h=>h.EpisodeId == 12)));
mocker.GetMock<HistoryProvider>()
.Setup(s => s.Add(It.Is<History>(h => h.EpisodeId == 99)));
mocker.Resolve<DownloadProvider>().DownloadReport(parseResult);
mocker.VerifyAllMocks();
}
}
}

View File

@ -41,7 +41,8 @@ public void parse_feed_xml(string fileName, int warns)
.Setup(c => c.GetSettings(It.IsAny<Type>()))
.Returns(fakeSettings);
var parseResults = mocker.Resolve<MockIndexer>().Fetch();
var mockIndexer = mocker.Resolve<MockIndexer>();
var parseResults = mockIndexer.Fetch();
foreach (var episodeParseResult in parseResults)
{
@ -51,6 +52,11 @@ public void parse_feed_xml(string fileName, int warns)
Assert.IsNotEmpty(parseResults);
Assert.ForAll(parseResults, s => Assert.AreEqual(mockIndexer.Name, s.Indexer));
Assert.ForAll(parseResults, s => Assert.AreNotEqual("", s.NzbTitle));
Assert.ForAll(parseResults, s => Assert.AreNotEqual(null, s.NzbTitle));
ExceptionVerification.ExcpectedWarns(warns);
}
@ -70,7 +76,8 @@ public void newzbin()
.Setup(c => c.GetSettings(It.IsAny<Type>()))
.Returns(fakeSettings);
var parseResults = mocker.Resolve<Newzbin>().Fetch();
var newzbinProvider = mocker.Resolve<Newzbin>();
var parseResults = newzbinProvider.Fetch();
foreach (var episodeParseResult in parseResults)
{
@ -80,6 +87,10 @@ public void newzbin()
Assert.IsNotEmpty(parseResults);
Assert.ForAll(parseResults, s => Assert.AreEqual(newzbinProvider.Name, s.Indexer));
Assert.ForAll(parseResults, s => Assert.AreNotEqual("", s.NzbTitle));
Assert.ForAll(parseResults, s => Assert.AreNotEqual(null, s.NzbTitle));
ExceptionVerification.ExcpectedWarns(1);
}
@ -111,7 +122,7 @@ public void custome_parser_partial_success(string title, int season, int episode
Assert.IsNotNull(result);
Assert.AreEqual(summary, result.EpisodeTitle);
Assert.AreEqual(season, result.SeasonNumber);
Assert.AreEqual(episode, result.Episodes[0]);
Assert.AreEqual(episode, result.EpisodeNumbers[0]);
Assert.AreEqual(quality, result.Quality);
}

View File

@ -23,37 +23,56 @@ namespace NzbDrone.Core.Test
// ReSharper disable InconsistentNaming
public class InventoryProviderTest : TestBase
{
private EpisodeParseResult parseResult;
private EpisodeParseResult parseResultMulti;
private Series series;
private Episode episode;
private Episode episode2;
private EpisodeParseResult parseResultSingle;
[SetUp]
public new void Setup()
{
parseResult = new EpisodeParseResult()
parseResultMulti = new EpisodeParseResult()
{
CleanTitle = "Title",
EpisodeTitle = "EpisodeTitle",
Language = LanguageType.English,
Proper = true,
Quality = QualityTypes.Bluray720,
Episodes = new List<int> { 3 },
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date
};
parseResultSingle = new EpisodeParseResult()
{
CleanTitle = "Title",
EpisodeTitle = "EpisodeTitle",
Language = LanguageType.English,
Proper = true,
Quality = QualityTypes.Bluray720,
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date
};
series = Builder<Series>.CreateNew()
.With(c => c.Monitored = true)
.With(d => d.CleanTitle = parseResult.CleanTitle)
.With(d => d.CleanTitle = parseResultMulti.CleanTitle)
.Build();
episode = Builder<Episode>.CreateNew()
.With(c => c.EpisodeNumber = parseResult.Episodes[0])
.With(c => c.SeasonNumber = parseResult.SeasonNumber)
.With(c => c.AirDate = parseResult.AirDate)
.With(c => c.EpisodeNumber = parseResultMulti.EpisodeNumbers[0])
.With(c => c.SeasonNumber = parseResultMulti.SeasonNumber)
.With(c => c.AirDate = parseResultMulti.AirDate)
.Build();
episode2 = Builder<Episode>.CreateNew()
.With(c => c.EpisodeNumber = parseResultMulti.EpisodeNumbers[1])
.With(c => c.SeasonNumber = parseResultMulti.SeasonNumber)
.With(c => c.AirDate = parseResultMulti.AirDate)
.Build();
base.Setup();
}
@ -71,7 +90,7 @@ public void not_monitored_series_should_be_skipped()
.Returns(series);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResult);
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
@ -90,7 +109,7 @@ public void no_db_series_should_be_skipped()
.Returns<Series>(null);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResult);
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
@ -107,12 +126,12 @@ public void unwannted_quality_should_be_skipped()
.Returns(series);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResult.Quality))
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResult);
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
@ -131,15 +150,15 @@ public void ignored_season_should_be_skipped()
.Returns(series);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResult.Quality))
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResult.SeasonNumber))
.Setup(p => p.IsIgnored(series.SeriesId, parseResultMulti.SeasonNumber))
.Returns(true);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResult);
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
@ -163,21 +182,29 @@ public void unwannted_file_should_be_skipped()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns(episode);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode2.SeriesId, episode2.SeasonNumber, episode2.EpisodeNumber))
.Returns(episode2);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResult.Quality))
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResult.SeasonNumber))
.Setup(p => p.IsIgnored(series.SeriesId, parseResultMulti.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResult, episode))
.Setup(p => p.IsNeeded(parseResultMulti, episode))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultMulti, episode2))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResult);
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
@ -198,25 +225,24 @@ public void file_in_history_should_be_skipped()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns(episode);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResult.Quality))
.Setup(p => p.QualityWanted(series.SeriesId, parseResultSingle.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResult.SeasonNumber))
.Setup(p => p.IsIgnored(series.SeriesId, parseResultSingle.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResult, episode))
.Setup(p => p.IsNeeded(parseResultSingle, episode))
.Returns(true);
mocker.GetMock<HistoryProvider>()
.Setup(p => p.Exists(episode.EpisodeId, parseResult.Quality, parseResult.Proper))
.Setup(p => p.Exists(episode.EpisodeId, parseResultSingle.Quality, parseResultSingle.Proper))
.Returns(true);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResult);
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultSingle);
//Assert
Assert.IsFalse(result);
@ -242,19 +268,19 @@ public void dailyshow_should_do_daily_lookup()
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResult.Quality))
.Setup(p => p.QualityWanted(series.SeriesId, parseResultSingle.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResult.SeasonNumber))
.Setup(p => p.IsIgnored(series.SeriesId, parseResultSingle.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResult, episode))
.Setup(p => p.IsNeeded(parseResultSingle, episode))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResult);
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultSingle);
//Assert
Assert.IsFalse(result);
@ -272,11 +298,11 @@ public void none_db_episode_should_be_added()
.Returns(series);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResult.Quality))
.Setup(p => p.QualityWanted(series.SeriesId, parseResultSingle.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResult.SeasonNumber))
.Setup(p => p.IsIgnored(series.SeriesId, parseResultSingle.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
@ -292,11 +318,11 @@ public void none_db_episode_should_be_added()
.Returns(12);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResult, It.IsAny<Episode>()))
.Setup(p => p.IsNeeded(parseResultSingle, It.IsAny<Episode>()))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResult);
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultSingle);
//Assert
Assert.IsFalse(result);
@ -305,7 +331,7 @@ public void none_db_episode_should_be_added()
[Test]
public void file_needed_should_return_true()
public void first_file_needed_should_return_true()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
@ -317,30 +343,83 @@ public void file_needed_should_return_true()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns(episode);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode2.SeriesId, episode2.SeasonNumber, episode2.EpisodeNumber))
.Returns(episode2);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResult.Quality))
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResult.SeasonNumber))
.Setup(p => p.IsIgnored(series.SeriesId, parseResultMulti.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResult, episode))
.Setup(p => p.IsNeeded(parseResultMulti, episode))
.Returns(true);
mocker.GetMock<HistoryProvider>()
.Setup(p => p.Exists(episode.EpisodeId, parseResult.Quality, parseResult.Proper))
.Setup(p => p.Exists(episode.EpisodeId, parseResultMulti.Quality, parseResultMulti.Proper))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResult);
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsTrue(result);
Assert.IsNotNull(parseResult.Series);
Assert.AreEqual(series, parseResult.Series);
Assert.Contains(parseResultMulti.Episodes, episode);
Assert.Contains(parseResultMulti.Episodes, episode2);
Assert.AreEqual(series, parseResultMulti.Series);
mocker.VerifyAllMocks();
}
[Test]
public void second_file_needed_should_return_true()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns(episode);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode2.SeriesId, episode2.SeasonNumber, episode2.EpisodeNumber))
.Returns(episode2);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultMulti.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultMulti, episode))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultMulti, episode2))
.Returns(true);
mocker.GetMock<HistoryProvider>()
.Setup(p => p.Exists(episode2.EpisodeId, parseResultMulti.Quality, parseResultMulti.Proper))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsTrue(result);
Assert.Contains(parseResultMulti.Episodes, episode);
Assert.Contains(parseResultMulti.Episodes, episode2);
Assert.AreEqual(series, parseResultMulti.Series);
mocker.VerifyAllMocks();
}
}

View File

@ -17,7 +17,7 @@ public class JobProviderTest : TestBase
[Test]
public void Run_Jobs_Updates_Last_Execution()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new FakeJob() };
IList<IJob> fakeJobs = new List<IJob> { new FakeJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -39,7 +39,7 @@ public void Run_Jobs_Updates_Last_Execution()
public void Run_Jobs_Updates_Last_Execution_Mark_as_unsuccesful()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new BrokenJob() };
IList<IJob> fakeJobs = new List<IJob> { new BrokenJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -63,7 +63,7 @@ public void Run_Jobs_Updates_Last_Execution_Mark_as_unsuccesful()
//after execution so the job can successfully run.
public void can_run_job_again()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new FakeJob() };
IList<IJob> fakeJobs = new List<IJob> { new FakeJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -84,7 +84,7 @@ public void can_run_job_again()
//after execution so the job can successfully run.
public void can_run_async_job_again()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new FakeJob() };
IList<IJob> fakeJobs = new List<IJob> { new FakeJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -106,7 +106,7 @@ public void can_run_async_job_again()
//after execution so the job can successfully run.
public void no_concurent_jobs()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new SlowJob() };
IList<IJob> fakeJobs = new List<IJob> { new SlowJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -129,7 +129,7 @@ public void no_concurent_jobs()
//after execution so the job can successfully run.
public void can_run_broken_async_job_again()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new BrokenJob() };
IList<IJob> fakeJobs = new List<IJob> { new BrokenJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -152,7 +152,7 @@ public void can_run_broken_async_job_again()
//after execution so the job can successfully run.
public void can_run_two_jobs_at_the_same_time()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new SlowJob() };
IList<IJob> fakeJobs = new List<IJob> { new SlowJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -186,7 +186,7 @@ public void can_queue_jobs_at_the_same_time()
{
var slowJob = new SlowJob();
IEnumerable<IJob> fakeJobs = new List<IJob> { slowJob };
IList<IJob> fakeJobs = new List<IJob> { slowJob };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -214,7 +214,7 @@ public void can_queue_jobs_at_the_same_time()
public void Init_Jobs()
{
var fakeTimer = new FakeJob();
IEnumerable<IJob> fakeJobs = new List<IJob> { fakeTimer };
IList<IJob> fakeJobs = new List<IJob> { fakeTimer };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -245,7 +245,7 @@ public void Init_Timers_only_registers_once()
for (int i = 0; i < 2; i++)
{
var fakeTimer = new FakeJob();
IEnumerable<IJob> fakeJobs = new List<IJob> { fakeTimer };
IList<IJob> fakeJobs = new List<IJob> { fakeTimer };
var mocker = new AutoMoqer();
mocker.SetConstant(repo);
@ -276,7 +276,7 @@ public void Init_Timers_sets_interval_0_to_disabled()
for (int i = 0; i < 2; i++)
{
var disabledJob = new DisabledJob();
IEnumerable<IJob> fakeJobs = new List<IJob> { disabledJob };
IList<IJob> fakeJobs = new List<IJob> { disabledJob };
var mocker = new AutoMoqer();
mocker.SetConstant(repo);
@ -302,7 +302,7 @@ public void Init_Timers_sets_interval_0_to_disabled()
[Test]
public void Get_Next_Execution_Time()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new FakeJob() };
IList<IJob> fakeJobs = new List<IJob> { new FakeJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -327,7 +327,7 @@ public void Disabled_isnt_run_by_scheduler()
var disabledJob = new DisabledJob();
IEnumerable<IJob> fakeJobs = new List<IJob> { disabledJob };
IList<IJob> fakeJobs = new List<IJob> { disabledJob };
var mocker = new AutoMoqer();
mocker.SetConstant(repo);
@ -348,7 +348,7 @@ public void Disabled_isnt_run_by_scheduler()
[Test]
public void SingleId_do_not_update_last_execution()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new FakeJob() };
IList<IJob> fakeJobs = new List<IJob> { new FakeJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
@ -369,7 +369,7 @@ public void SingleId_do_not_update_last_execution()
[Test]
public void SingleId_do_not_set_success()
{
IEnumerable<IJob> fakeJobs = new List<IJob> { new FakeJob() };
IList<IJob> fakeJobs = new List<IJob> { new FakeJob() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());

View File

@ -116,7 +116,7 @@ public void import_new_daily_file()
//Currently can't verify this since the list of episodes are loaded
//Dynamically by SubSonic
//Assert.AreEqual(fakeEpisode, result.Episodes[0]);
//Assert.AreEqual(fakeEpisode, result.EpisodeNumbers[0]);
Assert.AreEqual(fakeEpisode.SeriesId, result.SeriesId);
Assert.AreEqual(QualityTypes.HDTV, result.Quality);

View File

@ -85,6 +85,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="DownloadProviderTest.cs" />
<Compile Include="EpisodeStatusTest.cs" />
<Compile Include="ImportNewSeriesJobTest.cs" />
<Compile Include="DiskScanJobTest.cs" />

View File

@ -46,9 +46,9 @@ public void episode_parse(string postTitle, string title, int season, int episod
{
var result = Parser.ParseEpisodeInfo(postTitle);
Assert.AreEqual(season, result.SeasonNumber);
Assert.AreEqual(episode, result.Episodes[0]);
Assert.AreEqual(episode, result.EpisodeNumbers[0]);
Assert.AreEqual(Parser.NormalizeTitle(title), result.CleanTitle);
Assert.AreEqual(1, result.Episodes.Count);
Assert.AreEqual(1, result.EpisodeNumbers.Count);
}
[Test]
@ -60,9 +60,9 @@ public void episode_parse(string postTitle, string title, int season, int episod
public void file_path_parse(string path, int season, int episode)
{
var result = Parser.ParseEpisodeInfo(path);
Assert.Count(1, result.Episodes);
Assert.Count(1, result.EpisodeNumbers);
Assert.AreEqual(season, result.SeasonNumber);
Assert.AreEqual(episode, result.Episodes[0]);
Assert.AreEqual(episode, result.EpisodeNumbers[0]);
}
@ -110,10 +110,10 @@ public void episode_multipart_parse(string postTitle, string title, int season,
{
var result = Parser.ParseEpisodeInfo(postTitle);
Assert.AreEqual(season, result.SeasonNumber);
Assert.Count(episodes.Length, result.Episodes);
Assert.AreElementsEqualIgnoringOrder(episodes, result.Episodes);
Assert.Count(episodes.Length, result.EpisodeNumbers);
Assert.AreElementsEqualIgnoringOrder(episodes, result.EpisodeNumbers);
Assert.AreEqual(Parser.NormalizeTitle(title), result.CleanTitle);
Assert.AreEqual(count, result.Episodes.Count);
Assert.AreEqual(count, result.EpisodeNumbers.Count);
}
[Test]
@ -129,7 +129,7 @@ public void episode_daily_parse(string postTitle, string title, int year, int mo
var airDate = new DateTime(year, month, day);
Assert.AreEqual(Parser.NormalizeTitle(title), result.CleanTitle);
Assert.AreEqual(airDate, result.AirDate);
Assert.IsNull(result.Episodes);
Assert.IsNull(result.EpisodeNumbers);
}
@ -142,7 +142,7 @@ public void full_season_release_parse(string postTitle, string title, int season
var result = Parser.ParseEpisodeInfo(postTitle);
Assert.AreEqual(season, result.SeasonNumber);
Assert.AreEqual(Parser.NormalizeTitle(title), result.CleanTitle);
Assert.AreEqual(0, result.Episodes.Count);
Assert.AreEqual(0, result.EpisodeNumbers.Count);
}
[Test]

View File

@ -229,7 +229,7 @@ public void sab_title(int seasons, int[] episodes, string title, QualityTypes qu
var parsResult = new EpisodeParseResult()
{
AirDate = DateTime.Now,
Episodes = episodes.ToList(),
EpisodeNumbers = episodes.ToList(),
Proper = proper,
Quality = quality,
SeasonNumber = seasons,

View File

@ -11,7 +11,7 @@ public class EpisodeParseResult
internal int SeasonNumber { get; set; }
internal List<int> Episodes { get; set; }
internal List<int> EpisodeNumbers { get; set; }
internal string EpisodeTitle { get; set; }
@ -25,15 +25,21 @@ public class EpisodeParseResult
public string NzbUrl { get; set; }
public string NzbTitle { get; set; }
public Series Series { get; set; }
public IList<Episode> Episodes { get; set; }
public String Indexer { get; set; }
public override string ToString()
{
if (Episodes == null)
if (EpisodeNumbers == null)
return string.Format("{0} - {1}", CleanTitle, AirDate.Date);
return string.Format("{0} - S{1:00}E{2}", CleanTitle, SeasonNumber,
String.Join("-", Episodes));
String.Join("-", EpisodeNumbers));
}
}

View File

@ -68,7 +68,7 @@ internal static EpisodeParseResult ParseEpisodeInfo(string title)
Proper = title.ToLower().Contains("proper"),
CleanTitle = seriesName,
SeasonNumber = season,
Episodes = new List<int>()
EpisodeNumbers = new List<int>()
};
foreach (Match matchGroup in match)
@ -83,7 +83,7 @@ internal static EpisodeParseResult ParseEpisodeInfo(string title)
for (int i = first; i <= last; i++)
{
parsedEpisode.Episodes.Add(i);
parsedEpisode.EpisodeNumbers.Add(i);
}
}
}

View File

@ -13,11 +13,15 @@ namespace NzbDrone.Core.Providers
public class DownloadProvider
{
private readonly SabProvider _sabProvider;
private readonly HistoryProvider _historyProvider;
private readonly EpisodeProvider _episodeProvider;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public DownloadProvider(SabProvider sabProvider)
public DownloadProvider(SabProvider sabProvider, HistoryProvider historyProvider, EpisodeProvider episodeProvider)
{
_sabProvider = sabProvider;
_historyProvider = historyProvider;
_episodeProvider = episodeProvider;
}
public DownloadProvider()
@ -34,7 +38,25 @@ public virtual bool DownloadReport(EpisodeParseResult parseResult)
return false;
}
return _sabProvider.AddByUrl(parseResult.NzbUrl, sabTitle);
var addSuccess = _sabProvider.AddByUrl(parseResult.NzbUrl, sabTitle);
if (addSuccess)
{
foreach (var episode in parseResult.Episodes)
{
var history = new History();
history.Date = DateTime.Now;
history.Indexer = parseResult.Indexer;
history.IsProper = parseResult.Proper;
history.Quality = parseResult.Quality;
history.NzbTitle = parseResult.NzbTitle;
history.EpisodeId = episode.EpisodeId;
_historyProvider.Add(history);
}
}
return addSuccess;
}
}
}

View File

@ -77,6 +77,8 @@ public List<EpisodeParseResult> Fetch()
if (parsedEpisode != null)
{
parsedEpisode.NzbUrl = NzbDownloadUrl(item);
parsedEpisode.Indexer = Name;
parsedEpisode.NzbTitle = item.Title.Text;
result.Add(parsedEpisode);
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using NLog;
using NzbDrone.Core.Model;
@ -36,32 +37,28 @@ internal bool IsNeeded(EpisodeParseResult parseResult)
}
parseResult.Series = series;
parseResult.Episodes = new List<Episode>();
foreach (var episodeNumber in parseResult.Episodes)
if (!series.Monitored)
{
//Todo: How to handle full season files? Currently the episode list is completely empty for these releases
//Todo: Should we assume that the release contains all the episodes that belong to this season and add them from the DB?
//Todo: Fix this so it properly handles multi-epsiode releases (Currently as long as the first episode is needed we download it)
//Todo: for small releases this is less of an issue, but for Full Season Releases this could be an issue if we only need the first episode (or first few)
Logger.Debug("{0} is present in the DB but not tracked. skipping.", parseResult.CleanTitle);
return false;
}
if (!series.Monitored)
{
Logger.Debug("{0} is present in the DB but not tracked. skipping.", parseResult.CleanTitle);
return false;
}
if (!_seriesProvider.QualityWanted(series.SeriesId, parseResult.Quality))
{
Logger.Debug("Post doesn't meet the quality requirements [{0}]. skipping.", parseResult.Quality);
return false;
}
if (!_seriesProvider.QualityWanted(series.SeriesId, parseResult.Quality))
{
Logger.Debug("Post doesn't meet the quality requirements [{0}]. skipping.", parseResult.Quality);
return false;
}
if (_seasonProvider.IsIgnored(series.SeriesId, parseResult.SeasonNumber))
{
Logger.Debug("Season {0} is currently set to ignore. skipping.", parseResult.SeasonNumber);
return false;
}
if (_seasonProvider.IsIgnored(series.SeriesId, parseResult.SeasonNumber))
{
Logger.Debug("Season {0} is currently set to ignore. skipping.", parseResult.SeasonNumber);
return false;
}
foreach (var episodeNumber in parseResult.EpisodeNumbers)
{
var episodeInfo = _episodeProvider.GetEpisode(series.SeriesId, parseResult.SeasonNumber, episodeNumber);
if (episodeInfo == null)
{
@ -84,21 +81,33 @@ internal bool IsNeeded(EpisodeParseResult parseResult)
_episodeProvider.AddEpisode(episodeInfo);
}
parseResult.Episodes.Add(episodeInfo);
}
if (!_episodeProvider.IsNeeded(parseResult, episodeInfo))
foreach (var episode in parseResult.Episodes)
{
//Todo: How to handle full season files? Currently the episode list is completely empty for these releases
//Todo: Should we assume that the release contains all the episodes that belong to this season and add them from the DB?
//Todo: Fix this so it properly handles multi-epsiode releases (Currently as long as the first episode is needed we download it)
//Todo: for small releases this is less of an issue, but for Full Season Releases this could be an issue if we only need the first episode (or first few)
if (!_episodeProvider.IsNeeded(parseResult, episode))
{
Logger.Debug("Episode {0} is not needed. skipping.", parseResult);
return false;
continue;
}
if (_historyProvider.Exists(episodeInfo.EpisodeId, parseResult.Quality, parseResult.Proper))
if (_historyProvider.Exists(episode.EpisodeId, parseResult.Quality, parseResult.Proper))
{
Logger.Debug("Episode {0} is in history. skipping.", parseResult);
return false;
continue;
}
//Congragulations younge feed item! you have made it this far. you are truly special!!!
Logger.Debug("Episode {0} is needed", parseResult);
return true;
}

View File

@ -83,7 +83,7 @@ public virtual EpisodeFile ImportFile(Series series, string filePath)
var episodes = new List<Episode>();
//Check for daily shows
if (parseResult.Episodes == null)
if (parseResult.EpisodeNumbers == null)
{
var episode = _episodeProvider.GetEpisode(series.SeriesId, parseResult.AirDate.Date);
@ -98,7 +98,7 @@ public virtual EpisodeFile ImportFile(Series series, string filePath)
}
else
{
foreach (var episodeNumber in parseResult.Episodes)
foreach (var episodeNumber in parseResult.EpisodeNumbers)
{
var episode = _episodeProvider.GetEpisode(series.SeriesId, parseResult.SeasonNumber,
episodeNumber);

View File

@ -92,13 +92,13 @@ private string GetSabRequest(string action)
_configProvider.SabPassword);
}
public String GetSabTitle(EpisodeParseResult parseResult)
public virtual String GetSabTitle(EpisodeParseResult parseResult)
{
//Show Name - 1x01-1x02 - Episode Name
//Show Name - 1x01 - Episode Name
var episodeString = new List<String>();
foreach (var episode in parseResult.Episodes)
foreach (var episode in parseResult.EpisodeNumbers)
{
episodeString.Add(String.Format("{0}x{1}", parseResult.SeasonNumber, episode));
}

View File

@ -142,15 +142,14 @@ public ActionResult _AjaxSeasonGrid(int seasonId)
return View(new GridModel(episodes));
}
[GridAction]
public ActionResult _CustomBinding(GridCommand command, int seasonId)
//Local Helpers
private string GetEpisodePath(EpisodeFile file)
{
IEnumerable<Episode> data = GetData(command);
return View(new GridModel
{
Data = data,
Total = data.Count()
});
if (file == null)
return String.Empty;
//Return the path relative to the Series' Folder
return file.Path.Replace(file.Series.Path, "").Trim(Path.DirectorySeparatorChar);
}
public ActionResult SearchForSeries(string seriesName)
@ -174,66 +173,6 @@ public ActionResult SearchForSeries(string seriesName)
return PartialView("SeriesSearchResults", model);
}
private IEnumerable<Episode> GetData(GridCommand command)
{
return null;
/*
IQueryable<Episode> data = .Orders;
//Apply filtering
if (command.FilterDescriptors.Any())
{
data = data.Where(ExpressionBuilder.Expression<Order>(command.FilterDescriptors));
}
// Apply sorting
foreach (SortDescriptor sortDescriptor in command.SortDescriptors)
{
if (sortDescriptor.SortDirection == ListSortDirection.Ascending)
{
switch (sortDescriptor.Member)
{
case "OrderID":
data = data.OrderBy(ExpressionBuilder.Expression<Order, int>(sortDescriptor.Member));
break;
case "Customer.ContactName":
data = data.OrderBy(order => order.Customer.ContactName);
break;
case "ShipAddress":
data = data.OrderBy(order => order.ShipAddress);
break;
case "OrderDate":
data = data.OrderBy(order => order.OrderDate);
break;
}
}
else
{
switch (sortDescriptor.Member)
{
case "OrderID":
data = data.OrderByDescending(order => order.OrderID);
break;
case "Customer.ContactName":
data = data.OrderByDescending(order => order.Customer.ContactName);
break;
case "ShipAddress":
data = data.OrderByDescending(order => order.ShipAddress);
break;
case "OrderDate":
data = data.OrderByDescending(order => order.OrderDate);
break;
}
}
}
count = data.Count();
// ... and paging
if (command.PageSize > 0)
{
data = data.Skip((command.Page - 1) * command.PageSize);
}
data = data.Take(command.PageSize);
return data;*/
}
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult _SaveAjaxEditing(string id)
@ -301,16 +240,6 @@ public ActionResult RenameEpisode(int episodeId)
return RedirectToAction("Index");
}
//Local Helpers
private string GetEpisodePath(EpisodeFile file)
{
if (file == null)
return String.Empty;
//Return the path relative to the Series' Folder
return file.Path.Replace(file.Series.Path, "").Trim(Path.DirectorySeparatorChar);
}
private List<SeriesModel> GetSeriesModels(List<Series> seriesInDb)
{
var series = new List<SeriesModel>();

View File

@ -58,45 +58,47 @@
{
<br />
<h3>Season @season.SeasonNumber</h3>
<h3>
Season @season.SeasonNumber</h3>
<div class="grid-container">
@{Season season1 = season;
Html.Telerik().Grid<EpisodeModel>().Name("seasons_" + season.SeasonNumber)
.TableHtmlAttributes(new { @class = "Grid" })
.Columns(columns =>
{
columns.Bound(o => o.EpisodeId)
.ClientTemplate(
"<input type='checkbox' name='checkedEpisodes' value='<#= EpisodeId #>' />")
.Title("")
.Width(1)
.HtmlAttributes(new { style = "text-align:center" });
Html.Telerik().Grid<EpisodeModel>().Name("seasons_" + season.SeasonNumber)
.TableHtmlAttributes(new { @class = "Grid" })
.Columns(columns =>
{
columns.Bound(o => o.EpisodeId)
.ClientTemplate(
"<input type='checkbox' name='checkedEpisodes' value='<#= EpisodeId #>' />")
.Title("")
.Width(1)
.HtmlAttributes(new { style = "text-align:center" });
columns.Bound(c => c.EpisodeNumber).Width(10).Title("Episode");
columns.Bound(c => c.Title).Title("Title").Width(300);
columns.Bound(c => c.AirDate).Format("{0:d}").Width(10);
columns.Bound(c => c.Quality).Width(10);
columns.Bound(c => c.Path);
columns.Bound(c => c.Status);
})
.DetailView(detailView => detailView.ClientTemplate("<div><#= Overview #> </br><#= Path #> </div>"))
.ClientEvents(clientEvents =>
{
clientEvents.OnDataBinding("grid_bind");
clientEvents.OnDataBound("grid_bound");
})
.Sortable(rows => rows.OrderBy(epSort => epSort.Add(c => c.EpisodeNumber).Descending()).Enabled(true))
.Footer(true)
.DataBinding(
d =>
d.Ajax().Select("_AjaxSeasonGrid", "Series",
new RouteValueDictionary { { "seasonId", season1.SeasonId.ToString() } }))
.ToolBar(
c =>
c.Custom().Text("Rename Season").Action("RenameSeason", "Series", new { seasonId = season1.SeasonId })
.ButtonType(GridButtonType.Text))
.Render();}
<span class="grid-loader"><img src="@Url.Content("~/Content/Images/Loading.gif")" alt="Loading"/> Loading...</span>
columns.Bound(c => c.EpisodeNumber).Width(0).Title("Episode");
columns.Bound(c => c.Title).Title("Title");
columns.Bound(c => c.AirDate).Format("{0:d}").Width(0);
columns.Bound(c => c.Quality).Width(0);
columns.Bound(c => c.Status).Width(0);
})
.DetailView(detailView => detailView.ClientTemplate("<div><#= Overview #> </br><#= Path #> </div>"))
.ClientEvents(clientEvents =>
{
clientEvents.OnDataBinding("grid_bind");
clientEvents.OnDataBound("grid_bound");
})
.Sortable(rows => rows.OrderBy(epSort => epSort.Add(c => c.EpisodeNumber).Descending()).Enabled(true))
.Footer(true)
.DataBinding(
d =>
d.Ajax().Select("_AjaxSeasonGrid", "Series",
new RouteValueDictionary { { "seasonId", season1.SeasonId.ToString() } }))
.ToolBar(
c =>
c.Custom().Text("Rename Season").Action("RenameSeason", "Series", new { seasonId = season1.SeasonId })
.ButtonType(GridButtonType.Text))
.Render();}
<span class="grid-loader">
<img src="@Url.Content("~/Content/Images/Loading.gif")" alt="Loading"/>
Loading...</span>
</div>
}
@{var specialSeasons = Model.Seasons.Where(s => s.SeasonNumber == 0).FirstOrDefault();}
@ -104,10 +106,11 @@
{
<br />
<h3>Specials</h3>
<h3>
Specials</h3>
<div class="grid-container">
@{Html.Telerik().Grid<EpisodeModel>().Name("seasons_specials")
.TableHtmlAttributes(new {@class = "Grid"})
.TableHtmlAttributes(new { @class = "Grid" })
.Columns(columns =>
{
columns.Bound(o => o.EpisodeId)
@ -118,10 +121,10 @@
.HtmlAttributes(new { style = "text-align:center" });
columns.Bound(c => c.EpisodeNumber).Width(10).Title("Episode");
columns.Bound(c => c.Title).Title("Title").Width(300);
columns.Bound(c => c.Title).Title("Title").Width(10000);
columns.Bound(c => c.AirDate).Format("{0:d}").Width(10);
columns.Bound(c => c.Quality).Width(10);
columns.Bound(c => c.Path);
columns.Bound(c => c.Status).Width(10);
})
.DetailView(detailView => detailView.ClientTemplate("<div><#= Overview #> </br><#= Path #> </div>"))
.ClientEvents(clientEvents =>
@ -136,7 +139,9 @@
d.Ajax().Select("_AjaxSeasonGrid", "Series",
new RouteValueDictionary { { "seasonId", specialSeasons.SeasonId.ToString() } }))
.Render(); }
<span class="grid-loader"><img src="@Url.Content("~/Content/Images/Loading.gif")" alt="Loading"/> Loading...</span>
<span class="grid-loader">
<img src="@Url.Content("~/Content/Images/Loading.gif")" alt="Loading"/>
Loading...</span>
</div>
}
}