mirror of https://github.com/Radarr/Radarr
Merge branch 'master' of git://github.com/kayone/NzbDrone
This commit is contained in:
commit
fc7d3da540
|
@ -0,0 +1,295 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using AutoMoq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using MbUnit.Framework;
|
||||||
|
using Moq;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Model.Notification;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Providers.Indexer;
|
||||||
|
using NzbDrone.Core.Providers.Jobs;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public class EpisodeSearchJobTest : TestBase
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void ParseResult_should_return_after_match()
|
||||||
|
{
|
||||||
|
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(5)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var episode = Builder<Episode>.CreateNew().Build();
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
|
mocker.GetMock<InventoryProvider>()
|
||||||
|
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Returns(true);
|
||||||
|
|
||||||
|
|
||||||
|
mocker.GetMock<DownloadProvider>()
|
||||||
|
.Setup(c => c.DownloadReport(It.IsAny<EpisodeParseResult>())).Returns(true);
|
||||||
|
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
mocker.VerifyAllMocks();
|
||||||
|
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Once());
|
||||||
|
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(It.IsAny<EpisodeParseResult>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void higher_quality_should_be_called_first()
|
||||||
|
{
|
||||||
|
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(2)
|
||||||
|
.WhereTheFirst(1).Has(c => c.Quality = QualityTypes.Bluray1080p)
|
||||||
|
.AndTheNext(1).Has(c => c.Quality = QualityTypes.DVD)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var episode = Builder<Episode>.CreateNew().Build();
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
|
mocker.GetMock<InventoryProvider>()
|
||||||
|
.Setup(c => c.IsNeeded(parseResults[0])).Returns(true);
|
||||||
|
|
||||||
|
mocker.GetMock<DownloadProvider>()
|
||||||
|
.Setup(c => c.DownloadReport(parseResults[0])).Returns(true);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
mocker.VerifyAllMocks();
|
||||||
|
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(parseResults[0]), Times.Once());
|
||||||
|
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(parseResults[0]), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void when_same_quality_proper_should_be_called_first()
|
||||||
|
{
|
||||||
|
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(20)
|
||||||
|
.WhereAll().Have(c => c.Quality = QualityTypes.DVD)
|
||||||
|
.And(c => c.Proper = false)
|
||||||
|
.WhereRandom(1).Has(c => c.Proper = true)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Assert.Count(1, parseResults.Where(c => c.Proper));
|
||||||
|
|
||||||
|
var episode = Builder<Episode>.CreateNew().Build();
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
|
mocker.GetMock<InventoryProvider>()
|
||||||
|
.Setup(c => c.IsNeeded(It.Is<EpisodeParseResult>(p => p.Proper))).Returns(true);
|
||||||
|
|
||||||
|
mocker.GetMock<DownloadProvider>()
|
||||||
|
.Setup(c => c.DownloadReport(It.Is<EpisodeParseResult>(p => p.Proper))).Returns(true);
|
||||||
|
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
mocker.VerifyAllMocks();
|
||||||
|
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.Is<EpisodeParseResult>(p => p.Proper)), Times.Once());
|
||||||
|
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(It.Is<EpisodeParseResult>(p => p.Proper)), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void when_not_needed_should_check_the_rest()
|
||||||
|
{
|
||||||
|
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(4)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var episode = Builder<Episode>.CreateNew().Build();
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
|
mocker.GetMock<InventoryProvider>()
|
||||||
|
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
mocker.VerifyAllMocks();
|
||||||
|
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Exactly(4));
|
||||||
|
ExceptionVerification.ExcpectedWarns(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void failed_IsNeeded_should_check_the_rest()
|
||||||
|
{
|
||||||
|
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(4)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var episode = Builder<Episode>.CreateNew().Build();
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
|
mocker.GetMock<InventoryProvider>()
|
||||||
|
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Throws(new Exception());
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
mocker.VerifyAllMocks();
|
||||||
|
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Exactly(4));
|
||||||
|
ExceptionVerification.ExcpectedErrors(4);
|
||||||
|
ExceptionVerification.ExcpectedWarns(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Row(0)]
|
||||||
|
[Row(-1)]
|
||||||
|
[Row(-100)]
|
||||||
|
[ExpectedException(typeof(ArgumentOutOfRangeException))]
|
||||||
|
public void target_id_less_than_0_throws_exception(int target)
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
mocker.Resolve<EpisodeSearchJob>().Start(new ProgressNotification("Test"), target);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_search_all_providers()
|
||||||
|
{
|
||||||
|
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(4)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var episode = Builder<Episode>.CreateNew()
|
||||||
|
.With(c => c.Series = Builder<Series>.CreateNew().Build())
|
||||||
|
.With(c => c.SeasonNumber = 12)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
|
mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(c => c.GetEpisode(episode.EpisodeId))
|
||||||
|
.Returns(episode);
|
||||||
|
|
||||||
|
var indexer1 = new Mock<IndexerBase>();
|
||||||
|
indexer1.Setup(c => c.FetchEpisode(episode.Series.Title, episode.SeasonNumber, episode.EpisodeNumber))
|
||||||
|
.Returns(parseResults).Verifiable();
|
||||||
|
|
||||||
|
|
||||||
|
var indexer2 = new Mock<IndexerBase>();
|
||||||
|
indexer2.Setup(c => c.FetchEpisode(episode.Series.Title, episode.SeasonNumber, episode.EpisodeNumber))
|
||||||
|
.Returns(parseResults).Verifiable();
|
||||||
|
|
||||||
|
var indexers = new List<IndexerBase> { indexer1.Object, indexer2.Object };
|
||||||
|
|
||||||
|
mocker.GetMock<IndexerProvider>()
|
||||||
|
.Setup(c => c.GetEnabledIndexers())
|
||||||
|
.Returns(indexers);
|
||||||
|
|
||||||
|
mocker.GetMock<InventoryProvider>()
|
||||||
|
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mocker.Resolve<EpisodeSearchJob>().Start(new ProgressNotification("Test"), episode.EpisodeId);
|
||||||
|
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
mocker.VerifyAllMocks();
|
||||||
|
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Exactly(8));
|
||||||
|
ExceptionVerification.ExcpectedWarns(1);
|
||||||
|
indexer1.VerifyAll();
|
||||||
|
indexer2.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void failed_indexer_should_not_break_job()
|
||||||
|
{
|
||||||
|
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(4)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var episode = Builder<Episode>.CreateNew()
|
||||||
|
.With(c => c.Series = Builder<Series>.CreateNew().Build())
|
||||||
|
.With(c => c.SeasonNumber = 12)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
|
mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(c => c.GetEpisode(episode.EpisodeId))
|
||||||
|
.Returns(episode);
|
||||||
|
|
||||||
|
var indexer1 = new Mock<IndexerBase>();
|
||||||
|
indexer1.Setup(c => c.FetchEpisode(episode.Series.Title, episode.SeasonNumber, episode.EpisodeNumber))
|
||||||
|
.Returns(parseResults).Verifiable();
|
||||||
|
|
||||||
|
|
||||||
|
var indexer2 = new Mock<IndexerBase>();
|
||||||
|
indexer2.Setup(c => c.FetchEpisode(episode.Series.Title, episode.SeasonNumber, episode.EpisodeNumber))
|
||||||
|
.Throws(new Exception()).Verifiable();
|
||||||
|
|
||||||
|
var indexer3 = new Mock<IndexerBase>();
|
||||||
|
indexer2.Setup(c => c.FetchEpisode(episode.Series.Title, episode.SeasonNumber, episode.EpisodeNumber))
|
||||||
|
.Returns(parseResults).Verifiable();
|
||||||
|
|
||||||
|
|
||||||
|
var indexers = new List<IndexerBase> { indexer1.Object, indexer2.Object, indexer3.Object };
|
||||||
|
|
||||||
|
mocker.GetMock<IndexerProvider>()
|
||||||
|
.Setup(c => c.GetEnabledIndexers())
|
||||||
|
.Returns(indexers);
|
||||||
|
|
||||||
|
mocker.GetMock<InventoryProvider>()
|
||||||
|
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mocker.Resolve<EpisodeSearchJob>().Start(new ProgressNotification("Test"), episode.EpisodeId);
|
||||||
|
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
mocker.VerifyAllMocks();
|
||||||
|
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Exactly(8));
|
||||||
|
|
||||||
|
ExceptionVerification.ExcpectedWarns(1);
|
||||||
|
ExceptionVerification.ExcpectedErrors(1);
|
||||||
|
indexer1.VerifyAll();
|
||||||
|
indexer2.VerifyAll();
|
||||||
|
indexer3.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void no_episode_found_should_return_with_error_logged()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
|
mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(c => c.GetEpisode(It.IsAny<long>()))
|
||||||
|
.Returns<Episode>(null);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mocker.Resolve<EpisodeSearchJob>().Start(new ProgressNotification("Test"), 12);
|
||||||
|
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
mocker.VerifyAllMocks();
|
||||||
|
ExceptionVerification.ExcpectedErrors(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,17 +27,9 @@ namespace NzbDrone.Core.Test.Framework
|
||||||
|
|
||||||
internal static void AssertNoError()
|
internal static void AssertNoError()
|
||||||
{
|
{
|
||||||
if (_logs.Count != 0)
|
ExcpectedFatals(0);
|
||||||
{
|
ExcpectedErrors(0);
|
||||||
string errors = GetLogsString(_logs);
|
ExcpectedWarns(0);
|
||||||
|
|
||||||
var message = String.Format("{0} unexpected Fatal/Error/Warning were logged during execution.\n\r Use ExceptionVerification.Excpected methods if errors are excepted for this test.{1}{2}",
|
|
||||||
_logs.Count,
|
|
||||||
Environment.NewLine,
|
|
||||||
errors);
|
|
||||||
|
|
||||||
Assert.Fail(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetLogsString(IEnumerable<LogEventInfo> logs)
|
private static string GetLogsString(IEnumerable<LogEventInfo> logs)
|
||||||
|
@ -48,9 +40,9 @@ namespace NzbDrone.Core.Test.Framework
|
||||||
string exception = "";
|
string exception = "";
|
||||||
if (log.Exception != null)
|
if (log.Exception != null)
|
||||||
{
|
{
|
||||||
exception = log.Exception.ToString();
|
exception = log.Exception.Message;
|
||||||
}
|
}
|
||||||
errors += Environment.NewLine + String.Format("[{0}] {1}: {2} {3}", log.Level, log.LoggerName, log.FormattedMessage, exception);
|
errors += Environment.NewLine + String.Format("[{0}] {1}: {2} [{3}]", log.Level, log.LoggerName, log.FormattedMessage, exception);
|
||||||
}
|
}
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
@ -86,8 +78,14 @@ namespace NzbDrone.Core.Test.Framework
|
||||||
|
|
||||||
if (levelLogs.Count != count)
|
if (levelLogs.Count != count)
|
||||||
{
|
{
|
||||||
|
|
||||||
var message = String.Format("{0} {1}(s) were expected but {2} were logged.\n\r{3}",
|
var message = String.Format("{0} {1}(s) were expected but {2} were logged.\n\r{3}",
|
||||||
count, level, _logs.Count, GetLogsString(levelLogs));
|
count, level, levelLogs.Count, GetLogsString(levelLogs));
|
||||||
|
|
||||||
|
message =
|
||||||
|
"********************************************************************************************************************************\n\r"
|
||||||
|
+ message +
|
||||||
|
"\n\r********************************************************************************************************************************";
|
||||||
|
|
||||||
Assert.Fail(message);
|
Assert.Fail(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,8 @@ namespace NzbDrone.Core.Test
|
||||||
public class ImportNewSeriesJobTest : TestBase
|
public class ImportNewSeriesJobTest : TestBase
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void series_specific_scan_should_scan_series()
|
public void import_new_series_succesfull()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
var series = Builder<Series>.CreateListOfSize(2)
|
var series = Builder<Series>.CreateListOfSize(2)
|
||||||
.WhereAll().Have(s => s.Episodes = Builder<Episode>.CreateListOfSize(10).Build())
|
.WhereAll().Have(s => s.Episodes = Builder<Episode>.CreateListOfSize(10).Build())
|
||||||
.WhereAll().Have(s => s.LastInfoSync = null)
|
.WhereAll().Have(s => s.LastInfoSync = null)
|
||||||
|
@ -37,21 +35,38 @@ namespace NzbDrone.Core.Test
|
||||||
|
|
||||||
mocker.GetMock<SeriesProvider>()
|
mocker.GetMock<SeriesProvider>()
|
||||||
.Setup(p => p.GetAllSeries())
|
.Setup(p => p.GetAllSeries())
|
||||||
.Returns(series.AsQueryable())
|
.Returns(series.AsQueryable());
|
||||||
.Callback(() => series.ToList().ForEach(c => c.LastInfoSync = DateTime.Now));//Set the last scan time on the collection
|
|
||||||
|
|
||||||
mocker.GetMock<DiskScanJob>()
|
mocker.GetMock<DiskScanJob>()
|
||||||
.Setup(j => j.Start(notification, series[0].SeriesId));
|
.Setup(j => j.Start(notification, series[0].SeriesId))
|
||||||
|
.Callback(() => series[0].LastDiskSync = DateTime.Now)
|
||||||
|
.AtMostOnce();
|
||||||
|
|
||||||
mocker.GetMock<DiskScanJob>()
|
mocker.GetMock<DiskScanJob>()
|
||||||
.Setup(j => j.Start(notification, series[1].SeriesId));
|
.Setup(j => j.Start(notification, series[1].SeriesId))
|
||||||
|
.Callback(() => series[1].LastDiskSync = DateTime.Now)
|
||||||
|
.AtMostOnce();
|
||||||
|
|
||||||
mocker.GetMock<UpdateInfoJob>()
|
mocker.GetMock<UpdateInfoJob>()
|
||||||
.Setup(j => j.Start(notification, series[0].SeriesId));
|
.Setup(j => j.Start(notification, series[0].SeriesId))
|
||||||
|
.Callback(() => series[0].LastInfoSync = DateTime.Now)
|
||||||
|
.AtMostOnce();
|
||||||
|
|
||||||
mocker.GetMock<UpdateInfoJob>()
|
mocker.GetMock<UpdateInfoJob>()
|
||||||
.Setup(j => j.Start(notification, series[1].SeriesId));
|
.Setup(j => j.Start(notification, series[1].SeriesId))
|
||||||
|
.Callback(() => series[1].LastInfoSync = DateTime.Now)
|
||||||
|
.AtMostOnce();
|
||||||
|
|
||||||
|
mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(s => s.GetSeries(series[0].SeriesId)).Returns(series[0]);
|
||||||
|
|
||||||
|
mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(s => s.GetSeries(series[1].SeriesId)).Returns(series[1]);
|
||||||
|
|
||||||
|
|
||||||
|
mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(s => s.GetSeriesFiles(It.IsAny<int>())).Returns(new List<EpisodeFile>());
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
mocker.Resolve<ImportNewSeriesJob>().Start(notification, 0);
|
mocker.Resolve<ImportNewSeriesJob>().Start(notification, 0);
|
||||||
|
@ -61,81 +76,57 @@ namespace NzbDrone.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void series_with_no_episodes_should_skip_scan()
|
[Timeout(3)]
|
||||||
|
public void failed_import_should_not_be_stuck_in_loop()
|
||||||
{
|
{
|
||||||
var series = Builder<Series>.CreateNew()
|
var series = Builder<Series>.CreateListOfSize(2)
|
||||||
.With(s => s.SeriesId = 12)
|
.WhereAll().Have(s => s.Episodes = Builder<Episode>.CreateListOfSize(10).Build())
|
||||||
.With(s => s.Episodes = new List<Episode>())
|
.WhereAll().Have(s => s.LastInfoSync = null)
|
||||||
|
.WhereTheFirst(1).Has(s => s.SeriesId = 12)
|
||||||
|
.AndTheNext(1).Has(s => s.SeriesId = 15)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
var notification = new ProgressNotification("Test");
|
||||||
|
|
||||||
var mocker = new AutoMoqer(MockBehavior.Strict);
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
mocker.GetMock<SeriesProvider>()
|
mocker.GetMock<SeriesProvider>()
|
||||||
.Setup(p => p.GetSeries(series.SeriesId))
|
.Setup(p => p.GetAllSeries())
|
||||||
.Returns(series);
|
.Returns(series.AsQueryable());
|
||||||
|
|
||||||
|
mocker.GetMock<UpdateInfoJob>()
|
||||||
|
.Setup(j => j.Start(notification, series[0].SeriesId))
|
||||||
|
.Callback(() => series[0].LastInfoSync = DateTime.Now)
|
||||||
|
.AtMostOnce();
|
||||||
|
|
||||||
|
mocker.GetMock<UpdateInfoJob>()
|
||||||
|
.Setup(j => j.Start(notification, series[1].SeriesId))
|
||||||
|
.Throws(new InvalidOperationException())
|
||||||
|
.AtMostOnce();
|
||||||
|
|
||||||
|
mocker.GetMock<DiskScanJob>()
|
||||||
|
.Setup(j => j.Start(notification, series[0].SeriesId))
|
||||||
|
.Callback(() => series[0].LastDiskSync = DateTime.Now)
|
||||||
|
.AtMostOnce();
|
||||||
|
|
||||||
|
|
||||||
|
mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(s => s.GetSeries(series[0].SeriesId)).Returns(series[0]);
|
||||||
|
|
||||||
|
mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(s => s.GetSeriesFiles(It.IsAny<int>())).Returns(new List<EpisodeFile>());
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
mocker.Resolve<DiskScanJob>().Start(new ProgressNotification("Test"), series.SeriesId);
|
mocker.Resolve<ImportNewSeriesJob>().Start(notification, 0);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
mocker.VerifyAllMocks();
|
mocker.VerifyAllMocks();
|
||||||
|
ExceptionVerification.ExcpectedErrors(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void job_with_no_target_should_scan_all_series()
|
|
||||||
{
|
|
||||||
var series = Builder<Series>.CreateListOfSize(2)
|
|
||||||
.WhereTheFirst(1).Has(s => s.SeriesId = 12)
|
|
||||||
.AndTheNext(1).Has(s => s.SeriesId = 15)
|
|
||||||
.WhereAll().Have(s => s.Episodes = Builder<Episode>.CreateListOfSize(10).Build())
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var mocker = new AutoMoqer(MockBehavior.Strict);
|
|
||||||
|
|
||||||
mocker.GetMock<SeriesProvider>()
|
|
||||||
.Setup(p => p.GetAllSeries())
|
|
||||||
.Returns(series.AsQueryable());
|
|
||||||
|
|
||||||
mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(s => s.Scan(series[0]))
|
|
||||||
.Returns(new List<EpisodeFile>());
|
|
||||||
|
|
||||||
mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(s => s.Scan(series[1]))
|
|
||||||
.Returns(new List<EpisodeFile>());
|
|
||||||
|
|
||||||
mocker.Resolve<DiskScanJob>().Start(new ProgressNotification("Test"), 0);
|
|
||||||
|
|
||||||
|
|
||||||
mocker.VerifyAllMocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void job_with_no_target_should_scan_series_with_episodes()
|
|
||||||
{
|
|
||||||
var series = Builder<Series>.CreateListOfSize(2)
|
|
||||||
.WhereTheFirst(1).Has(s => s.SeriesId = 12)
|
|
||||||
.And(s => s.Episodes = Builder<Episode>.CreateListOfSize(10).Build())
|
|
||||||
.AndTheNext(1).Has(s => s.SeriesId = 15)
|
|
||||||
.And(s => s.Episodes = new List<Episode>())
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var mocker = new AutoMoqer(MockBehavior.Strict);
|
|
||||||
|
|
||||||
mocker.GetMock<SeriesProvider>()
|
|
||||||
.Setup(p => p.GetAllSeries())
|
|
||||||
.Returns(series.AsQueryable());
|
|
||||||
|
|
||||||
mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(s => s.Scan(series[0]))
|
|
||||||
.Returns(new List<EpisodeFile>());
|
|
||||||
|
|
||||||
mocker.Resolve<DiskScanJob>().Start(new ProgressNotification("Test"), 0);
|
|
||||||
|
|
||||||
|
|
||||||
mocker.VerifyAllMocks();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,151 +23,6 @@ namespace NzbDrone.Core.Test
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
public class IndexerProviderTest : TestBase
|
public class IndexerProviderTest : TestBase
|
||||||
{
|
{
|
||||||
[Test]
|
|
||||||
[Row("nzbsorg.xml", 0)]
|
|
||||||
[Row("nzbsrus.xml", 6)]
|
|
||||||
[Row("newzbin.xml", 1)]
|
|
||||||
[Row("nzbmatrix.xml", 1)]
|
|
||||||
public void parse_feed_xml(string fileName, int warns)
|
|
||||||
{
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.GetMock<HttpProvider>()
|
|
||||||
.Setup(h => h.DownloadStream(It.IsAny<String>(), It.IsAny<NetworkCredential>()))
|
|
||||||
.Returns(File.OpenRead(".\\Files\\Rss\\" + fileName));
|
|
||||||
|
|
||||||
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
|
||||||
mocker.GetMock<IndexerProvider>()
|
|
||||||
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
|
||||||
.Returns(fakeSettings);
|
|
||||||
|
|
||||||
var mockIndexer = mocker.Resolve<MockIndexer>();
|
|
||||||
var parseResults = mockIndexer.FetchRss();
|
|
||||||
|
|
||||||
foreach (var episodeParseResult in parseResults)
|
|
||||||
{
|
|
||||||
var Uri = new Uri(episodeParseResult.NzbUrl);
|
|
||||||
Assert.DoesNotContain(Uri.PathAndQuery, "//");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void newzbin()
|
|
||||||
{
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
mocker.GetMock<HttpProvider>()
|
|
||||||
.Setup(h => h.DownloadStream(It.IsAny<String>(), It.IsAny<NetworkCredential>()))
|
|
||||||
.Returns(File.OpenRead(".\\Files\\Rss\\newzbin.xml"));
|
|
||||||
|
|
||||||
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
|
||||||
mocker.GetMock<IndexerProvider>()
|
|
||||||
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
|
||||||
.Returns(fakeSettings);
|
|
||||||
|
|
||||||
var newzbinProvider = mocker.Resolve<Newzbin>();
|
|
||||||
var parseResults = newzbinProvider.FetchRss();
|
|
||||||
|
|
||||||
foreach (var episodeParseResult in parseResults)
|
|
||||||
{
|
|
||||||
var Uri = new Uri(episodeParseResult.NzbUrl);
|
|
||||||
Assert.DoesNotContain(Uri.PathAndQuery, "//");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
[Row("Adventure.Inc.S03E19.DVDRip.XviD-OSiTV", 3, 19, QualityTypes.DVD)]
|
|
||||||
public void custome_parser_partial_success(string title, int season, int episode, QualityTypes quality)
|
|
||||||
{
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
const string summary = "My fake summary";
|
|
||||||
|
|
||||||
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
|
||||||
mocker.GetMock<IndexerProvider>()
|
|
||||||
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
|
||||||
.Returns(fakeSettings);
|
|
||||||
|
|
||||||
var fakeRssItem = Builder<SyndicationItem>.CreateNew()
|
|
||||||
.With(c => c.Title = new TextSyndicationContent(title))
|
|
||||||
.With(c => c.Summary = new TextSyndicationContent(summary))
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var result = mocker.Resolve<CustomParserIndexer>().ParseFeed(fakeRssItem);
|
|
||||||
|
|
||||||
Assert.IsNotNull(result);
|
|
||||||
Assert.AreEqual(summary, result.EpisodeTitle);
|
|
||||||
Assert.AreEqual(season, result.SeasonNumber);
|
|
||||||
Assert.AreEqual(episode, result.EpisodeNumbers[0]);
|
|
||||||
Assert.AreEqual(quality, result.Quality);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
[Row("Adventure.Inc.DVDRip.XviD-OSiTV")]
|
|
||||||
public void custome_parser_full_parse(string title)
|
|
||||||
{
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
|
|
||||||
const string summary = "My fake summary";
|
|
||||||
|
|
||||||
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
|
||||||
mocker.GetMock<IndexerProvider>()
|
|
||||||
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
|
||||||
.Returns(fakeSettings);
|
|
||||||
|
|
||||||
var fakeRssItem = Builder<SyndicationItem>.CreateNew()
|
|
||||||
.With(c => c.Title = new TextSyndicationContent(title))
|
|
||||||
.With(c => c.Summary = new TextSyndicationContent(summary))
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var result = mocker.Resolve<CustomParserIndexer>().ParseFeed(fakeRssItem);
|
|
||||||
|
|
||||||
Assert.IsNotNull(result);
|
|
||||||
Assert.AreEqual(summary, result.EpisodeTitle);
|
|
||||||
ExceptionVerification.ExcpectedWarns(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void downloadFeed()
|
|
||||||
{
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
mocker.SetConstant(new HttpProvider());
|
|
||||||
|
|
||||||
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
|
||||||
mocker.GetMock<IndexerProvider>()
|
|
||||||
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
|
||||||
.Returns(fakeSettings);
|
|
||||||
|
|
||||||
mocker.Resolve<TestUrlIndexer>().FetchRss();
|
|
||||||
|
|
||||||
ExceptionVerification.IgnoreWarns();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Init_indexer_test()
|
public void Init_indexer_test()
|
||||||
{
|
{
|
||||||
|
@ -178,49 +33,32 @@ namespace NzbDrone.Core.Test
|
||||||
//Act
|
//Act
|
||||||
var indexerProvider = mocker.Resolve<IndexerProvider>();
|
var indexerProvider = mocker.Resolve<IndexerProvider>();
|
||||||
indexerProvider.InitializeIndexers(new List<IndexerBase> { mocker.Resolve<MockIndexer>() });
|
indexerProvider.InitializeIndexers(new List<IndexerBase> { mocker.Resolve<MockIndexer>() });
|
||||||
var indexers = indexerProvider.All();
|
var settings = indexerProvider.GetSettings(typeof(MockIndexer));
|
||||||
|
settings.Enable = true;
|
||||||
|
indexerProvider.SaveSettings(settings);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
Assert.Count(1, indexers);
|
Assert.Count(1, indexerProvider.GetAllISettings());
|
||||||
|
Assert.Count(1, indexerProvider.GetEnabledIndexers());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void unmapped_series_shouldnt_call_any_providers()
|
public void Init_indexer_with_disabled_job()
|
||||||
{
|
|
||||||
var mocker = new AutoMoqer(MockBehavior.Strict);
|
|
||||||
mocker.GetMock<SeriesProvider>()
|
|
||||||
.Setup(c => c.FindSeries(It.IsAny<String>()))
|
|
||||||
.Returns<Series>(null);
|
|
||||||
|
|
||||||
var indexer = mocker.Resolve<MockIndexer>();
|
|
||||||
//indexer.ProcessItem(new SyndicationItem { Title = new TextSyndicationContent("Adventure.Inc.S01E18.DVDRip.XviD-OSiTV") });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void nzbsorg_search_returns_valid_results()
|
|
||||||
{
|
{
|
||||||
var mocker = new AutoMoqer();
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
mocker.GetMock<ConfigProvider>()
|
mocker.SetConstant(MockLib.GetEmptyRepository());
|
||||||
.SetupGet(c => c.NzbsOrgUId)
|
|
||||||
.Returns("43516");
|
|
||||||
|
|
||||||
mocker.GetMock<ConfigProvider>()
|
|
||||||
.SetupGet(c => c.NzbsOrgHash)
|
|
||||||
.Returns("bc8edb4cc49d4ae440775adec5ac001f");
|
|
||||||
|
|
||||||
|
|
||||||
mocker.Resolve<HttpProvider>();
|
|
||||||
|
|
||||||
var result = mocker.Resolve<NzbsOrg>().FetchEpisode("Simpsons", 21, 23);
|
|
||||||
|
|
||||||
Assert.IsNotEmpty(result);
|
|
||||||
Assert.ForAll(result, r => r.CleanTitle == "simpsons");
|
|
||||||
Assert.ForAll(result, r => r.SeasonNumber == 21);
|
|
||||||
Assert.ForAll(result, r => r.EpisodeNumbers.Contains(23));
|
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var indexerProvider = mocker.Resolve<IndexerProvider>();
|
||||||
|
indexerProvider.InitializeIndexers(new List<IndexerBase> { mocker.Resolve<MockIndexer>() });
|
||||||
|
var settings = indexerProvider.GetSettings(typeof(MockIndexer));
|
||||||
|
settings.Enable = false;
|
||||||
|
indexerProvider.SaveSettings(settings);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Assert.Count(1, indexerProvider.GetAllISettings());
|
||||||
|
Assert.IsEmpty(indexerProvider.GetEnabledIndexers());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.ServiceModel.Syndication;
|
||||||
|
using System.Text;
|
||||||
|
using AutoMoq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using Gallio.Framework;
|
||||||
|
using MbUnit.Framework;
|
||||||
|
using MbUnit.Framework.ContractVerifiers;
|
||||||
|
using Moq;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
using NzbDrone.Core.Providers.Indexer;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public class IndexerTests : TestBase
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
[Row("nzbsorg.xml", 0)]
|
||||||
|
[Row("nzbsrus.xml", 6)]
|
||||||
|
[Row("newzbin.xml", 1)]
|
||||||
|
[Row("nzbmatrix.xml", 1)]
|
||||||
|
public void parse_feed_xml(string fileName, int warns)
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
mocker.GetMock<HttpProvider>()
|
||||||
|
.Setup(h => h.DownloadStream(It.IsAny<String>(), It.IsAny<NetworkCredential>()))
|
||||||
|
.Returns(File.OpenRead(".\\Files\\Rss\\" + fileName));
|
||||||
|
|
||||||
|
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
||||||
|
mocker.GetMock<IndexerProvider>()
|
||||||
|
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
||||||
|
.Returns(fakeSettings);
|
||||||
|
|
||||||
|
var mockIndexer = mocker.Resolve<MockIndexer>();
|
||||||
|
var parseResults = mockIndexer.FetchRss();
|
||||||
|
|
||||||
|
foreach (var episodeParseResult in parseResults)
|
||||||
|
{
|
||||||
|
var Uri = new Uri(episodeParseResult.NzbUrl);
|
||||||
|
Assert.DoesNotContain(Uri.PathAndQuery, "//");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void newzbin()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
mocker.GetMock<HttpProvider>()
|
||||||
|
.Setup(h => h.DownloadStream(It.IsAny<String>(), It.IsAny<NetworkCredential>()))
|
||||||
|
.Returns(File.OpenRead(".\\Files\\Rss\\newzbin.xml"));
|
||||||
|
|
||||||
|
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
||||||
|
mocker.GetMock<IndexerProvider>()
|
||||||
|
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
||||||
|
.Returns(fakeSettings);
|
||||||
|
|
||||||
|
var newzbinProvider = mocker.Resolve<Newzbin>();
|
||||||
|
var parseResults = newzbinProvider.FetchRss();
|
||||||
|
|
||||||
|
foreach (var episodeParseResult in parseResults)
|
||||||
|
{
|
||||||
|
var Uri = new Uri(episodeParseResult.NzbUrl);
|
||||||
|
Assert.DoesNotContain(Uri.PathAndQuery, "//");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Row("Adventure.Inc.S03E19.DVDRip.XviD-OSiTV", 3, 19, QualityTypes.DVD)]
|
||||||
|
public void custome_parser_partial_success(string title, int season, int episode, QualityTypes quality)
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
const string summary = "My fake summary";
|
||||||
|
|
||||||
|
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
||||||
|
mocker.GetMock<IndexerProvider>()
|
||||||
|
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
||||||
|
.Returns(fakeSettings);
|
||||||
|
|
||||||
|
var fakeRssItem = Builder<SyndicationItem>.CreateNew()
|
||||||
|
.With(c => c.Title = new TextSyndicationContent(title))
|
||||||
|
.With(c => c.Summary = new TextSyndicationContent(summary))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var result = mocker.Resolve<CustomParserIndexer>().ParseFeed(fakeRssItem);
|
||||||
|
|
||||||
|
Assert.IsNotNull(result);
|
||||||
|
Assert.AreEqual(summary, result.EpisodeTitle);
|
||||||
|
Assert.AreEqual(season, result.SeasonNumber);
|
||||||
|
Assert.AreEqual(episode, result.EpisodeNumbers[0]);
|
||||||
|
Assert.AreEqual(quality, result.Quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Row("Adventure.Inc.DVDRip.XviD-OSiTV")]
|
||||||
|
public void custome_parser_full_parse(string title)
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
const string summary = "My fake summary";
|
||||||
|
|
||||||
|
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
||||||
|
mocker.GetMock<IndexerProvider>()
|
||||||
|
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
||||||
|
.Returns(fakeSettings);
|
||||||
|
|
||||||
|
var fakeRssItem = Builder<SyndicationItem>.CreateNew()
|
||||||
|
.With(c => c.Title = new TextSyndicationContent(title))
|
||||||
|
.With(c => c.Summary = new TextSyndicationContent(summary))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var result = mocker.Resolve<CustomParserIndexer>().ParseFeed(fakeRssItem);
|
||||||
|
|
||||||
|
Assert.IsNotNull(result);
|
||||||
|
Assert.AreEqual(summary, result.EpisodeTitle);
|
||||||
|
ExceptionVerification.ExcpectedWarns(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void downloadFeed()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
mocker.SetConstant(new HttpProvider());
|
||||||
|
|
||||||
|
var fakeSettings = Builder<IndexerSetting>.CreateNew().Build();
|
||||||
|
mocker.GetMock<IndexerProvider>()
|
||||||
|
.Setup(c => c.GetSettings(It.IsAny<Type>()))
|
||||||
|
.Returns(fakeSettings);
|
||||||
|
|
||||||
|
mocker.Resolve<TestUrlIndexer>().FetchRss();
|
||||||
|
|
||||||
|
ExceptionVerification.IgnoreWarns();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void nzbsorg_search_returns_valid_results()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
mocker.GetMock<ConfigProvider>()
|
||||||
|
.SetupGet(c => c.NzbsOrgUId)
|
||||||
|
.Returns("43516");
|
||||||
|
|
||||||
|
mocker.GetMock<ConfigProvider>()
|
||||||
|
.SetupGet(c => c.NzbsOrgHash)
|
||||||
|
.Returns("bc8edb4cc49d4ae440775adec5ac001f");
|
||||||
|
|
||||||
|
|
||||||
|
mocker.Resolve<HttpProvider>();
|
||||||
|
|
||||||
|
var result = mocker.Resolve<NzbsOrg>().FetchEpisode("Simpsons", 21, 23);
|
||||||
|
|
||||||
|
Assert.IsNotEmpty(result);
|
||||||
|
Assert.ForAll(result, r => r.CleanTitle == "simpsons");
|
||||||
|
Assert.ForAll(result, r => r.SeasonNumber == 21);
|
||||||
|
Assert.ForAll(result, r => r.EpisodeNumbers.Contains(23));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -114,13 +114,13 @@ namespace NzbDrone.Core.Test
|
||||||
|
|
||||||
var timerProvider = mocker.Resolve<JobProvider>();
|
var timerProvider = mocker.Resolve<JobProvider>();
|
||||||
timerProvider.Initialize();
|
timerProvider.Initialize();
|
||||||
var firstRun = timerProvider.QueueJob(typeof(SlowJob),1);
|
var firstRun = timerProvider.QueueJob(typeof(SlowJob), 1);
|
||||||
var secondRun = timerProvider.QueueJob(typeof(SlowJob),2);
|
var secondRun = timerProvider.QueueJob(typeof(SlowJob), 2);
|
||||||
var third = timerProvider.QueueJob(typeof(SlowJob),3);
|
var third = timerProvider.QueueJob(typeof(SlowJob), 3);
|
||||||
|
|
||||||
|
|
||||||
Thread.Sleep(10000);
|
Thread.Sleep(10000);
|
||||||
|
//Asserts are done in ExceptionVerification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,9 +86,11 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="DownloadProviderTest.cs" />
|
<Compile Include="DownloadProviderTest.cs" />
|
||||||
|
<Compile Include="EpisodeSearchJobTest.cs" />
|
||||||
<Compile Include="EpisodeStatusTest.cs" />
|
<Compile Include="EpisodeStatusTest.cs" />
|
||||||
<Compile Include="ImportNewSeriesJobTest.cs" />
|
<Compile Include="ImportNewSeriesJobTest.cs" />
|
||||||
<Compile Include="DiskScanJobTest.cs" />
|
<Compile Include="DiskScanJobTest.cs" />
|
||||||
|
<Compile Include="IndexerTests.cs" />
|
||||||
<Compile Include="InventoryProviderTest.cs" />
|
<Compile Include="InventoryProviderTest.cs" />
|
||||||
<Compile Include="Framework\AutoMoq\AutoMoqer.cs" />
|
<Compile Include="Framework\AutoMoq\AutoMoqer.cs" />
|
||||||
<Compile Include="Framework\AutoMoq\AutoMoqerTest.cs" />
|
<Compile Include="Framework\AutoMoq\AutoMoqerTest.cs" />
|
||||||
|
|
|
@ -63,6 +63,9 @@ namespace NzbDrone.Core.Test
|
||||||
public void enteties_toString()
|
public void enteties_toString()
|
||||||
{
|
{
|
||||||
Console.WriteLine(new Episode().ToString());
|
Console.WriteLine(new Episode().ToString());
|
||||||
|
Console.WriteLine(new Season().ToString());
|
||||||
|
Console.WriteLine(new Series().ToString());
|
||||||
|
Console.WriteLine(new EpisodeFile().ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -110,8 +110,6 @@ namespace NzbDrone.Core
|
||||||
_kernel.Bind<IndexerBase>().To<NzbMatrix>().InSingletonScope();
|
_kernel.Bind<IndexerBase>().To<NzbMatrix>().InSingletonScope();
|
||||||
_kernel.Bind<IndexerBase>().To<NzbsRUs>().InSingletonScope();
|
_kernel.Bind<IndexerBase>().To<NzbsRUs>().InSingletonScope();
|
||||||
_kernel.Bind<IndexerBase>().To<Newzbin>().InSingletonScope();
|
_kernel.Bind<IndexerBase>().To<Newzbin>().InSingletonScope();
|
||||||
var indexers = _kernel.GetAll<IndexerBase>();
|
|
||||||
_kernel.Get<IndexerProvider>().InitializeIndexers(indexers.ToList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void BindJobs()
|
private static void BindJobs()
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>Properties\AnalysisRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
|
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
|
||||||
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
|
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
|
||||||
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
|
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
|
||||||
|
@ -264,6 +264,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
<None Include="Properties\AnalysisRules.ruleset" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Migrator.net\Migrator.Framework\Migrator.Framework.csproj">
|
<ProjectReference Include="..\Migrator.net\Migrator.Framework\Migrator.Framework.csproj">
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RuleSet Name="Copy of Microsoft Basic Correctness Rules" Description="These rules focus on logic errors and common mistakes made in the usage of framework APIs. Include this rule set to expand on the list of warnings reported by the minimum recommended rules." ToolsVersion="10.0">
|
||||||
|
<Include Path="minimumrecommendedrules.ruleset" Action="Default" />
|
||||||
|
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
|
||||||
|
<Rule Id="CA1008" Action="Warning" />
|
||||||
|
<Rule Id="CA1013" Action="Warning" />
|
||||||
|
<Rule Id="CA1301" Action="None" />
|
||||||
|
<Rule Id="CA1806" Action="Warning" />
|
||||||
|
<Rule Id="CA1816" Action="Warning" />
|
||||||
|
<Rule Id="CA1819" Action="Warning" />
|
||||||
|
<Rule Id="CA1820" Action="Warning" />
|
||||||
|
<Rule Id="CA1903" Action="Warning" />
|
||||||
|
<Rule Id="CA2004" Action="Warning" />
|
||||||
|
<Rule Id="CA2006" Action="Warning" />
|
||||||
|
<Rule Id="CA2101" Action="None" />
|
||||||
|
<Rule Id="CA2102" Action="Warning" />
|
||||||
|
<Rule Id="CA2105" Action="Warning" />
|
||||||
|
<Rule Id="CA2106" Action="Warning" />
|
||||||
|
<Rule Id="CA2115" Action="Warning" />
|
||||||
|
<Rule Id="CA2119" Action="Warning" />
|
||||||
|
<Rule Id="CA2120" Action="Warning" />
|
||||||
|
<Rule Id="CA2121" Action="Warning" />
|
||||||
|
<Rule Id="CA2122" Action="None" />
|
||||||
|
<Rule Id="CA2130" Action="Warning" />
|
||||||
|
<Rule Id="CA2205" Action="Warning" />
|
||||||
|
<Rule Id="CA2215" Action="Warning" />
|
||||||
|
<Rule Id="CA2221" Action="Warning" />
|
||||||
|
<Rule Id="CA2222" Action="Warning" />
|
||||||
|
<Rule Id="CA2223" Action="Warning" />
|
||||||
|
<Rule Id="CA2224" Action="Warning" />
|
||||||
|
<Rule Id="CA2226" Action="Warning" />
|
||||||
|
<Rule Id="CA2231" Action="Warning" />
|
||||||
|
<Rule Id="CA2239" Action="Warning" />
|
||||||
|
</Rules>
|
||||||
|
</RuleSet>
|
|
@ -6,7 +6,6 @@ using System.Web;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Model;
|
using NzbDrone.Core.Model;
|
||||||
using NzbDrone.Core.Providers.Core;
|
using NzbDrone.Core.Providers.Core;
|
||||||
using NzbDrone.Core.Repository;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Providers.Indexer
|
namespace NzbDrone.Core.Providers.Indexer
|
||||||
{
|
{
|
||||||
|
@ -24,6 +23,11 @@ namespace NzbDrone.Core.Providers.Indexer
|
||||||
_logger = LogManager.GetLogger(GetType().ToString());
|
_logger = LogManager.GetLogger(GetType().ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IndexerBase()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name for the feed
|
/// Gets the name for the feed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -35,15 +39,6 @@ namespace NzbDrone.Core.Providers.Indexer
|
||||||
protected abstract string[] Urls { get; }
|
protected abstract string[] Urls { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the rss url for specific episode search
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="seriesTitle">The series title.</param>
|
|
||||||
/// <param name="seasonNumber">The season number.</param>
|
|
||||||
/// <param name="episodeNumber">The episode number.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
protected abstract IList<String> GetSearchUrls(string seriesTitle, int seasonNumber, int episodeNumber);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the credential.
|
/// Gets the credential.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -53,10 +48,37 @@ namespace NzbDrone.Core.Providers.Indexer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the rss url for specific episode search
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seriesTitle">The series title.</param>
|
||||||
|
/// <param name="seasonNumber">The season number.</param>
|
||||||
|
/// <param name="episodeNumber">The episode number.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract IList<String> GetSearchUrls(string seriesTitle, int seasonNumber, int episodeNumber);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method can be overwritten to provide indexer specific info parsing
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">RSS item that needs to be parsed</param>
|
||||||
|
/// <param name="currentResult">Result of the built in parse function.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected virtual EpisodeParseResult CustomParser(SyndicationItem item, EpisodeParseResult currentResult)
|
||||||
|
{
|
||||||
|
return currentResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates direct link to download an NZB
|
||||||
|
/// </summary>
|
||||||
|
/// <param name = "item">RSS Feed item to generate the link for</param>
|
||||||
|
/// <returns>Download link URL</returns>
|
||||||
|
protected abstract string NzbDownloadUrl(SyndicationItem item);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fetches RSS feed and process each news item.
|
/// Fetches RSS feed and process each news item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IList<EpisodeParseResult> FetchRss()
|
public virtual IList<EpisodeParseResult> FetchRss()
|
||||||
{
|
{
|
||||||
_logger.Debug("Fetching feeds from " + Name);
|
_logger.Debug("Fetching feeds from " + Name);
|
||||||
|
|
||||||
|
@ -72,7 +94,7 @@ namespace NzbDrone.Core.Providers.Indexer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IList<EpisodeParseResult> FetchEpisode(string seriesTitle, int seasonNumber, int episodeNumber)
|
public virtual IList<EpisodeParseResult> FetchEpisode(string seriesTitle, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
_logger.Debug("Searching {0} for {1}-S{2}E{3:00}", Name, seriesTitle, seasonNumber, episodeNumber);
|
_logger.Debug("Searching {0} for {1}-S{2}E{3:00}", Name, seriesTitle, seasonNumber, episodeNumber);
|
||||||
|
|
||||||
|
@ -90,7 +112,7 @@ namespace NzbDrone.Core.Providers.Indexer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IList<EpisodeParseResult> Fetch(string url)
|
private IEnumerable<EpisodeParseResult> Fetch(string url)
|
||||||
{
|
{
|
||||||
var result = new List<EpisodeParseResult>();
|
var result = new List<EpisodeParseResult>();
|
||||||
|
|
||||||
|
@ -140,23 +162,5 @@ namespace NzbDrone.Core.Providers.Indexer
|
||||||
|
|
||||||
return CustomParser(item, episodeParseResult);
|
return CustomParser(item, episodeParseResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This method can be overwritten to provide indexer specific info parsing
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">RSS item that needs to be parsed</param>
|
|
||||||
/// <param name="currentResult">Result of the built in parse function.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
protected virtual EpisodeParseResult CustomParser(SyndicationItem item, EpisodeParseResult currentResult)
|
|
||||||
{
|
|
||||||
return currentResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generates direct link to download an NZB
|
|
||||||
/// </summary>
|
|
||||||
/// <param name = "item">RSS Feed item to generate the link for</param>
|
|
||||||
/// <returns>Download link URL</returns>
|
|
||||||
protected abstract string NzbDownloadUrl(SyndicationItem item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,6 +13,8 @@ namespace NzbDrone.Core.Providers
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
private readonly IRepository _repository;
|
private readonly IRepository _repository;
|
||||||
|
|
||||||
|
private IList<IndexerBase> _indexers = new List<IndexerBase>();
|
||||||
|
|
||||||
public IndexerProvider(IRepository repository)
|
public IndexerProvider(IRepository repository)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_repository = repository;
|
||||||
|
@ -23,7 +25,13 @@ namespace NzbDrone.Core.Providers
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual List<IndexerSetting> All()
|
public virtual IList<IndexerBase> GetEnabledIndexers()
|
||||||
|
{
|
||||||
|
var all = GetAllISettings();
|
||||||
|
return _indexers.Where(i => all.Exists(c => c.IndexProviderType == i.GetType().ToString() && c.Enable)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual List<IndexerSetting> GetAllISettings()
|
||||||
{
|
{
|
||||||
return _repository.All<IndexerSetting>().ToList();
|
return _repository.All<IndexerSetting>().ToList();
|
||||||
}
|
}
|
||||||
|
@ -47,23 +55,20 @@ namespace NzbDrone.Core.Providers
|
||||||
return _repository.Single<IndexerSetting>(s => s.IndexProviderType == type.ToString());
|
return _repository.Single<IndexerSetting>(s => s.IndexProviderType == type.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IndexerSetting GetSettings(int id)
|
|
||||||
{
|
|
||||||
return _repository.Single<IndexerSetting>(s => s.Id == id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void InitializeIndexers(IList<IndexerBase> indexers)
|
public virtual void InitializeIndexers(IList<IndexerBase> indexers)
|
||||||
{
|
{
|
||||||
Logger.Info("Initializing indexers. Count {0}", indexers.Count);
|
Logger.Info("Initializing indexers. Count {0}", indexers.Count);
|
||||||
|
|
||||||
var currentIndexers = All();
|
_indexers = indexers;
|
||||||
|
|
||||||
|
var currentIndexers = GetAllISettings();
|
||||||
|
|
||||||
foreach (var feedProvider in indexers)
|
foreach (var feedProvider in indexers)
|
||||||
{
|
{
|
||||||
IndexerBase indexerLocal = feedProvider;
|
IndexerBase indexerLocal = feedProvider;
|
||||||
if (!currentIndexers.Exists(c => c.IndexProviderType == indexerLocal.GetType().ToString()))
|
if (!currentIndexers.Exists(c => c.IndexProviderType == indexerLocal.GetType().ToString()))
|
||||||
{
|
{
|
||||||
var settings = new IndexerSetting()
|
var settings = new IndexerSetting
|
||||||
{
|
{
|
||||||
Enable = false,
|
Enable = false,
|
||||||
IndexProviderType = indexerLocal.GetType().ToString(),
|
IndexProviderType = indexerLocal.GetType().ToString(),
|
||||||
|
|
|
@ -12,20 +12,23 @@ namespace NzbDrone.Core.Providers
|
||||||
private readonly SeasonProvider _seasonProvider;
|
private readonly SeasonProvider _seasonProvider;
|
||||||
private readonly EpisodeProvider _episodeProvider;
|
private readonly EpisodeProvider _episodeProvider;
|
||||||
private readonly HistoryProvider _historyProvider;
|
private readonly HistoryProvider _historyProvider;
|
||||||
private readonly SabProvider _sabProvider;
|
|
||||||
|
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public InventoryProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvider, EpisodeProvider episodeProvider, HistoryProvider historyProvider, SabProvider sabProvider)
|
public InventoryProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvider, EpisodeProvider episodeProvider, HistoryProvider historyProvider)
|
||||||
{
|
{
|
||||||
_seriesProvider = seriesProvider;
|
_seriesProvider = seriesProvider;
|
||||||
_seasonProvider = seasonProvider;
|
_seasonProvider = seasonProvider;
|
||||||
_episodeProvider = episodeProvider;
|
_episodeProvider = episodeProvider;
|
||||||
_historyProvider = historyProvider;
|
_historyProvider = historyProvider;
|
||||||
_sabProvider = sabProvider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool IsNeeded(EpisodeParseResult parseResult)
|
public InventoryProvider()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool IsNeeded(EpisodeParseResult parseResult)
|
||||||
{
|
{
|
||||||
var series = _seriesProvider.FindSeries(parseResult.CleanTitle);
|
var series = _seriesProvider.FindSeries(parseResult.CleanTitle);
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,12 @@ using NLog;
|
||||||
using NzbDrone.Core.Model;
|
using NzbDrone.Core.Model;
|
||||||
using NzbDrone.Core.Model.Notification;
|
using NzbDrone.Core.Model.Notification;
|
||||||
using NzbDrone.Core.Providers.Indexer;
|
using NzbDrone.Core.Providers.Indexer;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Providers.Jobs
|
namespace NzbDrone.Core.Providers.Jobs
|
||||||
{
|
{
|
||||||
public class EpisodeSearchJob : IJob
|
public class EpisodeSearchJob : IJob
|
||||||
{
|
{
|
||||||
private readonly IEnumerable<IndexerBase> _indexers;
|
|
||||||
private readonly InventoryProvider _inventoryProvider;
|
private readonly InventoryProvider _inventoryProvider;
|
||||||
private readonly DownloadProvider _downloadProvider;
|
private readonly DownloadProvider _downloadProvider;
|
||||||
private readonly IndexerProvider _indexerProvider;
|
private readonly IndexerProvider _indexerProvider;
|
||||||
|
@ -19,9 +19,8 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
|
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public EpisodeSearchJob(IEnumerable<IndexerBase> indexers, InventoryProvider inventoryProvider, DownloadProvider downloadProvider, IndexerProvider indexerProvider, EpisodeProvider episodeProvider)
|
public EpisodeSearchJob(InventoryProvider inventoryProvider, DownloadProvider downloadProvider, IndexerProvider indexerProvider, EpisodeProvider episodeProvider)
|
||||||
{
|
{
|
||||||
_indexers = indexers;
|
|
||||||
_inventoryProvider = inventoryProvider;
|
_inventoryProvider = inventoryProvider;
|
||||||
_downloadProvider = downloadProvider;
|
_downloadProvider = downloadProvider;
|
||||||
_indexerProvider = indexerProvider;
|
_indexerProvider = indexerProvider;
|
||||||
|
@ -40,27 +39,53 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
|
|
||||||
public void Start(ProgressNotification notification, int targetId)
|
public void Start(ProgressNotification notification, int targetId)
|
||||||
{
|
{
|
||||||
var reports = new List<EpisodeParseResult>();
|
if (targetId <= 0)
|
||||||
|
throw new ArgumentOutOfRangeException("targetId");
|
||||||
|
|
||||||
var episode = _episodeProvider.GetEpisode(targetId);
|
var episode = _episodeProvider.GetEpisode(targetId);
|
||||||
|
if (episode == null)
|
||||||
|
{
|
||||||
|
Logger.Error("Unbale to find an episode {0} in database", targetId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var indexers = _indexerProvider.GetEnabledIndexers();
|
||||||
|
var reports = new List<EpisodeParseResult>();
|
||||||
|
|
||||||
foreach (var indexer in _indexers.Where(i => _indexerProvider.GetSettings(i.GetType()).Enable))
|
foreach (var indexer in indexers)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
notification.CurrentMessage = String.Format("Searching for {0} in {1}", episode, indexer.Name);
|
notification.CurrentMessage = String.Format("Searching for {0} in {1}", episode, indexer.Name);
|
||||||
reports.AddRange(indexer.FetchRss());
|
|
||||||
|
IList<EpisodeParseResult> indexerResults = new List<EpisodeParseResult>();
|
||||||
|
|
||||||
|
if (episode.IsDailyEpisode)
|
||||||
|
{
|
||||||
|
//TODO:Add support for daily episodes
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
indexerResults = indexer.FetchEpisode(episode.Series.Title, episode.SeasonNumber, episode.EpisodeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
reports.AddRange(indexerResults);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("An error has occured while fetching items from " + indexer.Name, e);
|
Logger.ErrorException("An error has occurred while fetching items from " + indexer.Name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug("Finished searching all indexers. Total {0}", reports.Count);
|
Logger.Debug("Finished searching all indexers. Total {0}", reports.Count);
|
||||||
notification.CurrentMessage = "Proccessing search results";
|
notification.CurrentMessage = "Processing search results";
|
||||||
|
|
||||||
foreach (var episodeParseResult in reports.OrderBy(c => c.Quality).ThenBy(c => c.Proper))
|
ProcessResults(notification, episode, reports);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProcessResults(ProgressNotification notification, Episode episode, IEnumerable<EpisodeParseResult> reports)
|
||||||
|
{
|
||||||
|
foreach (var episodeParseResult in reports.OrderByDescending(c => c.Quality).ThenByDescending(c => c.Proper))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -73,13 +98,11 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.ErrorException("An error has occured while processing parse result items from " + episodeParseResult, e);
|
Logger.ErrorException("An error has occurred while processing parse result items from " + episodeParseResult, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Logger.Warn("Unable to find {0} in any of indexers.", episode);
|
Logger.Warn("Unable to find {0} in any of indexers.", episode);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
@ -21,6 +22,8 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
|
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
private List<int> _attemptedSeries;
|
||||||
|
|
||||||
public ImportNewSeriesJob(SeriesProvider seriesProvider, SeasonProvider seasonProvider,
|
public ImportNewSeriesJob(SeriesProvider seriesProvider, SeasonProvider seasonProvider,
|
||||||
MediaFileProvider mediaFileProvider, UpdateInfoJob updateInfoJob, DiskScanJob diskScanJob)
|
MediaFileProvider mediaFileProvider, UpdateInfoJob updateInfoJob, DiskScanJob diskScanJob)
|
||||||
{
|
{
|
||||||
|
@ -43,12 +46,13 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
|
|
||||||
public void Start(ProgressNotification notification, int targetId)
|
public void Start(ProgressNotification notification, int targetId)
|
||||||
{
|
{
|
||||||
|
_attemptedSeries = new List<int>();
|
||||||
ScanSeries(notification);
|
ScanSeries(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ScanSeries(ProgressNotification notification)
|
private void ScanSeries(ProgressNotification notification)
|
||||||
{
|
{
|
||||||
var syncList = _seriesProvider.GetAllSeries().Where(s => s.LastInfoSync == null).ToList();
|
var syncList = _seriesProvider.GetAllSeries().Where(s => s.LastInfoSync == null && !_attemptedSeries.Contains(s.SeriesId)).ToList();
|
||||||
if (syncList.Count == 0)
|
if (syncList.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -58,6 +62,7 @@ namespace NzbDrone.Core.Providers.Jobs
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_attemptedSeries.Add(currentSeries.SeriesId);
|
||||||
notification.CurrentMessage = String.Format("Searching for '{0}'", new DirectoryInfo(currentSeries.Path).Name);
|
notification.CurrentMessage = String.Format("Searching for '{0}'", new DirectoryInfo(currentSeries.Path).Name);
|
||||||
|
|
||||||
_updateInfoJob.Start(notification, currentSeries.SeriesId);
|
_updateInfoJob.Start(notification, currentSeries.SeriesId);
|
||||||
|
|
|
@ -25,6 +25,14 @@ namespace NzbDrone.Core.Repository
|
||||||
|
|
||||||
public Boolean Ignored { get; set; }
|
public Boolean Ignored { get; set; }
|
||||||
|
|
||||||
|
[SubSonicIgnore]
|
||||||
|
public Boolean IsDailyEpisode
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return EpisodeNumber == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the grab date.
|
/// Gets or sets the grab date.
|
||||||
|
@ -72,10 +80,12 @@ namespace NzbDrone.Core.Repository
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if (EpisodeNumber == 0)
|
var seriesTitle = Series == null ? "[NULL]" : Series.Title;
|
||||||
return string.Format("{0} - {1}", Series.Title, AirDate.Date);
|
|
||||||
|
|
||||||
return string.Format("{0} - S{1:00}E{2}", Series.Title, SeasonNumber, EpisodeNumber);
|
if (IsDailyEpisode)
|
||||||
|
return string.Format("{0} - {1}", seriesTitle, AirDate.Date);
|
||||||
|
|
||||||
|
return string.Format("{0} - S{1:00}E{2}", seriesTitle, SeasonNumber, EpisodeNumber);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
|
||||||
|
namespace NzbDrone.Web.Controllers
|
||||||
|
{
|
||||||
|
public class StreamController : Controller
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// GET: /Stream/
|
||||||
|
|
||||||
|
public ActionResult Index()
|
||||||
|
{
|
||||||
|
return File(@"Z:\Clone High\Season 1\S01E02 - Episode Two- Election Blu-Galoo.avi", "video/divx");
|
||||||
|
//return File(@"Z:\30 Rock\Season 5\S05E04 - Live Show (East Coast Taping) - HD TV.mkv", "video/divx");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ namespace NzbDrone.Web.Controllers
|
||||||
|
|
||||||
public ActionResult Indexers()
|
public ActionResult Indexers()
|
||||||
{
|
{
|
||||||
return View(_indexerProvider.All());
|
return View(_indexerProvider.GetAllISettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
<MvcBuildViews>true</MvcBuildViews>
|
<MvcBuildViews>true</MvcBuildViews>
|
||||||
<EnableUpdateable>false</EnableUpdateable>
|
<EnableUpdateable>false</EnableUpdateable>
|
||||||
<ExcludeApp_Data>true</ExcludeApp_Data>
|
<ExcludeApp_Data>true</ExcludeApp_Data>
|
||||||
|
<CodeAnalysisRuleSet>BasicCorrectnessRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
|
@ -223,6 +224,7 @@
|
||||||
<Compile Include="Controllers\SeriesController.cs" />
|
<Compile Include="Controllers\SeriesController.cs" />
|
||||||
<Compile Include="Controllers\SettingsController.cs" />
|
<Compile Include="Controllers\SettingsController.cs" />
|
||||||
<Compile Include="Controllers\SharedController.cs" />
|
<Compile Include="Controllers\SharedController.cs" />
|
||||||
|
<Compile Include="Controllers\StreamController.cs" />
|
||||||
<Compile Include="Controllers\SystemController.cs" />
|
<Compile Include="Controllers\SystemController.cs" />
|
||||||
<Compile Include="Controllers\UpcomingController.cs" />
|
<Compile Include="Controllers\UpcomingController.cs" />
|
||||||
<Compile Include="Global.asax.cs">
|
<Compile Include="Global.asax.cs">
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<UseVSHostingProcess>true</UseVSHostingProcess>
|
<UseVSHostingProcess>true</UseVSHostingProcess>
|
||||||
|
<CodeAnalysisRuleSet>BasicCorrectnessRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
|
Loading…
Reference in New Issue