Merge remote-tracking branch 'origin/pneumatic'
This commit is contained in:
commit
0b8ca7c3b0
|
@ -0,0 +1 @@
|
||||||
|
plugin://plugin.program.pneumatic/?mode=strm&type=add_file&nzb=C:\Test\Pneumatic\30 Rock - 6x18 - Murphy Brown Lied to Us [SDTV].nzb&nzbname=30 Rock - 6x18 - Murphy Brown Lied to Us [SDTV]
|
|
@ -0,0 +1 @@
|
||||||
|
plugin://plugin.program.pneumatic/?mode=strm&type=add_file&nzb=C:\Test\Pneumatic\30 Rock - 6x19 - Live from Studio 6H (East Coast) [SDTV] [Proper].nzb&nzbname=30 Rock - 6x19 - Live from Studio 6H (East Coast) [SDTV] [Proper]
|
|
@ -0,0 +1 @@
|
||||||
|
plugin://plugin.program.pneumatic/?mode=strm&type=add_file&nzb=C:\Test\Pneumatic\30 Rock - 6x21 - The Return of Avery Jessup [SDTV].nzb&nzbname=30 Rock - 6x21 - The Return of Avery Jessup [SDTV]
|
|
@ -42,6 +42,14 @@ namespace NzbDrone.Common
|
||||||
.Max(c => c.LastWriteTimeUtc);
|
.Max(c => c.LastWriteTimeUtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual DateTime GetLastFileWrite(string path)
|
||||||
|
{
|
||||||
|
if (!FileExists(path))
|
||||||
|
throw new FileNotFoundException("File doesn't exist: " + path);
|
||||||
|
|
||||||
|
return new FileInfo(path).LastWriteTimeUtc;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual bool FolderExists(string path)
|
public virtual bool FolderExists(string path)
|
||||||
{
|
{
|
||||||
return Directory.Exists(path);
|
return Directory.Exists(path);
|
||||||
|
@ -209,5 +217,13 @@ namespace NzbDrone.Common
|
||||||
{
|
{
|
||||||
return String.Equals(firstPath.NormalizePath(), secondPath.NormalizePath(), StringComparison.InvariantCultureIgnoreCase);
|
return String.Equals(firstPath.NormalizePath(), secondPath.NormalizePath(), StringComparison.InvariantCultureIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual long GetFileSize(string path)
|
||||||
|
{
|
||||||
|
if (!FileExists(path))
|
||||||
|
throw new FileNotFoundException("File doesn't exist: " + path);
|
||||||
|
|
||||||
|
return new FileInfo(path).Length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -114,8 +114,15 @@
|
||||||
<Compile Include="ProviderTests\ConfigProviderTests\ConfigCachingFixture.cs" />
|
<Compile Include="ProviderTests\ConfigProviderTests\ConfigCachingFixture.cs" />
|
||||||
<Compile Include="ProviderTests\BannerProviderTest.cs" />
|
<Compile Include="ProviderTests\BannerProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\DecisionEngineTests\AllowedReleaseGroupSpecificationFixture.cs" />
|
<Compile Include="ProviderTests\DecisionEngineTests\AllowedReleaseGroupSpecificationFixture.cs" />
|
||||||
|
<Compile Include="ProviderTests\DiskScanProviderTests\CleanUpFixture.cs" />
|
||||||
|
<Compile Include="ProviderTests\DiskScanProviderTests\CleanUpDropFolderFixture.cs" />
|
||||||
|
<Compile Include="ProviderTests\DiskScanProviderTests\GetVideoFilesFixture.cs" />
|
||||||
|
<Compile Include="ProviderTests\DiskScanProviderTests\ScanFixture.cs" />
|
||||||
|
<Compile Include="ProviderTests\DownloadClientTests\PneumaticProviderFixture.cs" />
|
||||||
<Compile Include="ProviderTests\Metadata\Xbmc_ForEpisodeFile_Fixture.cs" />
|
<Compile Include="ProviderTests\Metadata\Xbmc_ForEpisodeFile_Fixture.cs" />
|
||||||
<Compile Include="ProviderTests\Metadata\Xbmc_ForSeries_Fixture.cs" />
|
<Compile Include="ProviderTests\Metadata\Xbmc_ForSeries_Fixture.cs" />
|
||||||
|
<Compile Include="ProviderTests\PostDownloadProviderTests\ProcessDropDirectoryFixture.cs" />
|
||||||
|
<Compile Include="ProviderTests\PostDownloadProviderTests\ProcessVideoFileFixture.cs" />
|
||||||
<Compile Include="ProviderTests\SearchHistoryProviderTest.cs" />
|
<Compile Include="ProviderTests\SearchHistoryProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\PlexProviderTest.cs" />
|
<Compile Include="ProviderTests\PlexProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\SeasonProviderTest.cs" />
|
<Compile Include="ProviderTests\SeasonProviderTest.cs" />
|
||||||
|
@ -139,9 +146,9 @@
|
||||||
<Compile Include="ProviderTests\ProwlProviderTest.cs" />
|
<Compile Include="ProviderTests\ProwlProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\GrowlProviderTest.cs" />
|
<Compile Include="ProviderTests\GrowlProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\DiskProviderTests\ExtractArchiveFixture.cs" />
|
<Compile Include="ProviderTests\DiskProviderTests\ExtractArchiveFixture.cs" />
|
||||||
<Compile Include="ProviderTests\PostDownloadProviderTests\PostDownloadProviderFixture.cs" />
|
<Compile Include="ProviderTests\PostDownloadProviderTests\GetFolderNameWithStatusFixture.cs" />
|
||||||
<Compile Include="JobTests\SearchJobTest.cs" />
|
<Compile Include="JobTests\SearchJobTest.cs" />
|
||||||
<Compile Include="ProviderTests\PostDownloadProviderTests\ProcessDownloadProviderFixture.cs" />
|
<Compile Include="ProviderTests\PostDownloadProviderTests\ProcessDownloadFixture.cs" />
|
||||||
<Compile Include="ProviderTests\JobProviderTests\TestJobs.cs" />
|
<Compile Include="ProviderTests\JobProviderTests\TestJobs.cs" />
|
||||||
<Compile Include="JobTests\AppUpdateJobFixture.cs" />
|
<Compile Include="JobTests\AppUpdateJobFixture.cs" />
|
||||||
<Compile Include="ProviderTests\UpdateProviderTests\GetUpdateLogFixture.cs" />
|
<Compile Include="ProviderTests\UpdateProviderTests\GetUpdateLogFixture.cs" />
|
||||||
|
@ -157,9 +164,9 @@
|
||||||
<Compile Include="ProviderTests\EventClientProviderTest.cs" />
|
<Compile Include="ProviderTests\EventClientProviderTest.cs" />
|
||||||
<Compile Include="CentralDispatchFixture.cs" />
|
<Compile Include="CentralDispatchFixture.cs" />
|
||||||
<Compile Include="ProviderTests\XbmcProviderTest.cs" />
|
<Compile Include="ProviderTests\XbmcProviderTest.cs" />
|
||||||
<Compile Include="ProviderTests\DiskScanProviderTest.cs" />
|
<Compile Include="ProviderTests\DiskScanProviderTests\MoveEpisodeFileFixture.cs" />
|
||||||
<Compile Include="ProviderTests\EpisodeProviderTest_GetEpisodesByParseResult.cs" />
|
<Compile Include="ProviderTests\EpisodeProviderTest_GetEpisodesByParseResult.cs" />
|
||||||
<Compile Include="ProviderTests\DiskScanProviderTest_ImportFile.cs" />
|
<Compile Include="ProviderTests\DiskScanProviderTests\ImportFileFixture.cs" />
|
||||||
<Compile Include="FluentTest.cs" />
|
<Compile Include="FluentTest.cs" />
|
||||||
<Compile Include="ProviderTests\LogProviderTests\LogProviderFixture.cs" />
|
<Compile Include="ProviderTests\LogProviderTests\LogProviderFixture.cs" />
|
||||||
<Compile Include="ProviderTests\UpcomingEpisodesProviderTest.cs" />
|
<Compile Include="ProviderTests\UpcomingEpisodesProviderTest.cs" />
|
||||||
|
|
|
@ -1,376 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using FizzWare.NBuilder;
|
|
||||||
using FluentAssertions;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Common;
|
|
||||||
using NzbDrone.Core.Model;
|
|
||||||
using NzbDrone.Core.Providers;
|
|
||||||
using NzbDrone.Core.Providers.Core;
|
|
||||||
using NzbDrone.Core.Repository;
|
|
||||||
using NzbDrone.Core.Repository.Quality;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Test.Common;
|
|
||||||
using NzbDrone.Test.Common.AutoMoq;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ProviderTests
|
|
||||||
{
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
public class DiskScanProviderTest : CoreTest
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void scan_series_should_update_the_last_scan_date()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<SeriesProvider>()
|
|
||||||
.Setup(c => c.UpdateSeries(It.Is<Series>(s => s.LastDiskSync != null))).Verifiable();
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(c => c.GetEpisodeBySeries(It.IsAny<long>()))
|
|
||||||
.Returns(new List<Episode> { new Episode() });
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>()
|
|
||||||
.Setup(c => c.FolderExists(It.IsAny<string>()))
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(c => c.GetSeriesFiles(It.IsAny<int>()))
|
|
||||||
.Returns(new List<EpisodeFile>());
|
|
||||||
|
|
||||||
Mocker.Resolve<DiskScanProvider>().Scan(new Series());
|
|
||||||
|
|
||||||
Mocker.VerifyAllMocks();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void cleanup_should_skip_existing_files()
|
|
||||||
{
|
|
||||||
WithStrictMocker();
|
|
||||||
var episodes = Builder<EpisodeFile>.CreateListOfSize(10).Build();
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>()
|
|
||||||
.Setup(e => e.FileExists(It.IsAny<String>()))
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
|
|
||||||
//Act
|
|
||||||
Mocker.Resolve<DiskScanProvider>().CleanUp(episodes);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Mocker.VerifyAllMocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void cleanup_should_delete_none_existing_files()
|
|
||||||
{
|
|
||||||
WithStrictMocker();
|
|
||||||
var episodes = Builder<EpisodeFile>.CreateListOfSize(10).Build();
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>()
|
|
||||||
.Setup(e => e.FileExists(It.IsAny<String>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(e => e.GetEpisodesByFileId(It.IsAny<int>()))
|
|
||||||
.Returns(new List<Episode>());
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(e => e.Delete(It.IsAny<int>()));
|
|
||||||
|
|
||||||
|
|
||||||
//Act
|
|
||||||
Mocker.Resolve<DiskScanProvider>().CleanUp(episodes);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Mocker.VerifyAllMocks();
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Verify(e => e.GetEpisodesByFileId(It.IsAny<int>()), Times.Exactly(10));
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Verify(e => e.Delete(It.IsAny<int>()), Times.Exactly(10));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void cleanup_should_delete_none_existing_files_remove_links_to_episodes()
|
|
||||||
{
|
|
||||||
WithStrictMocker();
|
|
||||||
var episodes = Builder<EpisodeFile>.CreateListOfSize(10).Build();
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>()
|
|
||||||
.Setup(e => e.FileExists(It.IsAny<String>()))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(e => e.GetEpisodesByFileId(It.IsAny<int>()))
|
|
||||||
.Returns(new List<Episode> { new Episode { EpisodeFileId = 10 }, new Episode { EpisodeFileId = 10 } });
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(e => e.UpdateEpisode(It.IsAny<Episode>()));
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(e => e.Delete(It.IsAny<int>()));
|
|
||||||
|
|
||||||
Mocker.GetMock<ConfigProvider>()
|
|
||||||
.SetupGet(s => s.AutoIgnorePreviouslyDownloadedEpisodes)
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
Mocker.Resolve<DiskScanProvider>().CleanUp(episodes);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Mocker.VerifyAllMocks();
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Verify(e => e.GetEpisodesByFileId(It.IsAny<int>()), Times.Exactly(10));
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Verify(e => e.UpdateEpisode(It.Is<Episode>(g=>g.EpisodeFileId == 0)), Times.Exactly(20));
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Verify(e => e.Delete(It.IsAny<int>()), Times.Exactly(10));
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Verify(e => e.Delete(It.IsAny<int>()), Times.Exactly(10));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void scan_series_should_log_warning_if_path_doesnt_exist_on_disk()
|
|
||||||
{
|
|
||||||
//Setup
|
|
||||||
WithStrictMocker();
|
|
||||||
|
|
||||||
var series = Builder<Series>.CreateNew()
|
|
||||||
.With(s => s.Path = @"C:\Test\TV\SeriesName\")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(c => c.CleanUpDatabase());
|
|
||||||
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>()
|
|
||||||
.Setup(c => c.FolderExists(series.Path))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
Mocker.Resolve<DiskScanProvider>().Scan(series, series.Path);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Mocker.VerifyAllMocks();
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void move_should_not_move_file_if_source_and_destination_are_the_same_path()
|
|
||||||
{
|
|
||||||
var fakeSeries = Builder<Series>.CreateNew()
|
|
||||||
.With(s => s.SeriesId = 5)
|
|
||||||
.With(s => s.Title = "30 Rock")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var fakeEpisode = Builder<Episode>.CreateListOfSize(1)
|
|
||||||
.All()
|
|
||||||
.With(e => e.SeriesId = fakeSeries.SeriesId)
|
|
||||||
.With(e => e.SeasonNumber = 1)
|
|
||||||
.With(e => e.EpisodeNumber = 1)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const string filename = @"30 Rock - S01E01 - TBD";
|
|
||||||
var fi = new FileInfo(Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", filename + ".avi"));
|
|
||||||
|
|
||||||
var file = Builder<EpisodeFile>.CreateNew()
|
|
||||||
.With(f => f.SeriesId = fakeSeries.SeriesId)
|
|
||||||
.With(f => f.Path = fi.FullName)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
Mocker.GetMock<SeriesProvider>()
|
|
||||||
.Setup(e => e.GetSeries(fakeSeries.SeriesId))
|
|
||||||
.Returns(fakeSeries);
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(e => e.GetEpisodesByFileId(file.EpisodeFileId))
|
|
||||||
.Returns(fakeEpisode);
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(e => e.GetNewFilename(fakeEpisode, fakeSeries.Title, It.IsAny<QualityTypes>(), It.IsAny<bool>(), It.IsAny<EpisodeFile>()))
|
|
||||||
.Returns(filename);
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(e => e.CalculateFilePath(It.IsAny<Series>(), fakeEpisode.First().SeasonNumber, filename, ".avi"))
|
|
||||||
.Returns(fi);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, false);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
result.Should().BeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void CleanUpDropFolder_should_do_nothing_if_no_files_are_found()
|
|
||||||
{
|
|
||||||
//Setup
|
|
||||||
var folder = @"C:\Test\DropDir\The Office";
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
|
|
||||||
.Returns(new string[0]);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Mocker.GetMock<MediaFileProvider>().Verify(v => v.GetFileByPath(It.IsAny<string>()), Times.Never());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void CleanUpDropFolder_should_do_nothing_if_no_conflicting_files_are_found()
|
|
||||||
{
|
|
||||||
//Setup
|
|
||||||
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<MediaFileProvider>().Setup(s => s.GetFileByPath(filename))
|
|
||||||
.Returns(() => null);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Mocker.GetMock<MediaFileProvider>().Verify(v => v.GetFileByPath(filename), Times.Once());
|
|
||||||
Mocker.GetMock<SeriesProvider>().Verify(v => v.GetSeries(It.IsAny<int>()), Times.Never());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void CleanUpDropFolder_should_move_file_if_a_conflict_is_found()
|
|
||||||
{
|
|
||||||
//Setup
|
|
||||||
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.SeriesId = seriesId)
|
|
||||||
.With(s => s.Title = "The Office")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var episode = Builder<Episode>.CreateListOfSize(1)
|
|
||||||
.All()
|
|
||||||
.With(e => e.SeriesId = seriesId)
|
|
||||||
.With(e => e.EpisodeFileId = episodeFile.EpisodeFileId)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>().Setup(v => v.GetFileByPath(filename))
|
|
||||||
.Returns(() => null);
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
|
|
||||||
.Returns(new string[] { filename });
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>().Setup(s => s.GetFileByPath(filename))
|
|
||||||
.Returns(episodeFile);
|
|
||||||
|
|
||||||
Mocker.GetMock<SeriesProvider>().Setup(s => s.GetSeries(It.IsAny<int>()))
|
|
||||||
.Returns(series);
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>().Setup(s => s.GetEpisodesByFileId(episodeFile.EpisodeFileId))
|
|
||||||
.Returns(episode);
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>().Setup(s => s.GetNewFilename(It.IsAny<IList<Episode>>(), series.Title, QualityTypes.Unknown, false, It.IsAny<EpisodeFile>()))
|
|
||||||
.Returns(newFilename);
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>().Setup(s => s.CalculateFilePath(It.IsAny<Series>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>()))
|
|
||||||
.Returns(new FileInfo(newFilePath));
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveFile(episodeFile.Path, newFilePath));
|
|
||||||
|
|
||||||
//Act
|
|
||||||
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Mocker.GetMock<MediaFileProvider>().Verify(v => v.GetFileByPath(filename), Times.Once());
|
|
||||||
Mocker.GetMock<DiskProvider>().Verify(v => v.MoveFile(filename.NormalizePath(), newFilePath), Times.Once());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void MoveEpisodeFile_should_use_EpisodeFiles_quality()
|
|
||||||
{
|
|
||||||
var fakeSeries = Builder<Series>.CreateNew()
|
|
||||||
.With(s => s.SeriesId = 5)
|
|
||||||
.With(s => s.Title = "30 Rock")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var fakeEpisode = Builder<Episode>.CreateListOfSize(1)
|
|
||||||
.All()
|
|
||||||
.With(e => e.SeriesId = fakeSeries.SeriesId)
|
|
||||||
.With(e => e.SeasonNumber = 1)
|
|
||||||
.With(e => e.EpisodeNumber = 1)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const string filename = @"30 Rock - S01E01 - TBD";
|
|
||||||
var fi = new FileInfo(Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", filename + ".mkv"));
|
|
||||||
var currentFilename = Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", "30.Rock.S01E01.Test.WED-DL.mkv");
|
|
||||||
const string message = "30 Rock - 1x01 - [WEBDL]";
|
|
||||||
|
|
||||||
var file = Builder<EpisodeFile>.CreateNew()
|
|
||||||
.With(f => f.SeriesId = fakeSeries.SeriesId)
|
|
||||||
.With(f => f.Path = currentFilename)
|
|
||||||
.With(f => f.Quality = QualityTypes.WEBDL)
|
|
||||||
.With(f => f.Proper = false)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
Mocker.GetMock<SeriesProvider>()
|
|
||||||
.Setup(e => e.GetSeries(fakeSeries.SeriesId))
|
|
||||||
.Returns(fakeSeries);
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(e => e.GetEpisodesByFileId(file.EpisodeFileId))
|
|
||||||
.Returns(fakeEpisode);
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(e => e.GetNewFilename(fakeEpisode, fakeSeries.Title, It.IsAny<QualityTypes>(), It.IsAny<bool>(), It.IsAny<EpisodeFile>()))
|
|
||||||
.Returns(filename);
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(e => e.CalculateFilePath(It.IsAny<Series>(), fakeEpisode.First().SeasonNumber, filename, ".mkv"))
|
|
||||||
.Returns(fi);
|
|
||||||
|
|
||||||
Mocker.GetMock<DownloadProvider>()
|
|
||||||
.Setup(s => s.GetDownloadTitle(It.Is<EpisodeParseResult>(e => e.Quality == new Quality{ QualityType = QualityTypes.WEBDL, Proper = false })))
|
|
||||||
.Returns(message);
|
|
||||||
|
|
||||||
Mocker.GetMock<ExternalNotificationProvider>()
|
|
||||||
.Setup(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny<Series>()));
|
|
||||||
|
|
||||||
//Act
|
|
||||||
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, true);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
Mocker.GetMock<ExternalNotificationProvider>()
|
|
||||||
.Verify(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny<Series>()), Times.Once());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using NzbDrone.Test.Common.AutoMoq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
|
{
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public class CleanUpDropFolderFixture : CoreTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void should_do_nothing_if_no_files_are_found()
|
||||||
|
{
|
||||||
|
//Setup
|
||||||
|
var folder = @"C:\Test\DropDir\The Office";
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
|
||||||
|
.Returns(new string[0]);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.GetMock<MediaFileProvider>().Verify(v => v.GetFileByPath(It.IsAny<string>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_do_nothing_if_no_conflicting_files_are_found()
|
||||||
|
{
|
||||||
|
//Setup
|
||||||
|
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<MediaFileProvider>().Setup(s => s.GetFileByPath(filename))
|
||||||
|
.Returns(() => null);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.GetMock<MediaFileProvider>().Verify(v => v.GetFileByPath(filename), Times.Once());
|
||||||
|
Mocker.GetMock<SeriesProvider>().Verify(v => v.GetSeries(It.IsAny<int>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_move_file_if_a_conflict_is_found()
|
||||||
|
{
|
||||||
|
//Setup
|
||||||
|
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.SeriesId = seriesId)
|
||||||
|
.With(s => s.Title = "The Office")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var episode = Builder<Episode>.CreateListOfSize(1)
|
||||||
|
.All()
|
||||||
|
.With(e => e.SeriesId = seriesId)
|
||||||
|
.With(e => e.EpisodeFileId = episodeFile.EpisodeFileId)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>().Setup(v => v.GetFileByPath(filename))
|
||||||
|
.Returns(() => null);
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>().Setup(s => s.GetFiles(folder, SearchOption.AllDirectories))
|
||||||
|
.Returns(new string[] { filename });
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>().Setup(s => s.GetFileByPath(filename))
|
||||||
|
.Returns(episodeFile);
|
||||||
|
|
||||||
|
Mocker.GetMock<SeriesProvider>().Setup(s => s.GetSeries(It.IsAny<int>()))
|
||||||
|
.Returns(series);
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>().Setup(s => s.GetEpisodesByFileId(episodeFile.EpisodeFileId))
|
||||||
|
.Returns(episode);
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>().Setup(s => s.GetNewFilename(It.IsAny<IList<Episode>>(), series.Title, QualityTypes.Unknown, false, It.IsAny<EpisodeFile>()))
|
||||||
|
.Returns(newFilename);
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>().Setup(s => s.CalculateFilePath(It.IsAny<Series>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||||
|
.Returns(new FileInfo(newFilePath));
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>().Setup(s => s.MoveFile(episodeFile.Path, newFilePath));
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<DiskScanProvider>().CleanUpDropFolder(folder);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.GetMock<MediaFileProvider>().Verify(v => v.GetFileByPath(filename), Times.Once());
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(v => v.MoveFile(filename.NormalizePath(), newFilePath), Times.Once());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using NzbDrone.Test.Common.AutoMoq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
|
{
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public class CleanUpFixture : CoreTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void should_skip_existing_files()
|
||||||
|
{
|
||||||
|
var episodes = Builder<EpisodeFile>.CreateListOfSize(10).Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(e => e.FileExists(It.IsAny<String>()))
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<DiskScanProvider>().CleanUp(episodes);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.VerifyAllMocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_delete_none_existing_files()
|
||||||
|
{
|
||||||
|
var episodes = Builder<EpisodeFile>.CreateListOfSize(10).Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(e => e.FileExists(It.IsAny<String>()))
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(e => e.GetEpisodesByFileId(It.IsAny<int>()))
|
||||||
|
.Returns(new List<Episode>());
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(e => e.Delete(It.IsAny<int>()));
|
||||||
|
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<DiskScanProvider>().CleanUp(episodes);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.VerifyAllMocks();
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Verify(e => e.GetEpisodesByFileId(It.IsAny<int>()), Times.Exactly(10));
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Verify(e => e.Delete(It.IsAny<int>()), Times.Exactly(10));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_delete_none_existing_files_remove_links_to_episodes()
|
||||||
|
{
|
||||||
|
var episodes = Builder<EpisodeFile>.CreateListOfSize(10).Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(e => e.FileExists(It.IsAny<String>()))
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(e => e.GetEpisodesByFileId(It.IsAny<int>()))
|
||||||
|
.Returns(new List<Episode> { new Episode { EpisodeFileId = 10 }, new Episode { EpisodeFileId = 10 } });
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(e => e.UpdateEpisode(It.IsAny<Episode>()));
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(e => e.Delete(It.IsAny<int>()));
|
||||||
|
|
||||||
|
Mocker.GetMock<ConfigProvider>()
|
||||||
|
.SetupGet(s => s.AutoIgnorePreviouslyDownloadedEpisodes)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<DiskScanProvider>().CleanUp(episodes);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.VerifyAllMocks();
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Verify(e => e.GetEpisodesByFileId(It.IsAny<int>()), Times.Exactly(10));
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Verify(e => e.UpdateEpisode(It.Is<Episode>(g=>g.EpisodeFileId == 0)), Times.Exactly(20));
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Verify(e => e.Delete(It.IsAny<int>()), Times.Exactly(10));
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Verify(e => e.Delete(It.IsAny<int>()), Times.Exactly(10));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using NzbDrone.Test.Common.AutoMoq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
|
{
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public class GetVideoFilesFixture : CoreTest
|
||||||
|
{
|
||||||
|
private string[] _files;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_files = new string[]
|
||||||
|
{
|
||||||
|
@"C:\Test\30 Rock1.mkv",
|
||||||
|
@"C:\Test\30 Rock2.avi",
|
||||||
|
@"C:\Test\30 Rock3.mp4",
|
||||||
|
@"C:\Test\30 Rock4.wmv",
|
||||||
|
@"C:\Test\movie.exe"
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(s => s.GetFiles(It.IsAny<String>(), SearchOption.AllDirectories))
|
||||||
|
.Returns(_files);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_check_all_directories()
|
||||||
|
{
|
||||||
|
var path = @"C:\Test\";
|
||||||
|
|
||||||
|
Mocker.Resolve<DiskScanProvider>().GetVideoFiles(path);
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(s => s.GetFiles(path, SearchOption.AllDirectories), Times.Once());
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(s => s.GetFiles(path, SearchOption.TopDirectoryOnly), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_check_all_directories_when_allDirectories_is_true()
|
||||||
|
{
|
||||||
|
var path = @"C:\Test\";
|
||||||
|
|
||||||
|
Mocker.Resolve<DiskScanProvider>().GetVideoFiles(path, true);
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(s => s.GetFiles(path, SearchOption.AllDirectories), Times.Once());
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(s => s.GetFiles(path, SearchOption.TopDirectoryOnly), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_check_top_level_directory_only_when_allDirectories_is_false()
|
||||||
|
{
|
||||||
|
var path = @"C:\Test\";
|
||||||
|
|
||||||
|
Mocker.Resolve<DiskScanProvider>().GetVideoFiles(path, false);
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(s => s.GetFiles(path, SearchOption.AllDirectories), Times.Never());
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(s => s.GetFiles(path, SearchOption.TopDirectoryOnly), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_video_files_only()
|
||||||
|
{
|
||||||
|
var path = @"C:\Test\";
|
||||||
|
|
||||||
|
Mocker.Resolve<DiskScanProvider>().GetVideoFiles(path).Should().HaveCount(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,10 +15,10 @@ using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
using NzbDrone.Test.Common.AutoMoq;
|
using NzbDrone.Test.Common.AutoMoq;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ProviderTests
|
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
{
|
{
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
public class DiskScanProviderTest_ImportFile : CoreTest
|
public class ImportFileFixture : CoreTest
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void import_new_file_should_succeed()
|
public void import_new_file_should_succeed()
|
|
@ -0,0 +1,130 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using NzbDrone.Test.Common.AutoMoq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
|
{
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public class MoveEpisodeFileFixture : CoreTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void should_not_move_file_if_source_and_destination_are_the_same_path()
|
||||||
|
{
|
||||||
|
var fakeSeries = Builder<Series>.CreateNew()
|
||||||
|
.With(s => s.SeriesId = 5)
|
||||||
|
.With(s => s.Title = "30 Rock")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var fakeEpisode = Builder<Episode>.CreateListOfSize(1)
|
||||||
|
.All()
|
||||||
|
.With(e => e.SeriesId = fakeSeries.SeriesId)
|
||||||
|
.With(e => e.SeasonNumber = 1)
|
||||||
|
.With(e => e.EpisodeNumber = 1)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
const string filename = @"30 Rock - S01E01 - TBD";
|
||||||
|
var fi = new FileInfo(Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", filename + ".avi"));
|
||||||
|
|
||||||
|
var file = Builder<EpisodeFile>.CreateNew()
|
||||||
|
.With(f => f.SeriesId = fakeSeries.SeriesId)
|
||||||
|
.With(f => f.Path = fi.FullName)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(e => e.GetSeries(fakeSeries.SeriesId))
|
||||||
|
.Returns(fakeSeries);
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(e => e.GetEpisodesByFileId(file.EpisodeFileId))
|
||||||
|
.Returns(fakeEpisode);
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(e => e.GetNewFilename(fakeEpisode, fakeSeries.Title, It.IsAny<QualityTypes>(), It.IsAny<bool>(), It.IsAny<EpisodeFile>()))
|
||||||
|
.Returns(filename);
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(e => e.CalculateFilePath(It.IsAny<Series>(), fakeEpisode.First().SeasonNumber, filename, ".avi"))
|
||||||
|
.Returns(fi);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, false);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
result.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_EpisodeFiles_quality()
|
||||||
|
{
|
||||||
|
var fakeSeries = Builder<Series>.CreateNew()
|
||||||
|
.With(s => s.SeriesId = 5)
|
||||||
|
.With(s => s.Title = "30 Rock")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var fakeEpisode = Builder<Episode>.CreateListOfSize(1)
|
||||||
|
.All()
|
||||||
|
.With(e => e.SeriesId = fakeSeries.SeriesId)
|
||||||
|
.With(e => e.SeasonNumber = 1)
|
||||||
|
.With(e => e.EpisodeNumber = 1)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
const string filename = @"30 Rock - S01E01 - TBD";
|
||||||
|
var fi = new FileInfo(Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", filename + ".mkv"));
|
||||||
|
var currentFilename = Path.Combine(@"C:\Test\TV\30 Rock\Season 01\", "30.Rock.S01E01.Test.WED-DL.mkv");
|
||||||
|
const string message = "30 Rock - 1x01 - [WEBDL]";
|
||||||
|
|
||||||
|
var file = Builder<EpisodeFile>.CreateNew()
|
||||||
|
.With(f => f.SeriesId = fakeSeries.SeriesId)
|
||||||
|
.With(f => f.Path = currentFilename)
|
||||||
|
.With(f => f.Quality = QualityTypes.WEBDL)
|
||||||
|
.With(f => f.Proper = false)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(e => e.GetSeries(fakeSeries.SeriesId))
|
||||||
|
.Returns(fakeSeries);
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(e => e.GetEpisodesByFileId(file.EpisodeFileId))
|
||||||
|
.Returns(fakeEpisode);
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(e => e.GetNewFilename(fakeEpisode, fakeSeries.Title, It.IsAny<QualityTypes>(), It.IsAny<bool>(), It.IsAny<EpisodeFile>()))
|
||||||
|
.Returns(filename);
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(e => e.CalculateFilePath(It.IsAny<Series>(), fakeEpisode.First().SeasonNumber, filename, ".mkv"))
|
||||||
|
.Returns(fi);
|
||||||
|
|
||||||
|
Mocker.GetMock<DownloadProvider>()
|
||||||
|
.Setup(s => s.GetDownloadTitle(It.Is<EpisodeParseResult>(e => e.Quality == new Quality{ QualityType = QualityTypes.WEBDL, Proper = false })))
|
||||||
|
.Returns(message);
|
||||||
|
|
||||||
|
Mocker.GetMock<ExternalNotificationProvider>()
|
||||||
|
.Setup(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny<Series>()));
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var result = Mocker.Resolve<DiskScanProvider>().MoveEpisodeFile(file, true);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
result.Should().NotBeNull();
|
||||||
|
Mocker.GetMock<ExternalNotificationProvider>()
|
||||||
|
.Verify(e => e.OnDownload("30 Rock - 1x01 - [WEBDL]", It.IsAny<Series>()), Times.Once());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using NzbDrone.Test.Common.AutoMoq;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
|
{
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public class ScanFixture : CoreTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void series_should_update_the_last_scan_date()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(c => c.UpdateSeries(It.Is<Series>(s => s.LastDiskSync != null))).Verifiable();
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(c => c.GetEpisodeBySeries(It.IsAny<long>()))
|
||||||
|
.Returns(new List<Episode> { new Episode() });
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(c => c.FolderExists(It.IsAny<string>()))
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(c => c.GetSeriesFiles(It.IsAny<int>()))
|
||||||
|
.Returns(new List<EpisodeFile>());
|
||||||
|
|
||||||
|
Mocker.Resolve<DiskScanProvider>().Scan(new Series());
|
||||||
|
|
||||||
|
Mocker.VerifyAllMocks();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void series_should_log_warning_if_path_doesnt_exist_on_disk()
|
||||||
|
{
|
||||||
|
//Setup
|
||||||
|
WithStrictMocker();
|
||||||
|
|
||||||
|
var series = Builder<Series>.CreateNew()
|
||||||
|
.With(s => s.Path = @"C:\Test\TV\SeriesName\")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(c => c.CleanUpDatabase());
|
||||||
|
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(c => c.FolderExists(series.Path))
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<DiskScanProvider>().Scan(series, series.Path);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.VerifyAllMocks();
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
using NzbDrone.Core.Providers.DownloadClients;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.ProviderTests.DownloadClientTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class PneumaticProviderFixture : CoreTest
|
||||||
|
{
|
||||||
|
private const string nzbUrl = "http://www.nzbs.com/url";
|
||||||
|
private const string title = "some_nzb_title";
|
||||||
|
private const string pneumaticFolder = @"d:\nzb\pneumatic\";
|
||||||
|
private const string nzbPath = @"d:\nzb\blackhole\some_nzb_title.nzb";
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ConfigProvider>().SetupGet(c => c.BlackholeDirectory).Returns(pneumaticFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WithExistingFile()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<DiskProvider>().Setup(c => c.FileExists(nzbPath)).Returns(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WithFailedDownload()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<HttpProvider>().Setup(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>())).Throws(new WebException());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_download_file_if_it_doesnt_exist()
|
||||||
|
{
|
||||||
|
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, title).Should().BeTrue();
|
||||||
|
|
||||||
|
Mocker.GetMock<HttpProvider>().Verify(c => c.DownloadFile(nzbUrl, nzbPath),Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_download_file_if_it_doesn_exist()
|
||||||
|
{
|
||||||
|
WithExistingFile();
|
||||||
|
|
||||||
|
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, title).Should().BeTrue();
|
||||||
|
|
||||||
|
Mocker.GetMock<HttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_on_failed_download()
|
||||||
|
{
|
||||||
|
WithFailedDownload();
|
||||||
|
|
||||||
|
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, title).Should().BeFalse();
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_skip_if_full_season_download()
|
||||||
|
{
|
||||||
|
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, "30 Rock - Season 1").Should().BeFalse();
|
||||||
|
ExceptionVerification.ExpectedErrors(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
public class PostDownloadProviderFixture : CoreTest
|
public class GetFolderNameWithStatusFixture : CoreTest
|
||||||
{
|
{
|
||||||
[TestCase(@"c:\_NzbDrone_InvalidEpisode_Title", @"c:\_UnknownSeries_Title", PostDownloadStatusType.UnknownSeries)]
|
[TestCase(@"c:\_NzbDrone_InvalidEpisode_Title", @"c:\_UnknownSeries_Title", PostDownloadStatusType.UnknownSeries)]
|
||||||
[TestCase(@"c:\Title", @"c:\_Failed_Title", PostDownloadStatusType.Failed)]
|
[TestCase(@"c:\Title", @"c:\_Failed_Title", PostDownloadStatusType.Failed)]
|
|
@ -18,7 +18,7 @@ using NzbDrone.Test.Common.AutoMoq;
|
||||||
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
|
namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class ProcessDownloadProviderFixture : CoreTest
|
public class ProcessDownloadFixture : CoreTest
|
||||||
{
|
{
|
||||||
Series fakeSeries;
|
Series fakeSeries;
|
||||||
|
|
||||||
|
@ -328,51 +328,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ProcessDropFolder_should_only_process_folders_that_arent_known_series_folders()
|
public void should_logError_and_return_if_size_exceeds_free_space()
|
||||||
{
|
|
||||||
WithLotsOfFreeDiskSpace();
|
|
||||||
|
|
||||||
var subFolders = new[]
|
|
||||||
{
|
|
||||||
@"c:\drop\episode1",
|
|
||||||
@"c:\drop\episode2",
|
|
||||||
@"c:\drop\episode3",
|
|
||||||
@"c:\drop\episode4"
|
|
||||||
};
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>()
|
|
||||||
.Setup(c => c.GetDirectories(It.IsAny<String>()))
|
|
||||||
.Returns(subFolders);
|
|
||||||
|
|
||||||
Mocker.GetMock<SeriesProvider>()
|
|
||||||
.Setup(c => c.SeriesPathExists(subFolders[1]))
|
|
||||||
.Returns(true);
|
|
||||||
|
|
||||||
Mocker.GetMock<SeriesProvider>()
|
|
||||||
.Setup(c => c.FindSeries(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);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
Mocker.Resolve<PostDownloadProvider>().ProcessDropFolder(@"C:\drop\");
|
|
||||||
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
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 ProcessDownload_should_logError_and_return_if_size_exceeds_free_space()
|
|
||||||
{
|
{
|
||||||
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
|
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
|
||||||
|
|
||||||
|
@ -403,7 +359,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ProcessDownload_should_process_if_free_disk_space_exceeds_size()
|
public void should_process_if_free_disk_space_exceeds_size()
|
||||||
{
|
{
|
||||||
WithLotsOfFreeDiskSpace();
|
WithLotsOfFreeDiskSpace();
|
||||||
WithValidSeries();
|
WithValidSeries();
|
||||||
|
@ -429,7 +385,7 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ProcessDownload_should_process_if_free_disk_space_equals_size()
|
public void should_process_if_free_disk_space_equals_size()
|
||||||
{
|
{
|
||||||
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
|
var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot");
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
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.Path = @"C:\Test\TV\30 Rock")
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WithLotsOfFreeDiskSpace()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<DiskProvider>().Setup(s => s.FreeDiskSpace(It.IsAny<DirectoryInfo>())).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<SeriesProvider>()
|
||||||
|
.Setup(c => c.SeriesPathExists(subFolders[1]))
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
Mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(c => c.FindSeries(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);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<PostDownloadProvider>().ProcessDropFolder(@"C:\drop\");
|
||||||
|
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
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<SeriesProvider>()
|
||||||
|
.Setup(c => c.FindSeries(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);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<PostDownloadProvider>().ProcessDropFolder(@"C:\drop\");
|
||||||
|
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(It.IsAny<Series>(), It.IsAny<String>()), Times.Exactly(4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Providers;
|
||||||
|
using NzbDrone.Core.Repository;
|
||||||
|
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.Path = @"C:\Test\TV\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<SeriesProvider>()
|
||||||
|
.Setup(c => c.FindSeries(It.IsAny<string>()))
|
||||||
|
.Returns(fakeSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
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<DirectoryInfo>())).Returns(1000000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WithImportedFile(string file)
|
||||||
|
{
|
||||||
|
var fakeEpisodeFile = Builder<EpisodeFile>.CreateNew()
|
||||||
|
.With(f => f.SeriesId = fakeSeries.SeriesId)
|
||||||
|
.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");
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.GetMock<SeriesProvider>().Setup(s => s.FindSeries(It.IsAny<String>())).Returns<Series>(null).Verifiable();
|
||||||
|
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.GetMock<SeriesProvider>().Verify(s => s.FindSeries(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");
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.GetMock<SeriesProvider>().Setup(s => s.FindSeries(It.IsAny<String>())).Returns<Series>(null);
|
||||||
|
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(s => s.GetFileSize(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);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(file);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.GetMock<DiskScanProvider>().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.Path = @"C:\Test\TV\30 Rock")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(c => c.FindSeries("rock"))
|
||||||
|
.Returns(series);
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(s => s.GetFileSize(downloadName))
|
||||||
|
.Returns(10);
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(s => s.FreeDiskSpace(new DirectoryInfo(series.Path)))
|
||||||
|
.Returns(9);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
|
||||||
|
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
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<SeriesProvider>()
|
||||||
|
.Setup(c => c.FindSeries("rock"))
|
||||||
|
.Returns(fakeSeries);
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(s => s.GetFileSize(downloadName))
|
||||||
|
.Returns(8);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
|
||||||
|
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
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<DirectoryInfo>()))
|
||||||
|
.Returns(10);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
Mocker.Resolve<PostDownloadProvider>().ProcessVideoFile(downloadName);
|
||||||
|
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Mocker.GetMock<DiskScanProvider>().Verify(c => c.ImportFile(fakeSeries, downloadName), Times.Once());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
public enum DownloadClientType
|
public enum DownloadClientType
|
||||||
{
|
{
|
||||||
Sabnzbd = 0,
|
Sabnzbd = 0,
|
||||||
Blackhole = 1
|
Blackhole = 1,
|
||||||
|
Pneumatic = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -289,6 +289,7 @@
|
||||||
<Compile Include="Model\Xbmc\IconType.cs" />
|
<Compile Include="Model\Xbmc\IconType.cs" />
|
||||||
<Compile Include="Providers\BannerProvider.cs" />
|
<Compile Include="Providers\BannerProvider.cs" />
|
||||||
<Compile Include="Providers\DecisionEngine\AllowedReleaseGroupSpecification.cs" />
|
<Compile Include="Providers\DecisionEngine\AllowedReleaseGroupSpecification.cs" />
|
||||||
|
<Compile Include="Providers\DownloadClients\PneumaticProvider.cs" />
|
||||||
<Compile Include="Providers\Indexer\NzbClub.cs" />
|
<Compile Include="Providers\Indexer\NzbClub.cs" />
|
||||||
<Compile Include="Providers\Indexer\NzbIndex.cs" />
|
<Compile Include="Providers\Indexer\NzbIndex.cs" />
|
||||||
<Compile Include="Providers\Indexer\FileSharingTalk.cs" />
|
<Compile Include="Providers\Indexer\FileSharingTalk.cs" />
|
||||||
|
|
|
@ -520,6 +520,12 @@ namespace NzbDrone.Core.Providers.Core
|
||||||
set { SetValue("AllowedReleaseGroups", value); }
|
set { SetValue("AllowedReleaseGroups", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual string PneumaticDirectory
|
||||||
|
{
|
||||||
|
get { return GetValue("PneumaticDirectory", String.Empty); }
|
||||||
|
set { SetValue("PneumaticDirectory", value); }
|
||||||
|
}
|
||||||
|
|
||||||
private string GetValue(string key)
|
private string GetValue(string key)
|
||||||
{
|
{
|
||||||
return GetValue(key, String.Empty);
|
return GetValue(key, String.Empty);
|
||||||
|
|
|
@ -284,11 +284,12 @@ namespace NzbDrone.Core.Providers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> GetVideoFiles(string path)
|
public virtual List<string> GetVideoFiles(string path, bool allDirectories = true)
|
||||||
{
|
{
|
||||||
Logger.Debug("Scanning '{0}' for video files", path);
|
Logger.Debug("Scanning '{0}' for video files", path);
|
||||||
|
|
||||||
var filesOnDisk = _diskProvider.GetFiles(path, SearchOption.AllDirectories);
|
var searchOption = allDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
||||||
|
var filesOnDisk = _diskProvider.GetFiles(path, searchOption);
|
||||||
|
|
||||||
var mediaFileList = filesOnDisk.Where(c => mediaExtentions.Contains(Path.GetExtension(c).ToLower())).ToList();
|
var mediaFileList = filesOnDisk.Where(c => mediaExtentions.Contains(Path.GetExtension(c).ToLower())).ToList();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using Ninject;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
using NzbDrone.Core.Providers.Core;
|
||||||
|
using NzbDrone.Core.Providers.DecisionEngine;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Providers.DownloadClients
|
||||||
|
{
|
||||||
|
public class PneumaticProvider : IDownloadClient
|
||||||
|
{
|
||||||
|
private readonly ConfigProvider _configProvider;
|
||||||
|
private readonly HttpProvider _httpProvider;
|
||||||
|
private readonly DiskProvider _diskProvider;
|
||||||
|
private readonly UpgradeHistorySpecification _upgradeHistorySpecification;
|
||||||
|
|
||||||
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
public PneumaticProvider(ConfigProvider configProvider, HttpProvider httpProvider,
|
||||||
|
DiskProvider diskProvider, UpgradeHistorySpecification upgradeHistorySpecification)
|
||||||
|
{
|
||||||
|
_configProvider = configProvider;
|
||||||
|
_httpProvider = httpProvider;
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_upgradeHistorySpecification = upgradeHistorySpecification;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PneumaticProvider()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool DownloadNzb(string url, string title)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Todo: Allow full season releases
|
||||||
|
if (Parser.ParseTitle(title).FullSeason)
|
||||||
|
{
|
||||||
|
logger.Warn("Skipping Full Season Release: {0}", title);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Save to the Pneumatic directory (The user will need to ensure its accessible by XBMC)
|
||||||
|
var filename = Path.Combine(_configProvider.PneumaticDirectory, title + ".nzb");
|
||||||
|
|
||||||
|
if (_diskProvider.FileExists(filename))
|
||||||
|
{
|
||||||
|
//Return true so a lesser quality is not returned.
|
||||||
|
logger.Info("NZB already exists on disk: {0}", filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Trace("Downloading NZB from: {0} to: {1}", url, filename);
|
||||||
|
_httpProvider.DownloadFile(url, filename);
|
||||||
|
|
||||||
|
logger.Trace("NZB Download succeeded, saved to: {0}", filename);
|
||||||
|
|
||||||
|
var contents = String.Format("plugin://plugin.program.pneumatic/?mode=strm&type=add_file&nzb={0}&nzbname={1}", filename, title);
|
||||||
|
_diskProvider.WriteAllText(Path.Combine(_configProvider.SabDropDirectory, title + ".strm"), contents);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.WarnException("Failed to download NZB: " + url, ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool IsInQueue(EpisodeParseResult newParseResult)
|
||||||
|
{
|
||||||
|
return !_upgradeHistorySpecification.IsSatisfiedBy(newParseResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ namespace NzbDrone.Core.Providers
|
||||||
private readonly ConfigProvider _configProvider;
|
private readonly ConfigProvider _configProvider;
|
||||||
private readonly BlackholeProvider _blackholeProvider;
|
private readonly BlackholeProvider _blackholeProvider;
|
||||||
private readonly SignalRProvider _signalRProvider;
|
private readonly SignalRProvider _signalRProvider;
|
||||||
|
private readonly PneumaticProvider _pneumaticProvider;
|
||||||
|
|
||||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ namespace NzbDrone.Core.Providers
|
||||||
public DownloadProvider(SabProvider sabProvider, HistoryProvider historyProvider,
|
public DownloadProvider(SabProvider sabProvider, HistoryProvider historyProvider,
|
||||||
EpisodeProvider episodeProvider, ExternalNotificationProvider externalNotificationProvider,
|
EpisodeProvider episodeProvider, ExternalNotificationProvider externalNotificationProvider,
|
||||||
ConfigProvider configProvider, BlackholeProvider blackholeProvider,
|
ConfigProvider configProvider, BlackholeProvider blackholeProvider,
|
||||||
SignalRProvider signalRProvider)
|
SignalRProvider signalRProvider, PneumaticProvider pneumaticProvider)
|
||||||
{
|
{
|
||||||
_sabProvider = sabProvider;
|
_sabProvider = sabProvider;
|
||||||
_historyProvider = historyProvider;
|
_historyProvider = historyProvider;
|
||||||
|
@ -34,6 +35,7 @@ namespace NzbDrone.Core.Providers
|
||||||
_configProvider = configProvider;
|
_configProvider = configProvider;
|
||||||
_blackholeProvider = blackholeProvider;
|
_blackholeProvider = blackholeProvider;
|
||||||
_signalRProvider = signalRProvider;
|
_signalRProvider = signalRProvider;
|
||||||
|
_pneumaticProvider = pneumaticProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DownloadProvider()
|
public DownloadProvider()
|
||||||
|
@ -54,16 +56,18 @@ namespace NzbDrone.Core.Providers
|
||||||
|
|
||||||
foreach (var episode in _episodeProvider.GetEpisodesByParseResult(parseResult))
|
foreach (var episode in _episodeProvider.GetEpisodesByParseResult(parseResult))
|
||||||
{
|
{
|
||||||
var history = new History();
|
var history = new History
|
||||||
history.Date = DateTime.Now;
|
{
|
||||||
history.Indexer = parseResult.Indexer;
|
Date = DateTime.Now,
|
||||||
history.IsProper = parseResult.Quality.Proper;
|
Indexer = parseResult.Indexer,
|
||||||
history.Quality = parseResult.Quality.QualityType;
|
IsProper = parseResult.Quality.Proper,
|
||||||
history.NzbTitle = parseResult.OriginalString;
|
Quality = parseResult.Quality.QualityType,
|
||||||
history.EpisodeId = episode.EpisodeId;
|
NzbTitle = parseResult.OriginalString,
|
||||||
history.SeriesId = episode.SeriesId;
|
EpisodeId = episode.EpisodeId,
|
||||||
history.NzbInfoUrl = parseResult.NzbInfoUrl;
|
SeriesId = episode.SeriesId,
|
||||||
history.ReleaseGroup = parseResult.ReleaseGroup;
|
NzbInfoUrl = parseResult.NzbInfoUrl,
|
||||||
|
ReleaseGroup = parseResult.ReleaseGroup,
|
||||||
|
};
|
||||||
|
|
||||||
_historyProvider.Add(history);
|
_historyProvider.Add(history);
|
||||||
_episodeProvider.MarkEpisodeAsFetched(episode.EpisodeId);
|
_episodeProvider.MarkEpisodeAsFetched(episode.EpisodeId);
|
||||||
|
@ -77,13 +81,16 @@ namespace NzbDrone.Core.Providers
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public virtual IDownloadClient GetActiveDownloadClient()
|
public virtual IDownloadClient GetActiveDownloadClient()
|
||||||
{
|
{
|
||||||
switch (_configProvider.DownloadClient)
|
switch (_configProvider.DownloadClient)
|
||||||
{
|
{
|
||||||
case DownloadClientType.Blackhole:
|
case DownloadClientType.Blackhole:
|
||||||
return _blackholeProvider;
|
return _blackholeProvider;
|
||||||
|
|
||||||
|
case DownloadClientType.Pneumatic:
|
||||||
|
return _pneumaticProvider;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return _sabProvider;
|
return _sabProvider;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,18 @@ namespace NzbDrone.Core.Providers
|
||||||
Logger.ErrorException("An error has occurred while importing folder" + subfolder, e);
|
Logger.ErrorException("An error has occurred while importing folder" + subfolder, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach(var videoFile in _diskScanProvider.GetVideoFiles(dropFolder, false))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProcessVideoFile(videoFile);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
Logger.ErrorException("An error has occurred while importing video file" + videoFile, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ProcessDownload(DirectoryInfo subfolderInfo)
|
public virtual void ProcessDownload(DirectoryInfo subfolderInfo)
|
||||||
|
@ -109,6 +121,40 @@ namespace NzbDrone.Core.Providers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void ProcessVideoFile(string videoFile)
|
||||||
|
{
|
||||||
|
if (_diskProvider.GetLastFileWrite(videoFile).AddMinutes(2) > DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
Logger.Trace("[{0}] is too fresh. skipping", videoFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var seriesName = Parser.ParseSeriesName(Path.GetFileNameWithoutExtension(videoFile));
|
||||||
|
var series = _seriesProvider.FindSeries(seriesName);
|
||||||
|
|
||||||
|
if (series == null)
|
||||||
|
{
|
||||||
|
Logger.Trace("Unknown Series on Import: {0}", videoFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var size = _diskProvider.GetFileSize(videoFile);
|
||||||
|
var freeSpace = _diskProvider.FreeDiskSpace(new DirectoryInfo(series.Path));
|
||||||
|
|
||||||
|
if (Convert.ToUInt64(size) > freeSpace)
|
||||||
|
{
|
||||||
|
Logger.Error("Not enough free disk space for series: {0}, {1}", series.Title, series.Path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var episodeFile = _diskScanProvider.ImportFile(series, videoFile);
|
||||||
|
if (episodeFile != null)
|
||||||
|
{
|
||||||
|
_diskScanProvider.MoveEpisodeFile(episodeFile, true);
|
||||||
|
_metadataProvider.CreateForEpisodeFile(episodeFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void TagFolder(DirectoryInfo directory, PostDownloadStatusType status)
|
private void TagFolder(DirectoryInfo directory, PostDownloadStatusType status)
|
||||||
{
|
{
|
||||||
//Turning off tagging folder for now, to stop messing people's series folders.
|
//Turning off tagging folder for now, to stop messing people's series folders.
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Core.Jobs;
|
using NzbDrone.Core.Jobs;
|
||||||
using NzbDrone.Core.Providers;
|
using NzbDrone.Core.Providers;
|
||||||
|
@ -23,6 +24,8 @@ namespace NzbDrone.Web.Controllers
|
||||||
private readonly TvDbProvider _tvDbProvider;
|
private readonly TvDbProvider _tvDbProvider;
|
||||||
private readonly DiskProvider _diskProvider;
|
private readonly DiskProvider _diskProvider;
|
||||||
|
|
||||||
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public AddSeriesController(RootDirProvider rootFolderProvider,
|
public AddSeriesController(RootDirProvider rootFolderProvider,
|
||||||
ConfigProvider configProvider,
|
ConfigProvider configProvider,
|
||||||
QualityProvider qualityProvider, TvDbProvider tvDbProvider,
|
QualityProvider qualityProvider, TvDbProvider tvDbProvider,
|
||||||
|
@ -83,17 +86,26 @@ namespace NzbDrone.Web.Controllers
|
||||||
foreach (var folder in unmappedList)
|
foreach (var folder in unmappedList)
|
||||||
{
|
{
|
||||||
var foldername = new DirectoryInfo(folder).Name;
|
var foldername = new DirectoryInfo(folder).Name;
|
||||||
var tvdbResult = _tvDbProvider.SearchSeries(foldername).FirstOrDefault();
|
|
||||||
|
|
||||||
var title = String.Empty;
|
try
|
||||||
var seriesId = 0;
|
|
||||||
if (tvdbResult != null)
|
|
||||||
{
|
{
|
||||||
title = tvdbResult.SeriesName;
|
var tvdbResult = _tvDbProvider.SearchSeries(foldername).FirstOrDefault();
|
||||||
seriesId = tvdbResult.Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.ExistingSeries.Add(new Tuple<string, string, int>(folder, title, seriesId));
|
var title = String.Empty;
|
||||||
|
var seriesId = 0;
|
||||||
|
if (tvdbResult != null)
|
||||||
|
{
|
||||||
|
title = tvdbResult.SeriesName;
|
||||||
|
seriesId = tvdbResult.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.ExistingSeries.Add(new Tuple<string, string, int>(folder, title, seriesId));
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
logger.WarnException("Failed to connect to TheTVDB to search for: " + foldername, ex);
|
||||||
|
return View();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultQuality = Convert.ToInt32(_configProvider.DefaultQualityProfile);
|
var defaultQuality = Convert.ToInt32(_configProvider.DefaultQualityProfile);
|
||||||
|
|
|
@ -111,7 +111,8 @@ namespace NzbDrone.Web.Controllers
|
||||||
SabTvCategorySelectList = tvCategorySelectList,
|
SabTvCategorySelectList = tvCategorySelectList,
|
||||||
DownloadClient = (int)_configProvider.DownloadClient,
|
DownloadClient = (int)_configProvider.DownloadClient,
|
||||||
BlackholeDirectory = _configProvider.BlackholeDirectory,
|
BlackholeDirectory = _configProvider.BlackholeDirectory,
|
||||||
DownloadClientSelectList = new SelectList(downloadClientTypes, "Key", "Value")
|
DownloadClientSelectList = new SelectList(downloadClientTypes, "Key", "Value"),
|
||||||
|
PneumaticDirectory = _configProvider.PneumaticDirectory
|
||||||
};
|
};
|
||||||
|
|
||||||
return View(model);
|
return View(model);
|
||||||
|
@ -430,6 +431,7 @@ namespace NzbDrone.Web.Controllers
|
||||||
_configProvider.SabDropDirectory = data.DownloadClientDropDirectory;
|
_configProvider.SabDropDirectory = data.DownloadClientDropDirectory;
|
||||||
_configProvider.BlackholeDirectory = data.BlackholeDirectory;
|
_configProvider.BlackholeDirectory = data.BlackholeDirectory;
|
||||||
_configProvider.DownloadClient = (DownloadClientType)data.DownloadClient;
|
_configProvider.DownloadClient = (DownloadClientType)data.DownloadClient;
|
||||||
|
_configProvider.PneumaticDirectory = data.PneumaticDirectory;
|
||||||
|
|
||||||
return GetSuccessResult();
|
return GetSuccessResult();
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,12 @@ namespace NzbDrone.Web.Models
|
||||||
[Description("What method do you download NZBs with?")]
|
[Description("What method do you download NZBs with?")]
|
||||||
public int DownloadClient { get; set; }
|
public int DownloadClient { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("Pneumatic Nzb Directory")]
|
||||||
|
[Description("Directory to save NZBs for Pneumatic, must be able from XBMC")]
|
||||||
|
[DisplayFormat(ConvertEmptyStringToNull = false)]
|
||||||
|
[RequiredIf("DownloadClient", (int)DownloadClientType.Pneumatic, ErrorMessage = "Required when Download Client is Blackhole")]
|
||||||
|
public string PneumaticDirectory { get; set; }
|
||||||
|
|
||||||
public SelectList SabTvCategorySelectList { get; set; }
|
public SelectList SabTvCategorySelectList { get; set; }
|
||||||
public SelectList DownloadClientSelectList { get; set; }
|
public SelectList DownloadClientSelectList { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,6 +554,9 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Views\Shared\_MINIPROFILER UPDATED Layout.cshtml" />
|
<Content Include="Views\Shared\_MINIPROFILER UPDATED Layout.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Views\Settings\Pneumatic.cshtml" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
|
|
@ -6,7 +6,14 @@
|
||||||
Layout = null;
|
Layout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Model.ExistingSeries.Count == 0)
|
@if (Model == null)
|
||||||
|
{
|
||||||
|
<h2 style="color: tomato">
|
||||||
|
Error searching TheTVDB, please try again later.
|
||||||
|
</h2>
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!Model.ExistingSeries.Any())
|
||||||
{
|
{
|
||||||
<h2 style="color: tomato">
|
<h2 style="color: tomato">
|
||||||
No series available. Try adding a new Root Folder.
|
No series available. Try adding a new Root Folder.
|
||||||
|
|
|
@ -41,12 +41,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="jquery-accordion" id="downloadClientAccordion">
|
<div class="jquery-accordion" id="downloadClientAccordion">
|
||||||
<h3>
|
<h3><a href="#">Sabnzbd</a></h3>
|
||||||
<a href="#">Sabnzbd</a></h3>
|
|
||||||
@{Html.RenderPartial("Sabnzbd", Model);}
|
@{Html.RenderPartial("Sabnzbd", Model);}
|
||||||
<h3>
|
|
||||||
<a href="#">Blackhole</a></h3>
|
<h3><a href="#">Blackhole</a></h3>
|
||||||
@{Html.RenderPartial("Blackhole", Model);}
|
@{Html.RenderPartial("Blackhole", Model);}
|
||||||
|
|
||||||
|
<h3><a href="#">Pneumatic</a></h3>
|
||||||
|
@{Html.RenderPartial("Pneumatic", Model);}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="save_button" disabled="disabled">
|
<button type="submit" class="save_button" disabled="disabled">
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
@using NzbDrone.Web.Helpers;
|
||||||
|
@model NzbDrone.Web.Models.DownloadClientSettingsModel
|
||||||
|
|
||||||
|
@{
|
||||||
|
Layout = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="downloadClient">
|
||||||
|
<label class="labelClass">@Html.LabelFor(m => m.PneumaticDirectory)
|
||||||
|
<span class="small">@Html.DescriptionFor(m => m.PneumaticDirectory)</span>
|
||||||
|
<span class="small">@Html.ValidationMessageFor(m => m.PneumaticDirectory)</span>
|
||||||
|
</label>
|
||||||
|
@Html.TextBoxFor(m => m.PneumaticDirectory, new { @class = "inputClass folderLookup" })
|
||||||
|
</div>
|
Loading…
Reference in New Issue