cleaned up parsing logic and structure.

pull/6/head
kay.one 11 years ago
parent cd2761d07d
commit 6e88f55a54

@ -154,22 +154,22 @@ namespace NzbDrone.Common.Test
public void empty_folder_should_return_folder_modified_date()
{
var tempfolder = new DirectoryInfo(TempFolder);
Mocker.Resolve<DiskProvider>().GetLastDirectoryWrite(TempFolder).Should().Be(tempfolder.LastWriteTimeUtc);
Mocker.Resolve<DiskProvider>().GetLastFolderWrite(TempFolder).Should().Be(tempfolder.LastWriteTimeUtc);
}
[Test]
public void folder_should_return_correct_value_for_last_write()
{
var appPath = new EnvironmentProvider().WorkingDirectory;
Mocker.Resolve<DiskProvider>().GetLastDirectoryWrite(appPath).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-10));
Mocker.Resolve<DiskProvider>().GetLastDirectoryWrite(appPath).Should().BeBefore(DateTime.UtcNow);
Mocker.Resolve<DiskProvider>().GetLastFolderWrite(appPath).Should().BeOnOrAfter(DateTime.UtcNow.AddMinutes(-10));
Mocker.Resolve<DiskProvider>().GetLastFolderWrite(appPath).Should().BeBefore(DateTime.UtcNow);
}
[Test]
[Explicit]
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);
}

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

@ -1,28 +1,22 @@

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

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

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

@ -1,30 +1,23 @@

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

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

@ -1,30 +1,24 @@

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

@ -1,26 +1,22 @@

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

@ -1,38 +1,28 @@

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

@ -1,17 +1,13 @@

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

@ -1,16 +1,12 @@

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

@ -43,7 +43,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
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}");
Mocker.Resolve<NzbgetProvider>()
Mocker.Resolve<NzbgetClient>()
.DownloadNzb(url, title, false)
.Should()
.BeTrue();
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
{
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));
}
}
}

@ -50,7 +50,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
{
WithEmptyQueue();
Mocker.Resolve<NzbgetProvider>()
Mocker.Resolve<NzbgetClient>()
.GetQueue()
.Should()
.BeEmpty();
@ -61,7 +61,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
{
WithFullQueue();
Mocker.Resolve<NzbgetProvider>()
Mocker.Resolve<NzbgetClient>()
.GetQueue()
.Should()
.HaveCount(1);
@ -72,7 +72,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
{
WithFailResponse();
Assert.Throws<ApplicationException>(() => Mocker.Resolve<NzbgetProvider>().GetQueue());
Assert.Throws<ApplicationException>(() => Mocker.Resolve<NzbgetClient>().GetQueue());
}
}
}

@ -42,7 +42,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
[Test]
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());
}
@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
{
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());
}
@ -62,7 +62,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
{
WithFailedDownload();
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, title, false).Should().BeFalse();
Mocker.Resolve<PneumaticClient>().DownloadNzb(nzbUrl, title, false).Should().BeFalse();
ExceptionVerification.ExpectedWarns(1);
}
@ -70,7 +70,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
[Test]
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]
@ -79,7 +79,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
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");
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());
}

@ -1,4 +1,4 @@
using System;
/*using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
@ -22,7 +22,6 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
[SetUp]
public void Setup()
{
string sabHost = "192.168.5.55";
int sabPort = 2222;
string apikey = "5c770e3197e4fe763423ee7c392c25d1";
@ -77,7 +76,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithEmptyQueue();
var result = Mocker.Resolve<SabProvider>().GetQueue();
var result = Mocker.Resolve<SabnzbdClient>().GetQueue();
result.Should().BeEmpty();
}
@ -87,7 +86,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithFailResponse();
Assert.Throws<ApplicationException>(() => Mocker.Resolve<SabProvider>().GetQueue(), "API Key Incorrect");
Assert.Throws<ApplicationException>(() => Mocker.Resolve<SabnzbdClient>().GetQueue(), "API Key Incorrect");
}
[Test]
@ -95,7 +94,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithFullQueue();
var result = Mocker.Resolve<SabProvider>().GetQueue();
var result = Mocker.Resolve<SabnzbdClient>().GetQueue();
result.Should().HaveCount(7);
}
@ -105,10 +104,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithUnknownPriorityQueue();
var result = Mocker.Resolve<SabProvider>().GetQueue();
var result = Mocker.Resolve<SabnzbdClient>().GetQueue();
result.Should().HaveCount(7);
result.Should().OnlyContain(i => i.Priority == SabPriorityType.Normal);
}
[Test]
@ -116,7 +114,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithFullQueue();
var parseResult = new IndexerParseResult
var parseResult = new RemoteEpisode
{
EpisodeTitle = "Title",
EpisodeNumbers = new List<int> { 5 },
@ -126,7 +124,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
};
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult);
var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeTrue();
}
@ -136,7 +134,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithFullQueue();
var parseResult = new IndexerParseResult
var parseResult = new RemoteEpisode
{
Quality = new QualityModel { Quality = Quality.Bluray720p, Proper = false },
AirDate = new DateTime(2011, 12, 01),
@ -144,7 +142,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
};
var result = Mocker.Resolve<SabProvider>().IsInQueue(parseResult);
var result = Mocker.Resolve<SabnzbdClient>().IsInQueue(parseResult);
result.Should().BeTrue();
}
@ -155,7 +153,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
WithFullQueue();
var parseResult = new IndexerParseResult
var parseResult = new RemoteEpisode
{
Quality = new QualityModel { Quality = Quality.Bluray720p, Proper = false },
FullSeason = true,
@ -163,7 +161,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
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();
}
@ -184,7 +182,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithFullQueue();
var parseResult = new IndexerParseResult
var parseResult = new RemoteEpisode
{
EpisodeTitle = "Title",
EpisodeNumbers = new List<int>(episodes),
@ -193,7 +191,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
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();
}
@ -213,7 +211,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithFullQueue();
var parseResult = new IndexerParseResult
var parseResult = new RemoteEpisode
{
EpisodeTitle = "Title",
EpisodeNumbers = new List<int>(episodes),
@ -222,7 +220,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
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();
}
@ -240,7 +238,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithFullQueue();
var parseResult = new IndexerParseResult
var parseResult = new RemoteEpisode
{
EpisodeTitle = "Title",
EpisodeNumbers = new List<int>(episodes),
@ -249,7 +247,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
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();
}
@ -267,7 +265,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithFullQueue();
var parseResult = new IndexerParseResult
var parseResult = new RemoteEpisode
{
EpisodeTitle = "Title",
EpisodeNumbers = new List<int>(episodes),
@ -276,7 +274,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
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();
}
@ -286,7 +284,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithEmptyQueue();
var parseResult = new IndexerParseResult
var parseResult = new RemoteEpisode
{
EpisodeTitle = "Title",
EpisodeNumbers = new List<int> { 1 },
@ -295,7 +293,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
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();
}
@ -305,7 +303,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
WithFullQueue();
var result = Mocker.Resolve<SabProvider>().GetQueue();
var result = Mocker.Resolve<SabnzbdClient>().GetQueue();
result.Should().NotBeEmpty();
var timeleft = result.First(q => q.Id == "SABnzbd_nzo_qv6ilb").Timeleft;
@ -323,4 +321,4 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
}
}
}*/

