From 853f7689bcccd1c5baf434b2b2a66c8b81fd6646 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 29 Aug 2012 17:20:48 -0700 Subject: [PATCH] Pneumatic added to server side --- NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 1 + .../PneumaticProviderFixture.cs | 78 ++++++++++++++++++ .../Providers/Core/ConfigProvider.cs | 6 ++ .../DownloadClients/PneumaticProvider.cs | 79 +++++++++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 NzbDrone.Core.Test/ProviderTests/DownloadClientTests/PneumaticProviderFixture.cs create mode 100644 NzbDrone.Core/Providers/DownloadClients/PneumaticProvider.cs diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 20c5a8d66..695e3e405 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -118,6 +118,7 @@ + diff --git a/NzbDrone.Core.Test/ProviderTests/DownloadClientTests/PneumaticProviderFixture.cs b/NzbDrone.Core.Test/ProviderTests/DownloadClientTests/PneumaticProviderFixture.cs new file mode 100644 index 000000000..7949c5ca5 --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/DownloadClientTests/PneumaticProviderFixture.cs @@ -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().SetupGet(c => c.BlackholeDirectory).Returns(pneumaticFolder); + } + + private void WithExistingFile() + { + Mocker.GetMock().Setup(c => c.FileExists(nzbPath)).Returns(true); + } + + private void WithFailedDownload() + { + Mocker.GetMock().Setup(c => c.DownloadFile(It.IsAny(), It.IsAny())).Throws(new WebException()); + } + + [Test] + public void should_download_file_if_it_doesnt_exist() + { + Mocker.Resolve().DownloadNzb(nzbUrl, title).Should().BeTrue(); + + Mocker.GetMock().Verify(c => c.DownloadFile(nzbUrl, nzbPath),Times.Once()); + } + + [Test] + public void should_not_download_file_if_it_doesn_exist() + { + WithExistingFile(); + + Mocker.Resolve().DownloadNzb(nzbUrl, title).Should().BeTrue(); + + Mocker.GetMock().Verify(c => c.DownloadFile(It.IsAny(), It.IsAny()), Times.Never()); + } + + [Test] + public void should_return_false_on_failed_download() + { + WithFailedDownload(); + + Mocker.Resolve().DownloadNzb(nzbUrl, title).Should().BeFalse(); + + ExceptionVerification.ExpectedWarns(1); + } + + [Test] + public void should_skip_if_full_season_download() + { + Mocker.Resolve().DownloadNzb(nzbUrl, "30 Rock - Season 1").Should().BeFalse(); + ExceptionVerification.ExpectedErrors(1); + } + + + } +} diff --git a/NzbDrone.Core/Providers/Core/ConfigProvider.cs b/NzbDrone.Core/Providers/Core/ConfigProvider.cs index 605af206b..06e4770f5 100644 --- a/NzbDrone.Core/Providers/Core/ConfigProvider.cs +++ b/NzbDrone.Core/Providers/Core/ConfigProvider.cs @@ -520,6 +520,12 @@ namespace NzbDrone.Core.Providers.Core set { SetValue("AllowedReleaseGroups", value); } } + public virtual string PneumaticDirectory + { + get { return GetValue("PneumaticDirectory", String.Empty); } + set { SetValue("PneumaticDirectory", value); } + } + private string GetValue(string key) { return GetValue(key, String.Empty); diff --git a/NzbDrone.Core/Providers/DownloadClients/PneumaticProvider.cs b/NzbDrone.Core/Providers/DownloadClients/PneumaticProvider.cs new file mode 100644 index 000000000..dc323d2e7 --- /dev/null +++ b/NzbDrone.Core/Providers/DownloadClients/PneumaticProvider.cs @@ -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(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); + } + } +}