1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-11-04 10:02:40 +01:00

cleaned up parsing logic and structure.

This commit is contained in:
kay.one 2013-04-14 18:41:39 -07:00
parent cd2761d07d
commit 6e88f55a54
120 changed files with 2149 additions and 3064 deletions

View File

@ -154,22 +154,22 @@ public void paths_should_not_be_equeal(string first, string second)
public void empty_folder_should_return_folder_modified_date() public void empty_folder_should_return_folder_modified_date()
{ {
var tempfolder = new DirectoryInfo(TempFolder); var tempfolder = new DirectoryInfo(TempFolder);
Mocker.Resolve<DiskProvider>().GetLastDirectoryWrite(TempFolder).Should().Be(tempfolder.LastWriteTimeUtc); Mocker.Resolve<DiskProvider>().GetLastFolderWrite(TempFolder).Should().Be(tempfolder.LastWriteTimeUtc);
} }
[Test] [Test]
public void folder_should_return_correct_value_for_last_write() public void folder_should_return_correct_value_for_last_write()
{ {
var appPath = new EnvironmentProvider().WorkingDirectory; var appPath = new EnvironmentProvider().WorkingDirectory;
Mocker.Resolve<DiskProvider>().GetLastDirectoryWrite(appPath).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-10)); Mocker.Resolve<DiskProvider>().GetLastFolderWrite(appPath).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-10));
Mocker.Resolve<DiskProvider>().GetLastDirectoryWrite(appPath).Should().BeBefore(DateTime.UtcNow); Mocker.Resolve<DiskProvider>().GetLastFolderWrite(appPath).Should().BeBefore(DateTime.UtcNow);
} }
[Test] [Test]
[Explicit] [Explicit]
public void check_last_write() public void check_last_write()
{ {
Console.WriteLine(Mocker.Resolve<DiskProvider>().GetLastDirectoryWrite(@"C:\DRIVERS")); Console.WriteLine(Mocker.Resolve<DiskProvider>().GetLastFolderWrite(@"C:\DRIVERS"));
Console.WriteLine(new DirectoryInfo(@"C:\DRIVERS").LastWriteTimeUtc); Console.WriteLine(new DirectoryInfo(@"C:\DRIVERS").LastWriteTimeUtc);
} }

View File

@ -24,7 +24,7 @@ static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public virtual DateTime GetLastDirectoryWrite(string path) public virtual DateTime GetLastFolderWrite(string path)
{ {
if (!FolderExists(path)) if (!FolderExists(path))
{ {
@ -50,6 +50,15 @@ public virtual DateTime GetLastFileWrite(string path)
return new FileInfo(path).LastWriteTimeUtc; return new FileInfo(path).LastWriteTimeUtc;
} }
public virtual void EnsureFolder(string path)
{
if (!FolderExists(path))
{
CreateFolder(path);
}
}
public virtual bool FolderExists(string path) public virtual bool FolderExists(string path)
{ {
return Directory.Exists(path); return Directory.Exists(path);
@ -84,7 +93,7 @@ public virtual long GetSize(string path)
return fi.Length; return fi.Length;
} }
public virtual String CreateDirectory(string path) public virtual String CreateFolder(string path)
{ {
return Directory.CreateDirectory(path).FullName; return Directory.CreateDirectory(path).FullName;
} }
@ -191,7 +200,7 @@ public virtual void InheritFolderPermissions(string filename)
File.SetAccessControl(filename, fs); File.SetAccessControl(filename, fs);
} }
public virtual ulong FreeDiskSpace(string path) public virtual ulong GetAvilableSpace(string path)
{ {
if (!FolderExists(path)) if (!FolderExists(path))
throw new DirectoryNotFoundException(path); throw new DirectoryNotFoundException(path);
@ -237,7 +246,7 @@ public virtual bool IsFolderLocked(string path)
{ {
var files = GetFileInfos(path, "*.*", SearchOption.AllDirectories); var files = GetFileInfos(path, "*.*", SearchOption.AllDirectories);
foreach(var fileInfo in files) foreach (var fileInfo in files)
{ {
if (IsFileLocked(fileInfo)) if (IsFileLocked(fileInfo))
return true; return true;

View File

@ -1,28 +1,22 @@
 using System.Collections.Generic;
using System.Linq;
using System;
using System.Collections.Generic;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.DecisionEngineTests namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
[TestFixture] [TestFixture]
public class AcceptableSizeSpecificationFixture : CoreTest public class AcceptableSizeSpecificationFixture : CoreTest<AcceptableSizeSpecification>
{ {
private IndexerParseResult parseResultMulti; private RemoteEpisode parseResultMulti;
private IndexerParseResult parseResultSingle; private RemoteEpisode parseResultSingle;
private Series series30minutes; private Series series30minutes;
private Series series60minutes; private Series series60minutes;
private QualitySize qualityType; private QualitySize qualityType;
@ -30,35 +24,26 @@ public class AcceptableSizeSpecificationFixture : CoreTest
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
parseResultMulti = new IndexerParseResult parseResultMulti = new RemoteEpisode
{ {
SeriesTitle = "Title", Report = new ReportInfo(),
Language = LanguageType.English,
Quality = new QualityModel(Quality.SDTV, true), Quality = new QualityModel(Quality.SDTV, true),
EpisodeNumbers = new List<int> { 3, 4 }, Episodes = new List<Episode> { new Episode(), new Episode() }
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date
}; };
parseResultSingle = new IndexerParseResult parseResultSingle = new RemoteEpisode
{ {
SeriesTitle = "Title", Report = new ReportInfo(),
Language = LanguageType.English,
Quality = new QualityModel(Quality.SDTV, true), Quality = new QualityModel(Quality.SDTV, true),
EpisodeNumbers = new List<int> { 3 }, Episodes = new List<Episode> { new Episode() }
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date
}; };
series30minutes = Builder<Series>.CreateNew() series30minutes = Builder<Series>.CreateNew()
.With(c => c.Monitored = true)
.With(d => d.CleanTitle = parseResultMulti.CleanTitle)
.With(c => c.Runtime = 30) .With(c => c.Runtime = 30)
.Build(); .Build();
series60minutes = Builder<Series>.CreateNew() series60minutes = Builder<Series>.CreateNew()
.With(c => c.Monitored = true)
.With(d => d.CleanTitle = parseResultMulti.CleanTitle)
.With(c => c.Runtime = 60) .With(c => c.Runtime = 60)
.Build(); .Build();
@ -73,19 +58,17 @@ public void Setup()
[Test] [Test]
public void IsAcceptableSize_true_single_episode_not_first_or_last_30_minute() public void IsAcceptableSize_true_single_episode_not_first_or_last_30_minute()
{ {
WithStrictMocker();
parseResultSingle.Series = series30minutes; parseResultSingle.Series = series30minutes;
parseResultSingle.Size = 184572800; parseResultSingle.Report.Size = 184572800;
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(false); .Returns(false);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeTrue(); result.Should().BeTrue();
@ -94,19 +77,17 @@ public void IsAcceptableSize_true_single_episode_not_first_or_last_30_minute()
[Test] [Test]
public void IsAcceptableSize_true_single_episode_not_first_or_last_60_minute() public void IsAcceptableSize_true_single_episode_not_first_or_last_60_minute()
{ {
WithStrictMocker();
parseResultSingle.Series = series60minutes; parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 368572800; parseResultSingle.Report.Size = 368572800;
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(false); .Returns(false);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeTrue(); result.Should().BeTrue();
@ -118,16 +99,16 @@ public void IsAcceptableSize_false_single_episode_not_first_or_last_30_minute()
WithStrictMocker(); WithStrictMocker();
parseResultSingle.Series = series30minutes; parseResultSingle.Series = series30minutes;
parseResultSingle.Size = 1.Gigabytes(); parseResultSingle.Report.Size = 1.Gigabytes();
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(false); .Returns(false);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeFalse(); result.Should().BeFalse();
@ -139,16 +120,16 @@ public void IsAcceptableSize_false_single_episode_not_first_or_last_60_minute()
WithStrictMocker(); WithStrictMocker();
parseResultSingle.Series = series60minutes; parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 1.Gigabytes(); parseResultSingle.Report.Size = 1.Gigabytes();
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(false); .Returns(false);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeFalse(); result.Should().BeFalse();
@ -160,16 +141,16 @@ public void IsAcceptableSize_true_multi_episode_not_first_or_last_30_minute()
WithStrictMocker(); WithStrictMocker();
parseResultMulti.Series = series30minutes; parseResultMulti.Series = series30minutes;
parseResultMulti.Size = 184572800; parseResultMulti.Report.Size = 184572800;
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(false); .Returns(false);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultMulti); bool result = Subject.IsSatisfiedBy(parseResultMulti);
result.Should().BeTrue(); result.Should().BeTrue();
@ -181,16 +162,16 @@ public void IsAcceptableSize_true_multi_episode_not_first_or_last_60_minute()
WithStrictMocker(); WithStrictMocker();
parseResultMulti.Series = series60minutes; parseResultMulti.Series = series60minutes;
parseResultMulti.Size = 368572800; parseResultMulti.Report.Size = 368572800;
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(false); .Returns(false);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultMulti); bool result = Subject.IsSatisfiedBy(parseResultMulti);
result.Should().BeTrue(); result.Should().BeTrue();
@ -202,16 +183,16 @@ public void IsAcceptableSize_false_multi_episode_not_first_or_last_30_minute()
WithStrictMocker(); WithStrictMocker();
parseResultMulti.Series = series30minutes; parseResultMulti.Series = series30minutes;
parseResultMulti.Size = 1.Gigabytes(); parseResultMulti.Report.Size = 1.Gigabytes();
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(false); .Returns(false);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultMulti); bool result = Subject.IsSatisfiedBy(parseResultMulti);
result.Should().BeFalse(); result.Should().BeFalse();
@ -223,16 +204,16 @@ public void IsAcceptableSize_false_multi_episode_not_first_or_last_60_minute()
WithStrictMocker(); WithStrictMocker();
parseResultMulti.Series = series60minutes; parseResultMulti.Series = series60minutes;
parseResultMulti.Size = 10.Gigabytes(); parseResultMulti.Report.Size = 10.Gigabytes();
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(false); .Returns(false);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultMulti); bool result = Subject.IsSatisfiedBy(parseResultMulti);
result.Should().BeFalse(); result.Should().BeFalse();
@ -244,16 +225,16 @@ public void IsAcceptableSize_true_single_episode_first_30_minute()
WithStrictMocker(); WithStrictMocker();
parseResultSingle.Series = series30minutes; parseResultSingle.Series = series30minutes;
parseResultSingle.Size = 184572800; parseResultSingle.Report.Size = 184572800;
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(true); .Returns(true);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeTrue(); result.Should().BeTrue();
@ -265,16 +246,16 @@ public void IsAcceptableSize_true_single_episode_first_60_minute()
WithStrictMocker(); WithStrictMocker();
parseResultSingle.Series = series60minutes; parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 368572800; parseResultSingle.Report.Size = 368572800;
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(true); .Returns(true);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeTrue(); result.Should().BeTrue();
@ -286,16 +267,16 @@ public void IsAcceptableSize_false_single_episode_first_30_minute()
WithStrictMocker(); WithStrictMocker();
parseResultSingle.Series = series30minutes; parseResultSingle.Series = series30minutes;
parseResultSingle.Size = 1.Gigabytes(); parseResultSingle.Report.Size = 1.Gigabytes();
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(true); .Returns(true);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeFalse(); result.Should().BeFalse();
@ -307,16 +288,16 @@ public void IsAcceptableSize_false_single_episode_first_60_minute()
WithStrictMocker(); WithStrictMocker();
parseResultSingle.Series = series60minutes; parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 10.Gigabytes(); parseResultSingle.Report.Size = 10.Gigabytes();
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(true); .Returns(true);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeFalse(); result.Should().BeFalse();
@ -328,17 +309,17 @@ public void IsAcceptableSize_true_unlimited_30_minute()
WithStrictMocker(); WithStrictMocker();
parseResultSingle.Series = series30minutes; parseResultSingle.Series = series30minutes;
parseResultSingle.Size = 18457280000; parseResultSingle.Report.Size = 18457280000;
qualityType.MaxSize = 0; qualityType.MaxSize = 0;
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(true); .Returns(true);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeTrue(); result.Should().BeTrue();
@ -350,17 +331,17 @@ public void IsAcceptableSize_true_unlimited_60_minute()
WithStrictMocker(); WithStrictMocker();
parseResultSingle.Series = series60minutes; parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 36857280000; parseResultSingle.Report.Size = 36857280000;
qualityType.MaxSize = 0; qualityType.MaxSize = 0;
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(true); .Returns(true);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeTrue(); result.Should().BeTrue();
@ -369,21 +350,22 @@ public void IsAcceptableSize_true_unlimited_60_minute()
[Test] [Test]
public void IsAcceptableSize_should_treat_daily_series_as_single_episode() public void IsAcceptableSize_should_treat_daily_series_as_single_episode()
{ {
parseResultSingle.Series = series60minutes; parseResultSingle.Series = series60minutes;
parseResultSingle.Size = 300.Megabytes(); parseResultSingle.Series.SeriesType = SeriesTypes.Daily;
parseResultSingle.AirDate = DateTime.Today;
parseResultSingle.EpisodeNumbers = null; parseResultSingle.Report.Size = 300.Megabytes();
qualityType.MaxSize = (int)600.Megabytes(); qualityType.MaxSize = (int)600.Megabytes();
Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType); Mocker.GetMock<IQualitySizeService>().Setup(s => s.Get(1)).Returns(qualityType);
Mocker.GetMock<IEpisodeService>().Setup( Mocker.GetMock<IEpisodeService>().Setup(
s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>())) s => s.IsFirstOrLastEpisodeOfSeason(It.IsAny<int>()))
.Returns(true); .Returns(true);
bool result = Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResultSingle); bool result = Subject.IsSatisfiedBy(parseResultSingle);
result.Should().BeTrue(); result.Should().BeTrue();
@ -392,12 +374,12 @@ public void IsAcceptableSize_should_treat_daily_series_as_single_episode()
[Test] [Test]
public void should_return_true_if_RAWHD() public void should_return_true_if_RAWHD()
{ {
var parseResult = new IndexerParseResult var parseResult = new RemoteEpisode
{ {
Quality = new QualityModel(Quality.RAWHD, false) Quality = new QualityModel(Quality.RAWHD, false)
}; };
Mocker.Resolve<AcceptableSizeSpecification>().IsSatisfiedBy(parseResult).Should().BeTrue(); Subject.IsSatisfiedBy(parseResult).Should().BeTrue();
} }
} }
} }

View File

@ -3,8 +3,9 @@
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Model;
using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.DecisionEngineTests namespace NzbDrone.Core.Test.DecisionEngineTests
@ -12,7 +13,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[TestFixture] [TestFixture]
public class AllowedDownloadSpecificationFixture : CoreTest<DownloadDecisionMaker> public class AllowedDownloadSpecificationFixture : CoreTest<DownloadDecisionMaker>
{ {
private List<IndexerParseResult> _parseResults; private List<ReportInfo> _reports;
private RemoteEpisode _remoteEpisode;
private Mock<IDecisionEngineSpecification> _pass1; private Mock<IDecisionEngineSpecification> _pass1;
private Mock<IDecisionEngineSpecification> _pass2; private Mock<IDecisionEngineSpecification> _pass2;
@ -33,15 +35,19 @@ public void Setup()
_fail2 = new Mock<IDecisionEngineSpecification>(); _fail2 = new Mock<IDecisionEngineSpecification>();
_fail3 = new Mock<IDecisionEngineSpecification>(); _fail3 = new Mock<IDecisionEngineSpecification>();
_pass1.Setup(c => c.IsSatisfiedBy(It.IsAny<IndexerParseResult>())).Returns(true); _pass1.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>())).Returns(true);
_pass2.Setup(c => c.IsSatisfiedBy(It.IsAny<IndexerParseResult>())).Returns(true); _pass2.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>())).Returns(true);
_pass3.Setup(c => c.IsSatisfiedBy(It.IsAny<IndexerParseResult>())).Returns(true); _pass3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>())).Returns(true);
_fail1.Setup(c => c.IsSatisfiedBy(It.IsAny<IndexerParseResult>())).Returns(false); _fail1.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>())).Returns(false);
_fail2.Setup(c => c.IsSatisfiedBy(It.IsAny<IndexerParseResult>())).Returns(false); _fail2.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>())).Returns(false);
_fail3.Setup(c => c.IsSatisfiedBy(It.IsAny<IndexerParseResult>())).Returns(false); _fail3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>())).Returns(false);
_parseResults = new List<IndexerParseResult>() { new IndexerParseResult() }; _reports = new List<ReportInfo>();
_remoteEpisode = new RemoteEpisode();
Mocker.GetMock<IParsingService>().Setup(c => c.Map(It.IsAny<ReportInfo>()))
.Returns(_remoteEpisode);
} }
@ -55,14 +61,14 @@ public void should_call_all_specifications()
{ {
GivenSpecifications(_pass1, _pass2, _pass3, _fail1, _fail2, _fail3); GivenSpecifications(_pass1, _pass2, _pass3, _fail1, _fail2, _fail3);
Subject.GetRssDecision(_parseResults).ToList(); Subject.GetRssDecision(_reports).ToList();
_fail1.Verify(c => c.IsSatisfiedBy(_parseResults[0]), Times.Once()); _fail1.Verify(c => c.IsSatisfiedBy(_remoteEpisode), Times.Once());
_fail2.Verify(c => c.IsSatisfiedBy(_parseResults[0]), Times.Once()); _fail2.Verify(c => c.IsSatisfiedBy(_remoteEpisode), Times.Once());
_fail3.Verify(c => c.IsSatisfiedBy(_parseResults[0]), Times.Once()); _fail3.Verify(c => c.IsSatisfiedBy(_remoteEpisode), Times.Once());
_pass1.Verify(c => c.IsSatisfiedBy(_parseResults[0]), Times.Once()); _pass1.Verify(c => c.IsSatisfiedBy(_remoteEpisode), Times.Once());
_pass2.Verify(c => c.IsSatisfiedBy(_parseResults[0]), Times.Once()); _pass2.Verify(c => c.IsSatisfiedBy(_remoteEpisode), Times.Once());
_pass3.Verify(c => c.IsSatisfiedBy(_parseResults[0]), Times.Once()); _pass3.Verify(c => c.IsSatisfiedBy(_remoteEpisode), Times.Once());
} }
[Test] [Test]
@ -70,7 +76,7 @@ public void should_return_rejected_if_one_of_specs_fail()
{ {
GivenSpecifications(_pass1, _fail1, _pass2, _pass3); GivenSpecifications(_pass1, _fail1, _pass2, _pass3);
var result = Subject.GetRssDecision(_parseResults); var result = Subject.GetRssDecision(_reports);
result.Single().Approved.Should().BeFalse(); result.Single().Approved.Should().BeFalse();
} }
@ -80,7 +86,7 @@ public void should_return_pass_if_all_specs_pass()
{ {
GivenSpecifications(_pass1, _pass2, _pass3); GivenSpecifications(_pass1, _pass2, _pass3);
var result = Subject.GetRssDecision(_parseResults); var result = Subject.GetRssDecision(_reports);
result.Single().Approved.Should().BeTrue(); result.Single().Approved.Should().BeTrue();
} }
@ -90,19 +96,11 @@ public void should_have_same_number_of_rejections_as_specs_that_failed()
{ {
GivenSpecifications(_pass1, _pass2, _pass3, _fail1, _fail2, _fail3); GivenSpecifications(_pass1, _pass2, _pass3, _fail1, _fail2, _fail3);
var result = Subject.GetRssDecision(_parseResults); var result = Subject.GetRssDecision(_reports);
result.Single().Rejections.Should().HaveCount(3); result.Single().Rejections.Should().HaveCount(3);
} }
[Test]
public void parse_result_should_be_attached_to_decision()
{
GivenSpecifications(_pass1, _pass2, _pass3, _fail1, _fail2, _fail3);
var result = Subject.GetRssDecision(_parseResults);
result.Single().ParseResult.Should().Be(_parseResults.Single());
}
} }
} }

View File

@ -1,11 +1,7 @@
using System; using FluentAssertions;
using System.Collections.Generic;
using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.DecisionEngineTests namespace NzbDrone.Core.Test.DecisionEngineTests
@ -14,45 +10,42 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
public class AllowedReleaseGroupSpecificationFixture : CoreTest<AllowedReleaseGroupSpecification> public class AllowedReleaseGroupSpecificationFixture : CoreTest<AllowedReleaseGroupSpecification>
{ {
private IndexerParseResult parseResult; private RemoteEpisode _parseResult;
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
parseResult = new IndexerParseResult _parseResult = new RemoteEpisode
{ {
SeriesTitle = "Title", Report = new ReportInfo
Language = LanguageType.English, {
Quality = new QualityModel(Quality.SDTV, true), ReleaseGroup = "2HD"
EpisodeNumbers = new List<int> { 3 }, }
SeasonNumber = 12, };
AirDate = DateTime.Now.AddDays(-12).Date,
ReleaseGroup = "2HD"
};
} }
[Test] [Test]
public void should_be_true_when_allowedReleaseGroups_is_empty() public void should_be_true_when_allowedReleaseGroups_is_empty()
{ {
Subject.IsSatisfiedBy(parseResult).Should().BeTrue(); Subject.IsSatisfiedBy(_parseResult).Should().BeTrue();
} }
[Test] [Test]
public void should_be_true_when_allowedReleaseGroups_is_nzbs_releaseGroup() public void should_be_true_when_allowedReleaseGroups_is_nzbs_releaseGroup()
{ {
Subject.IsSatisfiedBy(parseResult).Should().BeTrue(); Subject.IsSatisfiedBy(_parseResult).Should().BeTrue();
} }
[Test] [Test]
public void should_be_true_when_allowedReleaseGroups_contains_nzbs_releaseGroup() public void should_be_true_when_allowedReleaseGroups_contains_nzbs_releaseGroup()
{ {
Subject.IsSatisfiedBy(parseResult).Should().BeTrue(); Subject.IsSatisfiedBy(_parseResult).Should().BeTrue();
} }
[Test] [Test]
public void should_be_false_when_allowedReleaseGroups_does_not_contain_nzbs_releaseGroup() public void should_be_false_when_allowedReleaseGroups_does_not_contain_nzbs_releaseGroup()
{ {
Subject.IsSatisfiedBy(parseResult).Should().BeFalse(); Subject.IsSatisfiedBy(_parseResult).Should().BeFalse();
} }
} }
} }

View File

@ -1,30 +1,23 @@
 using System;
using System.Linq;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.DecisionEngineTests namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
[TestFixture] [TestFixture]
public class CustomStartDateSpecificationFixture : CoreTest public class CustomStartDateSpecificationFixture : CoreTest<CustomStartDateSpecification>
{ {
private CustomStartDateSpecification _customStartDateSpecification; private CustomStartDateSpecification _customStartDateSpecification;
private IndexerParseResult parseResultMulti; private RemoteEpisode parseResultMulti;
private IndexerParseResult parseResultSingle; private RemoteEpisode parseResultSingle;
private Series fakeSeries; private Series fakeSeries;
private Episode firstEpisode; private Episode firstEpisode;
private Episode secondEpisode; private Episode secondEpisode;
@ -42,21 +35,15 @@ public void Setup()
.With(c => c.CustomStartDate = null) .With(c => c.CustomStartDate = null)
.Build(); .Build();
parseResultMulti = new IndexerParseResult parseResultMulti = new RemoteEpisode
{ {
SeriesTitle = "Title",
Series = fakeSeries, Series = fakeSeries,
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
Episodes = new List<Episode> { firstEpisode, secondEpisode } Episodes = new List<Episode> { firstEpisode, secondEpisode }
}; };
parseResultSingle = new IndexerParseResult parseResultSingle = new RemoteEpisode
{ {
SeriesTitle = "Title",
Series = fakeSeries, Series = fakeSeries,
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
Episodes = new List<Episode> { firstEpisode } Episodes = new List<Episode> { firstEpisode }
}; };
} }

View File

@ -9,6 +9,8 @@
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine;
@ -20,21 +22,21 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
public class LanguageSpecificationFixture : CoreTest public class LanguageSpecificationFixture : CoreTest
{ {
private IndexerParseResult parseResult; private RemoteEpisode parseResult;
private void WithEnglishRelease() private void WithEnglishRelease()
{ {
parseResult = Builder<IndexerParseResult> parseResult = Builder<RemoteEpisode>
.CreateNew() .CreateNew()
.With(p => p.Language = LanguageType.English) .With(p => p.Language = Language.English)
.Build(); .Build();
} }
private void WithGermanRelease() private void WithGermanRelease()
{ {
parseResult = Builder<IndexerParseResult> parseResult = Builder<RemoteEpisode>
.CreateNew() .CreateNew()
.With(p => p.Language = LanguageType.German) .With(p => p.Language = Language.German)
.Build(); .Build();
} }

View File

@ -1,30 +1,24 @@
 using System;
using System.Linq;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.DecisionEngineTests namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
[TestFixture] [TestFixture]
public class MonitoredEpisodeSpecificationFixture : CoreTest public class MonitoredEpisodeSpecificationFixture : CoreTest<MonitoredEpisodeSpecification>
{ {
private MonitoredEpisodeSpecification monitoredEpisodeSpecification; private MonitoredEpisodeSpecification monitoredEpisodeSpecification;
private IndexerParseResult parseResultMulti; private RemoteEpisode parseResultMulti;
private IndexerParseResult parseResultSingle; private RemoteEpisode parseResultSingle;
private Series fakeSeries; private Series fakeSeries;
private Episode firstEpisode; private Episode firstEpisode;
private Episode secondEpisode; private Episode secondEpisode;
@ -38,33 +32,26 @@ public void Setup()
.With(c => c.Monitored = true) .With(c => c.Monitored = true)
.Build(); .Build();
parseResultMulti = new IndexerParseResult
var singleEpisodeList = new List<Episode> { firstEpisode };
var doubleEpisodeList = new List<Episode> { firstEpisode, secondEpisode };
parseResultMulti = new RemoteEpisode
{ {
SeriesTitle = "Title",
Series = fakeSeries, Series = fakeSeries,
EpisodeNumbers = new List<int> { 3, 4 }, Episodes = doubleEpisodeList
SeasonNumber = 12,
}; };
parseResultSingle = new IndexerParseResult parseResultSingle = new RemoteEpisode
{ {
SeriesTitle = "Title",
Series = fakeSeries, Series = fakeSeries,
EpisodeNumbers = new List<int> { 3 }, Episodes = singleEpisodeList
SeasonNumber = 12,
}; };
firstEpisode = new Episode { Ignored = false }; firstEpisode = new Episode { Ignored = false };
secondEpisode = new Episode { Ignored = false }; secondEpisode = new Episode { Ignored = false };
var singleEpisodeList = new List<Episode> { firstEpisode };
var doubleEpisodeList = new List<Episode> { firstEpisode, secondEpisode };
Mocker.GetMock<IEpisodeService>().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(singleEpisodeList);
Mocker.GetMock<IEpisodeService>().Setup(c => c.GetEpisodesByParseResult(parseResultMulti)).Returns(doubleEpisodeList);
Mocker.GetMock<ISeriesRepository>().Setup(c => c.GetByTitle(parseResultMulti.CleanTitle)).Returns(fakeSeries);
Mocker.GetMock<ISeriesRepository>().Setup(c => c.GetByTitle(parseResultSingle.CleanTitle)).Returns(fakeSeries);
} }
private void WithFirstEpisodeIgnored() private void WithFirstEpisodeIgnored()
@ -97,7 +84,7 @@ public void not_monitored_series_should_be_skipped()
public void not_in_db_should_be_skipped() public void not_in_db_should_be_skipped()
{ {
Mocker.GetMock<ISeriesRepository>() Mocker.GetMock<ISeriesRepository>()
.Setup(p => p.GetByTitle(It.IsAny<String>())) .Setup(p => p.FindByTitle(It.IsAny<String>()))
.Returns<Series>(null); .Returns<Series>(null);
monitoredEpisodeSpecification.IsSatisfiedBy(parseResultMulti).Should().BeFalse(); monitoredEpisodeSpecification.IsSatisfiedBy(parseResultMulti).Should().BeFalse();

View File

@ -1,26 +1,22 @@
 
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.DecisionEngineTests namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
[TestFixture] [TestFixture]
public class QualityAllowedByProfileSpecificationFixture : CoreTest public class QualityAllowedByProfileSpecificationFixture : CoreTest<QualityAllowedByProfileSpecification>
{ {
private QualityAllowedByProfileSpecification _qualityAllowedByProfile; private RemoteEpisode parseResult;
private IndexerParseResult parseResult;
public static object[] AllowedTestCases = public static object[] AllowedTestCases =
{ {
@ -39,18 +35,14 @@ public class QualityAllowedByProfileSpecificationFixture : CoreTest
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_qualityAllowedByProfile = Mocker.Resolve<QualityAllowedByProfileSpecification>();
var fakeSeries = Builder<Series>.CreateNew() var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p }) .With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p })
.Build(); .Build();
parseResult = new IndexerParseResult parseResult = new RemoteEpisode
{ {
Series = fakeSeries, Series = fakeSeries,
Quality = new QualityModel(Quality.DVD, true), Quality = new QualityModel(Quality.DVD, true),
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
}; };
} }
@ -60,7 +52,7 @@ public void should_allow_if_quality_is_defined_in_profile(Quality qualityType)
parseResult.Quality.Quality = qualityType; parseResult.Quality.Quality = qualityType;
parseResult.Series.QualityProfile.Allowed = new List<Quality> { Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p }; parseResult.Series.QualityProfile.Allowed = new List<Quality> { Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p };
_qualityAllowedByProfile.IsSatisfiedBy(parseResult).Should().BeTrue(); Subject.IsSatisfiedBy(parseResult).Should().BeTrue();
} }
[Test, TestCaseSource("DeniedTestCases")] [Test, TestCaseSource("DeniedTestCases")]
@ -69,7 +61,7 @@ public void should_not_allow_if_quality_is_not_defined_in_profile(Quality qualit
parseResult.Quality.Quality = qualityType; parseResult.Quality.Quality = qualityType;
parseResult.Series.QualityProfile.Allowed = new List<Quality> { Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p }; parseResult.Series.QualityProfile.Allowed = new List<Quality> { Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p };
_qualityAllowedByProfile.IsSatisfiedBy(parseResult).Should().BeFalse(); Subject.IsSatisfiedBy(parseResult).Should().BeFalse();
} }
} }
} }

