From 74fbc97835a33731d223ea327f211104c24cd51f Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Tue, 7 Nov 2017 17:39:16 +0100 Subject: [PATCH] IVirtualDiskProvider abstraction, need a lot of work on the class names. --- src/NzbDrone.Core/NzbDrone.Core.csproj | 11 ++++- .../TransferProviders/ITransferProvider.cs | 8 +++- .../TransferProviders/IVirtualDiskProvider.cs | 11 ++++- .../Providers/DefaultTransfer.cs | 41 +++++++++++++++++++ .../TransferProviders/Providers/Dummy.cs | 28 +++++++++++++ .../TransferProviders/TransferProviderBase.cs | 26 ++++++++++++ .../TransferProviderDefinition.cs | 14 +++++++ .../TransferProviderFactory.cs | 26 ------------ .../TransferProviderRepository.cs | 11 +++++ .../TransferProviderService.cs | 40 ++++++++++++++++++ 10 files changed, 186 insertions(+), 30 deletions(-) create mode 100644 src/NzbDrone.Core/TransferProviders/Providers/DefaultTransfer.cs create mode 100644 src/NzbDrone.Core/TransferProviders/Providers/Dummy.cs create mode 100644 src/NzbDrone.Core/TransferProviders/TransferProviderBase.cs create mode 100644 src/NzbDrone.Core/TransferProviders/TransferProviderDefinition.cs create mode 100644 src/NzbDrone.Core/TransferProviders/TransferProviderRepository.cs create mode 100644 src/NzbDrone.Core/TransferProviders/TransferProviderService.cs diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index df65f256f..e729263de 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -946,10 +946,14 @@ - + + + + + - + @@ -1126,7 +1130,10 @@ + + + diff --git a/src/NzbDrone.Core/TransferProviders/ITransferProvider.cs b/src/NzbDrone.Core/TransferProviders/ITransferProvider.cs index c965badd7..9f35e6476 100644 --- a/src/NzbDrone.Core/TransferProviders/ITransferProvider.cs +++ b/src/NzbDrone.Core/TransferProviders/ITransferProvider.cs @@ -5,10 +5,16 @@ using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.TransferProviders { - public interface ITransferProvider : IProvider, IVirtualDiskProvider + public interface ITransferProvider : IProvider { + // TODO: Perhaps change 'string' to 'DownloadClientPath' struct/class so we're more typesafe. + // Whether the TransferProvider is ready to be accessed. (Useful for external transfers that may not have finished yet) bool IsAvailable(string downloadClientPath); bool IsAvailable(DownloadClientItem item); + + // Returns a wrapper for the specific download. Optionally we might want to supply a 'tempDir' that's close to the series path, in case the TransferProvider needs an intermediate location. + IVirtualDiskProvider GetFileSystemWrapper(string downloadClientPath); + IVirtualDiskProvider GetFileSystemWrapper(DownloadClientItem item); } } diff --git a/src/NzbDrone.Core/TransferProviders/IVirtualDiskProvider.cs b/src/NzbDrone.Core/TransferProviders/IVirtualDiskProvider.cs index 9f23783f0..a5542028c 100644 --- a/src/NzbDrone.Core/TransferProviders/IVirtualDiskProvider.cs +++ b/src/NzbDrone.Core/TransferProviders/IVirtualDiskProvider.cs @@ -8,9 +8,18 @@ namespace NzbDrone.Core.TransferProviders { // Represents the remote filesystem, or contents of rar, or ... etc. // Any Move/Copy action should return an asynchroneous context representing the transfer in progress. So it can be shown in CDH / Activity->Queue. - public interface IVirtualDiskProvider // : IDiskProvider + public interface IVirtualDiskProvider // : IDiskProvider { + // Whether the VirtualFileSystem supports direct streaming of the file content. + bool SupportStreaming { get; } + + // Returns recursive list of all files in the 'volume'/'filesystem'/'dataset' (whatever we want to call it). + string[] GetFiles(); + // Copies file from the virtual filesystem to the actual one. TransferTask CopyFile(string vfsSourcePath, string destinationPath); + + // Move file from the virtual filesystem to the actual one. + TransferTask MoveFile(string vfsSourcePath, string destinationPath); } } diff --git a/src/NzbDrone.Core/TransferProviders/Providers/DefaultTransfer.cs b/src/NzbDrone.Core/TransferProviders/Providers/DefaultTransfer.cs new file mode 100644 index 000000000..83c1cb8e2 --- /dev/null +++ b/src/NzbDrone.Core/TransferProviders/Providers/DefaultTransfer.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentValidation.Results; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.TransferProviders.Providers +{ + // Represents a local filesystem transfer. + class DefaultTransfer : TransferProviderBase + { + public override IEnumerable DefaultDefinitions + { + get + { + yield return new TransferProviderDefinition + { + Enable = true, + Name = "Default", + ImplementationName = nameof(DefaultTransfer), + Implementation = nameof(DefaultTransfer), + Settings = NullConfig.Instance + }; + } + } + public override string Link + { + get { throw new NotImplementedException(); } + } + + public override string Name + { + get { throw new NotImplementedException(); } + } + + public override ValidationResult Test() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/NzbDrone.Core/TransferProviders/Providers/Dummy.cs b/src/NzbDrone.Core/TransferProviders/Providers/Dummy.cs new file mode 100644 index 000000000..40aaa8538 --- /dev/null +++ b/src/NzbDrone.Core/TransferProviders/Providers/Dummy.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FluentValidation.Results; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.TransferProviders.Providers +{ + // Marks the files are permanently unavailable. Perhaps useful in fire-and-forget. + class Dummy : TransferProviderBase + { + public override string Link + { + get { throw new NotImplementedException(); } + } + + public override string Name + { + get { throw new NotImplementedException(); } + } + + public override ValidationResult Test() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/NzbDrone.Core/TransferProviders/TransferProviderBase.cs b/src/NzbDrone.Core/TransferProviders/TransferProviderBase.cs new file mode 100644 index 000000000..3155ba4cf --- /dev/null +++ b/src/NzbDrone.Core/TransferProviders/TransferProviderBase.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentValidation.Results; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.TransferProviders +{ + public abstract class TransferProviderBase : ITransferProvider where TSettings : IProviderConfig, new() + { + public abstract string Name { get; } + + public Type ConfigContract => typeof(TSettings); + + public virtual ProviderMessage Message => null; + + public virtual IEnumerable DefaultDefinitions => new List(); + + public ProviderDefinition Definition { get; set; } + public abstract ValidationResult Test(); + + public abstract string Link { get; } + + public virtual object RequestAction(string action, IDictionary query) { return null; } + } +} diff --git a/src/NzbDrone.Core/TransferProviders/TransferProviderDefinition.cs b/src/NzbDrone.Core/TransferProviders/TransferProviderDefinition.cs new file mode 100644 index 000000000..6ba8486dc --- /dev/null +++ b/src/NzbDrone.Core/TransferProviders/TransferProviderDefinition.cs @@ -0,0 +1,14 @@ +using System; +using System.Linq; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.TransferProviders +{ + public class TransferProviderDefinition : ProviderDefinition + { + public int DownloadClientId { get; set; } + // OR + // Path could be extracted from download client. + //public string DownloadClientRootPath { get; set; } + } +} diff --git a/src/NzbDrone.Core/TransferProviders/TransferProviderFactory.cs b/src/NzbDrone.Core/TransferProviders/TransferProviderFactory.cs index 842549088..07da190c3 100644 --- a/src/NzbDrone.Core/TransferProviders/TransferProviderFactory.cs +++ b/src/NzbDrone.Core/TransferProviders/TransferProviderFactory.cs @@ -11,36 +11,10 @@ using NzbDrone.Core.Validation; namespace NzbDrone.Core.TransferProviders { - public class TransferProviderDefinition : ProviderDefinition - { - } - public interface ITransferProviderFactory : IProviderFactory { } - public abstract class TransferProviderBase : ITransferProvider where TSettings : IProviderConfig, new() - { - public abstract string Name { get; } - - public Type ConfigContract => typeof(TSettings); - - public virtual ProviderMessage Message => null; - - public IEnumerable DefaultDefinitions => new List(); - public ProviderDefinition Definition { get; set; } - public abstract ValidationResult Test(); - - public abstract string Link { get; } - - public virtual object RequestAction(string action, IDictionary query) { return null; } - } - - public interface ITransferProviderRepository : IProviderRepository - { - - } - public class TransferProviderFactory : ProviderFactory, ITransferProviderFactory { public TransferProviderFactory(ITransferProviderRepository providerRepository, IEnumerable providers, IContainer container, IEventAggregator eventAggregator, Logger logger) diff --git a/src/NzbDrone.Core/TransferProviders/TransferProviderRepository.cs b/src/NzbDrone.Core/TransferProviders/TransferProviderRepository.cs new file mode 100644 index 000000000..c5ca0481f --- /dev/null +++ b/src/NzbDrone.Core/TransferProviders/TransferProviderRepository.cs @@ -0,0 +1,11 @@ +using System; +using System.Linq; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.TransferProviders +{ + public interface ITransferProviderRepository : IProviderRepository + { + + } +} diff --git a/src/NzbDrone.Core/TransferProviders/TransferProviderService.cs b/src/NzbDrone.Core/TransferProviders/TransferProviderService.cs new file mode 100644 index 000000000..697948cb1 --- /dev/null +++ b/src/NzbDrone.Core/TransferProviders/TransferProviderService.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NLog; +using NzbDrone.Core.Download; +using NzbDrone.Core.ThingiProvider; +using NzbDrone.Core.TransferProviders.Providers; + +namespace NzbDrone.Core.TransferProviders +{ + public interface ITransferProviderService + { + ITransferProvider GetProvider(int downloadClientId); + } + + public class TransferProviderService : ITransferProviderService + { + private readonly ITransferProviderFactory _transferProviderFactory; + private readonly Logger _logger; + + public TransferProviderService(ITransferProviderFactory transferProviderFactory, Logger logger) + { + _transferProviderFactory = transferProviderFactory; + _logger = logger; + } + + public ITransferProvider GetProvider(int downloadClientId) + { + var definition = _transferProviderFactory.All().FirstOrDefault(v => v.DownloadClientId == downloadClientId); + + if (definition == null) + { + definition = _transferProviderFactory.GetDefaultDefinitions().First(v => v.ImplementationName == nameof(DefaultTransfer)); + } + + return _transferProviderFactory.GetInstance(definition); + } + } +}