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