View File

@ -1,38 +1,28 @@
 using FluentAssertions;
using System.Linq;
using System;
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.DecisionEngineTests namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
[TestFixture] [TestFixture]
public class RetentionSpecificationFixture : CoreTest public class RetentionSpecificationFixture : CoreTest<RetentionSpecification>
{ {
private RetentionSpecification retentionSpecification;
private IndexerParseResult parseResult; private RemoteEpisode parseResult;
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
retentionSpecification = Mocker.Resolve<RetentionSpecification>(); parseResult = new RemoteEpisode
parseResult = new IndexerParseResult
{ {
Age = 100 Report = new ReportInfo
{
Age = 100
}
}; };
} }
@ -60,35 +50,35 @@ private void WithEqualRetention()
public void unlimited_retention_should_return_true() public void unlimited_retention_should_return_true()
{ {
WithUnlimitedRetention(); WithUnlimitedRetention();
retentionSpecification.IsSatisfiedBy(parseResult).Should().BeTrue(); Subject.IsSatisfiedBy(parseResult).Should().BeTrue();
} }
[Test] [Test]
public void longer_retention_should_return_true() public void longer_retention_should_return_true()
{ {
WithLongRetention(); WithLongRetention();
retentionSpecification.IsSatisfiedBy(parseResult).Should().BeTrue(); Subject.IsSatisfiedBy(parseResult).Should().BeTrue();
} }
[Test] [Test]
public void equal_retention_should_return_true() public void equal_retention_should_return_true()
{ {
WithEqualRetention(); WithEqualRetention();
retentionSpecification.IsSatisfiedBy(parseResult).Should().BeTrue(); Subject.IsSatisfiedBy(parseResult).Should().BeTrue();
} }
[Test] [Test]
public void shorter_retention_should_return_false() public void shorter_retention_should_return_false()
{ {
WithShortRetention(); WithShortRetention();
retentionSpecification.IsSatisfiedBy(parseResult).Should().BeFalse(); Subject.IsSatisfiedBy(parseResult).Should().BeFalse();
} }
[Test] [Test]
public void zeroDay_report_should_return_true() public void zeroDay_report_should_return_true()
{ {
WithUnlimitedRetention(); WithUnlimitedRetention();
retentionSpecification.IsSatisfiedBy(parseResult).Should().BeTrue(); Subject.IsSatisfiedBy(parseResult).Should().BeTrue();
} }
} }
} }

View File

@ -1,17 +1,13 @@
 using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
@ -20,12 +16,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
[TestFixture] [TestFixture]
public class UpgradeDiskSpecificationFixture : CoreTest public class UpgradeDiskSpecificationFixture : CoreTest<UpgradeDiskSpecification>
{ {
private UpgradeDiskSpecification _upgradeDisk; private UpgradeDiskSpecification _upgradeDisk;
private IndexerParseResult parseResultMulti; private RemoteEpisode parseResultMulti;
private IndexerParseResult parseResultSingle; private RemoteEpisode parseResultSingle;
private EpisodeFile firstFile; private EpisodeFile firstFile;
private EpisodeFile secondFile; private EpisodeFile secondFile;
@ -45,21 +41,17 @@ public void Setup()
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p }) .With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p })
.Build(); .Build();
parseResultMulti = new IndexerParseResult parseResultMulti = new RemoteEpisode
{ {
Series = fakeSeries, Series = fakeSeries,
Quality = new QualityModel(Quality.DVD, true), Quality = new QualityModel(Quality.DVD, true),
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
Episodes = doubleEpisodeList Episodes = doubleEpisodeList
}; };
parseResultSingle = new IndexerParseResult parseResultSingle = new RemoteEpisode
{ {
Series = fakeSeries, Series = fakeSeries,
Quality = new QualityModel(Quality.DVD, true), Quality = new QualityModel(Quality.DVD, true),
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
Episodes = singleEpisodeList Episodes = singleEpisodeList
}; };
} }

View File

@ -1,16 +1,12 @@
 using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.History; using NzbDrone.Core.History;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
@ -18,12 +14,12 @@
namespace NzbDrone.Core.Test.DecisionEngineTests namespace NzbDrone.Core.Test.DecisionEngineTests
{ {
[TestFixture] [TestFixture]
public class UpgradeHistorySpecificationFixture : CoreTest public class UpgradeHistorySpecificationFixture : CoreTest<UpgradeHistorySpecification>
{ {
private UpgradeHistorySpecification _upgradeHistory; private UpgradeHistorySpecification _upgradeHistory;
private IndexerParseResult _parseResultMulti; private RemoteEpisode _parseResultMulti;
private IndexerParseResult _parseResultSingle; private RemoteEpisode _parseResultSingle;
private QualityModel _upgradableQuality; private QualityModel _upgradableQuality;
private QualityModel _notupgradableQuality; private QualityModel _notupgradableQuality;
private Series _fakeSeries; private Series _fakeSeries;
@ -45,21 +41,17 @@ public void Setup()
.With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p }) .With(c => c.QualityProfile = new QualityProfile { Cutoff = Quality.Bluray1080p })
.Build(); .Build();
_parseResultMulti = new IndexerParseResult _parseResultMulti = new RemoteEpisode
{ {
Series = _fakeSeries, Series = _fakeSeries,
Quality = new QualityModel(Quality.DVD, true), Quality = new QualityModel(Quality.DVD, true),
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
Episodes = doubleEpisodeList Episodes = doubleEpisodeList
}; };
_parseResultSingle = new IndexerParseResult _parseResultSingle = new RemoteEpisode
{ {
Series = _fakeSeries, Series = _fakeSeries,
Quality = new QualityModel(Quality.DVD, true), Quality = new QualityModel(Quality.DVD, true),
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
Episodes = singleEpisodeList Episodes = singleEpisodeList
}; };

View File

@ -43,7 +43,7 @@ public void should_add_item_to_queue()
It.Is<String>(c => c.Equals("{\"method\":\"appendurl\",\"params\":[\"30 Rock - S01E01 - Pilot [HDTV-720p]\",\"TV\",0,false,\"http://www.nzbdrone.com\"]}")))) It.Is<String>(c => c.Equals("{\"method\":\"appendurl\",\"params\":[\"30 Rock - S01E01 - Pilot [HDTV-720p]\",\"TV\",0,false,\"http://www.nzbdrone.com\"]}"))))
.Returns("{\"version\": \"1.1\",\"result\": true}"); .Returns("{\"version\": \"1.1\",\"result\": true}");
Mocker.Resolve<NzbgetProvider>() Mocker.Resolve<NzbgetClient>()
.DownloadNzb(url, title, false) .DownloadNzb(url, title, false)
.Should() .Should()
.BeTrue(); .BeTrue();
@ -54,7 +54,7 @@ public void should_throw_when_error_is_returned()
{ {
WithFailResponse(); WithFailResponse();
Assert.Throws<ApplicationException>(() => Mocker.Resolve<NzbgetProvider>().DownloadNzb("http://www.nzbdrone.com", "30 Rock - S01E01 - Pilot [HDTV-720p]", false)); Assert.Throws<ApplicationException>(() => Mocker.Resolve<NzbgetClient>().DownloadNzb("http://www.nzbdrone.com", "30 Rock - S01E01 - Pilot [HDTV-720p]", false));
} }
} }
} }

View File

@ -50,7 +50,7 @@ public void should_return_no_items_when_queue_is_empty()
{ {
WithEmptyQueue(); WithEmptyQueue();
Mocker.Resolve<NzbgetProvider>() Mocker.Resolve<NzbgetClient>()
.GetQueue() .GetQueue()
.Should() .Should()
.BeEmpty(); .BeEmpty();
@ -61,7 +61,7 @@ public void should_return_item_when_queue_has_item()
{ {
WithFullQueue(); WithFullQueue();
Mocker.Resolve<NzbgetProvider>() Mocker.Resolve<NzbgetClient>()
.GetQueue() .GetQueue()
.Should() .Should()
.HaveCount(1); .HaveCount(1);
@ -72,7 +72,7 @@ public void should_throw_when_error_is_returned()
{ {
WithFailResponse(); WithFailResponse();
Assert.Throws<ApplicationException>(() => Mocker.Resolve<NzbgetProvider>().GetQueue()); Assert.Throws<ApplicationException>(() => Mocker.Resolve<NzbgetClient>().GetQueue());
} }
} }
} }

View File

@ -42,7 +42,7 @@ private void WithFailedDownload()
[Test] [Test]
public void should_download_file_if_it_doesnt_exist() public void should_download_file_if_it_doesnt_exist()
{ {
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, title, false).Should().BeTrue(); Mocker.Resolve<PneumaticClient>().DownloadNzb(nzbUrl, title, false).Should().BeTrue();
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(nzbUrl, nzbPath),Times.Once()); Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(nzbUrl, nzbPath),Times.Once());
} }
@ -52,7 +52,7 @@ public void should_not_download_file_if_it_doesn_exist()
{ {
WithExistingFile(); WithExistingFile();
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, title, false).Should().BeTrue(); Mocker.Resolve<PneumaticClient>().DownloadNzb(nzbUrl, title, false).Should().BeTrue();
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never()); Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
} }
@ -62,7 +62,7 @@ public void should_return_false_on_failed_download()
{ {
WithFailedDownload(); WithFailedDownload();
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, title, false).Should().BeFalse(); Mocker.Resolve<PneumaticClient>().DownloadNzb(nzbUrl, title, false).Should().BeFalse();
ExceptionVerification.ExpectedWarns(1); ExceptionVerification.ExpectedWarns(1);
} }
@ -70,7 +70,7 @@ public void should_return_false_on_failed_download()
[Test] [Test]
public void should_skip_if_full_season_download() public void should_skip_if_full_season_download()
{ {
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, "30 Rock - Season 1", false).Should().BeFalse(); Mocker.Resolve<PneumaticClient>().DownloadNzb(nzbUrl, "30 Rock - Season 1", false).Should().BeFalse();
} }
[Test] [Test]
@ -79,7 +79,7 @@ public void should_replace_illegal_characters_in_title()
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]"; var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
var expectedFilename = Path.Combine(pneumaticFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV].nzb"); var expectedFilename = Path.Combine(pneumaticFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV].nzb");
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, illegalTitle, false).Should().BeTrue(); Mocker.Resolve<PneumaticClient>().DownloadNzb(nzbUrl, illegalTitle, false).Should().BeTrue();
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once()); Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
} }

View File

@ -1,4 +1,4 @@
using System; /*using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
@ -22,7 +22,6 @@ public class QueueFixture : CoreTest
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
string sabHost = "192.168.5.55"; string sabHost = "192.168.5.55";
int sabPort = 2222; int sabPort = 2222;
string apikey = "5c770e3197e4fe763423ee7c392c25d1"; string apikey = "5c770e3197e4fe763423ee7c392c25d1";
@ -77,7 +76,7 @@ public void GetQueue_should_return_an_empty_list_when_the_queue_is_empty()
{ {
WithEmptyQueue(); WithEmptyQueue();
var result = Mocker.Resolve<SabProvider>().GetQueue(); var result = Mocker.Resolve<SabnzbdClient>().GetQueue();
result.Should().BeEmpty(); result.Should().BeEmpty();
} }
@ -87,7 +86,7 @@ public void GetQueue_should_throw_when_there_is_an_error_getting_the_queue()
{ {
WithFailResponse(); WithFailResponse();
Assert.Throws<ApplicationException>(() => Mocker.Resolve<SabProvider>().GetQueue(), "API Key Incorrect"); Assert.Throws<ApplicationException>(() => Mocker.Resolve<SabnzbdClient>().GetQueue(), "API Key Incorrect");
} }
[Test] [Test]
@ -95,7 +94,7 @@ public void GetQueue_should_return_a_list_with_items_when_the_queue_has_items()
{ {
WithFullQueue(); WithFullQueue();
var result = Mocker.Resolve<SabProvider>().GetQueue(); var result = Mocker.Resolve<SabnzbdClient>().GetQueue();
result.Should().HaveCount(7); result.Should().HaveCount(7);
} }
@ -105,10 +104,9 @@ public void GetQueue_should_return_a_list_with_items_even_when_priority_is_non_s
{ {
WithUnknownPriorityQueue(); WithUnknownPriorityQueue();
var result = Mocker.Resolve<SabProvider>().GetQueue(); var result = Mocker.Resolve<SabnzbdClient>().GetQueue();
result.Should().HaveCount(7); result.Should().HaveCount(7);
result.Should().OnlyContain(i => i.Priority == SabPriorityType.Normal);
} }
[Test] [Test]
@ -116,7 +114,7 @@ public void is_in_queue_should_find_if_exact_episode_is_in_queue()
{ {
WithFullQueue(); WithFullQueue();
var parseResult = new IndexerParseResult var parseResult = new RemoteEpisode
{ {
EpisodeTitle = "Title", EpisodeTitle = "Title",
EpisodeNumbers = new List<int> { 5 }, EpisodeNumbers = new List<int> { 5 },
@ -126,7 +124,7 @@ public void is_in_queue_should_find_if_exact_episode_is_in_queue()
}; };
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult); var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeTrue(); result.Should().BeTrue();
} }
@ -136,7 +134,7 @@ public void is_in_queue_should_find_if_exact_daily_episode_is_in_queue()
{ {
WithFullQueue(); WithFullQueue();
var parseResult = new IndexerParseResult var parseResult = new RemoteEpisode
{ {
Quality = new QualityModel { Quality = Quality.Bluray720p, Proper = false }, Quality = new QualityModel { Quality = Quality.Bluray720p, Proper = false },
AirDate = new DateTime(2011, 12, 01), AirDate = new DateTime(2011, 12, 01),
@ -144,7 +142,7 @@ public void is_in_queue_should_find_if_exact_daily_episode_is_in_queue()
}; };
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult); var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeTrue(); result.Should().BeTrue();
} }
@ -155,7 +153,7 @@ public void is_in_queue_should_find_if_exact_full_season_release_is_in_queue()
WithFullQueue(); WithFullQueue();
var parseResult = new IndexerParseResult var parseResult = new RemoteEpisode
{ {
Quality = new QualityModel { Quality = Quality.Bluray720p, Proper = false }, Quality = new QualityModel { Quality = Quality.Bluray720p, Proper = false },
FullSeason = true, FullSeason = true,
@ -163,7 +161,7 @@ public void is_in_queue_should_find_if_exact_full_season_release_is_in_queue()
Series = new Series { Title = "My Name is earl", CleanTitle = Parser.NormalizeTitle("My Name is earl") }, Series = new Series { Title = "My Name is earl", CleanTitle = Parser.NormalizeTitle("My Name is earl") },
}; };
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult); var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeTrue(); result.Should().BeTrue();
} }
@ -184,7 +182,7 @@ public void IsInQueue_should_not_find_diffrent_episode_queue(int season, int[] e
{ {
WithFullQueue(); WithFullQueue();
var parseResult = new IndexerParseResult var parseResult = new RemoteEpisode
{ {
EpisodeTitle = "Title", EpisodeTitle = "Title",
EpisodeNumbers = new List<int>(episodes), EpisodeNumbers = new List<int>(episodes),
@ -193,7 +191,7 @@ public void IsInQueue_should_not_find_diffrent_episode_queue(int season, int[] e
Series = new Series { Title = title, CleanTitle = Parser.NormalizeTitle(title) }, Series = new Series { Title = title, CleanTitle = Parser.NormalizeTitle(title) },
}; };
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult); var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeFalse(); result.Should().BeFalse();
} }
@ -213,7 +211,7 @@ public void IsInQueue_should_find_same_or_lower_quality_episode_queue(int season
{ {
WithFullQueue(); WithFullQueue();
var parseResult = new IndexerParseResult var parseResult = new RemoteEpisode
{ {
EpisodeTitle = "Title", EpisodeTitle = "Title",
EpisodeNumbers = new List<int>(episodes), EpisodeNumbers = new List<int>(episodes),
@ -222,7 +220,7 @@ public void IsInQueue_should_find_same_or_lower_quality_episode_queue(int season
Series = new Series { Title = title, CleanTitle = Parser.NormalizeTitle(title) }, Series = new Series { Title = title, CleanTitle = Parser.NormalizeTitle(title) },
}; };
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult); var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeTrue(); result.Should().BeTrue();
} }
@ -240,7 +238,7 @@ public void IsInQueue_should_find_items_marked_as_duplicate(int season, int[] ep
{ {
WithFullQueue(); WithFullQueue();
var parseResult = new IndexerParseResult var parseResult = new RemoteEpisode
{ {
EpisodeTitle = "Title", EpisodeTitle = "Title",
EpisodeNumbers = new List<int>(episodes), EpisodeNumbers = new List<int>(episodes),
@ -249,7 +247,7 @@ public void IsInQueue_should_find_items_marked_as_duplicate(int season, int[] ep
Series = new Series { Title = title, CleanTitle = Parser.NormalizeTitle(title) }, Series = new Series { Title = title, CleanTitle = Parser.NormalizeTitle(title) },
}; };
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult); var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeTrue(); result.Should().BeTrue();
} }
@ -267,7 +265,7 @@ public void IsInQueue_should_find_double_episodes_(int season, int[] episodes, s
{ {
WithFullQueue(); WithFullQueue();
var parseResult = new IndexerParseResult var parseResult = new RemoteEpisode
{ {
EpisodeTitle = "Title", EpisodeTitle = "Title",
EpisodeNumbers = new List<int>(episodes), EpisodeNumbers = new List<int>(episodes),
@ -276,7 +274,7 @@ public void IsInQueue_should_find_double_episodes_(int season, int[] episodes, s
Series = new Series { Title = title, CleanTitle = Parser.NormalizeTitle(title) }, Series = new Series { Title = title, CleanTitle = Parser.NormalizeTitle(title) },
}; };
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult); var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeTrue(); result.Should().BeTrue();
} }
@ -286,7 +284,7 @@ public void IsInQueue_should_return_false_if_queue_is_empty()
{ {
WithEmptyQueue(); WithEmptyQueue();
var parseResult = new IndexerParseResult var parseResult = new RemoteEpisode
{ {
EpisodeTitle = "Title", EpisodeTitle = "Title",
EpisodeNumbers = new List<int> { 1 }, EpisodeNumbers = new List<int> { 1 },
@ -295,7 +293,7 @@ public void IsInQueue_should_return_false_if_queue_is_empty()
Series = new Series { Title = "Test", CleanTitle = Parser.NormalizeTitle("Test") }, Series = new Series { Title = "Test", CleanTitle = Parser.NormalizeTitle("Test") },
}; };
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult); var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeFalse(); result.Should().BeFalse();
} }
@ -305,7 +303,7 @@ public void GetQueue_should_parse_timeleft_with_hours_greater_than_24_hours()
{ {
WithFullQueue(); WithFullQueue();
var result = Mocker.Resolve<SabProvider>().GetQueue(); var result = Mocker.Resolve<SabnzbdClient>().GetQueue();
result.Should().NotBeEmpty(); result.Should().NotBeEmpty();
var timeleft = result.First(q => q.Id == "SABnzbd_nzo_qv6ilb").Timeleft; var timeleft = result.First(q => q.Id == "SABnzbd_nzo_qv6ilb").Timeleft;
@ -323,4 +321,4 @@ public void TearDown()
} }
} }*/

View File

@ -45,7 +45,7 @@ public void add_url_should_format_request_properly()
.Returns("{ \"status\": true }"); .Returns("{ \"status\": true }");
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, false).Should().BeTrue(); Mocker.Resolve<SabnzbdClient>().DownloadNzb(url, title, false).Should().BeTrue();
} }
[Test] [Test]
@ -54,7 +54,7 @@ public void add_by_url_should_detect_and_handle_sab_errors()
WithFailResponse(); WithFailResponse();
Assert.Throws<ApplicationException>(() => Mocker.Resolve<SabProvider>().DownloadNzb(url, title, false).Should().BeFalse()); Assert.Throws<ApplicationException>(() => Mocker.Resolve<SabnzbdClient>().DownloadNzb(url, title, false).Should().BeFalse());
//ExceptionVerification.ExpectedErrors(1); //ExceptionVerification.ExpectedErrors(1);
} }
@ -75,7 +75,7 @@ public void should_be_able_to_get_categories_when_config_is_passed_in()
.Returns(ReadAllText("Files","Categories_json.txt")); .Returns(ReadAllText("Files","Categories_json.txt"));
var result = Mocker.Resolve<SabProvider>().GetCategories(host, port, apikey, username, password); var result = Mocker.Resolve<SabnzbdClient>().GetCategories(host, port, apikey, username, password);
result.Should().NotBeNull(); result.Should().NotBeNull();
@ -90,7 +90,7 @@ public void should_be_able_to_get_categories_using_config()
.Returns(ReadAllText("Files","Categories_json.txt")); .Returns(ReadAllText("Files","Categories_json.txt"));
var result = Mocker.Resolve<SabProvider>().GetCategories(); var result = Mocker.Resolve<SabnzbdClient>().GetCategories();
result.Should().NotBeNull(); result.Should().NotBeNull();
@ -105,7 +105,7 @@ public void GetHistory_should_return_a_list_with_items_when_the_history_has_item
.Returns(ReadAllText("Files", "History.txt")); .Returns(ReadAllText("Files", "History.txt"));
var result = Mocker.Resolve<SabProvider>().GetHistory(); var result = Mocker.Resolve<SabnzbdClient>().GetHistory();
result.Should().HaveCount(1); result.Should().HaveCount(1);
@ -119,7 +119,7 @@ public void GetHistory_should_return_an_empty_list_when_the_queue_is_empty()
.Returns(ReadAllText("Files","HistoryEmpty.txt")); .Returns(ReadAllText("Files","HistoryEmpty.txt"));
var result = Mocker.Resolve<SabProvider>().GetHistory(); var result = Mocker.Resolve<SabnzbdClient>().GetHistory();
result.Should().BeEmpty(); result.Should().BeEmpty();
@ -133,7 +133,7 @@ public void GetHistory_should_return_an_empty_list_when_there_is_an_error_gettin
.Returns(ReadAllText("Files","JsonError.txt")); .Returns(ReadAllText("Files","JsonError.txt"));
Assert.Throws<ApplicationException>(() => Mocker.Resolve<SabProvider>().GetHistory(), "API Key Incorrect"); Assert.Throws<ApplicationException>(() => Mocker.Resolve<SabnzbdClient>().GetHistory(), "API Key Incorrect");
} }
[Test] [Test]
@ -146,7 +146,7 @@ public void GetVersion_should_return_the_version_using_passed_in_values()
.Returns(response); .Returns(response);
var result = Mocker.Resolve<SabProvider>().GetVersion("192.168.5.55", 2222, "5c770e3197e4fe763423ee7c392c25d1", "admin", "pass"); var result = Mocker.Resolve<SabnzbdClient>().GetVersion("192.168.5.55", 2222, "5c770e3197e4fe763423ee7c392c25d1", "admin", "pass");
result.Should().NotBeNull(); result.Should().NotBeNull();
@ -163,7 +163,7 @@ public void GetVersion_should_return_the_version_using_saved_values()
.Returns(response); .Returns(response);
var result = Mocker.Resolve<SabProvider>().GetVersion(); var result = Mocker.Resolve<SabnzbdClient>().GetVersion();
result.Should().NotBeNull(); result.Should().NotBeNull();
@ -180,7 +180,7 @@ public void Test_should_return_version_as_a_string()
.Returns(response); .Returns(response);
var result = Mocker.Resolve<SabProvider>().Test("192.168.5.55", 2222, "5c770e3197e4fe763423ee7c392c25d1", "admin", "pass"); var result = Mocker.Resolve<SabnzbdClient>().Test("192.168.5.55", 2222, "5c770e3197e4fe763423ee7c392c25d1", "admin", "pass");
result.Should().Be("0.6.9"); result.Should().Be("0.6.9");
@ -192,7 +192,7 @@ public void should_return_false_when_WebException_is_thrown()
Mocker.GetMock<IHttpProvider>() Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString(It.IsAny<String>())).Throws(new WebException()); .Setup(s => s.DownloadString(It.IsAny<String>())).Throws(new WebException());
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, false).Should().BeFalse(); Mocker.Resolve<SabnzbdClient>().DownloadNzb(url, title, false).Should().BeFalse();
ExceptionVerification.ExpectedErrors(1); ExceptionVerification.ExpectedErrors(1);
} }
@ -212,7 +212,7 @@ public void downloadNzb_should_use_sabRecentTvPriority_when_recentEpisode_is_tru
.Returns("{ \"status\": true }"); .Returns("{ \"status\": true }");
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, true).Should().BeTrue(); Mocker.Resolve<SabnzbdClient>().DownloadNzb(url, title, true).Should().BeTrue();
Mocker.GetMock<IHttpProvider>() Mocker.GetMock<IHttpProvider>()
.Verify(v => v.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"), Times.Once()); .Verify(v => v.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"), Times.Once());
@ -234,7 +234,7 @@ public void downloadNzb_should_use_sabBackogTvPriority_when_recentEpisode_is_fal
.Returns("{ \"status\": true }"); .Returns("{ \"status\": true }");
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, false).Should().BeTrue(); Mocker.Resolve<SabnzbdClient>().DownloadNzb(url, title, false).Should().BeTrue();
Mocker.GetMock<IHttpProvider>() Mocker.GetMock<IHttpProvider>()
.Verify(v => v.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=-1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"), Times.Once()); .Verify(v => v.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=-1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"), Times.Once());

View File

@ -6,6 +6,7 @@
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Download; using NzbDrone.Core.Download;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
@ -15,7 +16,7 @@ namespace NzbDrone.Core.Test.Download
[TestFixture] [TestFixture]
public class DownloadServiceFixture : CoreTest<DownloadService> public class DownloadServiceFixture : CoreTest<DownloadService>
{ {
private IndexerParseResult _parseResult; private RemoteEpisode _parseResult;
[SetUp] [SetUp]
public void Setup() public void Setup()
@ -29,10 +30,9 @@ public void Setup()
.All().With(s => s.SeriesId = 5) .All().With(s => s.SeriesId = 5)
.Build().ToList(); .Build().ToList();
_parseResult = Builder<IndexerParseResult>.CreateNew() _parseResult = Builder<RemoteEpisode>.CreateNew()
.With(c => c.Quality = new QualityModel(Quality.DVD, false)) .With(c => c.Quality = new QualityModel(Quality.DVD, false))
.With(c => c.Series = Builder<Series>.CreateNew().Build()) .With(c => c.Series = Builder<Series>.CreateNew().Build())
.With(c => c.EpisodeNumbers = new List<int> { 2 })
.With(c => c.Episodes = episodes) .With(c => c.Episodes = episodes)
.Build(); .Build();
} }

View File