@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.Returns("{ \"status\": true }");
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, false).Should().BeTrue();
Mocker.Resolve<SabnzbdClient>().DownloadNzb(url, title, false).Should().BeTrue();
}
[Test]
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
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);
}
@ -75,7 +75,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.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();
@ -90,7 +90,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.Returns(ReadAllText("Files","Categories_json.txt"));
var result = Mocker.Resolve<SabProvider>().GetCategories();
var result = Mocker.Resolve<SabnzbdClient>().GetCategories();
result.Should().NotBeNull();
@ -105,7 +105,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.Returns(ReadAllText("Files", "History.txt"));
var result = Mocker.Resolve<SabProvider>().GetHistory();
var result = Mocker.Resolve<SabnzbdClient>().GetHistory();
result.Should().HaveCount(1);
@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.Returns(ReadAllText("Files","HistoryEmpty.txt"));
var result = Mocker.Resolve<SabProvider>().GetHistory();
var result = Mocker.Resolve<SabnzbdClient>().GetHistory();
result.Should().BeEmpty();
@ -133,7 +133,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.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]
@ -146,7 +146,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.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();
@ -163,7 +163,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.Returns(response);
var result = Mocker.Resolve<SabProvider>().GetVersion();
var result = Mocker.Resolve<SabnzbdClient>().GetVersion();
result.Should().NotBeNull();
@ -180,7 +180,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.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");
@ -192,7 +192,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
Mocker.GetMock<IHttpProvider>()
.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);
}
@ -212,7 +212,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.Returns("{ \"status\": true }");
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, true).Should().BeTrue();
Mocker.Resolve<SabnzbdClient>().DownloadNzb(url, title, true).Should().BeTrue();
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());
@ -234,7 +234,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.Returns("{ \"status\": true }");
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, false).Should().BeTrue();
Mocker.Resolve<SabnzbdClient>().DownloadNzb(url, title, false).Should().BeTrue();
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());

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

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

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

@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.JobTests
{
Mocker.GetMock<EnvironmentProvider>().SetupGet(c => c.SystemTemp).Returns(@"C:\Temp\");
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 @@ namespace NzbDrone.Core.Test.JobTests
[Test]
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();

@ -35,10 +35,6 @@ namespace NzbDrone.Core.Test.JobTests
.Setup(p => p.Get(series.Id))
.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 });
@ -60,13 +56,6 @@ namespace NzbDrone.Core.Test.JobTests
.Setup(p => p.All())
.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);
@ -113,14 +102,6 @@ namespace NzbDrone.Core.Test.JobTests
.Setup(p => p.All())
.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.VerifyAllMocks();

@ -31,10 +31,10 @@ namespace NzbDrone.Core.Test.JobTests
{
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.GetMock<PostDownloadProvider>().Verify(s => s.ProcessDropFolder(path), Times.Once());
Mocker.GetMock<DropFolderImportService>().Verify(s => s.ProcessDropFolder(path), Times.Once());
}
[Test]
@ -42,7 +42,7 @@ namespace NzbDrone.Core.Test.JobTests
{
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.GetMock<IConfigService>().Verify(s => s.DownloadClientTvDirectory, Times.Never());
@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.JobTests
Mocker.GetMock<IConfigService>().SetupGet(s => s.DownloadClientTvDirectory).Returns(path);
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());
}
}
}

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

