aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs')
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs195
1 files changed, 191 insertions, 4 deletions
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs
index bcc39d11d..1f6641f3a 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
@@ -13,16 +14,97 @@ using Tango.FileSystem.Network;
using Tango.FSE.Common.Connection;
using Tango.FSE.Common.FileSystem;
using Tango.Transport;
+using Tango.Transport.Transporters;
+using Tango.WebRTC;
namespace Tango.FSE.UI.FileSystem
{
public class DefaultFileSystemProvider : ExtendedObject, IFileSystemProvider
{
private IMachineProvider _machineProvider;
+ private BasicTransporter _webRtcTransporter;
+ private const string WEB_RTC_CHANNEL_NAME = "FileSystemChannel";
+ private const long MAX_CHUNK_SIZE = 1024 * 10;
+ private const long MAX_CHUNK_SIZE_WEB_RTC = 1024 * 15;
+ private List<FileSystemHandler> _activeHandlers;
+
+ private bool _enableWebRTC;
+ public bool EnableWebRTC
+ {
+ get { return _enableWebRTC; }
+ set { _enableWebRTC = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isWebRtcAvailable;
+ public bool IsWebRtcAvailable
+ {
+ get { return _isWebRtcAvailable; }
+ private set { _isWebRtcAvailable = value; RaisePropertyChangedAuto(); }
+ }
public DefaultFileSystemProvider(IMachineProvider machineProvider)
{
+ _activeHandlers = new List<FileSystemHandler>();
+
+ EnableWebRTC = true; //TODO: From Settings..
_machineProvider = machineProvider;
+ _machineProvider.MachineConnected += _machineProvider_MachineConnected;
+ _machineProvider.MachineDisconnected += _machineProvider_MachineDisconnected;
+ }
+
+ private void _machineProvider_MachineDisconnected(object sender, MachineDisconnectedEventArgs e)
+ {
+ IsWebRtcAvailable = false;
+
+ foreach (var handler in _activeHandlers.ToList())
+ {
+ try
+ {
+ handler.RaiseFailed(new TransporterDisconnectedException("Machine disconnected."));
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
+ }
+ }
+
+ _activeHandlers.Clear();
+ }
+
+ private async void _machineProvider_MachineConnected(object sender, MachineConnectedEventArgs e)
+ {
+ if (EnableWebRTC)
+ {
+ try
+ {
+ IsWebRtcAvailable = false;
+
+ await _machineProvider.MachineOperator.SendGenericRequest<InitWebRtcRequest, InitWebRtcResponse>(new InitWebRtcRequest()
+ {
+ DataChannelName = WEB_RTC_CHANNEL_NAME
+ }, new TransportRequestConfig()
+ {
+ Timeout = TimeSpan.FromSeconds(60),
+ Priority = QueuePriority.Low
+ });
+
+ _webRtcTransporter = new BasicTransporter(new WebRtcTransportAdapter(_machineProvider.MachineOperator, WebRtcTransportAdapterMode.Active, WEB_RTC_CHANNEL_NAME));
+ _webRtcTransporter.UseKeepAlive = false;
+ _webRtcTransporter.ComponentName = "File System Active WebRTC Transporter";
+ await _webRtcTransporter.Connect();
+
+ IsWebRtcAvailable = true;
+
+ LogManager.Log("FileSystem via WebRTC is ready.");
+ }
+ catch (Exception ex)
+ {
+ IsWebRtcAvailable = false;
+ EnableWebRTC = false;
+
+ LogManager.Log(ex, "Error initializing FileSystem via WebRTC.");
+ }
+ }
}
public async Task<IFileSystemContainer> GetFolder(string path)
@@ -100,6 +182,8 @@ namespace Tango.FSE.UI.FileSystem
}
});
+ _activeHandlers.Add(handler);
+
ThreadFactory.StartNew(async () =>
{
try
@@ -135,11 +219,13 @@ namespace Tango.FSE.UI.FileSystem
}
catch (Exception ex)
{
+ _activeHandlers.Remove(handler);
handler.RaiseFailed(ex);
return;
}
long position = 0;
+ bool webRtcFailed = false;
var tempFile = TemporaryManager.CreateFile();
@@ -153,13 +239,32 @@ namespace Tango.FSE.UI.FileSystem
try
{
- var response = await _machineProvider.MachineOperator.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>(
- new ChunkDownloadRequest()
+ ChunkDownloadResponse response = null;
+ ChunkDownloadRequest request = new ChunkDownloadRequest()
{
- MaxChunkSize = 1024 * 10,
+ MaxChunkSize = MAX_CHUNK_SIZE,
OperationId = operationId,
Position = position,
- }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30), Priority = QueuePriority.Low });
+ };
+
+ if (_webRtcTransporter != null && _webRtcTransporter.State == TransportComponentState.Connected && EnableWebRTC && !webRtcFailed)
+ {
+ try
+ {
+ request.MaxChunkSize = MAX_CHUNK_SIZE_WEB_RTC;
+ response = await _webRtcTransporter.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>(request, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30), Priority = QueuePriority.Low });
+ }
+ catch (Exception ex)
+ {
+ webRtcFailed = true;
+ LogManager.Log(ex, "WebRTC chunk download failed. Falling back to standard download...");
+ continue;
+ }
+ }
+ else
+ {
+ response = await _machineProvider.MachineOperator.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>(request, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30), Priority = QueuePriority.Low });
+ }
using (FileStream fs = new FileStream(tempFile, FileMode.Append))
{
@@ -171,6 +276,7 @@ namespace Tango.FSE.UI.FileSystem
}
catch (Exception ex)
{
+ _activeHandlers.Remove(handler);
tempFile.Delete();
handler.RaiseFailed(ex);
return;
@@ -203,6 +309,8 @@ namespace Tango.FSE.UI.FileSystem
{
tempFile.Delete();
}
+
+ _activeHandlers.Remove(handler);
});
return Task.FromResult(handler);
@@ -212,5 +320,84 @@ namespace Tango.FSE.UI.FileSystem
{
throw new NotImplementedException();
}
+
+ public async Task Copy(FileSystemItem source, FileSystemItem target)
+ {
+ if (source.Type == FileSystemItemType.Drive)
+ {
+ throw new NotSupportedException("The source file system item is not supported for copying.");
+ }
+ if (target.Type == FileSystemItemType.File)
+ {
+ throw new NotSupportedException("The target file system item is not a valid container.");
+ }
+
+ await _machineProvider.MachineOperator.SendGenericRequest<CopyRequest, CopyResponse>(new CopyRequest()
+ {
+
+ Source = source.Path,
+ Destination = Path.Combine(target.Path, source.Name)
+
+ }, new TransportRequestConfig()
+ {
+ Timeout = TimeSpan.FromSeconds(120),
+ });
+ }
+
+ public async Task Move(FileSystemItem source, FileSystemItem target)
+ {
+ if (source.Type == FileSystemItemType.Drive)
+ {
+ throw new NotSupportedException("The source file system item is not supported for copying.");
+ }
+ if (target.Type == FileSystemItemType.File)
+ {
+ throw new NotSupportedException("The target file system item is not a valid container.");
+ }
+
+ await _machineProvider.MachineOperator.SendGenericRequest<MoveRequest, MoveResponse>(new MoveRequest()
+ {
+
+ Source = source.Path,
+ Destination = Path.Combine(target.Path, source.Name)
+
+ }, new TransportRequestConfig()
+ {
+ Timeout = TimeSpan.FromSeconds(120),
+ });
+ }
+
+ public async Task Rename(FileSystemItem source, string newName)
+ {
+ if (source.Type == FileSystemItemType.Drive)
+ {
+ throw new NotSupportedException("The source file system item is not supported for copying.");
+ }
+ if (newName.ToList().Exists(x => Path.GetInvalidFileNameChars().Contains(x)))
+ {
+ throw new ArgumentException("The new name contains invalid characters.");
+ }
+
+ await _machineProvider.MachineOperator.SendGenericRequest<MoveRequest, MoveResponse>(new MoveRequest()
+ {
+
+ Source = source.Path,
+ Destination = Path.Combine(Path.GetDirectoryName(source.Path), newName)
+
+ });
+ }
+
+ public async Task Delete(FileSystemItem item)
+ {
+ if (item.Type == FileSystemItemType.Drive)
+ {
+ throw new NotSupportedException("The source file system item is not supported for deletion.");
+ }
+
+ await _machineProvider.MachineOperator.SendGenericRequest<DeleteRequest, DeleteResponse>(new DeleteRequest()
+ {
+ Path = item.Path
+ }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(120) });
+ }
}
}