@ -1,9 +1,11 @@
using System; /*
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
@ -18,7 +20,7 @@ public class EpisodeParseResultTest : CoreTest
[Test] [Test]
public void tostring_single_season_episode() public void tostring_single_season_episode()
{ {
var parseResult = new IndexerParseResult(); var parseResult = new RemoteEpisode();
parseResult.SeriesTitle = "My Series"; parseResult.SeriesTitle = "My Series";
parseResult.SeasonNumber = 12; parseResult.SeasonNumber = 12;
parseResult.EpisodeNumbers = new List<int> { 3 }; parseResult.EpisodeNumbers = new List<int> { 3 };
@ -33,7 +35,7 @@ public void tostring_single_season_episode()
[Test] [Test]
public void tostring_single_season_episode_proper() public void tostring_single_season_episode_proper()
{ {
var parseResult = new IndexerParseResult(); var parseResult = new RemoteEpisode();
parseResult.SeriesTitle = "My Series"; parseResult.SeriesTitle = "My Series";
parseResult.SeasonNumber = 12; parseResult.SeasonNumber = 12;
parseResult.EpisodeNumbers = new List<int> { 3 }; parseResult.EpisodeNumbers = new List<int> { 3 };
@ -48,7 +50,7 @@ public void tostring_single_season_episode_proper()
[Test] [Test]
public void tostring_multi_season_episode() public void tostring_multi_season_episode()
{ {
var parseResult = new IndexerParseResult(); var parseResult = new RemoteEpisode();
parseResult.SeriesTitle = "My Series"; parseResult.SeriesTitle = "My Series";
parseResult.SeasonNumber = 12; parseResult.SeasonNumber = 12;
parseResult.EpisodeNumbers = new List<int> { 3, 4, 5 }; parseResult.EpisodeNumbers = new List<int> { 3, 4, 5 };
@ -63,7 +65,7 @@ public void tostring_multi_season_episode()
[Test] [Test]
public void tostring_multi_season_episode_proper() public void tostring_multi_season_episode_proper()
{ {
var parseResult = new IndexerParseResult(); var parseResult = new RemoteEpisode();
parseResult.SeriesTitle = "My Series"; parseResult.SeriesTitle = "My Series";
parseResult.SeasonNumber = 12; parseResult.SeasonNumber = 12;
parseResult.EpisodeNumbers = new List<int> { 3, 4, 5 }; parseResult.EpisodeNumbers = new List<int> { 3, 4, 5 };
@ -79,7 +81,7 @@ public void tostring_multi_season_episode_proper()
[Test] [Test]
public void tostring_full_season() public void tostring_full_season()
{ {
var parseResult = new IndexerParseResult(); var parseResult = new RemoteEpisode();
parseResult.SeriesTitle = "My Series"; parseResult.SeriesTitle = "My Series";
parseResult.SeasonNumber = 12; parseResult.SeasonNumber = 12;
parseResult.FullSeason = true; parseResult.FullSeason = true;
@ -94,7 +96,7 @@ public void tostring_full_season()
[Test] [Test]
public void tostring_full_season_proper() public void tostring_full_season_proper()
{ {
var parseResult = new IndexerParseResult(); var parseResult = new RemoteEpisode();
parseResult.SeriesTitle = "My Series"; parseResult.SeriesTitle = "My Series";
parseResult.SeasonNumber = 12; parseResult.SeasonNumber = 12;
parseResult.FullSeason = true; parseResult.FullSeason = true;
@ -108,7 +110,7 @@ public void tostring_full_season_proper()
[Test] [Test]
public void tostring_daily_show() public void tostring_daily_show()
{ {
var parseResult = new IndexerParseResult(); var parseResult = new RemoteEpisode();
parseResult.SeriesTitle = "My Series"; parseResult.SeriesTitle = "My Series";
parseResult.SeasonNumber = 12; parseResult.SeasonNumber = 12;
parseResult.FullSeason = true; parseResult.FullSeason = true;
@ -122,7 +124,7 @@ public void tostring_daily_show()
[Test] [Test]
public void tostring_daily_show_proper() public void tostring_daily_show_proper()
{ {
var parseResult = new IndexerParseResult(); var parseResult = new RemoteEpisode();
parseResult.SeriesTitle = "My Series"; parseResult.SeriesTitle = "My Series";
parseResult.SeasonNumber = 12; parseResult.SeasonNumber = 12;
parseResult.FullSeason = true; parseResult.FullSeason = true;
@ -162,7 +164,7 @@ public void create_proper_sab_titles(int seasons, int[] episodes, string title,
.With(e => e.Title = title) .With(e => e.Title = title)
.Build()); .Build());
var parsResult = new IndexerParseResult() var parsResult = new RemoteEpisode()
{ {
AirDate = DateTime.Now, AirDate = DateTime.Now,
EpisodeNumbers = episodes.ToList(), EpisodeNumbers = episodes.ToList(),
@ -184,7 +186,7 @@ public string create_proper_sab_season_title(bool proper)
.With(c => c.Title = "My Series Name") .With(c => c.Title = "My Series Name")
.Build(); .Build();
var parsResult = new IndexerParseResult() var parsResult = new RemoteEpisode()
{ {
AirDate = DateTime.Now, AirDate = DateTime.Now,
Quality = new QualityModel(Quality.Bluray720p, proper), Quality = new QualityModel(Quality.Bluray720p, proper),
@ -210,7 +212,7 @@ public string create_proper_sab_daily_titles(bool proper)
.With(e => e.Title = "My Episode Title") .With(e => e.Title = "My Episode Title")
.Build(); .Build();
var parsResult = new IndexerParseResult var parsResult = new RemoteEpisode
{ {
AirDate = new DateTime(2011, 12, 1), AirDate = new DateTime(2011, 12, 1),
Quality = new QualityModel(Quality.Bluray720p, proper), Quality = new QualityModel(Quality.Bluray720p, proper),
@ -238,7 +240,7 @@ public void should_not_repeat_the_same_episode_title()
.With(e => e.Title = "My Episode Title (2)") .With(e => e.Title = "My Episode Title (2)")
.Build(); .Build();
var parsResult = new IndexerParseResult var parsResult = new RemoteEpisode
{ {
AirDate = DateTime.Now, AirDate = DateTime.Now,
EpisodeNumbers = new List<int> { 10, 11 }, EpisodeNumbers = new List<int> { 10, 11 },
@ -253,3 +255,4 @@ public void should_not_repeat_the_same_episode_title()
} }
} }
*/

View File