@ -6,6 +6,8 @@ using NUnit.Framework;
using NzbDrone.Common.Contract;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
@ -79,16 +81,15 @@ namespace NzbDrone.Core.Test.ParserTests
[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)
{
var result = Parser.ParseTitle<IndexerParseResult>(postTitle);
var result = Parser.Parser.ParseTitle(postTitle);
result.Should().NotBeNull();
result.EpisodeNumbers.Should().HaveCount(1);
result.SeasonNumber.Should().Be(seasonNumber);
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);
}
[Test]
[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\robot chicken\Specials\S00E16 - Dear Consumer - SD TV.avi", 0, 16)]
@ -101,7 +102,7 @@ namespace NzbDrone.Core.Test.ParserTests
[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)
{
var result = Parser.ParsePath(path);
var result = Parser.Parser.ParsePath(path);
result.EpisodeNumbers.Should().HaveCount(1);
result.SeasonNumber.Should().Be(season);
result.EpisodeNumbers[0].Should().Be(episode);
@ -113,7 +114,7 @@ namespace NzbDrone.Core.Test.ParserTests
[Test]
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));
@ -125,7 +126,7 @@ namespace NzbDrone.Core.Test.ParserTests
{
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());
@ -153,10 +154,10 @@ namespace NzbDrone.Core.Test.ParserTests
[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)
{
var result = Parser.ParseTitle<ParseResult>(postTitle);
var result = Parser.Parser.ParseTitle(postTitle);
result.SeasonNumber.Should().Be(season);
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);
}
@ -173,10 +174,10 @@ namespace NzbDrone.Core.Test.ParserTests
[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)
{
var result = Parser.ParseTitle<ParseResult>(postTitle);
var result = Parser.Parser.ParseTitle(postTitle);
var airDate = new DateTime(year, month, day);
result.Should().NotBeNull();
result.CleanTitle.Should().Be(Parser.NormalizeTitle(title));
result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title));
result.AirDate.Should().Be(airDate);
result.EpisodeNumbers.Should().BeNull();
result.OriginalString.Should().Be(postTitle);
@ -187,7 +188,7 @@ namespace NzbDrone.Core.Test.ParserTests
{
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 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Adventure Time S02 720p HDTV x264 CRON", "Adventure Time", 2)]
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.CleanTitle.Should().Be(Parser.NormalizeTitle(title));
result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title));
result.EpisodeNumbers.Count.Should().Be(0);
result.FullSeason.Should().BeTrue();
result.OriginalString.Should().Be(postTitle);
@ -213,7 +214,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Parenthood.2010", "parenthood2010")]
public void series_name_normalize(string parsedSeriesName, string seriesName)
{
var result = Parser.NormalizeTitle(parsedSeriesName);
var result = Parser.Parser.NormalizeTitle(parsedSeriesName);
result.Should().Be(seriesName);
}
@ -225,7 +226,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("24", "24")]
public void Normalize_Title(string dirty, string clean)
{
var result = Parser.NormalizeTitle(dirty);
var result = Parser.Parser.NormalizeTitle(dirty);
result.Should().Be(clean);
}
@ -253,7 +254,7 @@ namespace NzbDrone.Core.Test.ParserTests
foreach (var s in dirtyFormat)
{
var dirty = String.Format(s, word);
Parser.NormalizeTitle(dirty).Should().Be("wordword");
Parser.Parser.NormalizeTitle(dirty).Should().Be("wordword");
}
}
@ -279,7 +280,7 @@ namespace NzbDrone.Core.Test.ParserTests
foreach (var s in dirtyFormat)
{
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 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Adventure Time S02 720p HDTV x264 CRON", "adventuretime")]
public void parse_series_name(string postTitle, string title)
{
var result = Parser.ParseSeriesName(postTitle);
result.Should().Be(Parser.NormalizeTitle(title));
var result = Parser.Parser.ParseSeriesName(postTitle);
result.Should().Be(Parser.Parser.NormalizeTitle(title));
}
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", LanguageType.English)]
[TestCase("Castle.2009.S01E14.French.HDTV.XviD-LOL", LanguageType.French)]
[TestCase("Castle.2009.S01E14.Spanish.HDTV.XviD-LOL", LanguageType.Spanish)]
[TestCase("Castle.2009.S01E14.German.HDTV.XviD-LOL", LanguageType.German)]
[TestCase("Castle.2009.S01E14.Germany.HDTV.XviD-LOL", LanguageType.English)]
[TestCase("Castle.2009.S01E14.Italian.HDTV.XviD-LOL", LanguageType.Italian)]
[TestCase("Castle.2009.S01E14.Danish.HDTV.XviD-LOL", LanguageType.Danish)]
[TestCase("Castle.2009.S01E14.Dutch.HDTV.XviD-LOL", LanguageType.Dutch)]
[TestCase("Castle.2009.S01E14.Japanese.HDTV.XviD-LOL", LanguageType.Japanese)]
[TestCase("Castle.2009.S01E14.Cantonese.HDTV.XviD-LOL", LanguageType.Cantonese)]
[TestCase("Castle.2009.S01E14.Mandarin.HDTV.XviD-LOL", LanguageType.Mandarin)]
[TestCase("Castle.2009.S01E14.Korean.HDTV.XviD-LOL", LanguageType.Korean)]
[TestCase("Castle.2009.S01E14.Russian.HDTV.XviD-LOL", LanguageType.Russian)]
[TestCase("Castle.2009.S01E14.Polish.HDTV.XviD-LOL", LanguageType.Polish)]
[TestCase("Castle.2009.S01E14.Vietnamese.HDTV.XviD-LOL", LanguageType.Vietnamese)]
[TestCase("Castle.2009.S01E14.Swedish.HDTV.XviD-LOL", LanguageType.Swedish)]
[TestCase("Castle.2009.S01E14.Norwegian.HDTV.XviD-LOL", LanguageType.Norwegian)]
[TestCase("Castle.2009.S01E14.Finnish.HDTV.XviD-LOL", LanguageType.Finnish)]
[TestCase("Castle.2009.S01E14.Turkish.HDTV.XviD-LOL", LanguageType.Turkish)]
[TestCase("Castle.2009.S01E14.Portuguese.HDTV.XviD-LOL", LanguageType.Portuguese)]
[TestCase("Castle.2009.S01E14.HDTV.XviD-LOL", LanguageType.English)]
[TestCase("person.of.interest.1x19.ita.720p.bdmux.x264-novarip", LanguageType.Italian)]
[TestCase("Salamander.S01E01.FLEMISH.HDTV.x264-BRiGAND", LanguageType.Flemish)]
[TestCase("H.Polukatoikia.S03E13.Greek.PDTV.XviD-Ouzo", LanguageType.Greek)]
[TestCase("Burn.Notice.S04E15.Brotherly.Love.GERMAN.DUBBED.WS.WEBRiP.XviD.REPACK-TVP", LanguageType.German)]
public void parse_language(string postTitle, LanguageType language)
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", Language.English)]
[TestCase("Castle.2009.S01E14.French.HDTV.XviD-LOL", Language.French)]
[TestCase("Castle.2009.S01E14.Spanish.HDTV.XviD-LOL", Language.Spanish)]
[TestCase("Castle.2009.S01E14.German.HDTV.XviD-LOL", Language.German)]
[TestCase("Castle.2009.S01E14.Germany.HDTV.XviD-LOL", Language.English)]
[TestCase("Castle.2009.S01E14.Italian.HDTV.XviD-LOL", Language.Italian)]
[TestCase("Castle.2009.S01E14.Danish.HDTV.XviD-LOL", Language.Danish)]
[TestCase("Castle.2009.S01E14.Dutch.HDTV.XviD-LOL", Language.Dutch)]
[TestCase("Castle.2009.S01E14.Japanese.HDTV.XviD-LOL", Language.Japanese)]
[TestCase("Castle.2009.S01E14.Cantonese.HDTV.XviD-LOL", Language.Cantonese)]
[TestCase("Castle.2009.S01E14.Mandarin.HDTV.XviD-LOL", Language.Mandarin)]
[TestCase("Castle.2009.S01E14.Korean.HDTV.XviD-LOL", Language.Korean)]
[TestCase("Castle.2009.S01E14.Russian.HDTV.XviD-LOL", Language.Russian)]
[TestCase("Castle.2009.S01E14.Polish.HDTV.XviD-LOL", Language.Polish)]
[TestCase("Castle.2009.S01E14.Vietnamese.HDTV.XviD-LOL", Language.Vietnamese)]
[TestCase("Castle.2009.S01E14.Swedish.HDTV.XviD-LOL", Language.Swedish)]
[TestCase("Castle.2009.S01E14.Norwegian.HDTV.XviD-LOL", Language.Norwegian)]
[TestCase("Castle.2009.S01E14.Finnish.HDTV.XviD-LOL", Language.Finnish)]
[TestCase("Castle.2009.S01E14.Turkish.HDTV.XviD-LOL", Language.Turkish)]
[TestCase("Castle.2009.S01E14.Portuguese.HDTV.XviD-LOL", Language.Portuguese)]
[TestCase("Castle.2009.S01E14.HDTV.XviD-LOL", Language.English)]
[TestCase("person.of.interest.1x19.ita.720p.bdmux.x264-novarip", Language.Italian)]
[TestCase("Salamander.S01E01.FLEMISH.HDTV.x264-BRiGAND", Language.Flemish)]
[TestCase("H.Polukatoikia.S03E13.Greek.PDTV.XviD-Ouzo", Language.Greek)]
[TestCase("Burn.Notice.S04E15.Brotherly.Love.GERMAN.DUBBED.WS.WEBRiP.XviD.REPACK-TVP", Language.German)]
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);
}
@ -339,9 +340,9 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Doctor Who Confidential Season 3", "Doctor Who Confidential", 3)]
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.FullSeason.Should().BeTrue();
result.OriginalString.Should().Be(postTitle);
@ -352,7 +353,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Instant Star S03 EXTRAS DVDRip XviD OSiTV")]
public void parse_season_extras(string postTitle)
{
var result = Parser.ParseTitle<ParseResult>(postTitle);
var result = Parser.Parser.ParseTitle(postTitle);
result.Should().BeNull();
}
@ -362,7 +363,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("CSI.S11.SUBPACK.DVDRip.XviD-REWARD")]
public void parse_season_subpack(string postTitle)
{
var result = Parser.ParseTitle<ParseResult>(postTitle);
var result = Parser.Parser.ParseTitle(postTitle);
result.Should().BeNull();
}
@ -370,7 +371,7 @@ namespace NzbDrone.Core.Test.ParserTests
[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)
{
Parser.ParseTitle<ParseResult>(title);
Parser.Parser.ParseTitle(title);
ExceptionVerification.IgnoreWarns();
ExceptionVerification.ExpectedErrors(1);
}
@ -386,7 +387,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("password - \"bdc435cb-93c4-4902-97ea-ca00568c3887.337\" yEnc")]
public void should_not_parse_encypted_posts(string title)
{
Parser.ParseTitle<ParseResult>(title).Should().BeNull();
Parser.Parser.ParseTitle(title).Should().BeNull();
ExceptionVerification.IgnoreWarns();
}
}

