diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-04-09 00:29:06 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-04-09 00:29:06 +0300 |
| commit | 5774f40b650a376e9b622dba9df6c43589b0d398 (patch) | |
| tree | 8d80f23cbb9cc264cc5be1bd82c52402eed612e6 /Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs | |
| parent | 42391bb46aa9dda0f56a7909268a2cffdf36f1d8 (diff) | |
| download | Tango-5774f40b650a376e9b622dba9df6c43589b0d398.tar.gz Tango-5774f40b650a376e9b622dba9df6c43589b0d398.zip | |
Logs, Comments & General organization on FSE/PPC.
Several improvements.
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.cs | 529 |
1 files changed, 408 insertions, 121 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 86ee2a73e..8381133bf 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Tango.Core; +using Tango.Core.ExtensionMethods; using Tango.Core.IO; using Tango.Core.Threading; using Tango.FileSystem; @@ -20,31 +21,79 @@ using Tango.WebRTC; namespace Tango.FSE.UI.FileSystem { + /// <summary> + /// Represents the <see cref="IFileSystemProvider"/> default implementation. + /// </summary> + /// <seealso cref="Tango.Core.ExtendedObject" /> + /// <seealso cref="Tango.FSE.Common.FileSystem.IFileSystemProvider" /> 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 * 100; - private const long MIN_CHUNK_SIZE = 1024; - private const long MAX_CHUNK_SIZE_WEB_RTC = 1024 * 50; - private const int WEB_RTC_MAX_RETRIES = 8; + private const long MAX_CHUNK_SIZE = 1024 * 100; //Max chunk size for the standard channel (WebSockets/SignalR). + private const long MIN_CHUNK_SIZE = 1024; //Min chunk size for the standard channel. + private const long MAX_CHUNK_SIZE_WEB_RTC = 1024 * 50; //Max chunk size for the WebRTC channel. + private const long MIN_CHUNK_SIZE_WEB_RTC = 1024; //Min chunk size for the WebRTC channel. + private const int WEB_RTC_MAX_RETRIES = 8; //Maximum number of retries per chunk for the WebRTC channel until falling back to standard channel. private List<FileSystemHandler> _activeHandlers; + #region Properties + private bool _enableWebRTC; + /// <summary> + /// Gets or sets a value indicating whether to enable a P2P WebRTC channel for fast transport. + /// </summary> public bool EnableWebRTC { get { return _enableWebRTC; } - set { _enableWebRTC = value; RaisePropertyChangedAuto(); } + set + { + _enableWebRTC = value; + RaisePropertyChangedAuto(); + + if (value) + { + LogManager.Log("File system WebRTC channel is now enabled."); + } + else + { + LogManager.Log("File system WebRTC channel is now disabled."); + } + } } private bool _isWebRtcAvailable; + /// <summary> + /// Gets a value indicating whether the WebRTC channel is available. + /// </summary> public bool IsWebRtcAvailable { get { return _isWebRtcAvailable; } - private set { _isWebRtcAvailable = value; RaisePropertyChangedAuto(); } + private set + { + _isWebRtcAvailable = value; + RaisePropertyChangedAuto(); + + if (value) + { + LogManager.Log("File system WebRTC channel is now available."); + } + else + { + LogManager.Log("File system WebRTC channel is now available."); + } + } } + #endregion + + #region Constructors + + /// <summary> + /// Initializes a new instance of the <see cref="DefaultFileSystemProvider"/> class. + /// </summary> + /// <param name="machineProvider">The machine provider.</param> public DefaultFileSystemProvider(IMachineProvider machineProvider) { _activeHandlers = new List<FileSystemHandler>(); @@ -55,6 +104,10 @@ namespace Tango.FSE.UI.FileSystem _machineProvider.MachineDisconnected += _machineProvider_MachineDisconnected; } + #endregion + + #region Machine Connection Event Handlers + private async void _machineProvider_MachineDisconnected(object sender, MachineDisconnectedEventArgs e) { IsWebRtcAvailable = false; @@ -89,7 +142,7 @@ namespace Tango.FSE.UI.FileSystem private async void _machineProvider_MachineConnected(object sender, MachineConnectedEventArgs e) { - if (EnableWebRTC) + if (_machineProvider.ConnectionType.IsRemote()) { try { @@ -121,47 +174,100 @@ namespace Tango.FSE.UI.FileSystem } } + #endregion + + #region Public Methods + + /// <summary> + /// Gets a folder by the specified path. + /// </summary> + /// <param name="path">The path.</param> + /// <returns></returns> public async Task<IFileSystemContainer> GetFolder(string path) { - var response = await _machineProvider.MachineOperator.SendGenericRequest<GetFileSystemItemRequest, GetFileSystemItemResponse>(new GetFileSystemItemRequest() + try { - Path = path - }, new TransportRequestConfig() - { - Timeout = TimeSpan.FromSeconds(30), - }); + LogManager.Log($"Retrieving remote folder '{path}'..."); - return FileSystemItem.FromDTO(response.FileSystemItem) as IFileSystemContainer; + var response = await _machineProvider.MachineOperator.SendGenericRequest<GetFileSystemItemRequest, GetFileSystemItemResponse>(new GetFileSystemItemRequest() + { + Path = path, + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(30), + }); + + return FileSystemItem.FromDTO(response.FileSystemItem) as IFileSystemContainer; + } + catch (Exception ex) + { + throw LogManager.Log(ex, "Error retrieving remote folder."); + } } + /// <summary> + /// Gets the specified special folder. + /// </summary> + /// <param name="specialFolder">The special folder.</param> + /// <returns></returns> public async Task<IFileSystemContainer> GetSpecialFolder(Environment.SpecialFolder specialFolder) { - var response = await _machineProvider.MachineOperator.SendGenericRequest<GetFileSystemItemRequest, GetFileSystemItemResponse>(new GetFileSystemItemRequest() - { - SpecialFolder = specialFolder - }, new TransportRequestConfig() + try { - Timeout = TimeSpan.FromSeconds(30), - }); + LogManager.Log($"Retrieving remote special folder '{specialFolder}'..."); + + var response = await _machineProvider.MachineOperator.SendGenericRequest<GetFileSystemItemRequest, GetFileSystemItemResponse>(new GetFileSystemItemRequest() + { + SpecialFolder = specialFolder + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(30), + }); - return FileSystemItem.FromDTO(response.FileSystemItem) as IFileSystemContainer; + return FileSystemItem.FromDTO(response.FileSystemItem) as IFileSystemContainer; + } + catch (Exception ex) + { + throw LogManager.Log(ex, "Error retrieving remote special folder."); + } } + /// <summary> + /// Gets the ThisPC (the root path of the PC). + /// </summary> + /// <returns></returns> public async Task<IFileSystemContainer> GetThisPC() { - var response = await _machineProvider.MachineOperator.SendGenericRequest<GetFileSystemItemRequest, GetFileSystemItemResponse>(new GetFileSystemItemRequest() - { - //No parameters at all - }, new TransportRequestConfig() + try { - Timeout = TimeSpan.FromSeconds(30), - }); + LogManager.Log("Retrieving remote root directory (This PC)..."); - return FileSystemItem.FromDTO(response.FileSystemItem) as IFileSystemContainer; + var response = await _machineProvider.MachineOperator.SendGenericRequest<GetFileSystemItemRequest, GetFileSystemItemResponse>(new GetFileSystemItemRequest() + { + //No parameters at all + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(30), + }); + + return FileSystemItem.FromDTO(response.FileSystemItem) as IFileSystemContainer; + } + catch (Exception ex) + { + throw LogManager.Log(ex, "Error retrieving remote root directory."); + } } + /// <summary> + /// Downloads the specified file or folder item. + /// </summary> + /// <param name="item">The file or folder.</param> + /// <param name="localTargetFolder">The local target folder.</param> + /// <returns></returns> public Task<FileSystemHandler> Download(FileSystemItem item, string localTargetFolder) { + LogManager.Log($"Downloading remote item '{item.Path}' to local path '{localTargetFolder}'..."); + String operationId = String.Empty; String destination = String.Empty; long downloadLength = 0; @@ -171,23 +277,28 @@ namespace Tango.FSE.UI.FileSystem destination = Path.Combine(localTargetFolder, item.Name); - handler = new FileSystemHandler(item.Type == FileSystemItemType.Folder ? FileSystemHandlerType.FolderDownload : FileSystemHandlerType.FileDownload, item, destination, async () => { if (!aborted) { + LogManager.Log($"Download aborted by user for '{item.Name}'. Aborting download..."); + aborted = true; try { + LogManager.Log("Sending abort download operation request..."); + var response = await _machineProvider.MachineOperator.SendGenericRequest<AbortOperationRequest, AbortOperationResponse>( new AbortOperationRequest() { OperationId = operationId }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30) }); + + LogManager.Log($"Download operation for '{item.Name} 'aborted successfully."); } catch (Exception ex) { - LogManager.Log(ex, "Error aborting the download operation."); + LogManager.Log(ex, $"Error aborting the download operation for '{item.Name}'."); } finally { @@ -204,24 +315,32 @@ namespace Tango.FSE.UI.FileSystem { if (item.Type == FileSystemItemType.File) { + LogManager.Log("Download item identified as a file. Sending file download request..."); + var response = await _machineProvider.MachineOperator.SendGenericRequest<FileDownloadRequest, FileDownloadResponse>( new FileDownloadRequest() { Path = item.Path }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(20) }); + LogManager.Log($"File download response received:\n{response.ToJsonString()}"); + operationId = response.OperationId; downloadLength = response.Length; handler.OperationId = operationId; } else if (item.Type == FileSystemItemType.Folder) { + LogManager.Log("Download item identified as a folder. Sending folder download request..."); + var response = await _machineProvider.MachineOperator.SendGenericRequest<FolderDownloadRequest, FolderDownloadResponse>( new FolderDownloadRequest() { Path = item.Path }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(60) }); + LogManager.Log($"folder download response received:\n{response.ToJsonString()}"); + operationId = response.OperationId; downloadLength = response.Length; handler.OperationId = operationId; @@ -233,6 +352,7 @@ namespace Tango.FSE.UI.FileSystem } catch (Exception ex) { + LogManager.Log(ex, $"Error downloading remote item '{item.Path}'."); _activeHandlers.Remove(handler); handler.RaiseFailed(ex); return; @@ -241,9 +361,14 @@ namespace Tango.FSE.UI.FileSystem long position = 0; bool webRtcFailed = false; int webRtcRetries = WEB_RTC_MAX_RETRIES; - long dynamixMaxChunkSizeSignalR = MAX_CHUNK_SIZE; + long dynamicMaxChunkSizeSignalR = MAX_CHUNK_SIZE; + long dynamicMaxChunkSizeWebRTC = MIN_CHUNK_SIZE_WEB_RTC; + bool isWebRTCChunkSizeFixed = false; var tempFile = TemporaryManager.CreateFile(); + LogManager.Log($"Generated temporary local file '{tempFile}'..."); + LogManager.Log("Starting chunks download..."); + LogManager.Log($"WebRTC active: {(IsWebRtcAvailable && EnableWebRTC).ToStringYesNo()}."); while (position < downloadLength && !aborted) { @@ -263,27 +388,36 @@ namespace Tango.FSE.UI.FileSystem Position = position, }; - if (_webRtcTransporter != null && _webRtcTransporter.State == TransportComponentState.Connected && EnableWebRTC && !webRtcFailed) + if (_webRtcTransporter != null && _webRtcTransporter.State == TransportComponentState.Connected && EnableWebRTC && !webRtcFailed && _machineProvider.ConnectionType == MachineConnectionTypes.SignalR) { try { - request.MaxChunkSize = MAX_CHUNK_SIZE_WEB_RTC; + request.MaxChunkSize = dynamicMaxChunkSizeWebRTC; + response = await _webRtcTransporter.SendGenericRequest<ChunkDownloadRequest, ChunkDownloadResponse>(request, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(2), Priority = QueuePriority.Low }); + if (!isWebRTCChunkSizeFixed) + { + dynamicMaxChunkSizeWebRTC = Math.Min(dynamicMaxChunkSizeWebRTC + 1024, MAX_CHUNK_SIZE_WEB_RTC); + } + webRtcRetries = WEB_RTC_MAX_RETRIES; } catch (Exception ex) { webRtcRetries--; + dynamicMaxChunkSizeWebRTC = Math.Max(dynamicMaxChunkSizeWebRTC - 1024, MIN_CHUNK_SIZE_WEB_RTC); + isWebRTCChunkSizeFixed = true; + if (webRtcRetries == 0) { webRtcFailed = true; - LogManager.Log(ex, "WebRTC chunk download failed. Falling back to standard download..."); + LogManager.Log(ex, $"WebRTC chunk download for '{item.Name}' failed after {WEB_RTC_MAX_RETRIES} retries with exception:\n{ex.FlattenMessage()}\nFalling back to SignalR download..."); } continue; @@ -291,7 +425,7 @@ namespace Tango.FSE.UI.FileSystem } else { - request.MaxChunkSize = dynamixMaxChunkSizeSignalR; + request.MaxChunkSize = dynamicMaxChunkSizeSignalR; Stopwatch watch = new Stopwatch(); watch.Start(); @@ -306,14 +440,14 @@ namespace Tango.FSE.UI.FileSystem if (watch.Elapsed.TotalSeconds < 1) { - dynamixMaxChunkSizeSignalR += 1024 * 10; + dynamicMaxChunkSizeSignalR += 1024 * 10; } else if (watch.Elapsed.TotalSeconds > 1) { - dynamixMaxChunkSizeSignalR -= 1024 * 10; + dynamicMaxChunkSizeSignalR -= 1024 * 10; } - dynamixMaxChunkSizeSignalR = Math.Max(dynamixMaxChunkSizeSignalR, MIN_CHUNK_SIZE); + dynamicMaxChunkSizeSignalR = Math.Max(dynamicMaxChunkSizeSignalR, MIN_CHUNK_SIZE); } using (FileStream fs = new FileStream(tempFile, FileMode.Append)) @@ -326,6 +460,7 @@ namespace Tango.FSE.UI.FileSystem } catch (Exception ex) { + LogManager.Log(ex, $"Download failed for '{item.Name}'."); _activeHandlers.Remove(handler); tempFile.Delete(); handler.RaiseFailed(ex); @@ -335,27 +470,37 @@ namespace Tango.FSE.UI.FileSystem if (!aborted) { + LogManager.Log($"Chunks completed for '{item.Name}'."); + try { if (item.Type == FileSystemItemType.File) { + LogManager.Log("Copying temporary file to destination directory..."); File.Copy(tempFile, destination, true); + + LogManager.Log("Removing temporary file..."); tempFile.Delete(); } else if (item.Type == FileSystemItemType.Folder) { + LogManager.Log("Extracting temporary zip file to destination directory..."); + using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile(tempFile)) { zip.ExtractAll(destination, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently); } + LogManager.Log("Removing temporary zip file..."); tempFile.Delete(); } + LogManager.Log($"Download completed successfully for '{item.Name}'."); handler.RaiseCompleted(); } catch (Exception ex) { + LogManager.Log(ex, $"Download failed on the final stage for {item.Name}."); handler.RaiseFailed(ex); } } @@ -370,6 +515,13 @@ namespace Tango.FSE.UI.FileSystem return Task.FromResult(handler); } + /// <summary> + /// Uploads the specified local file or folder. + /// </summary> + /// <param name="localSourcePath">The local source path.</param> + /// <param name="remoteFolder">The remote folder.</param> + /// <returns></returns> + /// <exception cref="System.IO.FileNotFoundException">Could not locate the local file or directory to upload.</exception> public Task<FileSystemHandler> Upload(String localSourcePath, FileSystemItem remoteFolder) { String operationId = String.Empty; @@ -381,44 +533,51 @@ namespace Tango.FSE.UI.FileSystem if (Directory.Exists(localSourcePath)) { + LogManager.Log($"Uploading local folder '{localSourcePath}' to remote path '{remoteFolder.Path}'..."); sourceItem = new FolderItem() { Path = localSourcePath }; isFolder = true; } else if (File.Exists(localSourcePath)) { + LogManager.Log($"Uploading local file '{localSourcePath}' to remote path '{remoteFolder.Path}'..."); sourceItem = new FileItem() { Path = localSourcePath }; isFolder = false; } else { - throw new FileNotFoundException("Could not locate the local file or directory to upload."); + throw LogManager.Log(new FileNotFoundException("Could not locate the local file or directory to upload."), "Error uploading local item to remote location."); } FileSystemHandler handler = null; handler = new FileSystemHandler(isFolder ? FileSystemHandlerType.FolderUpload : FileSystemHandlerType.FileUpload, sourceItem, destination, async () => - { - if (!aborted) - { - aborted = true; - try - { - var response = await _machineProvider.MachineOperator.SendGenericRequest<AbortOperationRequest, AbortOperationResponse>( - new AbortOperationRequest() - { - OperationId = operationId - }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30) }); - } - catch (Exception ex) - { - LogManager.Log(ex, "Error aborting the upload operation."); - } - finally - { - handler.RaiseAborted(); - } - } - }); + { + if (!aborted) + { + LogManager.Log($"Upload aborted by user for item '{sourceItem.Name}'. Aborting upload..."); + + aborted = true; + try + { + LogManager.Log("Sending upload operation abort request..."); + var response = await _machineProvider.MachineOperator.SendGenericRequest<AbortOperationRequest, AbortOperationResponse>( + new AbortOperationRequest() + { + OperationId = operationId + }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30) }); + + LogManager.Log($"Upload operation successfully aborted for item '{sourceItem.Name}'."); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error aborting the upload operation for item '{sourceItem.Name}'."); + } + finally + { + handler.RaiseAborted(); + } + } + }); _activeHandlers.Add(handler); @@ -428,23 +587,31 @@ namespace Tango.FSE.UI.FileSystem { if (!isFolder) { + LogManager.Log("Upload item identified as a file. Sending file upload request..."); + var response = await _machineProvider.MachineOperator.SendGenericRequest<FileUploadRequest, FileUploadResponse>( new FileUploadRequest() { Path = destination }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(20) }); + LogManager.Log($"File upload response received:\n{response.ToJsonString()}"); + operationId = response.OperationId; handler.OperationId = operationId; } else { + LogManager.Log("Upload item identified as a folder. Sending file upload request..."); + var response = await _machineProvider.MachineOperator.SendGenericRequest<FolderUploadRequest, FolderUploadResponse>( new FolderUploadRequest() { Path = destination }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(20) }); + LogManager.Log($"Folder upload response received:\n{response.ToJsonString()}"); + operationId = response.OperationId; handler.OperationId = operationId; } @@ -453,11 +620,13 @@ namespace Tango.FSE.UI.FileSystem { var originalPath = localSourcePath; localSourcePath = TemporaryManager.CreateImaginaryFile().Path; + LogManager.Log($"Compressing local folder to temporary zip file '{localSourcePath}'..."); ZipFile.CreateFromDirectory(originalPath, localSourcePath); } } catch (Exception ex) { + LogManager.Log(ex, $"Error uploading local item '{sourceItem.Name}'."); _activeHandlers.Remove(handler); handler.RaiseFailed(ex); return; @@ -467,6 +636,11 @@ namespace Tango.FSE.UI.FileSystem bool webRtcFailed = false; int webRtcRetries = WEB_RTC_MAX_RETRIES; long dynamixMaxChunkSizeSignalR = MAX_CHUNK_SIZE; + long dynamicMaxChunkSizeWebRTC = MIN_CHUNK_SIZE_WEB_RTC; + bool isWebRTCChunkSizeFixed = false; + + LogManager.Log("Starting chunks download..."); + LogManager.Log($"WebRTC active: {(IsWebRtcAvailable && EnableWebRTC).ToStringYesNo()}."); using (FileStream fs = new FileStream(localSourcePath, FileMode.Open)) { @@ -488,11 +662,11 @@ namespace Tango.FSE.UI.FileSystem OperationId = operationId, }; - if (_webRtcTransporter != null && _webRtcTransporter.State == TransportComponentState.Connected && EnableWebRTC && !webRtcFailed) + if (_webRtcTransporter != null && _webRtcTransporter.State == TransportComponentState.Connected && EnableWebRTC && !webRtcFailed && _machineProvider.ConnectionType == MachineConnectionTypes.SignalR) { try { - byte[] data = new byte[Math.Min(MAX_CHUNK_SIZE_WEB_RTC, fs.Length - fs.Position)]; + byte[] data = new byte[Math.Min(dynamicMaxChunkSizeWebRTC, fs.Length - fs.Position)]; fs.Read(data, 0, data.Length); request.Data = data; request.IsCompleted = fs.Position == fs.Length; @@ -503,16 +677,24 @@ namespace Tango.FSE.UI.FileSystem Priority = QueuePriority.Low }); + if (!isWebRTCChunkSizeFixed) + { + dynamicMaxChunkSizeWebRTC = Math.Min(dynamicMaxChunkSizeWebRTC + 1024, MAX_CHUNK_SIZE_WEB_RTC); + } + webRtcRetries = WEB_RTC_MAX_RETRIES; } catch (Exception ex) { webRtcRetries--; + dynamicMaxChunkSizeWebRTC = Math.Max(dynamicMaxChunkSizeWebRTC - 1024, MIN_CHUNK_SIZE_WEB_RTC); + isWebRTCChunkSizeFixed = true; + if (webRtcRetries == 0) { webRtcFailed = true; - LogManager.Log(ex, "WebRTC chunk upload failed. Falling back to standard upload..."); + LogManager.Log(ex, $"WebRTC chunk upload for '{sourceItem.Name}' failed after {WEB_RTC_MAX_RETRIES} retries with exception:\n{ex.FlattenMessage()}\nFalling back to SignalR upload..."); } continue; @@ -553,6 +735,8 @@ namespace Tango.FSE.UI.FileSystem } catch (Exception ex) { + LogManager.Log(ex, $"Upload failed for '{sourceItem.Name}'."); + _activeHandlers.Remove(handler); handler.RaiseFailed(ex); @@ -561,6 +745,7 @@ namespace Tango.FSE.UI.FileSystem try { fs.Dispose(); + LogManager.Log("Removing temporary zip file..."); File.Delete(localSourcePath); } catch { } @@ -572,6 +757,7 @@ namespace Tango.FSE.UI.FileSystem if (!aborted) { + LogManager.Log($"Upload for '{sourceItem.Name}' completed successfully."); handler.RaiseCompleted(); } @@ -579,6 +765,7 @@ namespace Tango.FSE.UI.FileSystem { try { + LogManager.Log("Removing temporary zip file..."); File.Delete(localSourcePath); } catch { } @@ -591,107 +778,207 @@ namespace Tango.FSE.UI.FileSystem return Task.FromResult(handler); } + /// <summary> + /// Copies the specified remote file or folder to the specified target remote folder. + /// </summary> + /// <param name="source">The remote source file or folder.</param> + /// <param name="target">The remote target folder.</param> + /// <returns></returns> + /// <exception cref="System.NotSupportedException"> + /// The source file system item is not supported for copying. + /// or + /// The target file system item is not a valid container. + /// </exception> 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) + try { - throw new NotSupportedException("The target file system item is not a valid container."); - } + LogManager.Log($"Copying remote item '{source.Path}' to '{target.Path}'..."); - await _machineProvider.MachineOperator.SendGenericRequest<CopyRequest, CopyResponse>(new CopyRequest() - { + 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) + Source = source.Path, + Destination = Path.Combine(target.Path, source.Name) - }, new TransportRequestConfig() + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(120), + }); + } + catch (Exception ex) { - Timeout = TimeSpan.FromSeconds(120), - }); + throw LogManager.Log(ex, "Error performing copy operation on remote file system."); + } } + /// <summary> + /// Moves the specified remote file or folder to the remote target folder. + /// </summary> + /// <param name="source">The remote source file or folder.</param> + /// <param name="target">The remote target folder.</param> + /// <returns></returns> + /// <exception cref="System.NotSupportedException"> + /// The source file system item is not supported for copying. + /// or + /// The target file system item is not a valid container. + /// </exception> public async Task Move(FileSystemItem source, FileSystemItem target) { - if (source.Type == FileSystemItemType.Drive) + try { - 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."); - } + LogManager.Log($"Moving remote item '{source.Path}' to '{target.Path}'..."); - await _machineProvider.MachineOperator.SendGenericRequest<MoveRequest, MoveResponse>(new MoveRequest() - { + if (source.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for moving."); + } + if (target.Type == FileSystemItemType.File) + { + throw new NotSupportedException("The target file system item is not a valid container."); + } - Source = source.Path, - Destination = Path.Combine(target.Path, source.Name) + await _machineProvider.MachineOperator.SendGenericRequest<MoveRequest, MoveResponse>(new MoveRequest() + { + + Source = source.Path, + Destination = Path.Combine(target.Path, source.Name) - }, new TransportRequestConfig() + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromSeconds(120), + }); + } + catch (Exception ex) { - Timeout = TimeSpan.FromSeconds(120), - }); + throw LogManager.Log(ex, "Error performing move operation on the remote file system item."); + } } + /// <summary> + /// Renames the specified file or folder. + /// </summary> + /// <param name="source">The remote source file or folder.</param> + /// <param name="newName">The new name.</param> + /// <returns></returns> + /// <exception cref="System.NotSupportedException">The source file system item is not supported for copying.</exception> + /// <exception cref="System.ArgumentException">The new name contains invalid characters.</exception> public async Task Rename(FileSystemItem source, string newName) { - if (source.Type == FileSystemItemType.Drive) + try { - throw new NotSupportedException("The source file system item is not supported for copying."); + LogManager.Log($"Renaming remote item '{source.Path}' to '{newName}'..."); + + if (source.Type == FileSystemItemType.Drive) + { + throw new NotSupportedException("The source file system item is not supported for renaming."); + } + 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) + }); } - if (newName.ToList().Exists(x => Path.GetInvalidFileNameChars().Contains(x))) + catch (Exception ex) { - throw new ArgumentException("The new name contains invalid characters."); + throw LogManager.Log(ex, "Error performing rename operation on the remote file system item."); } - - await _machineProvider.MachineOperator.SendGenericRequest<MoveRequest, MoveResponse>(new MoveRequest() - { - - Source = source.Path, - Destination = Path.Combine(Path.GetDirectoryName(source.Path), newName) - - }); } + /// <summary> + /// Deletes the specified file or folder. + /// </summary> + /// <param name="item">The remote file or folder.</param> + /// <returns></returns> + /// <exception cref="System.NotSupportedException">The source file system item is not supported for deletion.</exception> public async Task Delete(FileSystemItem item) { - if (item.Type == FileSystemItemType.Drive) + try { - throw new NotSupportedException("The source file system item is not supported for deletion."); - } + LogManager.Log($"Deleting remote item '{item.Path}'..."); + + 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() + await _machineProvider.MachineOperator.SendGenericRequest<DeleteRequest, DeleteResponse>(new DeleteRequest() + { + Path = item.Path + }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(120) }); + } + catch (Exception ex) { - Path = item.Path - }, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(120) }); + throw LogManager.Log(ex, "Error performing delete operation on the remote file system item."); + } } + /// <summary> + /// Creates a new folder at the specified remote parent. + /// </summary> + /// <param name="parent">The remote parent path.</param> + /// <param name="folderName">Name of the new folder.</param> + /// <returns></returns> public async Task<FolderItem> CreateFolder(FileSystemItem parent, string folderName) { - var response = await _machineProvider.MachineOperator.SendGenericRequest<CreateFolderRequest, CreateFolderResponse>(new CreateFolderRequest() + try { - Path = parent.Path, - FolderName = folderName, - }); + LogManager.Log($"Creating new folder '{folderName}' on the remote path '{parent.Path}'..."); + + var response = await _machineProvider.MachineOperator.SendGenericRequest<CreateFolderRequest, CreateFolderResponse>(new CreateFolderRequest() + { + Path = parent.Path, + FolderName = folderName, + }); - return FileSystemItem.FromDTO(response.FolderItem) as FolderItem; + return FileSystemItem.FromDTO(response.FolderItem) as FolderItem; + } + catch (Exception ex) + { + throw LogManager.Log(ex, "Error creating new folder on the remote file system location."); + } } + /// <summary> + /// Performs a disk space optimization. + /// </summary> + /// <returns></returns> public async Task<PerformDiskSpaceOptimizationResponse> PerformDiskSpaceOptimization() { - var response = await _machineProvider.MachineOperator.SendGenericRequest<PerformDiskSpaceOptimizationRequest, PerformDiskSpaceOptimizationResponse>(new PerformDiskSpaceOptimizationRequest() + try { + LogManager.Log("Performing disk space optimization on the remote file system."); - }, new TransportRequestConfig() - { - Timeout = TimeSpan.FromMinutes(5) - }); + var response = await _machineProvider.MachineOperator.SendGenericRequest<PerformDiskSpaceOptimizationRequest, PerformDiskSpaceOptimizationResponse>(new PerformDiskSpaceOptimizationRequest() + { + + }, new TransportRequestConfig() + { + Timeout = TimeSpan.FromMinutes(5) + }); - return response; + return response; + } + catch (Exception ex) + { + throw LogManager.Log(ex, "Error occurred while trying to perform the disk space optimization on the remote file system."); + } } + + #endregion } } |