@ -14,11 +14,11 @@ namespace NzbDrone.Core.Test
public class EpisodeStatusTest : CoreTest public class EpisodeStatusTest : CoreTest
{ {
[TestCase(1, false, false, EpisodeStatusType.NotAired)] [TestCase(1, false, false, EpisodeStatuses.NotAired)]
[TestCase(-2, false, false, EpisodeStatusType.Missing)] [TestCase(-2, false, false, EpisodeStatuses.Missing)]
[TestCase(0, false, false, EpisodeStatusType.AirsToday)] [TestCase(0, false, false, EpisodeStatuses.AirsToday)]
[TestCase(1, true, false, EpisodeStatusType.Ready)] [TestCase(1, true, false, EpisodeStatuses.Ready)]
public void no_grab_date(int offsetDays, bool hasEpisodes, bool ignored, EpisodeStatusType status) public void no_grab_date(int offsetDays, bool hasEpisodes, bool ignored, EpisodeStatuses status)
{ {
Episode episode = Builder<Episode>.CreateNew() Episode episode = Builder<Episode>.CreateNew()
.With(e => e.AirDate = DateTime.Now.AddDays(offsetDays)) .With(e => e.AirDate = DateTime.Now.AddDays(offsetDays))
@ -34,11 +34,11 @@ public void no_grab_date(int offsetDays, bool hasEpisodes, bool ignored, Episode
episode.Status.Should().Be(status); episode.Status.Should().Be(status);
} }
[TestCase(1, false, false, EpisodeStatusType.Missing)] [TestCase(1, false, false, EpisodeStatuses.Missing)]
[TestCase(-2, false, false, EpisodeStatusType.Missing)] [TestCase(-2, false, false, EpisodeStatuses.Missing)]
[TestCase(1, true, false, EpisodeStatusType.Ready)] [TestCase(1, true, false, EpisodeStatuses.Ready)]
public void old_grab_date(int offsetDays, bool hasEpisodes, bool ignored, public void old_grab_date(int offsetDays, bool hasEpisodes, bool ignored,
EpisodeStatusType status) EpisodeStatuses status)
{ {
Episode episode = Builder<Episode>.CreateNew() Episode episode = Builder<Episode>.CreateNew()
.With(e => e.Ignored = ignored) .With(e => e.Ignored = ignored)
@ -54,13 +54,13 @@ public void old_grab_date(int offsetDays, bool hasEpisodes, bool ignored,
episode.Status.Should().Be(status); episode.Status.Should().Be(status);
} }
[TestCase(1, false, false, EpisodeStatusType.Downloading)] [TestCase(1, false, false, EpisodeStatuses.Downloading)]
[TestCase(-2, false, false, EpisodeStatusType.Downloading)] [TestCase(-2, false, false, EpisodeStatuses.Downloading)]
[TestCase(1, true, false, EpisodeStatusType.Ready)] [TestCase(1, true, false, EpisodeStatuses.Ready)]
[TestCase(1, true, true, EpisodeStatusType.Ready)] [TestCase(1, true, true, EpisodeStatuses.Ready)]
[TestCase(1, false, true, EpisodeStatusType.Downloading)] [TestCase(1, false, true, EpisodeStatuses.Downloading)]
public void recent_grab_date(int offsetDays, bool hasEpisodes, bool ignored, public void recent_grab_date(int offsetDays, bool hasEpisodes, bool ignored,
EpisodeStatusType status) EpisodeStatuses status)
{ {
Episode episode = Builder<Episode>.CreateNew() Episode episode = Builder<Episode>.CreateNew()
.With(e => e.AirDate = DateTime.Now.AddDays(offsetDays)) .With(e => e.AirDate = DateTime.Now.AddDays(offsetDays))
@ -77,8 +77,8 @@ public void recent_grab_date(int offsetDays, bool hasEpisodes, bool ignored,
} }
[TestCase(1, true, true, EpisodeStatusType.Ready)] [TestCase(1, true, true, EpisodeStatuses.Ready)]
public void ignored_episode(int offsetDays, bool ignored, bool hasEpisodes, EpisodeStatusType status) public void ignored_episode(int offsetDays, bool ignored, bool hasEpisodes, EpisodeStatuses status)
{ {
Episode episode = Builder<Episode>.CreateNew() Episode episode = Builder<Episode>.CreateNew()
.With(e => e.AirDate = DateTime.Now.AddDays(offsetDays)) .With(e => e.AirDate = DateTime.Now.AddDays(offsetDays))
@ -105,15 +105,15 @@ public void low_air_date()
.Build(); .Build();
episode.Status.Should().Be(EpisodeStatusType.NotAired); episode.Status.Should().Be(EpisodeStatuses.NotAired);
} }
[TestCase(false, false, EpisodeStatusType.Failed, PostDownloadStatusType.Failed)] [TestCase(false, false, EpisodeStatuses.Failed, PostDownloadStatusType.Failed)]
[TestCase(false, false, EpisodeStatusType.Unpacking, PostDownloadStatusType.Unpacking)] [TestCase(false, false, EpisodeStatuses.Unpacking, PostDownloadStatusType.Unpacking)]
[TestCase(true, false, EpisodeStatusType.Ready, PostDownloadStatusType.Failed)] [TestCase(true, false, EpisodeStatuses.Ready, PostDownloadStatusType.Failed)]
[TestCase(true, true, EpisodeStatusType.Ready, PostDownloadStatusType.Unpacking)] [TestCase(true, true, EpisodeStatuses.Ready, PostDownloadStatusType.Unpacking)]
public void episode_downloaded_post_download_status_is_used(bool hasEpisodes, bool ignored, public void episode_downloaded_post_download_status_is_used(bool hasEpisodes, bool ignored,
EpisodeStatusType status, PostDownloadStatusType postDownloadStatus) EpisodeStatuses status, PostDownloadStatusType postDownloadStatus)
{ {
Episode episode = Builder<Episode>.CreateNew() Episode episode = Builder<Episode>.CreateNew()
.With(e => e.Ignored = ignored) .With(e => e.Ignored = ignored)

View File

@ -36,7 +36,7 @@ public void Setup()
{ {
Mocker.GetMock<EnvironmentProvider>().SetupGet(c => c.SystemTemp).Returns(@"C:\Temp\"); Mocker.GetMock<EnvironmentProvider>().SetupGet(c => c.SystemTemp).Returns(@"C:\Temp\");
Mocker.GetMock<ConfigFileProvider>().SetupGet(c => c.Guid).Returns(_clientGuid); Mocker.GetMock<ConfigFileProvider>().SetupGet(c => c.Guid).Returns(_clientGuid);
Mocker.GetMock<UpdateService>().Setup(c => c.GetAvailableUpdate(It.IsAny<Version>())).Returns(updatePackage); Mocker.GetMock<UpdateService>().Setup(c => c.GetAvailableUpdate()).Returns(updatePackage);
} }
@ -127,7 +127,7 @@ public void should_start_update_client()
[Test] [Test]
public void when_no_updates_are_available_should_return_without_error_or_warnings() public void when_no_updates_are_available_should_return_without_error_or_warnings()
{ {
Mocker.GetMock<UpdateService>().Setup(c => c.GetAvailableUpdate(It.IsAny<Version>())).Returns((UpdatePackage)null); Mocker.GetMock<UpdateService>().Setup(c => c.GetAvailableUpdate()).Returns((UpdatePackage)null);
StartUpdate(); StartUpdate();

View File

@ -35,10 +35,6 @@ public void series_specific_scan_should_scan_series()
.Setup(p => p.Get(series.Id)) .Setup(p => p.Get(series.Id))
.Returns(series); .Returns(series);
Mocker.GetMock<DiskScanProvider>()
.Setup(p => p.Scan(series))
.Returns(new List<EpisodeFile>());
Mocker.Resolve<DiskScanJob>().Start(new ProgressNotification("Test"), new { SeriesId = series.Id }); Mocker.Resolve<DiskScanJob>().Start(new ProgressNotification("Test"), new { SeriesId = series.Id });
@ -60,13 +56,6 @@ public void job_with_no_target_should_scan_all_series()
.Setup(p => p.All()) .Setup(p => p.All())
.Returns(series); .Returns(series);
Mocker.GetMock<DiskScanProvider>()
.Setup(s => s.Scan(series[0]))
.Returns(new List<EpisodeFile>());
Mocker.GetMock<DiskScanProvider>()
.Setup(s => s.Scan(series[1]))
.Returns(new List<EpisodeFile>());
Mocker.Resolve<DiskScanJob>().Start(new ProgressNotification("Test"), null); Mocker.Resolve<DiskScanJob>().Start(new ProgressNotification("Test"), null);
@ -113,14 +102,6 @@ public void job_with_no_target_should_scan_series_with_episodes()
.Setup(p => p.All()) .Setup(p => p.All())
.Returns(series); .Returns(series);
Mocker.GetMock<DiskScanProvider>()
.Setup(s => s.Scan(series[0]))
.Returns(new List<EpisodeFile>());
Mocker.GetMock<DiskScanProvider>()
.Setup(s => s.Scan(series[1]))
.Returns(new List<EpisodeFile>());
Mocker.Resolve<DiskScanJob>().Start(new ProgressNotification("Test"), null); Mocker.Resolve<DiskScanJob>().Start(new ProgressNotification("Test"), null);
Mocker.VerifyAllMocks(); Mocker.VerifyAllMocks();

View File

@ -31,10 +31,10 @@ public void should_use_options_Path_when_provided()
{ {
var path = @"C:\Test\Unsorted TV"; var path = @"C:\Test\Unsorted TV";
Mocker.GetMock<PostDownloadProvider>().Setup(s => s.ProcessDropFolder(path)); Mocker.GetMock<DropFolderImportService>().Setup(s => s.ProcessDropFolder(path));
Mocker.Resolve<PostDownloadScanJob>().Start(MockNotification, new { Path = path }); Mocker.Resolve<PostDownloadScanJob>().Start(MockNotification, new { Path = path });
Mocker.GetMock<PostDownloadProvider>().Verify(s => s.ProcessDropFolder(path), Times.Once()); Mocker.GetMock<DropFolderImportService>().Verify(s => s.ProcessDropFolder(path), Times.Once());
} }
[Test] [Test]
@ -42,7 +42,7 @@ public void should_not_get_sabDropDir_when_path_is_supplied()
{ {
var path = @"C:\Test\Unsorted TV"; var path = @"C:\Test\Unsorted TV";
Mocker.GetMock<PostDownloadProvider>().Setup(s => s.ProcessDropFolder(path)); Mocker.GetMock<DropFolderImportService>().Setup(s => s.ProcessDropFolder(path));
Mocker.Resolve<PostDownloadScanJob>().Start(MockNotification, new { Path = path }); Mocker.Resolve<PostDownloadScanJob>().Start(MockNotification, new { Path = path });
Mocker.GetMock<IConfigService>().Verify(s => s.DownloadClientTvDirectory, Times.Never()); Mocker.GetMock<IConfigService>().Verify(s => s.DownloadClientTvDirectory, Times.Never());
@ -67,7 +67,7 @@ public void should_use_sabDropDir_when_options_Path_is_not_provided()
Mocker.GetMock<IConfigService>().SetupGet(s => s.DownloadClientTvDirectory).Returns(path); Mocker.GetMock<IConfigService>().SetupGet(s => s.DownloadClientTvDirectory).Returns(path);
Mocker.Resolve<PostDownloadScanJob>().Start(MockNotification, null); Mocker.Resolve<PostDownloadScanJob>().Start(MockNotification, null);
Mocker.GetMock<PostDownloadProvider>().Verify(s => s.ProcessDropFolder(path), Times.Once()); Mocker.GetMock<DropFolderImportService>().Verify(s => s.ProcessDropFolder(path), Times.Once());
} }
} }
} }

View File

@ -152,10 +152,7 @@
<Compile Include="Configuration\ConfigCachingFixture.cs" /> <Compile Include="Configuration\ConfigCachingFixture.cs" />
<Compile Include="DecisionEngineTests\AllowedReleaseGroupSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\AllowedReleaseGroupSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\CustomStartDateSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\CustomStartDateSpecificationFixture.cs" />
<Compile Include="ProviderTests\DiskScanProviderTests\CleanUpDropFolderFixture.cs" />
<Compile Include="ProviderTests\DiskScanProviderTests\GetVideoFilesFixture.cs" /> <Compile Include="ProviderTests\DiskScanProviderTests\GetVideoFilesFixture.cs" />
<Compile Include="ProviderTests\PostDownloadProviderTests\ProcessDropDirectoryFixture.cs" />
<Compile Include="ProviderTests\PostDownloadProviderTests\ProcessVideoFileFixture.cs" />
<Compile Include="ProviderTests\RecycleBinProviderTests\CleanupFixture.cs" /> <Compile Include="ProviderTests\RecycleBinProviderTests\CleanupFixture.cs" />
<Compile Include="ProviderTests\RecycleBinProviderTests\EmptyFixture.cs" /> <Compile Include="ProviderTests\RecycleBinProviderTests\EmptyFixture.cs" />
<Compile Include="ProviderTests\RecycleBinProviderTests\DeleteFileFixture.cs" /> <Compile Include="ProviderTests\RecycleBinProviderTests\DeleteFileFixture.cs" />
@ -173,8 +170,7 @@
<Compile Include="ProviderTests\ProwlProviderTest.cs" /> <Compile Include="ProviderTests\ProwlProviderTest.cs" />
<Compile Include="ProviderTests\GrowlProviderTest.cs" /> <Compile Include="ProviderTests\GrowlProviderTest.cs" />
<Compile Include="ProviderTests\DiskProviderTests\ExtractArchiveFixture.cs" /> <Compile Include="ProviderTests\DiskProviderTests\ExtractArchiveFixture.cs" />
<Compile Include="ProviderTests\PostDownloadProviderTests\GetFolderNameWithStatusFixture.cs" /> <Compile Include="ProviderTests\PostDownloadProviderTests\DropFolderImportServiceFixture.cs" />
<Compile Include="ProviderTests\PostDownloadProviderTests\ProcessDownloadFixture.cs" />
<Compile Include="JobTests\TestJobs.cs" /> <Compile Include="JobTests\TestJobs.cs" />
<Compile Include="JobTests\AppUpdateJobFixture.cs" /> <Compile Include="JobTests\AppUpdateJobFixture.cs" />
<Compile Include="ProviderTests\XemCommunicationProviderTests\GetSceneTvdbMappingsFixture.cs" /> <Compile Include="ProviderTests\XemCommunicationProviderTests\GetSceneTvdbMappingsFixture.cs" />
@ -207,6 +203,7 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Qualities\QualityProfileFixture.cs" /> <Compile Include="Qualities\QualityProfileFixture.cs" />
<Compile Include="TvTests\SeriesProviderTest.cs" /> <Compile Include="TvTests\SeriesProviderTest.cs" />
<Compile Include="UpdateTests\UpdatePackageProviderFixture.cs" />
<Compile Include="UpdateTests\GetAvailableUpdateFixture.cs" /> <Compile Include="UpdateTests\GetAvailableUpdateFixture.cs" />
<Compile Include="UpdateTests\GetUpdateLogFixture.cs" /> <Compile Include="UpdateTests\GetUpdateLogFixture.cs" />
<Compile Include="XbmcVersionTests.cs" /> <Compile Include="XbmcVersionTests.cs" />

View File

@ -6,6 +6,8 @@
using NzbDrone.Common.Contract; using NzbDrone.Common.Contract;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
@ -79,16 +81,15 @@ public class ParserFixture : CoreTest
[TestCase("Portlandia.S03E10.Alexandra.720p.WEB-DL.AAC2.0.H.264-CROM.mkv", "Portlandia", 3, 10)] [TestCase("Portlandia.S03E10.Alexandra.720p.WEB-DL.AAC2.0.H.264-CROM.mkv", "Portlandia", 3, 10)]
public void ParseTitle_single(string postTitle, string title, int seasonNumber, int episodeNumber) public void ParseTitle_single(string postTitle, string title, int seasonNumber, int episodeNumber)
{ {
var result = Parser.ParseTitle<IndexerParseResult>(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.Should().NotBeNull(); result.Should().NotBeNull();
result.EpisodeNumbers.Should().HaveCount(1); result.EpisodeNumbers.Should().HaveCount(1);
result.SeasonNumber.Should().Be(seasonNumber); result.SeasonNumber.Should().Be(seasonNumber);
result.EpisodeNumbers.First().Should().Be(episodeNumber); result.EpisodeNumbers.First().Should().Be(episodeNumber);
result.CleanTitle.Should().Be(Parser.NormalizeTitle(title)); result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title));
result.OriginalString.Should().Be(postTitle); result.OriginalString.Should().Be(postTitle);
} }
[Test]
[TestCase(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)] [TestCase(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)]
[TestCase(@"z:\tv shows\modern marvels\Season 16\S16E03 - The Potato.mkv", 16, 3)] [TestCase(@"z:\tv shows\modern marvels\Season 16\S16E03 - The Potato.mkv", 16, 3)]
[TestCase(@"z:\tv shows\robot chicken\Specials\S00E16 - Dear Consumer - SD TV.avi", 0, 16)] [TestCase(@"z:\tv shows\robot chicken\Specials\S00E16 - Dear Consumer - SD TV.avi", 0, 16)]
@ -101,7 +102,7 @@ public void ParseTitle_single(string postTitle, string title, int seasonNumber,
[TestCase(@"S:\TV Drop\King of the Hill - 10x12 - 24 Hour Propane People [SDTV]\Hour Propane People.avi", 10, 12)] [TestCase(@"S:\TV Drop\King of the Hill - 10x12 - 24 Hour Propane People [SDTV]\Hour Propane People.avi", 10, 12)]
public void PathParse_tests(string path, int season, int episode) public void PathParse_tests(string path, int season, int episode)
{ {
var result = Parser.ParsePath(path); var result = Parser.Parser.ParsePath(path);
result.EpisodeNumbers.Should().HaveCount(1); result.EpisodeNumbers.Should().HaveCount(1);
result.SeasonNumber.Should().Be(season); result.SeasonNumber.Should().Be(season);
result.EpisodeNumbers[0].Should().Be(episode); result.EpisodeNumbers[0].Should().Be(episode);
@ -113,7 +114,7 @@ public void PathParse_tests(string path, int season, int episode)
[Test] [Test]
public void unparsable_path_should_report_the_path() public void unparsable_path_should_report_the_path()
{ {
Parser.ParsePath("C:\\").Should().BeNull(); Parser.Parser.ParsePath("C:\\").Should().BeNull();
MockedRestProvider.Verify(c => c.PostData(It.IsAny<string>(), It.IsAny<ParseErrorReport>()), Times.Exactly(2)); MockedRestProvider.Verify(c => c.PostData(It.IsAny<string>(), It.IsAny<ParseErrorReport>()), Times.Exactly(2));
@ -125,7 +126,7 @@ public void unparsable_title_should_report_title()
{ {
const string TITLE = "SOMETHING"; const string TITLE = "SOMETHING";
Parser.ParseTitle<ParseResult>(TITLE).Should().BeNull(); Parser.Parser.ParseTitle(TITLE).Should().BeNull();
MockedRestProvider.Verify(c => c.PostData(It.IsAny<string>(), It.Is<ParseErrorReport>(r => r.Title == TITLE)), Times.Once()); MockedRestProvider.Verify(c => c.PostData(It.IsAny<string>(), It.Is<ParseErrorReport>(r => r.Title == TITLE)), Times.Once());
@ -153,10 +154,10 @@ public void unparsable_title_should_report_title()
[TestCase("Hell.on.Wheels.S02E09-E10.720p.HDTV.x264-EVOLVE", "Hell on Wheels", 2, new[] { 9, 10 })] [TestCase("Hell.on.Wheels.S02E09-E10.720p.HDTV.x264-EVOLVE", "Hell on Wheels", 2, new[] { 9, 10 })]
public void TitleParse_multi(string postTitle, string title, int season, int[] episodes) public void TitleParse_multi(string postTitle, string title, int season, int[] episodes)
{ {
var result = Parser.ParseTitle<ParseResult>(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.SeasonNumber.Should().Be(season); result.SeasonNumber.Should().Be(season);
result.EpisodeNumbers.Should().BeEquivalentTo(episodes); result.EpisodeNumbers.Should().BeEquivalentTo(episodes);
result.CleanTitle.Should().Be(Parser.NormalizeTitle(title)); result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title));
result.OriginalString.Should().Be(postTitle); result.OriginalString.Should().Be(postTitle);
} }
@ -173,10 +174,10 @@ public void TitleParse_multi(string postTitle, string title, int season, int[] e
[TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "2020nz", 2011, 12, 2)] [TestCase("2020.NZ.2011.12.02.PDTV.XviD-C4TV", "2020nz", 2011, 12, 2)]
public void parse_daily_episodes(string postTitle, string title, int year, int month, int day) public void parse_daily_episodes(string postTitle, string title, int year, int month, int day)
{ {
var result = Parser.ParseTitle<ParseResult>(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
var airDate = new DateTime(year, month, day); var airDate = new DateTime(year, month, day);
result.Should().NotBeNull(); result.Should().NotBeNull();
result.CleanTitle.Should().Be(Parser.NormalizeTitle(title)); result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title));
result.AirDate.Should().Be(airDate); result.AirDate.Should().Be(airDate);
result.EpisodeNumbers.Should().BeNull(); result.EpisodeNumbers.Should().BeNull();
result.OriginalString.Should().Be(postTitle); result.OriginalString.Should().Be(postTitle);
@ -187,7 +188,7 @@ public void parse_daily_should_fail_if_episode_is_far_in_future()
{ {
var title = string.Format("{0:yyyy.MM.dd} - Denis Leary - HD TV.mkv", DateTime.Now.AddDays(2)); var title = string.Format("{0:yyyy.MM.dd} - Denis Leary - HD TV.mkv", DateTime.Now.AddDays(2));
Parser.ParseTitle<ParseResult>(title).Should().BeNull(); Parser.Parser.ParseTitle(title).Should().BeNull();
} }
@ -198,9 +199,9 @@ public void parse_daily_should_fail_if_episode_is_far_in_future()
[TestCase("Adventure Time S02 720p HDTV x264 CRON", "Adventure Time", 2)] [TestCase("Adventure Time S02 720p HDTV x264 CRON", "Adventure Time", 2)]
public void full_season_release_parse(string postTitle, string title, int season) public void full_season_release_parse(string postTitle, string title, int season)
{ {
var result = Parser.ParseTitle<ParseResult>(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.SeasonNumber.Should().Be(season); result.SeasonNumber.Should().Be(season);
result.CleanTitle.Should().Be(Parser.NormalizeTitle(title)); result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title));
result.EpisodeNumbers.Count.Should().Be(0); result.EpisodeNumbers.Count.Should().Be(0);
result.FullSeason.Should().BeTrue(); result.FullSeason.Should().BeTrue();
result.OriginalString.Should().Be(postTitle); result.OriginalString.Should().Be(postTitle);
@ -213,7 +214,7 @@ public void full_season_release_parse(string postTitle, string title, int season
[TestCase("Parenthood.2010", "parenthood2010")] [TestCase("Parenthood.2010", "parenthood2010")]
public void series_name_normalize(string parsedSeriesName, string seriesName) public void series_name_normalize(string parsedSeriesName, string seriesName)
{ {
var result = Parser.NormalizeTitle(parsedSeriesName); var result = Parser.Parser.NormalizeTitle(parsedSeriesName);
result.Should().Be(seriesName); result.Should().Be(seriesName);
} }
@ -225,7 +226,7 @@ public void series_name_normalize(string parsedSeriesName, string seriesName)
[TestCase("24", "24")] [TestCase("24", "24")]
public void Normalize_Title(string dirty, string clean) public void Normalize_Title(string dirty, string clean)
{ {
var result = Parser.NormalizeTitle(dirty); var result = Parser.Parser.NormalizeTitle(dirty);
result.Should().Be(clean); result.Should().Be(clean);
} }
@ -253,7 +254,7 @@ public void Normalize_removed_common_words(string word)
foreach (var s in dirtyFormat) foreach (var s in dirtyFormat)
{ {
var dirty = String.Format(s, word); var dirty = String.Format(s, word);
Parser.NormalizeTitle(dirty).Should().Be("wordword"); Parser.Parser.NormalizeTitle(dirty).Should().Be("wordword");
} }
} }
@ -279,7 +280,7 @@ public void Normalize_not_removed_common_words_in_the_middle(string word)
foreach (var s in dirtyFormat) foreach (var s in dirtyFormat)
{ {
var dirty = String.Format(s, word); var dirty = String.Format(s, word);
Parser.NormalizeTitle(dirty).Should().Be(("word" + word.ToLower() + "word")); Parser.Parser.NormalizeTitle(dirty).Should().Be(("word" + word.ToLower() + "word"));
} }
} }
@ -295,38 +296,38 @@ public void Normalize_not_removed_common_words_in_the_middle(string word)
[TestCase("Adventure Time S02 720p HDTV x264 CRON", "adventuretime")] [TestCase("Adventure Time S02 720p HDTV x264 CRON", "adventuretime")]
public void parse_series_name(string postTitle, string title) public void parse_series_name(string postTitle, string title)
{ {
var result = Parser.ParseSeriesName(postTitle); var result = Parser.Parser.ParseSeriesName(postTitle);
result.Should().Be(Parser.NormalizeTitle(title)); result.Should().Be(Parser.Parser.NormalizeTitle(title));
} }
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", LanguageType.English)] [TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", Language.English)]
[TestCase("Castle.2009.S01E14.French.HDTV.XviD-LOL", LanguageType.French)] [TestCase("Castle.2009.S01E14.French.HDTV.XviD-LOL", Language.French)]
[TestCase("Castle.2009.S01E14.Spanish.HDTV.XviD-LOL", LanguageType.Spanish)] [TestCase("Castle.2009.S01E14.Spanish.HDTV.XviD-LOL", Language.Spanish)]
[TestCase("Castle.2009.S01E14.German.HDTV.XviD-LOL", LanguageType.German)] [TestCase("Castle.2009.S01E14.German.HDTV.XviD-LOL", Language.German)]
[TestCase("Castle.2009.S01E14.Germany.HDTV.XviD-LOL", LanguageType.English)] [TestCase("Castle.2009.S01E14.Germany.HDTV.XviD-LOL", Language.English)]
[TestCase("Castle.2009.S01E14.Italian.HDTV.XviD-LOL", LanguageType.Italian)] [TestCase("Castle.2009.S01E14.Italian.HDTV.XviD-LOL", Language.Italian)]
[TestCase("Castle.2009.S01E14.Danish.HDTV.XviD-LOL", LanguageType.Danish)] [TestCase("Castle.2009.S01E14.Danish.HDTV.XviD-LOL", Language.Danish)]
[TestCase("Castle.2009.S01E14.Dutch.HDTV.XviD-LOL", LanguageType.Dutch)] [TestCase("Castle.2009.S01E14.Dutch.HDTV.XviD-LOL", Language.Dutch)]
[TestCase("Castle.2009.S01E14.Japanese.HDTV.XviD-LOL", LanguageType.Japanese)] [TestCase("Castle.2009.S01E14.Japanese.HDTV.XviD-LOL", Language.Japanese)]
[TestCase("Castle.2009.S01E14.Cantonese.HDTV.XviD-LOL", LanguageType.Cantonese)] [TestCase("Castle.2009.S01E14.Cantonese.HDTV.XviD-LOL", Language.Cantonese)]
[TestCase("Castle.2009.S01E14.Mandarin.HDTV.XviD-LOL", LanguageType.Mandarin)] [TestCase("Castle.2009.S01E14.Mandarin.HDTV.XviD-LOL", Language.Mandarin)]
[TestCase("Castle.2009.S01E14.Korean.HDTV.XviD-LOL", LanguageType.Korean)] [TestCase("Castle.2009.S01E14.Korean.HDTV.XviD-LOL", Language.Korean)]
[TestCase("Castle.2009.S01E14.Russian.HDTV.XviD-LOL", LanguageType.Russian)] [TestCase("Castle.2009.S01E14.Russian.HDTV.XviD-LOL", Language.Russian)]
[TestCase("Castle.2009.S01E14.Polish.HDTV.XviD-LOL", LanguageType.Polish)] [TestCase("Castle.2009.S01E14.Polish.HDTV.XviD-LOL", Language.Polish)]
[TestCase("Castle.2009.S01E14.Vietnamese.HDTV.XviD-LOL", LanguageType.Vietnamese)] [TestCase("Castle.2009.S01E14.Vietnamese.HDTV.XviD-LOL", Language.Vietnamese)]
[TestCase("Castle.2009.S01E14.Swedish.HDTV.XviD-LOL", LanguageType.Swedish)] [TestCase("Castle.2009.S01E14.Swedish.HDTV.XviD-LOL", Language.Swedish)]
[TestCase("Castle.2009.S01E14.Norwegian.HDTV.XviD-LOL", LanguageType.Norwegian)] [TestCase("Castle.2009.S01E14.Norwegian.HDTV.XviD-LOL", Language.Norwegian)]
[TestCase("Castle.2009.S01E14.Finnish.HDTV.XviD-LOL", LanguageType.Finnish)] [TestCase("Castle.2009.S01E14.Finnish.HDTV.XviD-LOL", Language.Finnish)]
[TestCase("Castle.2009.S01E14.Turkish.HDTV.XviD-LOL", LanguageType.Turkish)] [TestCase("Castle.2009.S01E14.Turkish.HDTV.XviD-LOL", Language.Turkish)]
[TestCase("Castle.2009.S01E14.Portuguese.HDTV.XviD-LOL", LanguageType.Portuguese)] [TestCase("Castle.2009.S01E14.Portuguese.HDTV.XviD-LOL", Language.Portuguese)]
[TestCase("Castle.2009.S01E14.HDTV.XviD-LOL", LanguageType.English)] [TestCase("Castle.2009.S01E14.HDTV.XviD-LOL", Language.English)]
[TestCase("person.of.interest.1x19.ita.720p.bdmux.x264-novarip", LanguageType.Italian)] [TestCase("person.of.interest.1x19.ita.720p.bdmux.x264-novarip", Language.Italian)]
[TestCase("Salamander.S01E01.FLEMISH.HDTV.x264-BRiGAND", LanguageType.Flemish)] [TestCase("Salamander.S01E01.FLEMISH.HDTV.x264-BRiGAND", Language.Flemish)]
[TestCase("H.Polukatoikia.S03E13.Greek.PDTV.XviD-Ouzo", LanguageType.Greek)] [TestCase("H.Polukatoikia.S03E13.Greek.PDTV.XviD-Ouzo", Language.Greek)]
[TestCase("Burn.Notice.S04E15.Brotherly.Love.GERMAN.DUBBED.WS.WEBRiP.XviD.REPACK-TVP", LanguageType.German)] [TestCase("Burn.Notice.S04E15.Brotherly.Love.GERMAN.DUBBED.WS.WEBRiP.XviD.REPACK-TVP", Language.German)]
public void parse_language(string postTitle, LanguageType language) public void parse_language(string postTitle, Language language)
{ {
var result = Parser.ParseTitle<ParseResult>(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.Language.Should().Be(language); result.Language.Should().Be(language);
} }
@ -339,9 +340,9 @@ public void parse_language(string postTitle, LanguageType language)
[TestCase("Doctor Who Confidential Season 3", "Doctor Who Confidential", 3)] [TestCase("Doctor Who Confidential Season 3", "Doctor Who Confidential", 3)]
public void parse_season_info(string postTitle, string seriesName, int seasonNumber) public void parse_season_info(string postTitle, string seriesName, int seasonNumber)
{ {
var result = Parser.ParseTitle<ParseResult>(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.CleanTitle.Should().Be(Parser.NormalizeTitle(seriesName)); result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(seriesName));
result.SeasonNumber.Should().Be(seasonNumber); result.SeasonNumber.Should().Be(seasonNumber);
result.FullSeason.Should().BeTrue(); result.FullSeason.Should().BeTrue();
result.OriginalString.Should().Be(postTitle); result.OriginalString.Should().Be(postTitle);
@ -352,7 +353,7 @@ public void parse_season_info(string postTitle, string seriesName, int seasonNum
[TestCase("Instant Star S03 EXTRAS DVDRip XviD OSiTV")] [TestCase("Instant Star S03 EXTRAS DVDRip XviD OSiTV")]
public void parse_season_extras(string postTitle) public void parse_season_extras(string postTitle)
{ {
var result = Parser.ParseTitle<ParseResult>(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.Should().BeNull(); result.Should().BeNull();
} }
@ -362,7 +363,7 @@ public void parse_season_extras(string postTitle)
[TestCase("CSI.S11.SUBPACK.DVDRip.XviD-REWARD")] [TestCase("CSI.S11.SUBPACK.DVDRip.XviD-REWARD")]
public void parse_season_subpack(string postTitle) public void parse_season_subpack(string postTitle)
{ {
var result = Parser.ParseTitle<ParseResult>(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.Should().BeNull(); result.Should().BeNull();
} }
@ -370,7 +371,7 @@ public void parse_season_subpack(string postTitle)
[TestCase("Fussball Bundesliga 10e2011e30 Spieltag FC Bayern Muenchen vs Bayer 04 Leverkusen German WS dTV XviD WoGS")] [TestCase("Fussball Bundesliga 10e2011e30 Spieltag FC Bayern Muenchen vs Bayer 04 Leverkusen German WS dTV XviD WoGS")]
public void unparsable_should_log_error_but_not_throw(string title) public void unparsable_should_log_error_but_not_throw(string title)
{ {
Parser.ParseTitle<ParseResult>(title); Parser.Parser.ParseTitle(title);
ExceptionVerification.IgnoreWarns(); ExceptionVerification.IgnoreWarns();
ExceptionVerification.ExpectedErrors(1); ExceptionVerification.ExpectedErrors(1);
} }
@ -386,7 +387,7 @@ public void parse_header(string title, string expected)
[TestCase("password - \"bdc435cb-93c4-4902-97ea-ca00568c3887.337\" yEnc")] [TestCase("password - \"bdc435cb-93c4-4902-97ea-ca00568c3887.337\" yEnc")]
public void should_not_parse_encypted_posts(string title) public void should_not_parse_encypted_posts(string title)
{ {
Parser.ParseTitle<ParseResult>(title).Should().BeNull(); Parser.Parser.ParseTitle(title).Should().BeNull();
ExceptionVerification.IgnoreWarns(); ExceptionVerification.IgnoreWarns();
} }
} }

View File

@ -96,7 +96,7 @@ public class QualityParserFixture : CoreTest
[Test, TestCaseSource("QualityParserCases")] [Test, TestCaseSource("QualityParserCases")]
public void quality_parse(string postTitle, Quality quality, bool proper) public void quality_parse(string postTitle, Quality quality, bool proper)
{ {
var result = Parser.ParseTitle<ParseResult>(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.Quality.Quality.Should().Be(quality); result.Quality.Quality.Should().Be(quality);
result.Quality.Proper.Should().Be(proper); result.Quality.Proper.Should().Be(proper);
} }
@ -105,7 +105,7 @@ public void quality_parse(string postTitle, Quality quality, bool proper)
public void parsing_our_own_quality_enum(Quality quality) public void parsing_our_own_quality_enum(Quality quality)
{ {
var fileName = String.Format("My series S01E01 [{0}]", quality); var fileName = String.Format("My series S01E01 [{0}]", quality);
var result = Parser.ParseTitle<ParseResult>(fileName); var result = Parser.Parser.ParseTitle(fileName);
result.Quality.Quality.Should().Be(quality); result.Quality.Quality.Should().Be(quality);
} }
} }

View File

@ -1,15 +1,8 @@
using System; using System.IO;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using FluentAssertions; using FluentAssertions;
using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests
{ {
@ -19,7 +12,7 @@ public class FreeDiskSpaceTest : CoreTest<DiskProvider>
[Test] [Test]
public void should_return_free_disk_space() public void should_return_free_disk_space()
{ {
var result = Subject.FreeDiskSpace(Directory.GetCurrentDirectory()); var result = Subject.GetAvilableSpace(Directory.GetCurrentDirectory());
//Checks to ensure that the free space on the first is greater than 0 (It should be in 99.99999999999999% of cases... I hope) //Checks to ensure that the free space on the first is greater than 0 (It should be in 99.99999999999999% of cases... I hope)
result.Should().BeGreaterThan(0); result.Should().BeGreaterThan(0);
@ -27,7 +20,7 @@ public void should_return_free_disk_space()
[Test] [Test]
public void should_throw_if_drive_doesnt_exist() public void should_throw_if_drive_doesnt_exist()
{ {
Assert.Throws<DirectoryNotFoundException>(() => Subject.FreeDiskSpace(@"Z:\NOT_A_REAL_PATH\DOES_NOT_EXIST")); Assert.Throws<DirectoryNotFoundException>(() => Subject.GetAvilableSpace(@"Z:\NOT_A_REAL_PATH\DOES_NOT_EXIST"));
} }
} }
} }

View File

@ -1,123 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
{
public class CleanUpDropFolderFixture : CoreTest
{
[Test]
public void should_do_nothing_if_no_files_are_found()
{
var folder = @"C:\Test\DropDir\The Office";
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
.Returns(new string[0]);
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
Mocker.GetMock<IMediaFileService>().Verify(v => v.GetFileByPath(It.IsAny<string>()), Times.Never());
}
[Test]
public void should_do_nothing_if_no_conflicting_files_are_found()
{
var folder = @"C:\Test\DropDir\The Office";
var filename = Path.Combine(folder, "NotAProblem.avi");
var episodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.Path = filename.NormalizePath())
.With(f => f.SeriesId = 12345)
.Build();
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
.Returns(new string[] { filename });
Mocker.GetMock<IMediaFileService>().Setup(s => s.GetFileByPath(filename))
.Returns(() => null);
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
Mocker.GetMock<IMediaFileService>().Verify(v => v.GetFileByPath(filename), Times.Once());
Mocker.GetMock<ISeriesRepository>().Verify(v => v.Get(It.IsAny<int>()), Times.Never());
}
[Test]
public void should_move_file_if_a_conflict_is_found()
{
var folder = @"C:\Test\DropDir\The Office";
var filename = Path.Combine(folder, "Problem.avi");
var seriesId = 12345;
var newFilename = "S01E01 - Title";
var newFilePath = @"C:\Test\TV\The Office\Season 01\S01E01 - Title.avi";
var episodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.Path = filename.NormalizePath())
.With(f => f.SeriesId = seriesId)
.Build();
var series = Builder<Series>.CreateNew()
.With(s => s.Id = seriesId)
.With(s => s.Title = "The Office")
.Build();
var episode = Builder<Episode>.CreateListOfSize(1)
.All()
.With(e => e.SeriesId = seriesId)
.With(e => e.EpisodeFile = episodeFile)
.Build().ToList();
Mocker.GetMock<IMediaFileService>().Setup(v => v.GetFileByPath(filename))
.Returns(() => null);
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
.Returns(new string[] { filename });
Mocker.GetMock<IMediaFileService>().Setup(s => s.GetFileByPath(filename))
.Returns(episodeFile);
Mocker.GetMock<ISeriesRepository>().Setup(s => s.Get(It.IsAny<int>()))
.Returns(series);
Mocker.GetMock<IEpisodeService>().Setup(s => s.GetEpisodesByFileId(episodeFile.Id))
.Returns(episode);
Mocker.GetMock<IBuildFileNames>().Setup(s => s.BuildFilename(It.IsAny<IList<Episode>>(), series, It.IsAny<EpisodeFile>()))
.Returns(newFilename);
Mocker.GetMock<IBuildFileNames>().Setup(s => s.BuildFilePath(It.IsAny<Series>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns(newFilePath);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FileExists(filename))
.Returns(true);
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveFile(episodeFile.Path, newFilePath));
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
Mocker.GetMock<IMediaFileService>().Verify(v => v.GetFileByPath(filename), Times.Once());
Mocker.GetMock<DiskProvider>().Verify(v => v.MoveFile(filename.NormalizePath(), newFilePath), Times.Once());
}
}
}

View File

@ -7,562 +7,281 @@
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
{ {
public class ImportFileFixture : CoreTest public class ImportFileFixture : CoreTest<DiskScanProvider>
{ {
public static object[] ImportTestCases =
{
new object[] { Quality.SDTV, false },
new object[] { Quality.DVD, true },
new object[] { Quality.HDTV720p, false }
};
private readonly long SIZE = 80.Megabytes();
private Series _series; private long _fileSize = 80.Megabytes();
private Series _fakeSeries;
private List<Episode> _fakeEpisodes;
private Episode _fakeEpisode;
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_series = Builder<Series> _fakeSeries = Builder<Series>
.CreateNew() .CreateNew()
.With(s => s.SeriesType = SeriesTypes.Standard)
.Build(); .Build();
_fakeEpisode = Builder<Episode>
.CreateNew()
.Build();
_fakeEpisodes = Builder<Episode>.CreateListOfSize(2)
.All()
.With(c => c.SeasonNumber = 3)
.With(e => e.EpisodeFile = new EpisodeFile())
.BuildList();
GivenNewFile();
GivenVideoDuration(TimeSpan.FromMinutes(20));
GivenFileSize(_fileSize);
} }
public void With80MBFile() private void GivenFileSize(long size)
{ {
_fileSize = size;
Mocker.GetMock<DiskProvider>() Mocker.GetMock<DiskProvider>()
.Setup(d => d.GetSize(It.IsAny<String>())) .Setup(d => d.GetSize(It.IsAny<String>()))
.Returns(80.Megabytes()); .Returns(size);
} }
public void WithDailySeries() private void GivenVideoDuration(TimeSpan duration)
{ {
_series.SeriesType = SeriesTypes.Daily; Mocker.GetMock<IVideoFileInfoReader>()
.Setup(d => d.GetRunTime(It.IsAny<String>()))
.Returns(duration);
}
private void GivenEpisodes(IEnumerable<Episode> episodes, QualityModel quality)
{
Mocker.GetMock<IParsingService>()
.Setup(c => c.GetEpisodes(It.IsAny<string>(), It.IsAny<Series>()))
.Returns(new LocalEpisode
{
Episodes = episodes.ToList(),
Quality = quality
});
}
private void GivenNewFile()
{
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
} }
[Test] [Test]
public void import_new_file_should_succeed() public void import_new_file_should_succeed()
{ {
const string newFile = @"WEEDS.S03E01.DUAL.dvd.HELLYWOOD.avi"; GivenEpisodes(new[] { _fakeEpisode }, new QualityModel());
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew().Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, newFile);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
var result = Subject.ImportFile(_fakeSeries, "file.ext");
VerifyFileImport(result);
} }
[Test, TestCaseSource("ImportTestCases")]
public void import_new_file_with_better_same_quality_should_succeed(Quality currentFileQuality, bool currentFileProper)
[Test]
public void import_new_file_with_same_quality_should_succeed()
{ {
const string newFile = @"WEEDS.S03E01.DUAL.1080p.HELLYWOOD.mkv"; _fakeEpisode.EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.SDTV) };
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.SDTV));
//Fakes var result = Subject.ImportFile(_fakeSeries, "file.ext");
var fakeSeries = Builder<Series>.CreateNew().Build(); VerifyFileImport(result);
var fakeEpisode = Builder<Episode>.CreateNew()
.With(e => e.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(g => g.Quality = new QualityModel(currentFileQuality, currentFileProper))
.Build()
).Build();
With80MBFile();
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, newFile);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
} }
[TestCase("WEEDS.S03E01.DUAL.DVD.XviD.AC3.-HELLYWOOD.avi")] [Test]
[TestCase("WEEDS.S03E01.DUAL.SDTV.XviD.AC3.-HELLYWOOD.avi")] public void import_new_file_with_better_quality_should_succeed()
public void import_new_file_episode_has_same_or_better_quality_should_skip(string fileName)
{ {
_fakeEpisode.EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.SDTV) };
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
//Fakes var result = Subject.ImportFile(_fakeSeries, "file.ext");
var fakeSeries = Builder<Series>.CreateNew().Build(); VerifyFileImport(result);
var fakeEpisode = Builder<Episode>.CreateNew()
.With(c => c.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(e => e.Quality = new QualityModel(Quality.Bluray720p)).Build()
)
.Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifySkipImport(result, Mocker);
} }
[Test]
public void import_new_file_episode_has_better_quality_should_skip()
{
_fakeEpisode.EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV1080p) };
GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.SDTV));
var result = Subject.ImportFile(_fakeSeries, "file.ext");
VerifySkipImport(result);
}
[Test] [Test]
public void import_unparsable_file_should_skip() public void import_unparsable_file_should_skip()
{ {
const string fileName = @"C:\Test\WEEDS.avi"; Mocker.GetMock<IParsingService>()
.Setup(c => c.GetEpisodes(It.IsAny<string>(), It.IsAny<Series>()))
.Returns<LocalEpisode>(null);
var fakeSeries = Builder<Series>.CreateNew().Build(); var result = Subject.ImportFile(_fakeSeries, "file.ext");
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>())).Returns(false);
With80MBFile();
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName); VerifySkipImport(result);
VerifySkipImport(result, Mocker);
ExceptionVerification.ExpectedWarns(1);
} }
[Test] [Test]
public void import_existing_file_should_skip() public void import_existing_file_should_skip()
{ {
const string fileName = "WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
var fakeSeries = Builder<Series>.CreateNew().Build();
WithStrictMocker();
Mocker.GetMock<IMediaFileService>() Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>())) .Setup(p => p.Exists(It.IsAny<String>()))
.Returns(true); .Returns(true);
With80MBFile(); var result = Subject.ImportFile(_fakeSeries, "file.ext");
VerifySkipImport(result);
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifySkipImport(result, Mocker);
} }
[Test] [Test]
public void import_file_with_no_episode_in_db_should_skip() public void import_file_with_no_episode_in_db_should_skip()
{ {
//Constants GivenEpisodes(new List<Episode>(), new QualityModel());
const string fileName = "WEEDS.S03E01.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
//Fakes var result = Subject.ImportFile(_fakeSeries, "file.ext");
var fakeSeries = Builder<Series>.CreateNew().Build();
//Mocks VerifySkipImport(result);
Mocker.GetMock<DiskProvider>(MockBehavior.Strict)
.Setup(e => e.IsChildOfPath(fileName, fakeSeries.Path)).Returns(false);
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(c => c.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>()))
.Returns(new List<Episode>());
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifySkipImport(result, Mocker);
}
[TestCase("WEEDS.S03E01.DUAL.DVD.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv")]
public void import_new_file_episode_has_better_quality_than_existing(string fileName)
{
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew()
.With(c => c.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(e => e.Quality = new QualityModel(Quality.SDTV)).Build()
)
.Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
Mocker.GetMock<RecycleBinProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Once());
}
[TestCase("WEEDS.S03E01.DUAL.hdtv.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.DVD.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv")]
public void import_new_multi_part_file_episode_has_equal_or_better_quality_than_existing(string fileName)
{
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisodes = Builder<Episode>.CreateListOfSize(2)
.All()
.With(e => e.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.Quality = new QualityModel(Quality.SDTV))
.Build())
.Build().ToList();
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(fakeEpisodes);
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifyFileImport(result, Mocker, fakeEpisodes[0], SIZE);
Mocker.GetMock<RecycleBinProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Once());
}
[TestCase("WEEDS.S03E01.DUAL.DVD.XviD.AC3.-HELLYWOOD.avi")]
[TestCase("WEEDS.S03E01.DUAL.HDTV.XviD.AC3.-HELLYWOOD.avi")]
public void skip_import_new_multi_part_file_episode_existing_has_better_quality(string fileName)
{
//Fakes
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisodes = Builder<Episode>.CreateListOfSize(2)
.All()
.With(e => e.EpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.Quality = new QualityModel(Quality.Bluray720p))
.Build())
.Build().ToList();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(fakeEpisodes);
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName);
VerifySkipImport(result, Mocker);
} }
[Test] [Test]
public void import_new_multi_part_file_episode_replace_two_files() public void import_new_multi_part_file_episode_with_better_quality_than_existing()
{ {
const string fileName = "WEEDS.S03E01E02.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv"; _fakeEpisodes[0].EpisodeFile = new EpisodeFile();
_fakeEpisodes[1].EpisodeFile = new EpisodeFile();
//Fakes _fakeEpisodes[0].EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.SDTV) };
var fakeSeries = Builder<Series>.CreateNew().Build(); _fakeEpisodes[1].EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.SDTV) };
var fakeEpisodeFiles = Builder<EpisodeFile>.CreateListOfSize(2) GivenEpisodes(_fakeEpisodes, new QualityModel(Quality.HDTV1080p));
.All()
.With(e => e.Quality = new QualityModel(Quality.SDTV))
.Build();
var fakeEpisode1 = Builder<Episode>.CreateNew() var result = Subject.ImportFile(_fakeSeries, "file.ext");
.With(c => c.EpisodeFile = fakeEpisodeFiles[0])
.Build();
var fakeEpisode2 = Builder<Episode>.CreateNew()
.With(c => c.EpisodeFile = fakeEpisodeFiles[1])
.Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode1, fakeEpisode2 });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName); VerifyFileImport(result);
VerifyFileImport(result, Mocker, fakeEpisode1, SIZE);
Mocker.GetMock<RecycleBinProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Exactly(2));
} }
[Test] [Test]
public void should_import_new_episode_no_existing_episode_file() public void skip_import_new_multi_part_file_episode_existing_has_better_quality()
{ {
const string fileName = "WEEDS.S03E01E02.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv"; _fakeEpisodes[0].EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV1080p) };
_fakeEpisodes[1].EpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV1080p) };
//Fakes GivenEpisodes(_fakeEpisodes, new QualityModel(Quality.SDTV));
var fakeSeries = Builder<Series>.CreateNew().Build();
var fakeEpisode = Builder<Episode>.CreateNew() var result = Subject.ImportFile(_fakeSeries, "file.ext");
.Build();
//Mocks
With80MBFile();
Mocker.GetMock<IMediaFileService>()
.Setup(p => p.Exists(It.IsAny<String>()))
.Returns(false);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, fileName); VerifySkipImport(result);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
} }
[Test]
public void should_set_parseResult_SceneSource_if_not_in_series_Path()
{
var series = Builder<Series>
.CreateNew()
.With(s => s.Path == @"C:\Test\TV\30 Rock")
.Build();
const string path = @"C:\Test\Unsorted TV\30 Rock\30.rock.s01e01.pilot.mkv";
With80MBFile();
Mocker.GetMock<IEpisodeService>().Setup(s => s.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>()))
.Returns(new List<Episode>());
Mocker.GetMock<DiskProvider>().Setup(s => s.IsChildOfPath(path, series.Path))
.Returns(false);
Mocker.Resolve<DiskScanProvider>().ImportFile(series, path);
Mocker.Verify<IEpisodeService>(s => s.GetEpisodesByParseResult(It.Is<IndexerParseResult>(p => p.SceneSource)), Times.Once());
}
[Test] [Test]
public void should_not_set_parseResult_SceneSource_if_in_series_Path() public void should_skip_if_file_size_is_under_70MB_and_runTime_under_3_minutes()
{ {
var series = Builder<Series> GivenFileSize(50.Megabytes());
.CreateNew() GivenVideoDuration(TimeSpan.FromMinutes(1));
.With(s => s.Path == @"C:\Test\TV\30 Rock")
.Build();
const string path = @"C:\Test\TV\30 Rock\30.rock.s01e01.pilot.mkv"; GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
With80MBFile(); var result = Subject.ImportFile(_fakeSeries, "file.ext");
Mocker.GetMock<IEpisodeService>().Setup(s => s.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())) VerifySkipImport(result);
.Returns(new List<Episode>());
Mocker.GetMock<DiskProvider>().Setup(s => s.IsChildOfPath(path, series.Path))
.Returns(true);
Mocker.Resolve<DiskScanProvider>().ImportFile(series, path);
Mocker.Verify<IEpisodeService>(s => s.GetEpisodesByParseResult(It.Is<IndexerParseResult>(p => p.SceneSource == false)), Times.Once());
}
[Test]
public void should_return_null_if_file_size_is_under_70MB_and_runTime_under_3_minutes()
{
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi";
Mocker.GetMock<IMediaFileService>()
.Setup(m => m.Exists(path))
.Returns(false);
Mocker.GetMock<DiskProvider>()
.Setup(d => d.GetSize(path))
.Returns(20.Megabytes());
Mocker.GetMock<MediaInfoProvider>()
.Setup(s => s.GetRunTime(path))
.Returns(60);
Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path).Should().BeNull();
} }
[Test] [Test]
public void should_import_if_file_size_is_under_70MB_but_runTime_over_3_minutes() public void should_import_if_file_size_is_under_70MB_but_runTime_over_3_minutes()
{ {
var fakeEpisode = Builder<Episode>.CreateNew() GivenFileSize(50.Megabytes());
.Build(); GivenVideoDuration(TimeSpan.FromMinutes(20));
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi"; GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
Mocker.GetMock<IMediaFileService>() var result = Subject.ImportFile(_fakeSeries, "file.ext");
.Setup(m => m.Exists(path))
.Returns(false);
Mocker.GetMock<DiskProvider>() VerifyFileImport(result);
.Setup(d => d.GetSize(path))
.Returns(20.Megabytes());
Mocker.GetMock<MediaInfoProvider>()
.Setup(s => s.GetRunTime(path))
.Returns(600);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path);
VerifyFileImport(result, Mocker, fakeEpisode, 20.Megabytes());
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never()); Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
} }
[Test] [Test]
public void should_import_if_file_size_is_over_70MB_but_runTime_under_3_minutes() public void should_import_if_file_size_is_over_70MB_but_runTime_under_3_minutes()
{ {
With80MBFile(); GivenFileSize(100.Megabytes());
GivenVideoDuration(TimeSpan.FromMinutes(1));
var fakeEpisode = Builder<Episode>.CreateNew() GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
.Build();
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi"; var result = Subject.ImportFile(_fakeSeries, "file.ext");
Mocker.GetMock<IMediaFileService>() VerifyFileImport(result);
.Setup(m => m.Exists(path))
.Returns(false);
Mocker.GetMock<MediaInfoProvider>()
.Setup(s => s.GetRunTime(path))
.Returns(60);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path);
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
} }
[Test] [Test]
public void should_import_special_even_if_file_size_is_under_70MB_and_runTime_under_3_minutes() public void should_import_special_even_if_file_size_is_under_70MB_and_runTime_under_3_minutes()
{ {
With80MBFile(); GivenFileSize(10.Megabytes());
GivenVideoDuration(TimeSpan.FromMinutes(1));
var fakeEpisode = Builder<Episode>.CreateNew() _fakeEpisode.SeasonNumber = 0;
.Build();
const string path = @"C:\Test\TV\30.rock.s00e01.pre-pilot.avi"; GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
Mocker.GetMock<IMediaFileService>() var result = Subject.ImportFile(_fakeSeries, "file.ext");
.Setup(m => m.Exists(path))
.Returns(false);
Mocker.GetMock<DiskProvider>() VerifyFileImport(result);
.Setup(d => d.GetSize(path))
.Returns(20.Megabytes());
Mocker.GetMock<MediaInfoProvider>()
.Setup(s => s.GetRunTime(path))
.Returns(60);
Mocker.GetMock<IEpisodeService>()
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<IndexerParseResult>())).Returns(new List<Episode> { fakeEpisode });
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path);
VerifyFileImport(result, Mocker, fakeEpisode, 20.Megabytes());
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
} }
[Test] [Test]
public void should_return_null_if_daily_series_with_file_size_is_under_70MB_and_runTime_under_3_minutes() public void should_skip_if_daily_series_with_file_size_is_under_70MB_and_runTime_under_3_minutes()
{ {
WithDailySeries(); GivenFileSize(10.Megabytes());
GivenVideoDuration(TimeSpan.FromMinutes(1));
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi"; _fakeEpisode.SeasonNumber = 0;
_fakeSeries.SeriesType = SeriesTypes.Daily;
Mocker.GetMock<IMediaFileService>() GivenEpisodes(new[] { _fakeEpisode }, new QualityModel(Quality.HDTV1080p));
.Setup(m => m.Exists(path))
.Returns(false);
Mocker.GetMock<DiskProvider>() var result = Subject.ImportFile(_fakeSeries, "file.ext");
.Setup(d => d.GetSize(path))
.Returns(20.Megabytes());
Mocker.GetMock<MediaInfoProvider>() VerifySkipImport(result);
.Setup(s => s.GetRunTime(path))
.Returns(60);
Mocker.Resolve<DiskScanProvider>().ImportFile(_series, path).Should().BeNull();
} }
private static void VerifyFileImport(EpisodeFile result, AutoMoqer Mocker, Episode fakeEpisode, long size) private void VerifyFileImport(EpisodeFile result)
{ {
result.Should().NotBeNull(); result.Should().NotBeNull();
result.SeriesId.Should().Be(fakeEpisode.SeriesId); result.SeriesId.Should().Be(_fakeSeries.Id);
result.Size.Should().Be(size); result.Size.Should().Be(_fileSize);
result.DateAdded.Should().HaveDay(DateTime.Now.Day); result.DateAdded.Should().HaveDay(DateTime.Now.Day);
Mocker.GetMock<IMediaFileService>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Once());
//Get the count of episodes linked Mocker.GetMock<IMediaFileService>().Verify(c => c.Add(result), Times.Once());
var count = Mocker.GetMock<IEpisodeService>().Object.GetEpisodesByParseResult(null).Count;
Mocker.GetMock<IEpisodeService>().Verify(p => p.UpdateEpisode(It.Is<Episode>(e => e.EpisodeFileId == result.Id)), Times.Exactly(count));
} }
private static void VerifySkipImport(EpisodeFile result, AutoMoqer Mocker) private void VerifySkipImport(EpisodeFile result)
{ {
result.Should().BeNull(); result.Should().BeNull();
Mocker.GetMock<IMediaFileService>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Never()); Mocker.GetMock<IMediaFileService>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Never());
Mocker.GetMock<IEpisodeService>().Verify(p => p.UpdateEpisode(It.IsAny<Episode>()), Times.Never());
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
} }
} }
} }