@ -96,7 +96,7 @@ namespace NzbDrone.Core.Test.ParserTests
[Test, TestCaseSource("QualityParserCases")]
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.Proper.Should().Be(proper);
}
@ -105,7 +105,7 @@ namespace NzbDrone.Core.Test.ParserTests
public void parsing_our_own_quality_enum(Quality 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);
}
}

@ -1,15 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.IO;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common.AutoMoq;
namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests
{
@ -19,7 +12,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests
[Test]
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)
result.Should().BeGreaterThan(0);
@ -27,7 +20,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests
[Test]
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"));
}
}
}

@ -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());
}
}
}

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

@ -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());
}
}
}

@ -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);
}
}
}

@ -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());
}
}
}

@ -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));
}
}
}

@ -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());
}
}
}

@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
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));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>()))
@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests
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));
Mocker.GetMock<DiskProvider>().Setup(s => s.GetLastFileWrite(It.IsAny<String>()))

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FluentAssertions;
using Moq;
using NUnit.Framework;
@ -16,7 +15,7 @@ using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.RootFolderTests
{
[TestFixture]
public class FreeSpaceOnDrivesFixture : CoreTest<RootFolderService>
{
[Test]
@ -31,7 +30,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
.Returns(@"C:\");
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(@"C:\"))
.Setup(s => s.GetAvilableSpace(@"C:\"))
.Returns(123456);
var result = Subject.FreeSpaceOnDrives();
@ -52,7 +51,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
.Returns(@"C:\");
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(@"C:\"))
.Setup(s => s.GetAvilableSpace(@"C:\"))
.Returns(123456);
var result = Subject.FreeSpaceOnDrives();
@ -77,7 +76,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
.Returns(@"D:\");
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(It.IsAny<string>()))
.Setup(s => s.GetAvilableSpace(It.IsAny<string>()))
.Returns(123456);
var result = Subject.FreeSpaceOnDrives();
@ -97,7 +96,7 @@ namespace NzbDrone.Core.Test.RootFolderTests
.Returns(@"C:\");
Mocker.GetMock<DiskProvider>()
.Setup(s => s.FreeDiskSpace(It.IsAny<string>()))
.Setup(s => s.GetAvilableSpace(It.IsAny<string>()))
.Throws(new DirectoryNotFoundException());
var result = Subject.FreeSpaceOnDrives();

@ -25,7 +25,10 @@ namespace NzbDrone.Core.Test.UpdateTests
[TestCase("1.0.0.0")]
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();
}
@ -33,7 +36,9 @@ namespace NzbDrone.Core.Test.UpdateTests
[Test]
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();
}
@ -43,7 +48,9 @@ namespace NzbDrone.Core.Test.UpdateTests
[TestCase("0.0.10.10")]
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.Version.Should().Be(LatestTestVersion);

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

@ -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>
{
}
}

@ -1,12 +1,14 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine
{
public class DownloadDecision
{
public IndexerParseResult ParseResult { get; private set; }
public RemoteEpisode Episode { get; private set; }
public IEnumerable<string> Rejections { get; private set; }
public bool Approved
@ -17,23 +19,10 @@ namespace NzbDrone.Core.DecisionEngine
}
}
public DownloadDecision(IndexerParseResult parseResult, params string[] rejections)
public DownloadDecision(RemoteEpisode episode, params string[] rejections)
{
ParseResult = parseResult;
Episode = episode;
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();
}
}
}

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

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

@ -1,5 +1,8 @@
using System.Linq;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
@ -23,7 +26,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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);
@ -47,24 +50,19 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
//Multiply maxSize by 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)
//TODO: is this check really necessary? shouldn't we blowup?
if (subject.EpisodeNumbers != null)
maxSize = maxSize * subject.EpisodeNumbers.Count;
maxSize = maxSize * subject.Episodes.Count;
//Check if there was only one episode parsed
//and it is the first or last episode of the season
if (subject.EpisodeNumbers != null && subject.EpisodeNumbers.Count == 1 &&
_episodeService.IsFirstOrLastEpisodeOfSeason(series.Id,
subject.SeasonNumber, subject.EpisodeNumbers[0]))
if (subject.Episodes.Count == 1 && _episodeService.IsFirstOrLastEpisodeOfSeason(subject.Episodes.Single().Id))
{
maxSize = maxSize * 2;
}
//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;
}

@ -2,6 +2,8 @@ using System;
using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
@ -25,7 +27,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
}
}
public virtual bool IsSatisfiedBy(IndexerParseResult subject)
public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{
_logger.Trace("Beginning release group check for: {0}", subject);
@ -37,16 +39,18 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
if (string.IsNullOrWhiteSpace(allowed))
return true;
var releaseGroup = subject.Report.ReleaseGroup;
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;
}
}
_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;
}
}

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

@ -1,5 +1,7 @@
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
@ -20,10 +22,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
}
}
public virtual bool IsSatisfiedBy(IndexerParseResult subject)
public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{
_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);
return false;

@ -1,6 +1,8 @@
using System.Linq;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.DecisionEngine.Specifications
@ -26,29 +28,16 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
}
}
public virtual bool IsSatisfiedBy(IndexerParseResult subject)
public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{
var series = _seriesRepository.GetByTitle(subject.CleanTitle);
if (series == null)
if (!subject.Series.Monitored)
{
_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;
}
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
if (episodes.Any(episode => !episode.Ignored))
if (subject.Episodes.Any(episode => !episode.Ignored))
{
return true;
}

@ -1,6 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.Download;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
@ -21,9 +27,34 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
}
}
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)));
}
}

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

@ -1,6 +1,8 @@
using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
@ -24,12 +26,14 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
}
}
public virtual bool IsSatisfiedBy(IndexerParseResult subject)
public virtual bool IsSatisfiedBy(RemoteEpisode subject)
{
_logger.Trace("Checking if report meets retention requirements. {0}", subject.Age);
if (_configService.Retention > 0 && subject.Age > _configService.Retention)
var age = subject.Report.Age;
_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;
}

@ -1,6 +1,8 @@
using NLog;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.DecisionEngine.Specifications.Search
@ -23,7 +25,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
return "Episode doesn't match";
}
}
public bool IsSatisfiedBy(IndexerParseResult indexerParseResult, SearchDefinitionBase searchDefinitionBase)
public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchDefinitionBase searchDefinitionBase)
{
var dailySearchSpec = searchDefinitionBase as DailyEpisodeSearchDefinition;
@ -31,7 +33,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
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.");
return false;

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

@ -1,6 +1,8 @@
using NLog;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications.Search
{
@ -21,17 +23,17 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
}
}
public bool IsSatisfiedBy(IndexerParseResult indexerParseResult, SearchDefinitionBase searchDefinitionBase)
public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchDefinitionBase searchDefinitionBase)
{
var singleEpisodeSpec = searchDefinitionBase as SeasonSearchDefinition;
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.");
return false;
}
return true;
}
}