View File

@ -0,0 +1,145 @@
using System;
using System.IO;
using FizzWare.NBuilder;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
{
[TestFixture]
public class DropFolderImportServiceFixture : CoreTest<DropFolderImportService>
{
private EpisodeFile _fakeEpisodeFile;
private string[] _subFolders = new[] { "c:\\root\\foldername" };
private string[] _videoFiles = new[] { "c:\\root\\foldername\\video.ext" };
[SetUp]
public void Setup()
{
_fakeEpisodeFile = Builder<EpisodeFile>.CreateNew().Build();
Mocker.GetMock<DiskScanProvider>().Setup(c => c.GetVideoFiles(It.IsAny<string>(), It.IsAny<bool>()))
.Returns(_videoFiles);
Mocker.GetMock<DiskProvider>().Setup(c => c.GetDirectories(It.IsAny<string>()))
.Returns(_subFolders);
}
private void WithOldWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.Now.AddDays(-5));
}
private void WithRecentFolderWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow);
}
[Test]
public void should_import_file()
{
Subject.ProcessDropFolder("c:\\drop\\");
VerifyImport();
}
[Test]
public void should_skip_if_folder_is_too_fresh()
{
WithRecentFolderWrite();
Subject.ProcessDropFolder("c:\\drop\\");
VerifyNoImport();
}
[Test]
public void should_search_for_series_using_folder_name()
{
WithOldWrite();
Subject.ProcessDropFolder("c:\\drop\\");
Mocker.GetMock<ISeriesService>().Verify(c => c.FindByTitle("foldername"), Times.Once());
}
[Test]
public void should_search_for_series_using_file_name()
{
/*WithOldWrite();
WithValidSeries();
WithImportableFiles();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
Subject.ProcessDownload(droppedFolder);
Mocker.GetMock<DiskScanProvider>()
.Verify(c => c.Scan(_fakeSeries, It.IsAny<string>()));*/
}
[Test]
public void all_imported_files_should_be_moved()
{
Mocker.GetMock<DiskScanProvider>().Setup(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<string>()))
.Returns(_fakeEpisodeFile);
Subject.ProcessDropFolder("c:\\drop\\");
Mocker.GetMock<IMoveEpisodeFiles>().Verify(c => c.MoveEpisodeFile(_fakeEpisodeFile, true), Times.Once());
}
[Test]
public void should_not_attempt_move_if_nothing_is_imported()
{
Mocker.GetMock<DiskScanProvider>().Setup(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<string>()))
.Returns<EpisodeFile>(null);
Subject.ProcessDropFolder("c:\\drop\\");
Mocker.GetMock<IMoveEpisodeFiles>().Verify(c => c.MoveEpisodeFile(It.IsAny<EpisodeFile>(), It.IsAny<bool>()), Times.Never());
}
[Test]
public void should_skip_if_folder_is_in_use_by_another_process()
{
Mocker.GetMock<DiskProvider>().Setup(c => c.IsFileLocked(It.IsAny<FileInfo>()))
.Returns(true);
Subject.ProcessDropFolder("c:\\drop\\");
VerifyNoImport();
}
private void VerifyNoImport()
{
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<string>()),
Times.Never());
}
private void VerifyImport()
{
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<string>()),
Times.Once());
}
}
}

View File

@ -1,44 +0,0 @@

using System.Linq;
using System;
using System.IO;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
{
[TestFixture]
public class GetFolderNameWithStatusFixture : CoreTest
{
[TestCase(@"c:\_NzbDrone_InvalidEpisode_Title", @"c:\_UnknownSeries_Title", PostDownloadStatusType.UnknownSeries)]
[TestCase(@"c:\Title", @"c:\_Failed_Title", PostDownloadStatusType.Failed)]
[TestCase(@"c:\Root\Test Title", @"c:\Root\_ParseError_Test Title", PostDownloadStatusType.ParseError)]
public void GetFolderNameWithStatus_should_return_a_string_with_the_error_removing_existing_error(string currentName, string excpectedName, PostDownloadStatusType status)
{
PostDownloadProvider.GetTaggedFolderName(new DirectoryInfo(currentName), status).Should().Be(
excpectedName);
}
[TestCase(PostDownloadStatusType.NoError)]
[ExpectedException(typeof(InvalidOperationException))]
public void GetFolderNameWithStatus_should_throw_if_status_is_not_an_error(PostDownloadStatusType status)
{
PostDownloadProvider.GetTaggedFolderName(new DirectoryInfo(TempFolder), status);
}
[TestCase("_NzbDrone_ParseError_The Office (US) - S01E01 - Episode Title", "The Office (US) - S01E01 - Episode Title")]
[TestCase("_Status_The Office (US) - S01E01 - Episode Title", "The Office (US) - S01E01 - Episode Title")]
[TestCase("The Office (US) - S01E01 - Episode Title", "The Office (US) - S01E01 - Episode Title")]
[TestCase("_The Office (US) - S01E01 - Episode Title", "_The Office (US) - S01E01 - Episode Title")]
public void RemoveStatus_should_remove_status_string_from_folder_name(string folderName, string cleanFolderName)
{
PostDownloadProvider.RemoveStatusFromFolderName(folderName).Should().Be(cleanFolderName);
}
}
}

View File

@ -1,469 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using Marr.Data;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
{
[TestFixture]
public class ProcessDownloadFixture : CoreTest
{
Series fakeSeries;
[SetUp]
public void Setup()
{
fakeSeries = Builder<Series>.CreateNew()
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
}
private void WithOldWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastDirectoryWrite(It.IsAny<String>()))
.Returns(DateTime.Now.AddDays(-5));
}
private void WithRecentWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastDirectoryWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow);
}
private void WithValidSeries()
{
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle(It.IsAny<string>()))
.Returns(fakeSeries);
Mocker.GetMock<DiskProvider>()
.Setup(c => c.FolderExists(fakeSeries.Path))
.Returns(true);
}
private void WithImportableFiles()
{
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.Scan(It.IsAny<Series>(), It.IsAny<string>()))
.Returns(Builder<EpisodeFile>.CreateListOfSize(1).Build().ToList());
}
private void WithLotsOfFreeDiskSpace()
{
Mocker.GetMock<DiskProvider>().Setup(s => s.FreeDiskSpace(It.IsAny<string>())).Returns(1000000000);
}
private void WithImportedFiles(string droppedFolder)
{
var fakeEpisodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
.All()
.With(f => f.SeriesId = fakeSeries.Id)
.Build().ToList();
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder)).Returns(fakeEpisodeFiles);
}
[Test]
public void should_skip_if_folder_is_tagged_and_too_fresh()
{
WithStrictMocker();
WithRecentWrite();
var droppedFolder = new DirectoryInfo(TempFolder + "\\_test\\");
droppedFolder.Create();
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
}
[Test]
public void should_continue_processing_if_folder_is_tagged_and_not_fresh()
{
WithOldWrite();
var droppedFolder = new DirectoryInfo(TempFolder + "\\_test\\");
droppedFolder.Create();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null).Verifiable();
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.IgnoreWarns();
}
[Test]
public void should_search_for_series_using_title_without_status()
{
WithOldWrite();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\_unpack_The Office - S01E01 - Episode Title");
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns<Series>(null).Verifiable();
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.IgnoreWarns();
}
[Test]
public void should_search_for_series_using_folder_name()
{
WithOldWrite();
WithValidSeries();
WithImportableFiles();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.GetMock<DiskScanProvider>()
.Verify(c=>c.Scan(fakeSeries, It.IsAny<string>()));
}
[Test]
public void should_search_for_series_using_file_name()
{
WithOldWrite();
WithValidSeries();
WithImportableFiles();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.GetMock<DiskScanProvider>()
.Verify(c => c.Scan(fakeSeries, It.IsAny<string>()));
}
[Test]
[Ignore("Disabled tagging")]
public void when_series_isnt_found_folder_should_be_tagged_as_unknown_series()
{
WithStrictMocker();
WithOldWrite();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
var taggedFolder = @"C:\Test\Unsorted TV\_UnknownSeries_The Office - S01E01 - Episode Title";
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns<Series>(null);
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(droppedFolder.FullName, taggedFolder));
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.ExpectedWarns(1);
}
[Test]
[Ignore("Disabled tagging")]
public void when_no_files_are_imported_folder_should_be_tagged_with_parse_error()
{
WithStrictMocker();
WithOldWrite();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - S01E01 - Episode Title");
var taggedFolder = @"C:\Test\Unsorted TV\_ParseError_The Office - S01E01 - Episode Title";
var fakeSeries = Builder<Series>.CreateNew()
.With(s => s.Title = "The Office")
.Build();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(new List<EpisodeFile>());
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(droppedFolder.FullName, taggedFolder));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize + 10.Megabytes());
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.ExpectedWarns(1);
}
[Test]
[Ignore("Disabled tagging")]
public void when_no_file_are_imported_and_folder_size_isnt_small_enought_folder_should_be_tagged_unknown()
{
WithStrictMocker();
WithOldWrite();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - Season 01");
var taggedFolder = PostDownloadProvider.GetTaggedFolderName(droppedFolder, PostDownloadStatusType.Unknown);
var fakeSeries = Builder<Series>.CreateNew()
.With(s => s.Title = "The Office")
.Build();
var fakeEpisodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
.All()
.With(f => f.SeriesId = fakeSeries.Id)
.Build().ToList();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries);
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveDirectory(droppedFolder.FullName, taggedFolder));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize + 10.Megabytes());
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles);
Mocker.GetMock<IMoveEpisodeFiles>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
ExceptionVerification.ExpectedWarns(1);
}
[TestCase(@"\_UnknownSeries_The Office - S01E01 - Episode Title")]
[TestCase(@"\_UnknownSeries_The Office - S01E01 - Episode Title\")]
[TestCase("\\Test\\_UnknownSeries_The Office - S01E01 - Episode Title\\")]
[TestCase("\\Test\\_UnknownSeries_The Office - S01E01 - Episode Title")]
public void folder_shouldnt_be_tagged_with_same_tag_again(string path)
{
var droppedFolder = new DirectoryInfo(TempFolder + path);
droppedFolder.Create();
WithOldWrite();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
Mocker.GetMock<DiskProvider>().Verify(c => c.MoveDirectory(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
}
[Test]
public void folder_should_not_be_tagged_if_existing_tag_is_diffrent()
{
WithOldWrite();
var droppedFolder = new DirectoryInfo(TempFolder + @"\_UnknownEpisode_The Office - S01E01 - Episode Title");
droppedFolder.Create();
droppedFolder.LastWriteTime = DateTime.Now.AddHours(-1);
var taggedFolder = TempFolder + @"\_UnknownSeries_The Office - S01E01 - Episode Title";
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
Mocker.GetMock<DiskProvider>().Verify(c => c.MoveDirectory(droppedFolder.FullName, taggedFolder), Times.Never());
ExceptionVerification.IgnoreWarns();
}
[Test]
public void when_files_are_imported_and_folder_is_small_enough_dir_should_be_deleted()
{
WithStrictMocker();
WithLotsOfFreeDiskSpace();
var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - Season 01");
WithImportedFiles(droppedFolder.FullName);
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.CleanUpDropFolder(droppedFolder.FullName));
Mocker.GetMock<IMoveEpisodeFiles>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize - 1.Megabytes());
Mocker.GetMock<DiskProvider>().Setup(s => s.DeleteFolder(droppedFolder.FullName, true));
Mocker.GetMock<DiskProvider>().Setup(s => s.FolderExists(fakeSeries.Path)).Returns(true);
Mocker.GetMock<DiskProvider>().Setup(s => s.IsFolderLocked(droppedFolder.FullName)).Returns(false);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.VerifyAllMocks();
}
[Test]
public void all_imported_files_should_be_moved()
{
var droppedFolder = new DirectoryInfo(TempFolder);
var fakeSeries = Builder<Series>.CreateNew()
.Build();
var fakeEpisodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
.Build().ToList();
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<string>())).Returns(fakeSeries);
Mocker.GetMock<DiskProvider>().Setup(s => s.FolderExists(fakeSeries.Path)).Returns(true);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(droppedFolder);
Mocker.GetMock<IMoveEpisodeFiles>().Verify(c => c.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true),
Times.Exactly(fakeEpisodeFiles.Count));
Mocker.VerifyAllMocks();
}
[Test]
public void should_logError_and_return_if_size_exceeds_free_space()
{
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
var series = Builder<Series>.CreateNew()
.With(s => s.Title = "30 Rock")
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle("rock"))
.Returns(series);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetDirectorySize(downloadName.FullName))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(series.Path))
.Returns(true);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(series.Path))
.Returns(9);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(series, downloadName.FullName), Times.Never());
ExceptionVerification.ExpectedErrors(1);
}
[Test]
public void should_process_if_free_disk_space_exceeds_size()
{
WithLotsOfFreeDiskSpace();
WithValidSeries();
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
WithImportedFiles(downloadName.FullName);
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle("rock"))
.Returns(fakeSeries);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetDirectorySize(downloadName.FullName))
.Returns(8);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(fakeSeries, downloadName.FullName), Times.Once());
}
[Test]
public void should_process_if_free_disk_space_equals_size()
{
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
WithImportedFiles(downloadName.FullName);
WithValidSeries();
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetDirectorySize(downloadName.FullName))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(It.IsAny<string>()))
.Returns(10);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(fakeSeries, downloadName.FullName), Times.Once());
}
[Test]
public void should_create_series_directory_if_series_path_does_not_exist()
{
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
WithValidSeries();
WithLotsOfFreeDiskSpace();
WithImportedFiles(downloadName.FullName);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(fakeSeries.Path))
.Returns(false);
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle("office")).Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>().Setup(s => s.CleanUpDropFolder(downloadName.FullName));
Mocker.GetMock<IMoveEpisodeFiles>().Setup(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true)).Returns(new EpisodeFile());
Mocker.GetMock<DiskProvider>().Setup(s => s.GetDirectorySize(downloadName.FullName)).Returns(Constants.IgnoreFileSize - 1.Megabytes());
Mocker.GetMock<DiskProvider>().Setup(s => s.DeleteFolder(downloadName.FullName, true));
Mocker.GetMock<DiskProvider>().Setup(s => s.IsFolderLocked(downloadName.FullName)).Returns(false);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskProvider>().Verify(c => c.CreateDirectory(fakeSeries.Path), Times.Once());
ExceptionVerification.ExpectedWarns(1);
}
[Test]
public void should_skip_if_folder_is_in_use_by_another_process()
{
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
WithValidSeries();
Mocker.GetMock<DiskProvider>()
.Setup(s => s.IsFolderLocked(downloadName.FullName))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessDownload(downloadName);
Mocker.GetMock<DiskProvider>().Verify(c => c.GetDirectorySize(It.IsAny<String>()), Times.Never());
}
}
}

View File

@ -1,135 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using Marr.Data;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
{
[TestFixture]
public class ProcessDropDirectoryFixture : CoreTest
{
Series fakeSeries;
[SetUp]
public void Setup()
{
fakeSeries = Builder<Series>.CreateNew()
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
}
private void WithLotsOfFreeDiskSpace()
{
Mocker.GetMock<DiskProvider>().Setup(s => s.FreeDiskSpace(It.IsAny<string>())).Returns(1000000000);
}
[Test]
public void ProcessDropFolder_should_only_process_folders_that_arent_known_series_folders()
{
WithLotsOfFreeDiskSpace();
var subFolders = new[]
{
@"c:\drop\episode1",
@"c:\drop\episode2",
@"c:\drop\episode3",
@"c:\drop\episode4"
};
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.GetVideoFiles(It.IsAny<String>(), false))
.Returns(new List<String>());
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetDirectories(It.IsAny<String>()))
.Returns(subFolders);
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.SeriesPathExists(subFolders[1]))
.Returns(true);
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle(It.IsAny<String>()))
.Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.Scan(It.IsAny<Series>(), It.IsAny<String>()))
.Returns(new List<EpisodeFile>());
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetDirectorySize(It.IsAny<String>()))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(c => c.FolderExists(It.IsAny<String>()))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessDropFolder(@"C:\drop\");
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(It.IsAny<Series>(), subFolders[0]), Times.Once());
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(It.IsAny<Series>(), subFolders[1]), Times.Never());
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(It.IsAny<Series>(), subFolders[2]), Times.Once());
Mocker.GetMock<DiskScanProvider>().Verify(c => c.Scan(It.IsAny<Series>(), subFolders[3]), Times.Once());
}
[Test]
public void ProcessDropFolder_should_process_individual_video_files_in_drop_folder()
{
WithLotsOfFreeDiskSpace();
var files = new List<String>
{
@"c:\drop\30 Rock - episode1.avi",
@"c:\drop\30 Rock - episode2.mkv",
@"c:\drop\30 Rock - episode3.mp4",
@"c:\drop\30 Rock - episode4.wmv"
};
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.GetVideoFiles(It.IsAny<String>(), false))
.Returns(files);
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle(It.IsAny<String>()))
.Returns(fakeSeries);
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.Scan(It.IsAny<Series>(), It.IsAny<String>()))
.Returns(new List<EpisodeFile>());
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetDirectorySize(It.IsAny<String>()))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(c => c.FolderExists(It.IsAny<String>()))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessDropFolder(@"C:\drop\");
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<String>()), Times.Exactly(4));
}
}
}

View File

@ -1,267 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FizzWare.NBuilder;
using Marr.Data;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
{
[TestFixture]
public class ProcessVideoFileFixture : CoreTest
{
Series fakeSeries;
[SetUp]
public void Setup()
{
fakeSeries = Builder<Series>.CreateNew()
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
}
private void WithOldWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastFileWrite(It.IsAny<String>()))
.Returns(DateTime.Now.AddDays(-5));
}
private void WithRecentWrite()
{
Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetLastFileWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow);
}
private void WithValidSeries()
{
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle(It.IsAny<string>()))
.Returns(fakeSeries);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(fakeSeries.Path))
.Returns(true);
}
private void WithImportableFiles()
{
Mocker.GetMock<DiskScanProvider>()
.Setup(c => c.Scan(It.IsAny<Series>(), It.IsAny<string>()))
.Returns(Builder<EpisodeFile>.CreateListOfSize(1).Build().ToList());
}
private void WithLotsOfFreeDiskSpace()
{
Mocker.GetMock<DiskProvider>().Setup(s => s.FreeDiskSpace(It.IsAny<string>())).Returns(1000000000);
}
private void WithImportedFile(string file)
{
var fakeEpisodeFile = Builder<EpisodeFile>.CreateNew()
.With(f => f.SeriesId = fakeSeries.Id)
.Build();
Mocker.GetMock<DiskScanProvider>().Setup(s => s.ImportFile(fakeSeries, file)).Returns(fakeEpisodeFile);
}
[Test]
public void should_skip_if_and_too_fresh()
{
WithStrictMocker();
WithRecentWrite();
var file = Path.Combine(TempFolder, "test.avi");
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
}
[Test]
public void should_continue_processing_if_not_fresh()
{
WithOldWrite();
var file = Path.Combine(TempFolder, "test.avi");
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null).Verifiable();
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
Mocker.GetMock<ISeriesRepository>().Verify(s => s.GetByTitle(It.IsAny<String>()), Times.Once());
ExceptionVerification.IgnoreWarns();
}
[Test]
public void should_return_if_series_is_not_found()
{
WithOldWrite();
var file = Path.Combine(TempFolder, "test.avi");
Mocker.GetMock<ISeriesRepository>().Setup(s => s.GetByTitle(It.IsAny<String>())).Returns<Series>(null);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
Mocker.GetMock<DiskProvider>().Verify(s => s.GetSize(It.IsAny<String>()), Times.Never());
ExceptionVerification.IgnoreWarns();
}
[Test]
public void should_move_file_if_imported()
{
WithLotsOfFreeDiskSpace();
WithOldWrite();
var file = Path.Combine(TempFolder, "test.avi");
WithValidSeries();
WithImportedFile(file);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
Mocker.GetMock<IMoveEpisodeFiles>().Verify(s => s.MoveEpisodeFile(It.IsAny<EpisodeFile>(), true), Times.Once());
ExceptionVerification.IgnoreWarns();
}
[Test]
public void should_logError_and_return_if_size_exceeds_free_space()
{
var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv";
var series = Builder<Series>.CreateNew()
.With(s => s.Title = "30 Rock")
.With(s => s.RootFolder = new LazyLoaded<RootFolder>(new RootFolder { Path = @"C:\Test\TV" }))
.With(s => s.FolderName = "30 Rock")
.Build();
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle("rock"))
.Returns(series);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetSize(downloadName))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(series.Path))
.Returns(9);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(series.Path))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(series, downloadName), Times.Never());
ExceptionVerification.ExpectedErrors(1);
}
[Test]
public void should_process_if_free_disk_space_exceeds_size()
{
WithLotsOfFreeDiskSpace();
WithValidSeries();
var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv";
Mocker.GetMock<ISeriesRepository>()
.Setup(c => c.GetByTitle("rock"))
.Returns(fakeSeries);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetSize(downloadName))
.Returns(8);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(fakeSeries, downloadName), Times.Once());
}
[Test]
public void should_process_if_free_disk_space_equals_size()
{
var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv";
WithValidSeries();
Mocker.GetMock<DiskProvider>()
.Setup(s => s.GetDirectorySize(downloadName))
.Returns(10);
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(It.IsAny<string>()))
.Returns(10);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(fakeSeries, downloadName), Times.Once());
}
[Test]
public void should_return_if_series_Path_doesnt_exist()
{
var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv";
WithValidSeries();
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FolderExists(fakeSeries.Path))
.Returns(false);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
ExceptionVerification.ExpectedWarns(1);
}
[Test]
public void should_skip_if_file_is_in_use_by_another_process()
{
var downloadName = @"C:\Test\Drop\30.Rock.S01E01.Pilot.mkv";
WithValidSeries();
Mocker.GetMock<DiskProvider>()
.Setup(s => s.IsFileLocked(It.Is<FileInfo>(f => f.FullName == downloadName)))
.Returns(true);
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(fakeSeries, downloadName), Times.Never());
}
}
}

View File