@ -1,14 +1,17 @@
using System.Linq;
using NLog;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications.Search
{
public class SingleEpisodeMatchSpecification : IDecisionEngineSearchSpecification
public class SingleEpisodeSearchMatchSpecification : IDecisionEngineSearchSpecification
{
private readonly Logger _logger;
public SingleEpisodeMatchSpecification(Logger logger)
public SingleEpisodeSearchMatchSpecification(Logger logger)
{
_logger = logger;
}
@ -21,18 +24,18 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
}
}
public bool IsSatisfiedBy(IndexerParseResult indexerParseResult, SearchDefinitionBase searchDefinitionBase)
public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchDefinitionBase searchDefinitionBase)
{
var singleEpisodeSpec = searchDefinitionBase as SingleEpisodeSearchDefinition;
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.");
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.");
return false;

@ -1,8 +1,7 @@
using System;
using System.Linq;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
@ -25,13 +24,16 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
}
}
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))
{
_logger.Trace("Comparing file quality with report. Existing file is {0}", file.Quality);
if (!_qualityUpgradableSpecification.IsUpgradable(subject.Series.QualityProfile, file.Quality, subject.Quality))
{
return false;
}
if (subject.Quality.Proper && file.DateAdded < DateTime.Today.AddDays(-7))
{

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

@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.IO;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Model;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download.Clients
{
@ -14,24 +16,25 @@ namespace NzbDrone.Core.Download.Clients
private readonly IConfigService _configService;
private readonly IHttpProvider _httpProvider;
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,
DiskProvider diskProvider, UpgradeHistorySpecification upgradeHistorySpecification)
DiskProvider diskProvider, Logger logger)
{
_configService = configService;
_httpProvider = httpProvider;
_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
{
@ -42,26 +45,26 @@ namespace NzbDrone.Core.Download.Clients
if (_diskProvider.FileExists(filename))
{
//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;
}
logger.Trace("Downloading NZB from: {0} to: {1}", url, filename);
_logger.Trace("Downloading NZB from: {0} to: {1}", 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;
}
catch (Exception ex)
{
logger.WarnException("Failed to download NZB: " + url, ex);
_logger.WarnException("Failed to download NZB: " + url, ex);
return false;
}
}
public virtual bool IsInQueue(IndexerParseResult newParseResult)
public IEnumerable<QueueItem> GetQueue()
{
return !_upgradeHistorySpecification.IsSatisfiedBy(newParseResult);
return new QueueItem[0];
}
}
}

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

@ -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; }
}
}

@ -1,66 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Newtonsoft.Json;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Download.Clients.Nzbget
{
public class NzbgetProvider : IDownloadClient
public class NzbgetClient : IDownloadClient
{
private readonly IConfigService _configService;
private readonly IHttpProvider _httpProvider;
private readonly Logger _logger;
public NzbgetProvider(IConfigService configService, IHttpProvider httpProvider, Logger logger)
public NzbgetClient(IConfigService configService, IHttpProvider httpProvider, Logger logger)
{
_configService = configService;
_httpProvider = httpProvider;
_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)
{
try
@ -71,7 +31,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
var command = new JsonRequest
{
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);
@ -93,19 +53,30 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
return false;
}
public virtual List<QueueItem> GetQueue()
public virtual IEnumerable<QueueItem> GetQueue()
{
var command = new JsonRequest
{
Method = "listgroups",
Params = null
Method = "listgroups",
Params = null
};
var response = PostCommand(JsonConvert.SerializeObject(command));
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)
@ -144,11 +115,11 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
var version = GetVersion(host, port, username, password);
return version.Result;
}
catch(Exception ex)
catch (Exception ex)
{
_logger.DebugException("Failed to Test Nzbget", ex);
}
return String.Empty;
}

@ -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; }
}
}

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
@ -9,10 +10,12 @@ using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Model;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download.Clients
{
public class PneumaticProvider : IDownloadClient
public class PneumaticClient : IDownloadClient
{
private readonly IConfigService _configService;
private readonly IHttpProvider _httpProvider;
@ -20,7 +23,7 @@ namespace NzbDrone.Core.Download.Clients
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public PneumaticProvider(IConfigService configService, IHttpProvider httpProvider,
public PneumaticClient(IConfigService configService, IHttpProvider httpProvider,
DiskProvider diskProvider)
{
_configService = configService;
@ -33,7 +36,7 @@ namespace NzbDrone.Core.Download.Clients
try
{
//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);
return false;
@ -68,7 +71,12 @@ namespace NzbDrone.Core.Download.Clients
}
}
public virtual bool IsInQueue(IndexerParseResult newParseResult)
public IEnumerable<QueueItem> GetQueue()
{
return new QueueItem[0];
}
public virtual bool IsInQueue(RemoteEpisode newEpisode)
{
return false;
}

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

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

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using Newtonsoft.Json;
@ -8,61 +7,21 @@ using Newtonsoft.Json.Linq;
using NLog;
using NzbDrone.Common;
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
{
public class SabProvider : IDownloadClient
public class SabnzbdClient : IDownloadClient
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private readonly IConfigService _configService;
private readonly IHttpProvider _httpProvider;
public SabProvider(IConfigService configService, IHttpProvider httpProvider)
public SabnzbdClient(IConfigService configService, IHttpProvider httpProvider)
{
_configService = configService;
_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)
{
try
@ -80,7 +39,7 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
logger.Info("Adding report [{0}] to the queue.", title);
var response = _httpProvider.DownloadString(request);
logger.Debug("Queue Response: [{0}]", response);
CheckForError(response);
@ -95,15 +54,26 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
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 response = _httpProvider.DownloadString(request);
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)
@ -191,11 +161,11 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
var version = GetVersion(host, port, apiKey, username, password);
return version.Version;
}
catch(Exception ex)
catch (Exception ex)
{
logger.DebugException("Failed to Test SABnzbd", ex);
}
return String.Empty;
}

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

@ -6,13 +6,15 @@ using NzbDrone.Common.Eventing;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Download
{
public interface IDownloadService
{
bool DownloadReport(IndexerParseResult parseResult);
bool DownloadReport(RemoteEpisode episode);
}
public class DownloadService : IDownloadService
@ -32,31 +34,31 @@ namespace NzbDrone.Core.Download
_logger = logger;
}
public bool DownloadReport(IndexerParseResult parseResult)
public bool DownloadReport(RemoteEpisode episode)
{
var downloadTitle = parseResult.OriginalString;
var downloadTitle = episode.Report.Title;
if (!_configService.DownloadClientUseSceneName)
{
downloadTitle = parseResult.GetDownloadTitle();
downloadTitle = episode.GetDownloadTitle();
}
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)
{
_logger.Info("Report sent to download client. {0}", downloadTitle);
_eventAggregator.Publish(new EpisodeGrabbedEvent(parseResult));
_eventAggregator.Publish(new EpisodeGrabbedEvent(episode));
}
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));
}
}
}

@ -1,15 +1,17 @@
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Download
{
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;
}
}
}

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

@ -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; }
}
}