@ -18,7 +18,7 @@ public class CleanupFixture : CoreTest
private void WithExpired() private void WithExpired()
{ {
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastDirectoryWrite(It.IsAny<String>())) Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow.AddDays(-10)); .Returns(DateTime.UtcNow.AddDays(-10));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>())) Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>()))
@ -27,7 +27,7 @@ private void WithExpired()
private void WithNonExpired() private void WithNonExpired()
{ {
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastDirectoryWrite(It.IsAny<String>())) Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFolderWrite(It.IsAny<String>()))
.Returns(DateTime.UtcNow.AddDays(-3)); .Returns(DateTime.UtcNow.AddDays(-3));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>())) Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>()))

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
@ -31,7 +30,7 @@ public void should_return_one_drive_when_only_one_root_dir_exists()
.Returns(@"C:\"); .Returns(@"C:\");
Mocker.GetMock<DiskProvider>() Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(@"C:\")) .Setup(s => s.GetAvilableSpace(@"C:\"))
.Returns(123456); .Returns(123456);
var result = Subject.FreeSpaceOnDrives(); var result = Subject.FreeSpaceOnDrives();
@ -52,7 +51,7 @@ public void should_return_one_drive_when_two_rootDirs_on_the_same_drive_exist()
.Returns(@"C:\"); .Returns(@"C:\");
Mocker.GetMock<DiskProvider>() Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(@"C:\")) .Setup(s => s.GetAvilableSpace(@"C:\"))
.Returns(123456); .Returns(123456);
var result = Subject.FreeSpaceOnDrives(); var result = Subject.FreeSpaceOnDrives();
@ -77,7 +76,7 @@ public void should_return_two_drives_when_two_rootDirs_on_the_different_drive_ex
.Returns(@"D:\"); .Returns(@"D:\");
Mocker.GetMock<DiskProvider>() Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(It.IsAny<string>())) .Setup(s => s.GetAvilableSpace(It.IsAny<string>()))
.Returns(123456); .Returns(123456);
var result = Subject.FreeSpaceOnDrives(); var result = Subject.FreeSpaceOnDrives();
@ -97,7 +96,7 @@ public void should_skip_rootDir_if_not_found_on_disk()
.Returns(@"C:\"); .Returns(@"C:\");
Mocker.GetMock<DiskProvider>() Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(It.IsAny<string>())) .Setup(s => s.GetAvilableSpace(It.IsAny<string>()))
.Throws(new DirectoryNotFoundException()); .Throws(new DirectoryNotFoundException());
var result = Subject.FreeSpaceOnDrives(); var result = Subject.FreeSpaceOnDrives();

View File

@ -25,7 +25,10 @@ public void Setup()
[TestCase("1.0.0.0")] [TestCase("1.0.0.0")]
public void should_return_null_if_latest_is_lower_than_current_version(string currentVersion) public void should_return_null_if_latest_is_lower_than_current_version(string currentVersion)
{ {
var updatePackage = Subject.GetAvailableUpdate(new Version(currentVersion));
Mocker.GetMock<EnvironmentProvider>().SetupGet(c => c.Version).Returns(new Version(currentVersion));
var updatePackage = Subject.GetAvailableUpdate();
updatePackage.Should().BeNull(); updatePackage.Should().BeNull();
} }
@ -33,7 +36,9 @@ public void should_return_null_if_latest_is_lower_than_current_version(string cu
[Test] [Test]
public void should_return_null_if_latest_is_equal_to_current_version() public void should_return_null_if_latest_is_equal_to_current_version()
{ {
var updatePackage = Subject.GetAvailableUpdate(LatestTestVersion); Mocker.GetMock<EnvironmentProvider>().SetupGet(c => c.Version).Returns(LatestTestVersion);
var updatePackage = Subject.GetAvailableUpdate();
updatePackage.Should().BeNull(); updatePackage.Should().BeNull();
} }
@ -43,7 +48,9 @@ public void should_return_null_if_latest_is_equal_to_current_version()
[TestCase("0.0.10.10")] [TestCase("0.0.10.10")]
public void should_return_update_if_latest_is_higher_than_current_version(string currentVersion) public void should_return_update_if_latest_is_higher_than_current_version(string currentVersion)
{ {
var updatePackage = Subject.GetAvailableUpdate(new Version(currentVersion)); Mocker.GetMock<EnvironmentProvider>().SetupGet(c => c.Version).Returns(new Version(currentVersion));
var updatePackage = Subject.GetAvailableUpdate();
updatePackage.Should().NotBeNull(); updatePackage.Should().NotBeNull();
updatePackage.Version.Should().Be(LatestTestVersion); updatePackage.Version.Should().Be(LatestTestVersion);

View File

@ -7,21 +7,21 @@
namespace NzbDrone.Core.Test.UpdateTests namespace NzbDrone.Core.Test.UpdateTests
{ {
class GetUpdateLogFixture : CoreTest class GetUpdateLogFixture : CoreTest<UpdateService>
{ {
String UpdateLogFolder; String _updateLogFolder;
[SetUp] [SetUp]
public void setup() public void Setup()
{ {
WithTempAsAppPath(); WithTempAsAppPath();
UpdateLogFolder = Mocker.GetMock<EnvironmentProvider>().Object.GetUpdateLogFolder(); _updateLogFolder = Mocker.GetMock<EnvironmentProvider>().Object.GetUpdateLogFolder();
Mocker.GetMock<DiskProvider>() Mocker.GetMock<DiskProvider>()
.Setup(c => c.GetFiles(UpdateLogFolder, SearchOption.TopDirectoryOnly)) .Setup(c => c.GetFiles(_updateLogFolder, SearchOption.TopDirectoryOnly))
.Returns(new [] .Returns(new[]
{ {
"C:\\nzbdrone\\update\\2011.09.20-19-08.txt", "C:\\nzbdrone\\update\\2011.09.20-19-08.txt",
"C:\\nzbdrone\\update\\2011.10.20-20-08.txt", "C:\\nzbdrone\\update\\2011.10.20-20-08.txt",
@ -29,7 +29,7 @@ public void setup()
}); });
Mocker.GetMock<DiskProvider>() Mocker.GetMock<DiskProvider>()
.Setup(c => c.FolderExists(UpdateLogFolder)) .Setup(c => c.FolderExists(_updateLogFolder))
.Returns(true); .Returns(true);
} }
@ -38,18 +38,17 @@ public void setup()
public void get_logs_should_return_empty_list_if_directory_doesnt_exist() public void get_logs_should_return_empty_list_if_directory_doesnt_exist()
{ {
Mocker.GetMock<DiskProvider>() Mocker.GetMock<DiskProvider>()
.Setup(c => c.FolderExists(UpdateLogFolder)) .Setup(c => c.FolderExists(_updateLogFolder))
.Returns(false); .Returns(false);
var logs = Mocker.Resolve<UpdateService>().UpdateLogFile(); Subject.GetUpdateLogFiles().Should().BeEmpty();
logs.Should().BeEmpty();
} }
[Test] [Test]
public void get_logs_should_return_list_of_files_in_log_folder() public void get_logs_should_return_list_of_files_in_log_folder()
{ {
var logs = Mocker.Resolve<UpdateService>().UpdateLogFile(); var logs = Subject.GetUpdateLogFiles();
logs.Should().HaveCount(3); logs.Should().HaveCount(3);
} }

View File

@ -0,0 +1,15 @@
using System;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Update;
namespace NzbDrone.Core.Test.UpdateTests
{
public class UpdatePackageProviderFixture : CoreTest<UpdatePackageProvider>
{
}
}

View File

@ -1,12 +1,14 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine namespace NzbDrone.Core.DecisionEngine
{ {
public class DownloadDecision public class DownloadDecision
{ {
public IndexerParseResult ParseResult { get; private set; } public RemoteEpisode Episode { get; private set; }
public IEnumerable<string> Rejections { get; private set; } public IEnumerable<string> Rejections { get; private set; }
public bool Approved public bool Approved
@ -17,23 +19,10 @@ public bool Approved
} }
} }
public DownloadDecision(IndexerParseResult parseResult, params string[] rejections) public DownloadDecision(RemoteEpisode episode, params string[] rejections)
{ {
ParseResult = parseResult; Episode = episode;
Rejections = rejections.ToList(); Rejections = rejections.ToList();
} }
public static IndexerParseResult PickBestReport(IEnumerable<DownloadDecision> downloadDecisions)
{
var reports = downloadDecisions
.Where(c => c.Approved)
.Select(c => c.ParseResult)
.OrderByDescending(c => c.Quality)
.ThenBy(c => c.EpisodeNumbers.MinOrDefault())
.ThenBy(c => c.Age);
return reports.SingleOrDefault();
}
} }
} }

View File

@ -2,62 +2,64 @@
using System.Linq; using System.Linq;
using NzbDrone.Core.DecisionEngine.Specifications.Search; using NzbDrone.Core.DecisionEngine.Specifications.Search;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model; using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine namespace NzbDrone.Core.DecisionEngine
{ {
public interface IMakeDownloadDecision public interface IMakeDownloadDecision
{ {
IEnumerable<DownloadDecision> GetRssDecision(IEnumerable<IndexerParseResult> episodeParseResults); IEnumerable<DownloadDecision> GetRssDecision(IEnumerable<ReportInfo> reports);
IEnumerable<DownloadDecision> GetSearchDecision(IEnumerable<IndexerParseResult> episodeParseResult, SearchDefinitionBase searchDefinitionBase); IEnumerable<DownloadDecision> GetSearchDecision(IEnumerable<ReportInfo> reports, SearchDefinitionBase searchDefinitionBase);
} }
public class DownloadDecisionMaker : IMakeDownloadDecision public class DownloadDecisionMaker : IMakeDownloadDecision
{ {
private readonly IEnumerable<IRejectWithReason> _specifications; private readonly IEnumerable<IRejectWithReason> _specifications;
private readonly IParsingService _parsingService;
public DownloadDecisionMaker(IEnumerable<IRejectWithReason> specifications) public DownloadDecisionMaker(IEnumerable<IRejectWithReason> specifications, IParsingService parsingService)
{ {
_specifications = specifications; _specifications = specifications;
_parsingService = parsingService;
} }
public IEnumerable<DownloadDecision> GetRssDecision(IEnumerable<IndexerParseResult> episodeParseResults) public IEnumerable<DownloadDecision> GetRssDecision(IEnumerable<ReportInfo> reports)
{ {
foreach (var parseResult in episodeParseResults) foreach (var report in reports)
{ {
parseResult.Decision = new DownloadDecision(parseResult, GetGeneralRejectionReasons(parseResult).ToArray()); var parseResult = _parsingService.Map(report);
yield return parseResult.Decision; yield return new DownloadDecision(parseResult, GetGeneralRejectionReasons(parseResult).ToArray());
} }
} }
public IEnumerable<DownloadDecision> GetSearchDecision(IEnumerable<IndexerParseResult> episodeParseResults, SearchDefinitionBase searchDefinitionBase) public IEnumerable<DownloadDecision> GetSearchDecision(IEnumerable<ReportInfo> reports, SearchDefinitionBase searchDefinitionBase)
{ {
foreach (var parseResult in episodeParseResults) foreach (var report in reports)
{ {
var parseResult = _parsingService.Map(report);
var generalReasons = GetGeneralRejectionReasons(parseResult); var generalReasons = GetGeneralRejectionReasons(parseResult);
var searchReasons = GetSearchRejectionReasons(parseResult, searchDefinitionBase); var searchReasons = GetSearchRejectionReasons(parseResult, searchDefinitionBase);
parseResult.Decision = new DownloadDecision(parseResult, generalReasons.Union(searchReasons).ToArray()); yield return new DownloadDecision(parseResult, generalReasons.Union(searchReasons).ToArray());
yield return parseResult.Decision;
} }
} }
private IEnumerable<string> GetGeneralRejectionReasons(IndexerParseResult indexerParseResult) private IEnumerable<string> GetGeneralRejectionReasons(RemoteEpisode report)
{ {
return _specifications return _specifications
.OfType<IDecisionEngineSpecification>() .OfType<IDecisionEngineSpecification>()
.Where(spec => !spec.IsSatisfiedBy(indexerParseResult)) .Where(spec => !spec.IsSatisfiedBy(report))
.Select(spec => spec.RejectionReason); .Select(spec => spec.RejectionReason);
} }
private IEnumerable<string> GetSearchRejectionReasons(IndexerParseResult indexerParseResult, SearchDefinitionBase searchDefinitionBase) private IEnumerable<string> GetSearchRejectionReasons(RemoteEpisode report, SearchDefinitionBase searchDefinitionBase)
{ {
return _specifications return _specifications
.OfType<IDecisionEngineSearchSpecification>() .OfType<IDecisionEngineSearchSpecification>()
.Where(spec => !spec.IsSatisfiedBy(indexerParseResult, searchDefinitionBase)) .Where(spec => !spec.IsSatisfiedBy(report, searchDefinitionBase))
.Select(spec => spec.RejectionReason); .Select(spec => spec.RejectionReason);
} }
} }

View File

@ -1,9 +1,11 @@
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine namespace NzbDrone.Core.DecisionEngine
{ {
public interface IDecisionEngineSpecification : IRejectWithReason public interface IDecisionEngineSpecification : IRejectWithReason
{ {
bool IsSatisfiedBy(IndexerParseResult subject); bool IsSatisfiedBy(RemoteEpisode subject);
} }
} }

View File

@ -1,5 +1,8 @@
using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
@ -23,7 +26,7 @@ public string RejectionReason
get { return "File size too big or small"; } get { return "File size too big or small"; }
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
_logger.Trace("Beginning size check for: {0}", subject); _logger.Trace("Beginning size check for: {0}", subject);
@ -47,24 +50,19 @@ public virtual bool IsSatisfiedBy(IndexerParseResult subject)
//Multiply maxSize by Series.Runtime //Multiply maxSize by Series.Runtime
maxSize = maxSize * series.Runtime; maxSize = maxSize * series.Runtime;
//Multiply maxSize by the number of episodes parsed (if EpisodeNumbers is null it will be treated as a single episode) maxSize = maxSize * subject.Episodes.Count;
//TODO: is this check really necessary? shouldn't we blowup?
if (subject.EpisodeNumbers != null)
maxSize = maxSize * subject.EpisodeNumbers.Count;
//Check if there was only one episode parsed //Check if there was only one episode parsed
//and it is the first or last episode of the season //and it is the first or last episode of the season
if (subject.EpisodeNumbers != null && subject.EpisodeNumbers.Count == 1 && if (subject.Episodes.Count == 1 && _episodeService.IsFirstOrLastEpisodeOfSeason(subject.Episodes.Single().Id))
_episodeService.IsFirstOrLastEpisodeOfSeason(series.Id,
subject.SeasonNumber, subject.EpisodeNumbers[0]))
{ {
maxSize = maxSize * 2; maxSize = maxSize * 2;
} }
//If the parsed size is greater than maxSize we don't want it //If the parsed size is greater than maxSize we don't want it
if (subject.Size > maxSize) if (subject.Report.Size > maxSize)
{ {
_logger.Trace("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Size, maxSize); _logger.Trace("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Report.Size, maxSize);
return false; return false;
} }

View File

@ -2,6 +2,8 @@
using NLog; using NLog;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications namespace NzbDrone.Core.DecisionEngine.Specifications
{ {
@ -25,7 +27,7 @@ public string RejectionReason
} }
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
_logger.Trace("Beginning release group check for: {0}", subject); _logger.Trace("Beginning release group check for: {0}", subject);
@ -37,16 +39,18 @@ public virtual bool IsSatisfiedBy(IndexerParseResult subject)
if (string.IsNullOrWhiteSpace(allowed)) if (string.IsNullOrWhiteSpace(allowed))
return true; return true;
var releaseGroup = subject.Report.ReleaseGroup;
foreach (var group in allowed.Trim(',', ' ').Split(',')) foreach (var group in allowed.Trim(',', ' ').Split(','))
{ {
if (subject.ReleaseGroup.Equals(group.Trim(' '), StringComparison.CurrentCultureIgnoreCase)) if (releaseGroup.Equals(group.Trim(' '), StringComparison.CurrentCultureIgnoreCase))
{ {
_logger.Trace("Item: {0}'s release group is wanted: {1}", subject, subject.ReleaseGroup); _logger.Trace("Item: {0}'s release group is wanted: {1}", subject, releaseGroup);
return true; return true;
} }
} }
_logger.Trace("Item: {0}'s release group is not wanted: {1}", subject, subject.ReleaseGroup); _logger.Trace("Item: {0}'s release group is not wanted: {1}", subject, releaseGroup);
return false; return false;
} }
} }

View File

@ -1,6 +1,8 @@
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications namespace NzbDrone.Core.DecisionEngine.Specifications
{ {
@ -22,7 +24,7 @@ public string RejectionReason
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
if (!subject.Series.CustomStartDate.HasValue) if (!subject.Series.CustomStartDate.HasValue)
{ {

View File

@ -1,5 +1,7 @@
using NLog; using NLog;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications namespace NzbDrone.Core.DecisionEngine.Specifications
{ {
@ -20,10 +22,10 @@ public string RejectionReason
} }
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
_logger.Trace("Checking if report meets language requirements. {0}", subject.Language); _logger.Trace("Checking if report meets language requirements. {0}", subject.Language);
if (subject.Language != LanguageType.English) if (subject.Language != Language.English)
{ {
_logger.Trace("Report Language: {0} rejected because it is not English", subject.Language); _logger.Trace("Report Language: {0} rejected because it is not English", subject.Language);
return false; return false;

View File

@ -1,6 +1,8 @@
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
namespace NzbDrone.Core.DecisionEngine.Specifications namespace NzbDrone.Core.DecisionEngine.Specifications
@ -26,29 +28,16 @@ public string RejectionReason
} }
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
var series = _seriesRepository.GetByTitle(subject.CleanTitle); if (!subject.Series.Monitored)
if (series == null)
{ {
_logger.Trace("{0} is not mapped to any series in DB. skipping", subject.CleanTitle); _logger.Debug("{0} is present in the DB but not tracked. skipping.", subject.Series.Title);
return false; return false;
} }
subject.Series = series;
if (!series.Monitored)
{
_logger.Debug("{0} is present in the DB but not tracked. skipping.", subject.CleanTitle);
return false;
}
var episodes = _episodeService.GetEpisodesByParseResult(subject);
subject.Episodes = episodes;
//return monitored if any of the episodes are monitored //return monitored if any of the episodes are monitored
if (episodes.Any(episode => !episode.Ignored)) if (subject.Episodes.Any(episode => !episode.Ignored))
{ {
return true; return true;
} }

View File

@ -1,6 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Download; using NzbDrone.Core.Download;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.DecisionEngine.Specifications namespace NzbDrone.Core.DecisionEngine.Specifications
{ {
@ -21,9 +27,34 @@ public string RejectionReason
} }
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
return !_downloadClientProvider.GetDownloadClient().IsInQueue(subject); var downloadClient = _downloadClientProvider.GetDownloadClient();
var queue = downloadClient.GetQueue().Select(q => Parser.Parser.ParseTitle(q.Title));
return !IsInQueue(subject, queue);
}
public virtual bool IsInQueue(RemoteEpisode newEpisode, IEnumerable<ParsedEpisodeInfo> queue)
{
var matchingTitle = queue.Where(q => String.Equals(q.SeriesTitle, newEpisode.Series.CleanTitle, StringComparison.InvariantCultureIgnoreCase));
var matchingTitleWithQuality = matchingTitle.Where(q => q.Quality >= newEpisode.Quality);
if (newEpisode.Series.SeriesType == SeriesTypes.Daily)
{
return matchingTitleWithQuality.Any(q => q.AirDate.Value.Date == newEpisode.AirDate.Value.Date);
}
var matchingSeason = matchingTitleWithQuality.Where(q => q.SeasonNumber == newEpisode.SeasonNumber);
if (newEpisode.FullSeason)
{
return matchingSeason.Any();
}
return matchingSeason.Any(q => q.EpisodeNumbers != null && q.EpisodeNumbers.Any(e => newEpisode.EpisodeNumbers.Contains(e)));
} }
} }

View File

@ -1,5 +1,7 @@
using NLog; using NLog;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications namespace NzbDrone.Core.DecisionEngine.Specifications
{ {
@ -20,7 +22,7 @@ public string RejectionReason
} }
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
_logger.Trace("Checking if report meets quality requirements. {0}", subject.Quality); _logger.Trace("Checking if report meets quality requirements. {0}", subject.Quality);
if (!subject.Series.QualityProfile.Allowed.Contains(subject.Quality.Quality)) if (!subject.Series.QualityProfile.Allowed.Contains(subject.Quality.Quality))

View File

@ -1,6 +1,8 @@
using NLog; using NLog;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications namespace NzbDrone.Core.DecisionEngine.Specifications
{ {
@ -24,12 +26,14 @@ public string RejectionReason
} }
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
_logger.Trace("Checking if report meets retention requirements. {0}", subject.Age); var age = subject.Report.Age;
if (_configService.Retention > 0 && subject.Age > _configService.Retention)
_logger.Trace("Checking if report meets retention requirements. {0}", age);
if (_configService.Retention > 0 && age > _configService.Retention)
{ {
_logger.Trace("Report age: {0} rejected by user's retention limit", subject.Age); _logger.Trace("Report age: {0} rejected by user's retention limit", age);
return false; return false;
} }

View File

@ -1,6 +1,8 @@
using NLog; using NLog;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
namespace NzbDrone.Core.DecisionEngine.Specifications.Search namespace NzbDrone.Core.DecisionEngine.Specifications.Search
@ -23,7 +25,7 @@ public string RejectionReason
return "Episode doesn't match"; return "Episode doesn't match";
} }
} }
public bool IsSatisfiedBy(IndexerParseResult indexerParseResult, SearchDefinitionBase searchDefinitionBase) public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchDefinitionBase searchDefinitionBase)
{ {
var dailySearchSpec = searchDefinitionBase as DailyEpisodeSearchDefinition; var dailySearchSpec = searchDefinitionBase as DailyEpisodeSearchDefinition;
@ -31,7 +33,7 @@ public bool IsSatisfiedBy(IndexerParseResult indexerParseResult, SearchDefinitio
var episode = _episodeService.GetEpisode(dailySearchSpec.SeriesId, dailySearchSpec.Airtime); var episode = _episodeService.GetEpisode(dailySearchSpec.SeriesId, dailySearchSpec.Airtime);
if (!indexerParseResult.AirDate.HasValue || indexerParseResult.AirDate.Value != episode.AirDate.Value) if (!remoteEpisode.AirDate.HasValue || remoteEpisode.AirDate.Value != episode.AirDate.Value)
{ {
_logger.Trace("Episode AirDate does not match searched episode number, skipping."); _logger.Trace("Episode AirDate does not match searched episode number, skipping.");
return false; return false;

View File

@ -1,11 +1,13 @@
using NzbDrone.Core.IndexerSearch; using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications.Search namespace NzbDrone.Core.DecisionEngine.Specifications.Search
{ {
public interface IDecisionEngineSearchSpecification : IRejectWithReason public interface IDecisionEngineSearchSpecification : IRejectWithReason
{ {
bool IsSatisfiedBy(IndexerParseResult indexerParseResult, SearchDefinitionBase searchDefinitionBase); bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchDefinitionBase searchDefinitionBase);
} }
} }

View File

@ -1,6 +1,8 @@
using NLog; using NLog;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications.Search namespace NzbDrone.Core.DecisionEngine.Specifications.Search
{ {
@ -21,12 +23,12 @@ public string RejectionReason
} }
} }
public bool IsSatisfiedBy(IndexerParseResult indexerParseResult, SearchDefinitionBase searchDefinitionBase) public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchDefinitionBase searchDefinitionBase)
{ {
var singleEpisodeSpec = searchDefinitionBase as SeasonSearchDefinition; var singleEpisodeSpec = searchDefinitionBase as SeasonSearchDefinition;
if (singleEpisodeSpec == null) return true; if (singleEpisodeSpec == null) return true;
if (singleEpisodeSpec.SeasonNumber != indexerParseResult.SeasonNumber) if (singleEpisodeSpec.SeasonNumber != remoteEpisode.SeasonNumber)
{ {
_logger.Trace("Season number does not match searched season number, skipping."); _logger.Trace("Season number does not match searched season number, skipping.");
return false; return false;

View File

@ -1,14 +1,17 @@
using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications.Search namespace NzbDrone.Core.DecisionEngine.Specifications.Search
{ {
public class SingleEpisodeMatchSpecification : IDecisionEngineSearchSpecification public class SingleEpisodeSearchMatchSpecification : IDecisionEngineSearchSpecification
{ {
private readonly Logger _logger; private readonly Logger _logger;
public SingleEpisodeMatchSpecification(Logger logger) public SingleEpisodeSearchMatchSpecification(Logger logger)
{ {
_logger = logger; _logger = logger;
} }
@ -21,18 +24,18 @@ public string RejectionReason
} }
} }
public bool IsSatisfiedBy(IndexerParseResult indexerParseResult, SearchDefinitionBase searchDefinitionBase) public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchDefinitionBase searchDefinitionBase)
{ {
var singleEpisodeSpec = searchDefinitionBase as SingleEpisodeSearchDefinition; var singleEpisodeSpec = searchDefinitionBase as SingleEpisodeSearchDefinition;
if (singleEpisodeSpec == null) return true; if (singleEpisodeSpec == null) return true;
if (singleEpisodeSpec.SeasonNumber != indexerParseResult.SeasonNumber) if (singleEpisodeSpec.SeasonNumber != remoteEpisode.SeasonNumber)
{ {
_logger.Trace("Season number does not match searched season number, skipping."); _logger.Trace("Season number does not match searched season number, skipping.");
return false; return false;
} }
if (!indexerParseResult.EpisodeNumbers.Contains(singleEpisodeSpec.EpisodeNumber)) if (!remoteEpisode.Episodes.Select(c => c.EpisodeNumber).Contains(singleEpisodeSpec.EpisodeNumber))
{ {
_logger.Trace("Episode number does not match searched episode number, skipping."); _logger.Trace("Episode number does not match searched episode number, skipping.");
return false; return false;

View File

@ -1,8 +1,7 @@
using System; using System;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.DecisionEngine.Specifications namespace NzbDrone.Core.DecisionEngine.Specifications
{ {
@ -25,13 +24,16 @@ public string RejectionReason
} }
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
foreach (var file in subject.Episodes.Select(c => c.EpisodeFile).Where(c => c != null)) foreach (var file in subject.Episodes.Select(c => c.EpisodeFile).Where(c => c != null))
{ {
_logger.Trace("Comparing file quality with report. Existing file is {0}", file.Quality); _logger.Trace("Comparing file quality with report. Existing file is {0}", file.Quality);
if (!_qualityUpgradableSpecification.IsUpgradable(subject.Series.QualityProfile, file.Quality, subject.Quality)) if (!_qualityUpgradableSpecification.IsUpgradable(subject.Series.QualityProfile, file.Quality, subject.Quality))
{
return false; return false;
}
if (subject.Quality.Proper && file.DateAdded < DateTime.Today.AddDays(-7)) if (subject.Quality.Proper && file.DateAdded < DateTime.Today.AddDays(-7))
{ {

View File

@ -1,6 +1,6 @@
using NLog; using NLog;
using NzbDrone.Core.History; using NzbDrone.Core.History;
using NzbDrone.Core.Model; using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications namespace NzbDrone.Core.DecisionEngine.Specifications
{ {
@ -25,7 +25,7 @@ public string RejectionReason
} }
} }
public virtual bool IsSatisfiedBy(IndexerParseResult subject) public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{ {
foreach (var episode in subject.Episodes) foreach (var episode in subject.Episodes)
{ {

View File

@ -1,11 +1,13 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Organizer; using NzbDrone.Core.Organizer;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download.Clients namespace NzbDrone.Core.Download.Clients
{ {
@ -14,24 +16,25 @@ public class BlackholeProvider : IDownloadClient
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly IHttpProvider _httpProvider; private readonly IHttpProvider _httpProvider;
private readonly DiskProvider _diskProvider; private readonly DiskProvider _diskProvider;
private readonly UpgradeHistorySpecification _upgradeHistorySpecification; private readonly Logger _logger;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public BlackholeProvider(IConfigService configService, IHttpProvider httpProvider, public BlackholeProvider(IConfigService configService, IHttpProvider httpProvider,
DiskProvider diskProvider, UpgradeHistorySpecification upgradeHistorySpecification) DiskProvider diskProvider, Logger logger)
{ {
_configService = configService; _configService = configService;
_httpProvider = httpProvider; _httpProvider = httpProvider;
_diskProvider = diskProvider; _diskProvider = diskProvider;
_upgradeHistorySpecification = upgradeHistorySpecification; _logger = logger;
} }
public BlackholeProvider()
public bool IsInQueue(RemoteEpisode newEpisode)
{ {
throw new NotImplementedException();
} }
public virtual bool DownloadNzb(string url, string title, bool recentlyAired) public bool DownloadNzb(string url, string title, bool recentlyAired)
{ {
try try
{ {
@ -42,26 +45,26 @@ public virtual bool DownloadNzb(string url, string title, bool recentlyAired)
if (_diskProvider.FileExists(filename)) if (_diskProvider.FileExists(filename))
{ {
//Return true so a lesser quality is not returned. //Return true so a lesser quality is not returned.
logger.Info("NZB already exists on disk: {0}", filename); _logger.Info("NZB already exists on disk: {0}", filename);
return true; return true;
} }
logger.Trace("Downloading NZB from: {0} to: {1}", url, filename); _logger.Trace("Downloading NZB from: {0} to: {1}", url, filename);
_httpProvider.DownloadFile(url, filename); _httpProvider.DownloadFile(url, filename);
logger.Trace("NZB Download succeeded, saved to: {0}", filename); _logger.Trace("NZB Download succeeded, saved to: {0}", filename);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.WarnException("Failed to download NZB: " + url, ex); _logger.WarnException("Failed to download NZB: " + url, ex);
return false; return false;
} }
} }
public virtual bool IsInQueue(IndexerParseResult newParseResult) public IEnumerable<QueueItem> GetQueue()
{ {
return !_upgradeHistorySpecification.IsSatisfiedBy(newParseResult); return new QueueItem[0];
} }
} }
} }

View File

@ -1,16 +1,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace NzbDrone.Core.Download.Clients.Nzbget namespace NzbDrone.Core.Download.Clients.Nzbget
{ {
public class Queue public class NzbGetQueue
{ {
public String Version { get; set; } public String Version { get; set; }
[JsonProperty(PropertyName = "result")] [JsonProperty(PropertyName = "result")]
public List<QueueItem> QueueItems { get; set; } public List<NzbGetQueueItem> QueueItems { get; set; }
} }
} }

View File

@ -0,0 +1,18 @@
using System;
using NzbDrone.Core.Model;
namespace NzbDrone.Core.Download.Clients.Nzbget
{
public class NzbGetQueueItem
{
private string _nzbName;
public Int32 NzbId { get; set; }
public string NzbName { get; set; }
public String Category { get; set; }
public Int32 FileSizeMb { get; set; }
public Int32 RemainingSizeMb { get; set; }
}
}

View File

@ -1,66 +1,26 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using Newtonsoft.Json; using Newtonsoft.Json;
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Download.Clients.Nzbget namespace NzbDrone.Core.Download.Clients.Nzbget
{ {
public class NzbgetProvider : IDownloadClient public class NzbgetClient : IDownloadClient
{ {
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly IHttpProvider _httpProvider; private readonly IHttpProvider _httpProvider;
private readonly Logger _logger; private readonly Logger _logger;
public NzbgetProvider(IConfigService configService, IHttpProvider httpProvider, Logger logger) public NzbgetClient(IConfigService configService, IHttpProvider httpProvider, Logger logger)
{ {
_configService = configService; _configService = configService;
_httpProvider = httpProvider; _httpProvider = httpProvider;
_logger = logger; _logger = logger;
} }
public NzbgetProvider()
{
}
public virtual bool IsInQueue(IndexerParseResult newParseResult)
{
try
{
var queue = GetQueue().Where(c => c.ParseResult != null);
var matchigTitle = queue.Where(q => String.Equals(q.ParseResult.CleanTitle, newParseResult.Series.CleanTitle, StringComparison.InvariantCultureIgnoreCase));
var matchingTitleWithQuality = matchigTitle.Where(q => q.ParseResult.Quality >= newParseResult.Quality);
if (newParseResult.Series.SeriesType == SeriesTypes.Daily)
{
return matchingTitleWithQuality.Any(q => q.ParseResult.AirDate.Value.Date == newParseResult.AirDate.Value.Date);
}
var matchingSeason = matchingTitleWithQuality.Where(q => q.ParseResult.SeasonNumber == newParseResult.SeasonNumber);
if (newParseResult.FullSeason)
{
return matchingSeason.Any();
}
return matchingSeason.Any(q => q.ParseResult.EpisodeNumbers != null && q.ParseResult.EpisodeNumbers.Any(e => newParseResult.EpisodeNumbers.Contains(e)));
}
catch (Exception ex)
{
_logger.WarnException("Unable to connect to Nzbget to check queue.", ex);
return false;
}
}
public virtual bool DownloadNzb(string url, string title, bool recentlyAired) public virtual bool DownloadNzb(string url, string title, bool recentlyAired)
{ {
try try
@ -71,7 +31,7 @@ public virtual bool DownloadNzb(string url, string title, bool recentlyAired)
var command = new JsonRequest var command = new JsonRequest
{ {
Method = "appendurl", Method = "appendurl",
Params = new object[]{ title, cat, priority, false, url } Params = new object[] { title, cat, priority, false, url }
}; };
_logger.Info("Adding report [{0}] to the queue.", title); _logger.Info("Adding report [{0}] to the queue.", title);
@ -93,19 +53,30 @@ public virtual bool DownloadNzb(string url, string title, bool recentlyAired)
return false; return false;
} }
public virtual List<QueueItem> GetQueue() public virtual IEnumerable<QueueItem> GetQueue()
{ {
var command = new JsonRequest var command = new JsonRequest
{ {
Method = "listgroups", Method = "listgroups",
Params = null Params = null
}; };
var response = PostCommand(JsonConvert.SerializeObject(command)); var response = PostCommand(JsonConvert.SerializeObject(command));
CheckForError(response); CheckForError(response);
return JsonConvert.DeserializeObject<Queue>(response).QueueItems; var itmes = JsonConvert.DeserializeObject<NzbGetQueue>(response).QueueItems;
foreach (var nzbGetQueueItem in itmes)
{
var queueItem = new QueueItem();
queueItem.Id = nzbGetQueueItem.NzbId.ToString();
queueItem.Title = nzbGetQueueItem.NzbName;
queueItem.Size = nzbGetQueueItem.FileSizeMb;
queueItem.SizeLeft = nzbGetQueueItem.RemainingSizeMb;
yield return queueItem;
}
} }
public virtual VersionModel GetVersion(string host = null, int port = 0, string username = null, string password = null) public virtual VersionModel GetVersion(string host = null, int port = 0, string username = null, string password = null)
@ -144,7 +115,7 @@ public virtual string Test(string host, int port, string username, string passwo
var version = GetVersion(host, port, username, password); var version = GetVersion(host, port, username, password);
return version.Result; return version.Result;
} }
catch(Exception ex) catch (Exception ex)
{ {
_logger.DebugException("Failed to Test Nzbget", ex); _logger.DebugException("Failed to Test Nzbget", ex);
} }

View File

@ -1,31 +0,0 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using NzbDrone.Core.Model;
namespace NzbDrone.Core.Download.Clients.Nzbget
{
public class QueueItem
{
private string _title;
public Int32 NzbId { get; set; }
[JsonProperty(PropertyName = "NzbName")]
public string Title
{
get { return _title; }
set
{
_title = value;
ParseResult = Parser.ParseTitle<ParseResult>(value.Replace("DUPLICATE / ", String.Empty));
}
}
public String Category { get; set; }
public Int32 FileSizeMb { get; set; }
public Int32 RemainingSizeMb { get; set; }
public ParseResult ParseResult { private set; get; }
}
}

View File

@ -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;
@ -9,10 +10,12 @@
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Organizer; using NzbDrone.Core.Organizer;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download.Clients namespace NzbDrone.Core.Download.Clients
{ {
public class PneumaticProvider : IDownloadClient public class PneumaticClient : IDownloadClient
{ {
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly IHttpProvider _httpProvider; private readonly IHttpProvider _httpProvider;
@ -20,7 +23,7 @@ public class PneumaticProvider : IDownloadClient
private static readonly Logger logger = LogManager.GetCurrentClassLogger(); private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public PneumaticProvider(IConfigService configService, IHttpProvider httpProvider, public PneumaticClient(IConfigService configService, IHttpProvider httpProvider,
DiskProvider diskProvider) DiskProvider diskProvider)
{ {
_configService = configService; _configService = configService;
@ -33,7 +36,7 @@ public virtual bool DownloadNzb(string url, string title, bool recentlyAired)
try try
{ {
//Todo: Allow full season releases //Todo: Allow full season releases
if (Parser.ParseTitle<ParseResult>(title).FullSeason) if (Parser.Parser.ParseTitle(title).FullSeason)
{ {
logger.Info("Skipping Full Season Release: {0}", title); logger.Info("Skipping Full Season Release: {0}", title);
return false; return false;
@ -68,7 +71,12 @@ public virtual bool DownloadNzb(string url, string title, bool recentlyAired)
} }
} }
public virtual bool IsInQueue(IndexerParseResult newParseResult) public IEnumerable<QueueItem> GetQueue()
{
return new QueueItem[0];
}
public virtual bool IsInQueue(RemoteEpisode newEpisode)
{ {
return false; return false;
} }

View File

@ -1,4 +1,4 @@
namespace NzbDrone.Core.Download.Clients namespace NzbDrone.Core.Download.Clients.Sabnzbd
{ {
public class ConnectionInfoModel public class ConnectionInfoModel
{ {

View File

@ -19,15 +19,7 @@ public class SabQueueItem
private string _title; private string _title;
[JsonProperty(PropertyName = "filename")] [JsonProperty(PropertyName = "filename")]
public string Title public string Title { get; set; }
{
get { return _title; }
set
{
_title = value;
ParseResult = Parser.ParseTitle<ParseResult>(value.Replace("DUPLICATE / ", String.Empty));
}
}
[JsonConverter(typeof(SabnzbdPriorityTypeConverter))] [JsonConverter(typeof(SabnzbdPriorityTypeConverter))]
public SabPriorityType Priority { get; set; } public SabPriorityType Priority { get; set; }
@ -42,7 +34,5 @@ public string Title
[JsonProperty(PropertyName = "nzo_id")] [JsonProperty(PropertyName = "nzo_id")]
public string Id { get; set; } public string Id { get; set; }
public ParseResult ParseResult { private set; get; }
} }
} }

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Web; using System.Web;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -8,61 +7,21 @@
using NLog; using NLog;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Model;
using NzbDrone.Core.Tv;
using RestSharp.Contrib;
using HttpUtility = System.Web.HttpUtility;
namespace NzbDrone.Core.Download.Clients.Sabnzbd namespace NzbDrone.Core.Download.Clients.Sabnzbd
{ {
public class SabProvider : IDownloadClient public class SabnzbdClient : IDownloadClient
{ {
private static readonly Logger logger = LogManager.GetCurrentClassLogger(); private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly IHttpProvider _httpProvider; private readonly IHttpProvider _httpProvider;
public SabProvider(IConfigService configService, IHttpProvider httpProvider) public SabnzbdClient(IConfigService configService, IHttpProvider httpProvider)
{ {
_configService = configService; _configService = configService;
_httpProvider = httpProvider; _httpProvider = httpProvider;
} }
public SabProvider()
{
}
public virtual bool IsInQueue(IndexerParseResult newParseResult)
{
try
{
var queue = GetQueue().Where(c => c.ParseResult != null);
var matchigTitle = queue.Where(q => String.Equals(q.ParseResult.CleanTitle, newParseResult.Series.CleanTitle, StringComparison.InvariantCultureIgnoreCase));
var matchingTitleWithQuality = matchigTitle.Where(q => q.ParseResult.Quality >= newParseResult.Quality);
if (newParseResult.Series.SeriesType == SeriesTypes.Daily)
{
return matchingTitleWithQuality.Any(q => q.ParseResult.AirDate.Value.Date == newParseResult.AirDate.Value.Date);
}
var matchingSeason = matchingTitleWithQuality.Where(q => q.ParseResult.SeasonNumber == newParseResult.SeasonNumber);
if (newParseResult.FullSeason)
{
return matchingSeason.Any();
}
return matchingSeason.Any(q => q.ParseResult.EpisodeNumbers != null && q.ParseResult.EpisodeNumbers.Any(e => newParseResult.EpisodeNumbers.Contains(e)));
}
catch (Exception ex)
{
logger.WarnException("Unable to connect to SABnzbd to check queue.", ex);
return false;
}
}
public virtual bool DownloadNzb(string url, string title, bool recentlyAired) public virtual bool DownloadNzb(string url, string title, bool recentlyAired)
{ {
try try
@ -95,15 +54,26 @@ public virtual bool DownloadNzb(string url, string title, bool recentlyAired)
return false; return false;
} }
public virtual List<SabQueueItem> GetQueue(int start = 0, int limit = 0) public IEnumerable<QueueItem> GetQueue()
{ {
string action = String.Format("mode=queue&output=json&start={0}&limit={1}", start, limit); string action = String.Format("mode=queue&output=json&start={0}&limit={1}", 0, 0);
string request = GetSabRequest(action); string request = GetSabRequest(action);
string response = _httpProvider.DownloadString(request); string response = _httpProvider.DownloadString(request);
CheckForError(response); CheckForError(response);
return JsonConvert.DeserializeObject<SabQueue>(JObject.Parse(response).SelectToken("queue").ToString()).Items; var sabQeueu = JsonConvert.DeserializeObject<SabQueue>(JObject.Parse(response).SelectToken("queue").ToString()).Items;
foreach (var sabQueueItem in sabQeueu)
{
var queueItem = new QueueItem();
queueItem.Id = sabQueueItem.Id;
queueItem.Title = sabQueueItem.Title;
queueItem.Size = sabQueueItem.Size;
queueItem.SizeLeft = sabQueueItem.Size;
yield return queueItem;
}
} }
public virtual List<SabHistoryItem> GetHistory(int start = 0, int limit = 0) public virtual List<SabHistoryItem> GetHistory(int start = 0, int limit = 0)
@ -191,7 +161,7 @@ public virtual string Test(string host, int port, string apiKey, string username
var version = GetVersion(host, port, apiKey, username, password); var version = GetVersion(host, port, apiKey, username, password);
return version.Version; return version.Version;
} }
catch(Exception ex) catch (Exception ex)
{ {
logger.DebugException("Failed to Test SABnzbd", ex); logger.DebugException("Failed to Test SABnzbd", ex);
} }

View File

@ -14,23 +14,23 @@ public interface IProvideDownloadClient
public class DownloadClientProvider : IProvideDownloadClient public class DownloadClientProvider : IProvideDownloadClient
{ {
private readonly SabProvider _sabProvider; private readonly SabnzbdClient _sabnzbdClient;
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly BlackholeProvider _blackholeProvider; private readonly BlackholeProvider _blackholeProvider;
private readonly PneumaticProvider _pneumaticProvider; private readonly PneumaticClient _pneumaticClient;
private readonly NzbgetProvider _nzbgetProvider; private readonly NzbgetClient _nzbgetClient;
public DownloadClientProvider(SabProvider sabProvider, IConfigService configService, public DownloadClientProvider(SabnzbdClient sabnzbdClient, IConfigService configService,
BlackholeProvider blackholeProvider, BlackholeProvider blackholeProvider,
PneumaticProvider pneumaticProvider, PneumaticClient pneumaticClient,
NzbgetProvider nzbgetProvider) NzbgetClient nzbgetClient)
{ {
_sabProvider = sabProvider; _sabnzbdClient = sabnzbdClient;
_configService = configService; _configService = configService;
_blackholeProvider = blackholeProvider; _blackholeProvider = blackholeProvider;
_pneumaticProvider = pneumaticProvider; _pneumaticClient = pneumaticClient;
_nzbgetProvider = nzbgetProvider; _nzbgetClient = nzbgetClient;
} }
public IDownloadClient GetDownloadClient() public IDownloadClient GetDownloadClient()
@ -41,13 +41,13 @@ public IDownloadClient GetDownloadClient()
return _blackholeProvider; return _blackholeProvider;
case DownloadClientType.Pneumatic: case DownloadClientType.Pneumatic:
return _pneumaticProvider; return _pneumaticClient;
case DownloadClientType.Nzbget: case DownloadClientType.Nzbget:
return _nzbgetProvider; return _nzbgetClient;
default: default:
return _sabProvider; return _sabnzbdClient;
} }
} }
} }

View File

@ -6,13 +6,15 @@
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Download namespace NzbDrone.Core.Download
{ {
public interface IDownloadService public interface IDownloadService
{ {
bool DownloadReport(IndexerParseResult parseResult); bool DownloadReport(RemoteEpisode episode);
} }
public class DownloadService : IDownloadService public class DownloadService : IDownloadService
@ -32,31 +34,31 @@ public DownloadService(IProvideDownloadClient downloadClientProvider, IConfigSer
_logger = logger; _logger = logger;
} }
public bool DownloadReport(IndexerParseResult parseResult) public bool DownloadReport(RemoteEpisode episode)
{ {
var downloadTitle = parseResult.OriginalString; var downloadTitle = episode.Report.Title;
if (!_configService.DownloadClientUseSceneName) if (!_configService.DownloadClientUseSceneName)
{ {
downloadTitle = parseResult.GetDownloadTitle(); downloadTitle = episode.GetDownloadTitle();
} }
var provider = _downloadClientProvider.GetDownloadClient(); var provider = _downloadClientProvider.GetDownloadClient();
var recentEpisode = ContainsRecentEpisode(parseResult); var recentEpisode = ContainsRecentEpisode(episode);
bool success = provider.DownloadNzb(parseResult.NzbUrl, downloadTitle, recentEpisode); bool success = provider.DownloadNzb(episode.Report.NzbUrl, downloadTitle, recentEpisode);
if (success) if (success)
{ {
_logger.Info("Report sent to download client. {0}", downloadTitle); _logger.Info("Report sent to download client. {0}", downloadTitle);
_eventAggregator.Publish(new EpisodeGrabbedEvent(parseResult)); _eventAggregator.Publish(new EpisodeGrabbedEvent(episode));
} }
return success; return success;
} }
private static bool ContainsRecentEpisode(IndexerParseResult parseResult) private static bool ContainsRecentEpisode(RemoteEpisode episode)
{ {
return parseResult.Episodes.Any(e => e.AirDate >= DateTime.Today.AddDays(-7)); return episode.Episodes.Any(e => e.AirDate >= DateTime.Today.AddDays(-7));
} }
} }
} }

View File

@ -1,15 +1,17 @@
using NzbDrone.Common.Eventing; using NzbDrone.Common.Eventing;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download namespace NzbDrone.Core.Download
{ {
public class EpisodeGrabbedEvent : IEvent public class EpisodeGrabbedEvent : IEvent
{ {
public IndexerParseResult ParseResult { get; private set; } public RemoteEpisode Episode { get; private set; }
public EpisodeGrabbedEvent(IndexerParseResult parseResult) public EpisodeGrabbedEvent(RemoteEpisode episode)
{ {
ParseResult = parseResult; Episode = episode;
} }
} }
} }

View File

@ -1,11 +1,13 @@
using System.Linq; using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
namespace NzbDrone.Core.Download namespace NzbDrone.Core.Download
{ {
public interface IDownloadClient public interface IDownloadClient
{ {
bool IsInQueue(IndexerParseResult newParseResult);
bool DownloadNzb(string url, string title, bool recentlyAired); bool DownloadNzb(string url, string title, bool recentlyAired);
IEnumerable<QueueItem> GetQueue();
} }
} }

View File

@ -0,0 +1,23 @@
using System;
using Newtonsoft.Json;
using NzbDrone.Core.Download.Clients.Sabnzbd;
using NzbDrone.Core.Download.Clients.Sabnzbd.JsonConverters;
using NzbDrone.Core.Model;
namespace NzbDrone.Core.Download
{
public class QueueItem
{
public decimal Size { get; set; }
public string Title { get; set; }
public decimal SizeLeft { get; set; }
public int Percentage { get; set; }
public string Id { get; set; }
public TimeSpan Timeleft { get; set; }
}
}

View File

@ -83,7 +83,7 @@ public void Handle(EpisodeGrabbedEvent message)
try try
{ {
_logger.Trace("Sending grab notification to {0}", Name); _logger.Trace("Sending grab notification to {0}", Name);
OnGrab(message.ParseResult.GetDownloadTitle()); OnGrab(message.Episode.GetDownloadTitle());
} }
catch (Exception e) catch (Exception e)
@ -100,7 +100,7 @@ public void Handle(EpisodeDownloadedEvent message)
try try
{ {
_logger.Trace("Sending download notification to {0}", Name); _logger.Trace("Sending download notification to {0}", Name);
OnDownload(message.ParseResult.ToString(), message.ParseResult.Series); OnDownload(message.ParseResult.ToString(), message.Series);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -50,17 +50,17 @@ public virtual QualityModel GetBestQualityInHistory(int episodeId)
public void Handle(EpisodeGrabbedEvent message) public void Handle(EpisodeGrabbedEvent message)
{ {
foreach (var episode in message.ParseResult.Episodes) foreach (var episode in message.Episode.Episodes)
{ {
var history = new History var history = new History
{ {
Date = DateTime.Now, Date = DateTime.Now,
Indexer = message.ParseResult.Indexer, Indexer = message.Episode.Report.Indexer,
Quality = message.ParseResult.Quality, Quality = message.Episode.Quality,
NzbTitle = message.ParseResult.OriginalString, NzbTitle = message.Episode.Report.Title,
EpisodeId = episode.Id, EpisodeId = episode.Id,
NzbInfoUrl = message.ParseResult.NzbInfoUrl, NzbInfoUrl = message.Episode.Report.NzbInfoUrl,
ReleaseGroup = message.ParseResult.ReleaseGroup, ReleaseGroup = message.Episode.Report.ReleaseGroup,
}; };
_historyRepository.Insert(history); _historyRepository.Insert(history);

View File

@ -2,7 +2,6 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
{ {
public class SingleEpisodeSearchDefinition : SearchDefinitionBase public class SingleEpisodeSearchDefinition : SearchDefinitionBase
{ {
//TODO make sure these are populated with scene if required //TODO make sure these are populated with scene if required
public int EpisodeNumber { get; set; } public int EpisodeNumber { get; set; }
public int SeasonNumber { get; set; } public int SeasonNumber { get; set; }

View File

@ -7,6 +7,8 @@
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
using System.Linq; using System.Linq;
@ -105,10 +107,10 @@ private List<DownloadDecision> PartialSeasonSearch(SeasonSearchDefinition search
return spec; return spec;
} }
private List<DownloadDecision> Dispatch(Func<IIndexerBase, IEnumerable<IndexerParseResult>> searchAction, SearchDefinitionBase definitionBase) private List<DownloadDecision> Dispatch(Func<IIndexerBase, IEnumerable<ReportInfo>> searchAction, SearchDefinitionBase definitionBase)
{ {
var indexers = _indexerService.GetAvailableIndexers(); var indexers = _indexerService.GetAvailableIndexers();
var parseResults = new List<IndexerParseResult>(); var parseResults = new List<ReportInfo>();
Parallel.ForEach(indexers, indexer => Parallel.ForEach(indexers, indexer =>
{ {

View File

@ -6,12 +6,14 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NLog; using NLog;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
{ {
public interface IParseFeed public interface IParseFeed
{ {
IEnumerable<IndexerParseResult> Process(Stream source); IEnumerable<ReportInfo> Process(Stream source);
} }
public class BasicRssParser : IParseFeed public class BasicRssParser : IParseFeed
@ -23,12 +25,12 @@ public BasicRssParser()
_logger = LogManager.GetCurrentClassLogger(); _logger = LogManager.GetCurrentClassLogger();
} }
public IEnumerable<IndexerParseResult> Process(Stream source) public IEnumerable<ReportInfo> Process(Stream source)
{ {
var reader = new SyndicationFeedXmlReader(source); var reader = new SyndicationFeedXmlReader(source);
var feed = SyndicationFeed.Load(reader).Items; var feed = SyndicationFeed.Load(reader).Items;
var result = new List<IndexerParseResult>(); var result = new List<ReportInfo>();
foreach (var syndicationItem in feed) foreach (var syndicationItem in feed)
{ {
@ -38,7 +40,7 @@ public IEnumerable<IndexerParseResult> Process(Stream source)
if (parsedEpisode != null) if (parsedEpisode != null)
{ {
parsedEpisode.NzbUrl = GetNzbUrl(syndicationItem); parsedEpisode.NzbUrl = GetNzbUrl(syndicationItem);
parsedEpisode.NzbInfoUrl = GetNzbUrl(syndicationItem); parsedEpisode.NzbInfoUrl = GetNzbInfoUrl(syndicationItem);
result.Add(parsedEpisode); result.Add(parsedEpisode);
} }
} }
@ -68,23 +70,20 @@ protected virtual string GetNzbInfoUrl(SyndicationItem item)
return String.Empty; return String.Empty;
} }
protected virtual IndexerParseResult PostProcessor(SyndicationItem item, IndexerParseResult currentResult) protected virtual ReportInfo PostProcessor(SyndicationItem item, ReportInfo currentResult)
{ {
return currentResult; return currentResult;
} }
private IndexerParseResult ParseFeed(SyndicationItem item) private ReportInfo ParseFeed(SyndicationItem item)
{ {
var title = GetTitle(item); var title = GetTitle(item);
var episodeParseResult = Parser.ParseTitle<IndexerParseResult>(title); var episodeParseResult = new ReportInfo();
if (episodeParseResult != null)
{ episodeParseResult.Title = title;
episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PublishDate.Date).Days; episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PublishDate.Date).Days;
episodeParseResult.OriginalString = title; episodeParseResult.ReleaseGroup = ParseReleaseGroup(title);
episodeParseResult.SceneSource = true;
episodeParseResult.ReleaseGroup = ParseReleaseGroup(title);
}
_logger.Trace("Parsed: {0} from: {1}", episodeParseResult, item.Title.Text); _logger.Trace("Parsed: {0} from: {1}", episodeParseResult, item.Title.Text);

View File

@ -1,5 +1,7 @@
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.FileSharingTalk namespace NzbDrone.Core.Indexers.FileSharingTalk
{ {
@ -10,7 +12,7 @@ protected override string GetNzbInfoUrl(SyndicationItem item)
return item.Id; return item.Id;
} }
protected override IndexerParseResult PostProcessor(SyndicationItem item, IndexerParseResult currentResult) protected override ReportInfo PostProcessor(SyndicationItem item, ReportInfo currentResult)
{ {
if (currentResult != null) if (currentResult != null)
{ {

View File

@ -5,17 +5,19 @@
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
{ {
public interface IFetchFeedFromIndexers public interface IFetchFeedFromIndexers
{ {
IList<IndexerParseResult> FetchRss(IIndexerBase indexer); IList<ReportInfo> FetchRss(IIndexerBase indexer);
IList<IndexerParseResult> Fetch(IIndexerBase indexer, SeasonSearchDefinition searchDefinition); IList<ReportInfo> Fetch(IIndexerBase indexer, SeasonSearchDefinition searchDefinition);
IList<IndexerParseResult> Fetch(IIndexerBase indexer, SingleEpisodeSearchDefinition searchDefinition); IList<ReportInfo> Fetch(IIndexerBase indexer, SingleEpisodeSearchDefinition searchDefinition);
IList<IndexerParseResult> Fetch(IIndexerBase indexer, PartialSeasonSearchDefinition searchDefinition); IList<ReportInfo> Fetch(IIndexerBase indexer, PartialSeasonSearchDefinition searchDefinition);
IList<IndexerParseResult> Fetch(IIndexerBase indexer, DailyEpisodeSearchDefinition searchDefinition); IList<ReportInfo> Fetch(IIndexerBase indexer, DailyEpisodeSearchDefinition searchDefinition);
} }
public class FetchFeedService : IFetchFeedFromIndexers public class FetchFeedService : IFetchFeedFromIndexers
@ -31,7 +33,7 @@ public FetchFeedService(IHttpProvider httpProvider, Logger logger)
} }
public virtual IList<IndexerParseResult> FetchRss(IIndexerBase indexer) public virtual IList<ReportInfo> FetchRss(IIndexerBase indexer)
{ {
_logger.Debug("Fetching feeds from " + indexer.Name); _logger.Debug("Fetching feeds from " + indexer.Name);
@ -42,7 +44,7 @@ public virtual IList<IndexerParseResult> FetchRss(IIndexerBase indexer)
return result; return result;
} }
public IList<IndexerParseResult> Fetch(IIndexerBase indexer, SeasonSearchDefinition searchDefinition) public IList<ReportInfo> Fetch(IIndexerBase indexer, SeasonSearchDefinition searchDefinition)
{ {
_logger.Debug("Searching for {0}", searchDefinition); _logger.Debug("Searching for {0}", searchDefinition);
@ -54,7 +56,7 @@ public IList<IndexerParseResult> Fetch(IIndexerBase indexer, SeasonSearchDefinit
return result; return result;
} }
public IList<IndexerParseResult> Fetch(IIndexerBase indexer, SingleEpisodeSearchDefinition searchDefinition) public IList<ReportInfo> Fetch(IIndexerBase indexer, SingleEpisodeSearchDefinition searchDefinition)
{ {
_logger.Debug("Searching for {0}", searchDefinition); _logger.Debug("Searching for {0}", searchDefinition);
@ -67,7 +69,7 @@ public IList<IndexerParseResult> Fetch(IIndexerBase indexer, SingleEpisodeSearch
} }
public IList<IndexerParseResult> Fetch(IIndexerBase indexer, PartialSeasonSearchDefinition searchDefinition) public IList<ReportInfo> Fetch(IIndexerBase indexer, PartialSeasonSearchDefinition searchDefinition)
{ {
_logger.Debug("Searching for {0}", searchDefinition); _logger.Debug("Searching for {0}", searchDefinition);
@ -79,7 +81,7 @@ public IList<IndexerParseResult> Fetch(IIndexerBase indexer, PartialSeasonSearch
return result; return result;
} }
public IList<IndexerParseResult> Fetch(IIndexerBase indexer, DailyEpisodeSearchDefinition searchDefinition) public IList<ReportInfo> Fetch(IIndexerBase indexer, DailyEpisodeSearchDefinition searchDefinition)
{ {
_logger.Debug("Searching for {0}", searchDefinition); _logger.Debug("Searching for {0}", searchDefinition);
@ -90,9 +92,9 @@ public IList<IndexerParseResult> Fetch(IIndexerBase indexer, DailyEpisodeSearchD
return result; return result;
} }
private List<IndexerParseResult> Fetch(IIndexerBase indexer, IEnumerable<string> urls) private List<ReportInfo> Fetch(IIndexerBase indexer, IEnumerable<string> urls)
{ {
var result = new List<IndexerParseResult>(); var result = new List<ReportInfo>();
foreach (var url in urls) foreach (var url in urls)
{ {

View File

@ -1,6 +1,8 @@
using System; using System;
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.Newznab namespace NzbDrone.Core.Indexers.Newznab
{ {
@ -18,7 +20,7 @@ protected override string GetNzbInfoUrl(SyndicationItem item)
return item.Id; return item.Id;
} }
protected override IndexerParseResult PostProcessor(SyndicationItem item, IndexerParseResult currentResult) protected override ReportInfo PostProcessor(SyndicationItem item, ReportInfo currentResult)
{ {
if (currentResult != null) if (currentResult != null)
{ {

View File

@ -2,12 +2,14 @@
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.NzbClub namespace NzbDrone.Core.Indexers.NzbClub
{ {
public class NzbClubParser : BasicRssParser public class NzbClubParser : BasicRssParser
{ {
protected override IndexerParseResult PostProcessor(SyndicationItem item, IndexerParseResult currentResult) protected override ReportInfo PostProcessor(SyndicationItem item, ReportInfo currentResult)
{ {
if (currentResult != null) if (currentResult != null)
{ {

View File

@ -2,6 +2,8 @@
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.NzbIndex namespace NzbDrone.Core.Indexers.NzbIndex
{ {
@ -18,7 +20,7 @@ protected override string GetNzbInfoUrl(SyndicationItem item)
return item.Links[0].Uri.ToString(); return item.Links[0].Uri.ToString();
} }
protected override IndexerParseResult PostProcessor(SyndicationItem item, IndexerParseResult currentResult) protected override ReportInfo PostProcessor(SyndicationItem item, ReportInfo currentResult)
{ {
if (currentResult != null) if (currentResult != null)
{ {

View File

@ -1,12 +1,14 @@
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.NzbsRUs namespace NzbDrone.Core.Indexers.NzbsRUs
{ {
public class NzbsrusParser : BasicRssParser public class NzbsrusParser : BasicRssParser
{ {
protected override IndexerParseResult PostProcessor(SyndicationItem item, IndexerParseResult currentResult) protected override ReportInfo PostProcessor(SyndicationItem item, ReportInfo currentResult)
{ {
if (currentResult != null) if (currentResult != null)
{ {

View File

@ -4,6 +4,8 @@
using NLog; using NLog;
using Newtonsoft.Json; using Newtonsoft.Json;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.Nzbx namespace NzbDrone.Core.Indexers.Nzbx
{ {
@ -18,9 +20,9 @@ public NzbxParser(Logger logger)
_serializer = new JsonSerializer(); _serializer = new JsonSerializer();
} }
public IEnumerable<IndexerParseResult> Process(Stream source) public IEnumerable<ReportInfo> Process(Stream source)
{ {
var result = new List<IndexerParseResult>(); var result = new List<ReportInfo>();
var jsonReader = new JsonTextReader(new StreamReader(source)); var jsonReader = new JsonTextReader(new StreamReader(source));
var feed = _serializer.Deserialize<List<NzbxRecentItem>>(jsonReader); var feed = _serializer.Deserialize<List<NzbxRecentItem>>(jsonReader);
@ -28,18 +30,14 @@ public IEnumerable<IndexerParseResult> Process(Stream source)
{ {
try try
{ {
var episodeParseResult = Parser.ParseTitle<IndexerParseResult>(item.Name); var episodeParseResult = new ReportInfo();
if (episodeParseResult != null) episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PostDate).Days;
{ episodeParseResult.Title = item.Name;
episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PostDate).Days; episodeParseResult.NzbUrl = String.Format("http://nzbx.co/nzb?{0}*|*{1}", item.Guid, item.Name);
episodeParseResult.OriginalString = item.Name; episodeParseResult.NzbInfoUrl = String.Format("http://nzbx.co/d?{0}", item.Guid);
episodeParseResult.SceneSource = true; episodeParseResult.Size = item.Size;
episodeParseResult.NzbUrl = String.Format("http://nzbx.co/nzb?{0}*|*{1}", item.Guid, item.Name);
episodeParseResult.NzbInfoUrl = String.Format("http://nzbx.co/d?{0}", item.Guid);
episodeParseResult.Size = item.Size;
result.Add(episodeParseResult); result.Add(episodeParseResult);
}
} }
catch (Exception itemEx) catch (Exception itemEx)
{ {

View File

@ -2,6 +2,8 @@
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.Omgwtfnzbs namespace NzbDrone.Core.Indexers.Omgwtfnzbs
{ {
@ -26,7 +28,7 @@ protected override string GetNzbInfoUrl(SyndicationItem item)
return String.Empty; return String.Empty;
} }
protected override IndexerParseResult PostProcessor(SyndicationItem item, IndexerParseResult currentResult) protected override ReportInfo PostProcessor(SyndicationItem item, ReportInfo currentResult)
{ {
if (currentResult != null) if (currentResult != null)
{ {

View File

@ -6,6 +6,8 @@
using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download; using NzbDrone.Core.Download;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers namespace NzbDrone.Core.Indexers
{ {
@ -40,10 +42,10 @@ public void Sync()
var qualifiedReports = decisions var qualifiedReports = decisions
.Where(c => c.Approved) .Where(c => c.Approved)
.Select(c => c.ParseResult) .Select(c => c.Episode)
.OrderByDescending(c => c.Quality) .OrderByDescending(c => c.Quality)
.ThenBy(c => c.EpisodeNumbers.MinOrDefault()) .ThenBy(c => c.Episodes.Select(e => e.EpisodeNumber).MinOrDefault())
.ThenBy(c => c.Age); .ThenBy(c => c.Report.Age);
foreach (var episodeParseResult in qualifiedReports) foreach (var episodeParseResult in qualifiedReports)
@ -65,7 +67,7 @@ public void Sync()
public interface IFetchAndParseRss public interface IFetchAndParseRss
{ {
List<IndexerParseResult> Fetch(); List<ReportInfo> Fetch();
} }
public class FetchAndParseRssService : IFetchAndParseRss public class FetchAndParseRssService : IFetchAndParseRss
@ -79,9 +81,9 @@ public FetchAndParseRssService(IIndexerService indexerService, IFetchFeedFromInd
_feedFetcher = feedFetcher; _feedFetcher = feedFetcher;
} }
public List<IndexerParseResult> Fetch() public List<ReportInfo> Fetch()
{ {
var result = new List<IndexerParseResult>(); var result = new List<ReportInfo>();
var indexers = _indexerService.GetAvailableIndexers(); var indexers = _indexerService.GetAvailableIndexers();

View File

@ -1,5 +1,7 @@
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.Wombles namespace NzbDrone.Core.Indexers.Wombles
{ {
@ -15,7 +17,7 @@ protected override string GetNzbInfoUrl(SyndicationItem item)
return null; return null;
} }
protected override IndexerParseResult PostProcessor(SyndicationItem item, IndexerParseResult currentResult) protected override ReportInfo PostProcessor(SyndicationItem item, ReportInfo currentResult)
{ {
if (currentResult != null) if (currentResult != null)
{ {

View File

@ -12,13 +12,13 @@ public class PostDownloadScanJob : IJob
{ {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly PostDownloadProvider _postDownloadProvider; private readonly DropFolderImportService _dropFolderImportService;
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly DiskProvider _diskProvider; private readonly DiskProvider _diskProvider;
public PostDownloadScanJob(PostDownloadProvider postDownloadProvider,IConfigService configService, DiskProvider diskProvider) public PostDownloadScanJob(DropFolderImportService dropFolderImportService,IConfigService configService, DiskProvider diskProvider)
{ {
_postDownloadProvider = postDownloadProvider; _dropFolderImportService = dropFolderImportService;
_configService = configService; _configService = configService;
_diskProvider = diskProvider; _diskProvider = diskProvider;
} }
@ -59,7 +59,7 @@ public virtual void Start(ProgressNotification notification, dynamic options)
return; return;
} }
_postDownloadProvider.ProcessDropFolder(dropFolder); _dropFolderImportService.ProcessDropFolder(dropFolder);
} }
} }
} }

View File

@ -49,7 +49,7 @@ public virtual void Start(ProgressNotification notification, dynamic options)
{ {
notification.CurrentMessage = "Checking for updates"; notification.CurrentMessage = "Checking for updates";
var updatePackage = _updateService.GetAvailableUpdate(_environmentProvider.Version); var updatePackage = _updateService.GetAvailableUpdate();
//No updates available //No updates available
if (updatePackage == null) if (updatePackage == null)
@ -88,7 +88,7 @@ public virtual void Start(ProgressNotification notification, dynamic options)
var process = _processProvider.Start(startInfo); var process = _processProvider.Start(startInfo);
notification.CurrentMessage = "Update in progress. NzbDrone will restart shortly."; notification.CurrentMessage = "Update in progress. NzbDrone will restart shortly.";
_processProvider.WaitForExit(process); _processProvider.WaitForExit(process);
} }
} }
} }

View File

@ -26,8 +26,9 @@ public EpisodeFile(EpisodeFile source)
public long Size { get; set; } public long Size { get; set; }
public DateTime DateAdded { get; set; } public DateTime DateAdded { get; set; }
public string SceneName { get; set; } public string SceneName { get; set; }
public string ReleaseGroup { get; set; }
public QualityModel Quality { get; set; } public QualityModel Quality { get; set; }
public LazyList<Episode> Episodes { get; set; }
} }
} }

View File

@ -59,7 +59,7 @@ public EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, bool newDownload = f
return null; return null;
} }
_diskProvider.CreateDirectory(new FileInfo(newFile).DirectoryName); _diskProvider.CreateFolder(new FileInfo(newFile).DirectoryName);
_logger.Debug("Moving [{0}] > [{1}]", episodeFile.Path, newFile); _logger.Debug("Moving [{0}] > [{1}]", episodeFile.Path, newFile);
_diskProvider.MoveFile(episodeFile.Path, newFile); _diskProvider.MoveFile(episodeFile.Path, newFile);
@ -78,14 +78,12 @@ public EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, bool newDownload = f
episodeFile.Path = newFile; episodeFile.Path = newFile;
_mediaFileService.Update(episodeFile); _mediaFileService.Update(episodeFile);
var parseResult = Parser.ParsePath(episodeFile.Path); var parseResult = Parser.Parser.ParsePath(episodeFile.Path);
parseResult.Series = series;
parseResult.Quality = episodeFile.Quality; parseResult.Quality = episodeFile.Quality;
parseResult.Episodes = episodes;
if (newDownload) if (newDownload)
{ {
_eventAggregator.Publish(new EpisodeDownloadedEvent(parseResult)); _eventAggregator.Publish(new EpisodeDownloadedEvent(parseResult, series));
} }
return episodeFile; return episodeFile;

View File

@ -1,15 +1,20 @@
using NzbDrone.Common.Eventing; using NzbDrone.Common.Eventing;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.MediaFiles.Events namespace NzbDrone.Core.MediaFiles.Events
{ {
public class EpisodeDownloadedEvent : IEvent public class EpisodeDownloadedEvent : IEvent
{ {
public FileNameParseResult ParseResult { get; private set; } public ParsedEpisodeInfo ParseResult { get; private set; }
public Series Series { get; set; }
public EpisodeDownloadedEvent(FileNameParseResult parseResult) public EpisodeDownloadedEvent(ParsedEpisodeInfo parseResult, Series series)
{ {
ParseResult = parseResult; ParseResult = parseResult;
Series = series;
} }
} }
} }

View File

@ -0,0 +1,15 @@
using System.Collections.Generic;
using NzbDrone.Common.Eventing;
namespace NzbDrone.Core.MediaFiles.Events
{
public class EpisodeFileAddedEvent : IEvent
{
public EpisodeFile EpisodeFile { get; private set; }
public EpisodeFileAddedEvent(EpisodeFile episodeFile)
{
EpisodeFile = episodeFile;
}
}
}

View File

@ -39,7 +39,9 @@ public MediaFileService(IMediaFileRepository mediaFileRepository, IConfigService
public EpisodeFile Add(EpisodeFile episodeFile) public EpisodeFile Add(EpisodeFile episodeFile)
{ {
return _mediaFileRepository.Insert(episodeFile); var addedFile = _mediaFileRepository.Insert(episodeFile);
_eventAggregator.Publish(new EpisodeFileAddedEvent(addedFile));
return addedFile;
} }
public void Update(EpisodeFile episodeFile) public void Update(EpisodeFile episodeFile)

View File

@ -1,147 +0,0 @@
using System;
using System.Linq;
using System.Collections.Generic;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Model
{
public class ParseResult
{
public string SeriesTitle { get; set; }
public string CleanTitle
{
get
{
return Parser.NormalizeTitle(SeriesTitle);
}
}
public string EpisodeTitle { get; set; }
public int SeasonNumber { get; set; }
public List<int> EpisodeNumbers { get; set; }
public DateTime? AirDate { get; set; }
public QualityModel Quality { get; set; }
public LanguageType Language { get; set; }
public string OriginalString { get; set; }
public Series Series { get; set; }
public bool FullSeason { get; set; }
public long Size { get; set; }
public bool SceneSource { get; set; }
public IList<Episode> Episodes { get; set; }
public override string ToString()
{
string episodeString = "[Unknown Episode]";
if (AirDate != null && EpisodeNumbers == null)
{
episodeString = string.Format("{0}", AirDate.Value.ToString("yyyy-MM-dd"));
}
else if (FullSeason)
{
episodeString = string.Format("Season {0:00}", SeasonNumber);
}
else if (EpisodeNumbers != null && EpisodeNumbers.Any())
{
episodeString = string.Format("S{0:00}E{1}", SeasonNumber, String.Join("-", EpisodeNumbers.Select(c => c.ToString("00"))));
}
return string.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
}
}
public class IndexerParseResult : ParseResult
{
public DownloadDecision Decision { get; set; }
public string NzbUrl { get; set; }
public string NzbInfoUrl { get; set; }
public String Indexer { get; set; }
public int Age { get; set; }
public string ReleaseGroup { get; set; }
public string GetDownloadTitle()
{
var seriesTitle = FileNameBuilder.CleanFilename(Series.Title);
//Handle Full Naming
if (FullSeason)
{
var seasonResult = String.Format("{0} - Season {1} [{2}]", seriesTitle,
SeasonNumber, Quality.Quality);
if (Quality.Proper)
seasonResult += " [Proper]";
return seasonResult;
}
if (Series.SeriesType == SeriesTypes.Daily)
{
var dailyResult = String.Format("{0} - {1:yyyy-MM-dd} - {2} [{3}]", seriesTitle,
AirDate, Episodes.First().Title, Quality.Quality);
if (Quality.Proper)
dailyResult += " [Proper]";
return dailyResult;
}
//Show Name - 1x01-1x02 - Episode Name
//Show Name - 1x01 - Episode Name
var episodeString = new List<String>();
var episodeNames = new List<String>();
foreach (var episode in Episodes)
{
episodeString.Add(String.Format("{0}x{1:00}", episode.SeasonNumber, episode.EpisodeNumber));
episodeNames.Add(Parser.CleanupEpisodeTitle(episode.Title));
}
var epNumberString = String.Join("-", episodeString);
string episodeName;
if (episodeNames.Distinct().Count() == 1)
episodeName = episodeNames.First();
else
episodeName = String.Join(" + ", episodeNames.Distinct());
var result = String.Format("{0} - {1} - {2} [{3}]", seriesTitle, epNumberString, episodeName, Quality.Quality);
if (Quality.Proper)
{
result += " [Proper]";
}
return result;
}
}
public class FileNameParseResult :ParseResult
{
}
}

View File

@ -1,9 +1,4 @@
using System; namespace NzbDrone.Core.Model
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Core.Model
{ {
public class MediaInfoModel public class MediaInfoModel
{ {

View File

@ -228,15 +228,16 @@
<Compile Include="DecisionEngine\Specifications\MonitoredEpisodeSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\MonitoredEpisodeSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\QualityAllowedByProfileSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\QualityAllowedByProfileSpecification.cs" />
<Compile Include="DecisionEngine\QualityUpgradableSpecification.cs" /> <Compile Include="DecisionEngine\QualityUpgradableSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\Search\SingleEpisodeMatchSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\Search\SingleEpisodeSearchMatchSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\UpgradeDiskSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\UpgradeDiskSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\UpgradeHistorySpecification.cs" /> <Compile Include="DecisionEngine\Specifications\UpgradeHistorySpecification.cs" />
<Compile Include="Download\Clients\ConnectionInfoModel.cs" /> <Compile Include="Download\Clients\Sabnzbd\ConnectionInfoModel.cs" />
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdPriorityTypeConverter.cs" /> <Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdPriorityTypeConverter.cs" />
<Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdQueueTimeConverter.cs" /> <Compile Include="Download\Clients\Sabnzbd\JsonConverters\SabnzbdQueueTimeConverter.cs" />
<Compile Include="Download\Clients\Sabnzbd\SabAutoConfigureService.cs" /> <Compile Include="Download\Clients\Sabnzbd\SabAutoConfigureService.cs" />
<Compile Include="Download\DownloadClientProvider.cs" /> <Compile Include="Download\DownloadClientProvider.cs" />
<Compile Include="Download\DownloadClientType.cs" /> <Compile Include="Download\DownloadClientType.cs" />
<Compile Include="Download\SabQueueItem.cs" />
<Compile Include="Indexers\IIndexerBase.cs" /> <Compile Include="Indexers\IIndexerBase.cs" />
<Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" /> <Compile Include="Indexers\IndexerSettingUpdatedEvent.cs" />
<Compile Include="Indexers\IndexerWithSetting.cs" /> <Compile Include="Indexers\IndexerWithSetting.cs" />
@ -307,6 +308,7 @@
<Compile Include="Lifecycle\ApplicationStartedEvent.cs" /> <Compile Include="Lifecycle\ApplicationStartedEvent.cs" />
<Compile Include="MediaCover\MediaCover.cs" /> <Compile Include="MediaCover\MediaCover.cs" />
<Compile Include="MediaFiles\EpisodeFileMovingService.cs" /> <Compile Include="MediaFiles\EpisodeFileMovingService.cs" />
<Compile Include="MediaFiles\Events\EpisodeFileAddedEvent.cs" />
<Compile Include="MediaFiles\Events\EpisodeFileDeletedEvent.cs" /> <Compile Include="MediaFiles\Events\EpisodeFileDeletedEvent.cs" />
<Compile Include="MediaFiles\GhostFileCleanupService.cs" /> <Compile Include="MediaFiles\GhostFileCleanupService.cs" />
<Compile Include="MediaFiles\MediaFileRepository.cs" /> <Compile Include="MediaFiles\MediaFileRepository.cs" />
@ -335,18 +337,25 @@
<Compile Include="Download\Clients\Nzbget\ErrorModel.cs" /> <Compile Include="Download\Clients\Nzbget\ErrorModel.cs" />
<Compile Include="Download\Clients\Nzbget\JsonError.cs" /> <Compile Include="Download\Clients\Nzbget\JsonError.cs" />
<Compile Include="Download\Clients\Nzbget\JsonRequest.cs" /> <Compile Include="Download\Clients\Nzbget\JsonRequest.cs" />
<Compile Include="Download\Clients\Nzbget\Queue.cs" /> <Compile Include="Download\Clients\Nzbget\NzbGetQueue.cs" />
<Compile Include="Download\Clients\Nzbget\QueueItem.cs" /> <Compile Include="Download\Clients\Nzbget\NzbGetQueueItem.cs" />
<Compile Include="Download\Clients\Nzbget\PriorityType.cs" /> <Compile Include="Download\Clients\Nzbget\PriorityType.cs" />
<Compile Include="Download\Clients\Nzbget\VersionModel.cs" /> <Compile Include="Download\Clients\Nzbget\VersionModel.cs" />
<Compile Include="Indexers\Nzbx\NzbxRecentItem.cs" /> <Compile Include="Indexers\Nzbx\NzbxRecentItem.cs" />
<Compile Include="Model\PostDownloadStatusType.cs" /> <Compile Include="Model\PostDownloadStatusType.cs" />
<Compile Include="Model\LanguageType.cs" />
<Compile Include="Model\MisnamedEpisodeModel.cs" /> <Compile Include="Model\MisnamedEpisodeModel.cs" />
<Compile Include="Organizer\NameSpecification.cs" /> <Compile Include="Organizer\NameSpecification.cs" />
<Compile Include="Parser\Language.cs" />
<Compile Include="Parser\Model\LocalEpisode.cs" />
<Compile Include="Parser\Model\ParsedEpisodeInfo.cs" />
<Compile Include="Parser\Model\RemoteEpisode.cs" />
<Compile Include="Parser\Model\ReportInfo.cs" />
<Compile Include="Parser\Parser.cs" />
<Compile Include="Parser\ParsingService.cs" />
<Compile Include="Qualities\QualitySizeRepository.cs" /> <Compile Include="Qualities\QualitySizeRepository.cs" />
<Compile Include="Qualities\QualityProfileRepository.cs" /> <Compile Include="Qualities\QualityProfileRepository.cs" />
<Compile Include="Tv\EpisodeService.cs" /> <Compile Include="Tv\EpisodeService.cs" />
<Compile Include="Tv\EpisodeStatuses.cs" />
<Compile Include="Tv\Events\EpisodeInfoUpdatedEvent.cs" /> <Compile Include="Tv\Events\EpisodeInfoUpdatedEvent.cs" />
<Compile Include="Tv\Events\EpisodeInfoAddedEvent.cs" /> <Compile Include="Tv\Events\EpisodeInfoAddedEvent.cs" />
<Compile Include="Tv\Events\SeriesAddedEvent.cs" /> <Compile Include="Tv\Events\SeriesAddedEvent.cs" />
@ -377,9 +386,9 @@
<Compile Include="Model\Xem\XemSceneTvdbMapping.cs" /> <Compile Include="Model\Xem\XemSceneTvdbMapping.cs" />
<Compile Include="Model\Xem\XemValues.cs" /> <Compile Include="Model\Xem\XemValues.cs" />
<Compile Include="MediaCover\MediaCoverService.cs" /> <Compile Include="MediaCover\MediaCoverService.cs" />
<Compile Include="Download\Clients\Nzbget\NzbgetProvider.cs" /> <Compile Include="Download\Clients\Nzbget\NzbgetClient.cs" />
<Compile Include="Providers\MediaInfoProvider.cs" /> <Compile Include="Providers\VideoFileInfoReader.cs" />
<Compile Include="Download\Clients\PneumaticProvider.cs" /> <Compile Include="Download\Clients\PneumaticClient.cs" />
<Compile Include="Providers\RecycleBinProvider.cs" /> <Compile Include="Providers\RecycleBinProvider.cs" />
<Compile Include="Tv\SeasonService.cs" /> <Compile Include="Tv\SeasonService.cs" />
<Compile Include="Instrumentation\TrimLogsJob.cs" /> <Compile Include="Instrumentation\TrimLogsJob.cs" />
@ -415,7 +424,7 @@
<Compile Include="Download\IDownloadClient.cs"> <Compile Include="Download\IDownloadClient.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Download\Clients\Sabnzbd\SabProvider.cs"> <Compile Include="Download\Clients\Sabnzbd\SabnzbdClient.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Download\DownloadService.cs"> <Compile Include="Download\DownloadService.cs">
@ -470,7 +479,7 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="ExternalNotification\PlexProvider.cs" /> <Compile Include="ExternalNotification\PlexProvider.cs" />
<Compile Include="Providers\PostDownloadProvider.cs"> <Compile Include="Providers\DropfolderImportService.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Providers\ProwlProvider.cs"> <Compile Include="Providers\ProwlProvider.cs">
@ -505,12 +514,9 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="ExternalNotification\ExternalNotificationDefinition.cs" /> <Compile Include="ExternalNotification\ExternalNotificationDefinition.cs" />
<Compile Include="Model\IndexerParseResult.cs" />
<Compile Include="Model\EpisodeStatusType.cs" />
<Compile Include="Download\Clients\Sabnzbd\SabPriorityType.cs" /> <Compile Include="Download\Clients\Sabnzbd\SabPriorityType.cs" />
<Compile Include="MediaFiles\EpisodeFile.cs" /> <Compile Include="MediaFiles\EpisodeFile.cs" />
<Compile Include="Model\Notification\ProgressNotificationStatus.cs" /> <Compile Include="Model\Notification\ProgressNotificationStatus.cs" />
<Compile Include="Parser.cs" />
<Compile Include="Model\Notification\ProgressNotification.cs" /> <Compile Include="Model\Notification\ProgressNotification.cs" />
<Compile Include="Tv\Episode.cs" /> <Compile Include="Tv\Episode.cs" />
<Compile Include="Instrumentation\Log.cs" /> <Compile Include="Instrumentation\Log.cs" />
@ -521,7 +527,7 @@
<Compile Include="Tv\Series.cs" /> <Compile Include="Tv\Series.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tv\SeriesStatusType.cs" /> <Compile Include="Tv\SeriesStatusType.cs" />
<Compile Include="Update\AvailableUpdateService.cs" /> <Compile Include="Update\UpdatePackageProvider.cs" />
<Compile Include="Update\UpdatePackage.cs" /> <Compile Include="Update\UpdatePackage.cs" />
<Compile Include="Update\UpdateProvider.cs" /> <Compile Include="Update\UpdateProvider.cs" />
</ItemGroup> </ItemGroup>

View File

@ -53,7 +53,7 @@ public string BuildFilename(IList<Episode> episodes, Series series, EpisodeFile
var episodeNames = new List<string> var episodeNames = new List<string>
{ {
Parser.CleanupEpisodeTitle(sortedEpisodes.First().Title) Parser.Parser.CleanupEpisodeTitle(sortedEpisodes.First().Title)
}; };
var result = String.Empty; var result = String.Empty;
@ -85,7 +85,7 @@ public string BuildFilename(IList<Episode> episodes, Series series, EpisodeFile
} }
result = result.Replace("%0e", String.Format("{0:00}", episode.EpisodeNumber)); result = result.Replace("%0e", String.Format("{0:00}", episode.EpisodeNumber));
episodeNames.Add(Parser.CleanupEpisodeTitle(episode.Title)); episodeNames.Add(Parser.Parser.CleanupEpisodeTitle(episode.Title));
} }
} }

View File

@ -1,6 +1,6 @@
namespace NzbDrone.Core.Model namespace NzbDrone.Core.Parser
{ {
public enum LanguageType public enum Language
{ {
English = 0, English = 0,
French = 1, French = 1,

View File

@ -0,0 +1,16 @@
using System.Collections.Generic;
using NzbDrone.Core.Tv;
using System.Linq;
namespace NzbDrone.Core.Parser.Model
{
public class LocalEpisode
{
//public ParsedEpisodeInfo ParsedEpisodeInfo { get; set; }
public List<Episode> Episodes { get; set; }
public QualityModel Quality { get; set; }
public int SeasonNumber { get { return Episodes.Select(c => c.SeasonNumber).Distinct().Single(); } }
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Parser.Model
{
public class ParsedEpisodeInfo
{
public string SeriesTitle { get; set; }
public string OriginalString { get; set; }
public QualityModel Quality { get; set; }
public int SeasonNumber { get; set; }
public List<int> EpisodeNumbers { get; set; }
public DateTime? AirDate { get; set; }
public Language Language { get; set; }
public bool FullSeason { get; set; }
public bool SceneSource { get; set; }
public override string ToString()
{
string episodeString = "[Unknown Episode]";
if (AirDate != null && EpisodeNumbers == null)
{
episodeString = string.Format("{0}", AirDate.Value.ToString("yyyy-MM-dd"));
}
else if (FullSeason)
{
episodeString = string.Format("Season {0:00}", SeasonNumber);
}
else if (EpisodeNumbers != null && EpisodeNumbers.Any())
{
episodeString = string.Format("S{0:00}E{1}", SeasonNumber, String.Join("-", EpisodeNumbers.Select(c => c.ToString("00"))));
}
return string.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
}
}
}

View File

@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Parser.Model
{
public class RemoteEpisode
{
public ReportInfo Report { get; set; }
public bool FullSeason { get; set; }
public Series Series { get; set; }
public List<Episode> Episodes { get; set; }
public QualityModel Quality { get; set; }
public Language Language { get; set; }
public int SeasonNumber
{
get { return Episodes.Select(e => e.SeasonNumber).Distinct().SingleOrDefault(); }
}
public DateTime? AirDate
{
get
{
return Episodes.Single().AirDate;
}
}
public IEnumerable<int> EpisodeNumbers
{
get
{
return Episodes.Select(c => c.EpisodeNumber).Distinct();
}
}
public string GetDownloadTitle()
{
var seriesTitle = FileNameBuilder.CleanFilename(Series.Title);
//Handle Full Naming
if (FullSeason)
{
var seasonResult = String.Format("{0} - Season {1} [{2}]", seriesTitle, SeasonNumber, Quality);
if (Quality.Proper)
seasonResult += " [Proper]";
return seasonResult;
}
if (Series.SeriesType == SeriesTypes.Daily)
{
var dailyResult = String.Format("{0} - {1:yyyy-MM-dd} - {2} [{3}]", seriesTitle,
AirDate, Episodes.First().Title, Quality);
if (Quality.Proper)
dailyResult += " [Proper]";
return dailyResult;
}
//Show Name - 1x01-1x02 - Episode Name
//Show Name - 1x01 - Episode Name
var episodeString = new List<string>();
var episodeNames = new List<string>();
foreach (var episode in Episodes)
{
episodeString.Add(String.Format("{0}x{1:00}", episode.SeasonNumber, episode.EpisodeNumber));
episodeNames.Add(Core.Parser.Parser.CleanupEpisodeTitle(episode.Title));
}
var epNumberString = String.Join("-", episodeString);
string episodeName;
if (episodeNames.Distinct().Count() == 1)
episodeName = episodeNames.First();
else
episodeName = String.Join(" + ", episodeNames.Distinct());
var result = String.Format("{0} - {1} - {2} [{3}]", seriesTitle, epNumberString, episodeName, Quality);
if (Quality.Proper)
{
result += " [Proper]";
}
return result;
}
public override string ToString()
{
throw new NotImplementedException();
}
}
}

Some files were not shown because too many files have changed in this diff Show More