@ -83,7 +83,7 @@ namespace NzbDrone.Core.ExternalNotification
try
{
_logger.Trace("Sending grab notification to {0}", Name);
OnGrab(message.ParseResult.GetDownloadTitle());
OnGrab(message.Episode.GetDownloadTitle());
}
catch (Exception e)
@ -100,7 +100,7 @@ namespace NzbDrone.Core.ExternalNotification
try
{
_logger.Trace("Sending download notification to {0}", Name);
OnDownload(message.ParseResult.ToString(), message.ParseResult.Series);
OnDownload(message.ParseResult.ToString(), message.Series);
}
catch (Exception e)
{

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

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

@ -7,6 +7,8 @@ using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
using System.Linq;
@ -105,10 +107,10 @@ namespace NzbDrone.Core.IndexerSearch
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 parseResults = new List<IndexerParseResult>();
var parseResults = new List<ReportInfo>();
Parallel.ForEach(indexers, indexer =>
{

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

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

@ -5,17 +5,19 @@ using NLog;
using NzbDrone.Common;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers
{
public interface IFetchFeedFromIndexers
{
IList<IndexerParseResult> FetchRss(IIndexerBase indexer);
IList<ReportInfo> FetchRss(IIndexerBase indexer);
IList<IndexerParseResult> Fetch(IIndexerBase indexer, SeasonSearchDefinition searchDefinition);
IList<IndexerParseResult> Fetch(IIndexerBase indexer, SingleEpisodeSearchDefinition searchDefinition);
IList<IndexerParseResult> Fetch(IIndexerBase indexer, PartialSeasonSearchDefinition searchDefinition);
IList<IndexerParseResult> Fetch(IIndexerBase indexer, DailyEpisodeSearchDefinition searchDefinition);
IList<ReportInfo> Fetch(IIndexerBase indexer, SeasonSearchDefinition searchDefinition);
IList<ReportInfo> Fetch(IIndexerBase indexer, SingleEpisodeSearchDefinition searchDefinition);
IList<ReportInfo> Fetch(IIndexerBase indexer, PartialSeasonSearchDefinition searchDefinition);
IList<ReportInfo> Fetch(IIndexerBase indexer, DailyEpisodeSearchDefinition searchDefinition);
}
public class FetchFeedService : IFetchFeedFromIndexers
@ -31,7 +33,7 @@ namespace NzbDrone.Core.Indexers
}
public virtual IList<IndexerParseResult> FetchRss(IIndexerBase indexer)
public virtual IList<ReportInfo> FetchRss(IIndexerBase indexer)
{
_logger.Debug("Fetching feeds from " + indexer.Name);
@ -42,7 +44,7 @@ namespace NzbDrone.Core.Indexers
return result;
}
public IList<IndexerParseResult> Fetch(IIndexerBase indexer, SeasonSearchDefinition searchDefinition)
public IList<ReportInfo> Fetch(IIndexerBase indexer, SeasonSearchDefinition searchDefinition)
{
_logger.Debug("Searching for {0}", searchDefinition);
@ -54,7 +56,7 @@ namespace NzbDrone.Core.Indexers
return result;
}
public IList<IndexerParseResult> Fetch(IIndexerBase indexer, SingleEpisodeSearchDefinition searchDefinition)
public IList<ReportInfo> Fetch(IIndexerBase indexer, SingleEpisodeSearchDefinition searchDefinition)
{
_logger.Debug("Searching for {0}", searchDefinition);
@ -67,7 +69,7 @@ namespace NzbDrone.Core.Indexers
}
public IList<IndexerParseResult> Fetch(IIndexerBase indexer, PartialSeasonSearchDefinition searchDefinition)
public IList<ReportInfo> Fetch(IIndexerBase indexer, PartialSeasonSearchDefinition searchDefinition)
{
_logger.Debug("Searching for {0}", searchDefinition);
@ -79,7 +81,7 @@ namespace NzbDrone.Core.Indexers
return result;
}
public IList<IndexerParseResult> Fetch(IIndexerBase indexer, DailyEpisodeSearchDefinition searchDefinition)
public IList<ReportInfo> Fetch(IIndexerBase indexer, DailyEpisodeSearchDefinition searchDefinition)
{
_logger.Debug("Searching for {0}", searchDefinition);
@ -90,9 +92,9 @@ namespace NzbDrone.Core.Indexers
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)
{

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

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

@ -2,6 +2,8 @@ using System;
using System.ServiceModel.Syndication;
using System.Text.RegularExpressions;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.NzbIndex
{
@ -18,7 +20,7 @@ namespace NzbDrone.Core.Indexers.NzbIndex
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)
{

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

@ -4,6 +4,8 @@ using System.IO;
using NLog;
using Newtonsoft.Json;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.Nzbx
{
@ -18,9 +20,9 @@ namespace NzbDrone.Core.Indexers.Nzbx
_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 feed = _serializer.Deserialize<List<NzbxRecentItem>>(jsonReader);
@ -28,18 +30,14 @@ namespace NzbDrone.Core.Indexers.Nzbx
{
try
{
var episodeParseResult = Parser.ParseTitle<IndexerParseResult>(item.Name);
if (episodeParseResult != null)
{
episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PostDate).Days;
episodeParseResult.OriginalString = item.Name;
episodeParseResult.SceneSource = true;
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;
var episodeParseResult = new ReportInfo();
episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PostDate).Days;
episodeParseResult.Title = item.Name;
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)
{

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

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

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

@ -12,13 +12,13 @@ namespace NzbDrone.Core.Jobs.Implementations
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly PostDownloadProvider _postDownloadProvider;
private readonly DropFolderImportService _dropFolderImportService;
private readonly IConfigService _configService;
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;
_diskProvider = diskProvider;
}
@ -59,7 +59,7 @@ namespace NzbDrone.Core.Jobs.Implementations
return;
}
_postDownloadProvider.ProcessDropFolder(dropFolder);
_dropFolderImportService.ProcessDropFolder(dropFolder);
}
}
}

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

@ -26,8 +26,9 @@ namespace NzbDrone.Core.MediaFiles
public long Size { get; set; }
public DateTime DateAdded { get; set; }
public string SceneName { get; set; }
public string ReleaseGroup { get; set; }
public QualityModel Quality { get; set; }
public LazyList<Episode> Episodes { get; set; }
}
}

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

@ -1,15 +1,20 @@
using NzbDrone.Common.Eventing;
using NzbDrone.Core.Model;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.MediaFiles.Events
{
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;
Series = series;
}
}
}

@ -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;
}
}
}

@ -39,7 +39,9 @@ namespace NzbDrone.Core.MediaFiles
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)

@ -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
{
}
}

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

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

@ -53,7 +53,7 @@ namespace NzbDrone.Core.Organizer
var episodeNames = new List<string>
{
Parser.CleanupEpisodeTitle(sortedEpisodes.First().Title)
Parser.Parser.CleanupEpisodeTitle(sortedEpisodes.First().Title)
};
var result = String.Empty;
@ -85,7 +85,7 @@ namespace NzbDrone.Core.Organizer
}
result = result.Replace("%0e", String.Format("{0:00}", episode.EpisodeNumber));
episodeNames.Add(Parser.CleanupEpisodeTitle(episode.Title));
episodeNames.Add(Parser.Parser.CleanupEpisodeTitle(episode.Title));
}
}

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

@ -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(); } }
}
}

@ -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);
}
}
}

@ -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

Loading…
Cancel
Save