Browse Source

Merge pull request #404 from Moonlight-Panel/v2_FileManagerImprovements

Improved file manager. This is the first merge of this branch. More commits are planned
Masu Baumgartner 1 year ago
parent
commit
c9fe469f5b

File diff suppressed because it is too large
+ 0 - 0
Moonlight/Assets/FileManager/js/dropzone.js


+ 9 - 0
Moonlight/Core/Configuration/CoreConfiguration.cs

@@ -39,6 +39,15 @@ public class CoreConfiguration
         [Description("Specifies the location of the key .pem file to load")]
         [Description("Specifies the location of the key .pem file to load")]
         [JsonProperty("KeyPath")]
         [JsonProperty("KeyPath")]
         public string KeyPath { get; set; } = "";
         public string KeyPath { get; set; } = "";
+
+        [Description("Specifies the file upload limit per http request in megabytes")]
+        [JsonProperty("UploadLimit")]
+        public int UploadLimit { get; set; } = 100;
+
+        [Description(
+            "Specifies the maximum message size moonlight can receive via the websocket connection in kilobytes")]
+        [JsonProperty("MessageSizeLimit")]
+        public int MessageSizeLimit { get; set; } = 1024;
     }
     }
     
     
     public class DatabaseData
     public class DatabaseData

+ 12 - 1
Moonlight/Core/CoreFeature.cs

@@ -64,15 +64,26 @@ public class CoreFeature : MoonlightFeature
         
         
         // Add external services and blazor/asp.net stuff
         // Add external services and blazor/asp.net stuff
         builder.Services.AddRazorPages();
         builder.Services.AddRazorPages();
-        builder.Services.AddServerSideBlazor();
         builder.Services.AddHttpContextAccessor();
         builder.Services.AddHttpContextAccessor();
         builder.Services.AddControllers();
         builder.Services.AddControllers();
         builder.Services.AddBlazorTable();
         builder.Services.AddBlazorTable();
+        
+        // Configure blazor pipeline in detail
+        builder.Services.AddServerSideBlazor().AddHubOptions(options =>
+        {
+            options.MaximumReceiveMessageSize = ByteSizeValue.FromKiloBytes(config.Http.MessageSizeLimit).Bytes;
+        });
 
 
         // Setup authentication if required
         // Setup authentication if required
         if (config.Authentication.UseDefaultAuthentication)
         if (config.Authentication.UseDefaultAuthentication)
             builder.Services.AddScoped<IAuthenticationProvider, DefaultAuthenticationProvider>();
             builder.Services.AddScoped<IAuthenticationProvider, DefaultAuthenticationProvider>();
         
         
+        // Setup http upload limit
+        context.Builder.WebHost.ConfigureKestrel(options =>
+        {
+            options.Limits.MaxRequestBodySize = ByteSizeValue.FromMegaBytes(config.Http.UploadLimit).Bytes;
+        });
+        
         // Assets
         // Assets
         
         
         // - Javascript
         // - Javascript

+ 0 - 1
Moonlight/Features/FileManager/FileManagerFeature.cs

@@ -26,7 +26,6 @@ public class FileManagerFeature : MoonlightFeature
         var config = new ConfigService<CoreConfiguration>(PathBuilder.File("storage", "configs", "core.json"));
         var config = new ConfigService<CoreConfiguration>(PathBuilder.File("storage", "configs", "core.json"));
         context.Builder.Services.AddSingleton(new JwtService<FileManagerJwtType>(config.Get().Security.Token));
         context.Builder.Services.AddSingleton(new JwtService<FileManagerJwtType>(config.Get().Security.Token));
         
         
-        context.AddAsset("FileManager", "js/dropzone.js");
         context.AddAsset("FileManager", "js/filemanager.js");
         context.AddAsset("FileManager", "js/filemanager.js");
         context.AddAsset("FileManager", "editor/ace.css");
         context.AddAsset("FileManager", "editor/ace.css");
         context.AddAsset("FileManager", "editor/ace.js");
         context.AddAsset("FileManager", "editor/ace.js");

+ 38 - 0
Moonlight/Features/FileManager/Implementations/ArchiveSelectionAction.cs

@@ -0,0 +1,38 @@
+using MoonCore.Exceptions;
+using MoonCore.Helpers;
+using MoonCoreUI.Services;
+using Moonlight.Features.FileManager.Interfaces;
+using Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
+
+namespace Moonlight.Features.FileManager.Implementations;
+
+public class ArchiveSelectionAction : IFileManagerSelectionAction
+{
+    public string Name => "Archive";
+    public string Color => "primary";
+
+    public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry[] entries,
+        IServiceProvider provider)
+    {
+        if (!access.Actions.GetType().IsAssignableFrom(typeof(IArchiveFileActions)))
+            throw new DisplayException("This file access does not support archiving");
+
+        var archiveAccess = access as IArchiveFileActions;
+
+        if (archiveAccess == null)
+            throw new DisplayException("This file access does not support archiving");
+
+        var alertService = provider.GetRequiredService<AlertService>();
+
+        var fileName = await alertService.Text("Enter the archive file name", "",
+            Formatter.FormatDate(DateTime.UtcNow) + ".tar.gz");
+
+        if (string.IsNullOrEmpty(fileName) || fileName.Contains("..")) // => canceled
+            return;
+
+        await archiveAccess.Archive(
+            access.CurrentDirectory + fileName,
+            entries.Select(x => access.CurrentDirectory + x.Name).ToArray()
+        );
+    }
+}

+ 2 - 2
Moonlight/Features/FileManager/Models/Abstractions/FileAccess/BaseFileAccess.cs

@@ -4,9 +4,9 @@ namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
 
 
 public class BaseFileAccess : IDisposable
 public class BaseFileAccess : IDisposable
 {
 {
-    private readonly IFileActions Actions;
+    public readonly IFileActions Actions;
 
 
-    private string CurrentDirectory = "/";
+    public string CurrentDirectory { get; private set; } = "/";
 
 
     public BaseFileAccess(IFileActions actions)
     public BaseFileAccess(IFileActions actions)
     {
     {

+ 6 - 0
Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IArchiveFileActions.cs

@@ -0,0 +1,6 @@
+namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
+
+public interface IArchiveFileActions
+{
+    public Task Archive(string path, string[] files);
+}

+ 0 - 7
Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileCompressAccess.cs

@@ -1,7 +0,0 @@
-namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
-
-public interface IFileCompressAccess
-{
-    public Task Compress(string[] names);
-    public Task Decompress(string name);
-}

+ 0 - 6
Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileLaunchAccess.cs

@@ -1,6 +0,0 @@
-namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
-
-public interface IFileLaunchAccess
-{
-    public Task<string> GetLaunchUrl();
-}

+ 5 - 1
Moonlight/Features/FileManager/Services/FileManagerInteropService.cs

@@ -30,7 +30,11 @@ public class FileManagerInteropService
 
 
     public async Task UpdateUrl(string urlId, string url)
     public async Task UpdateUrl(string urlId, string url)
     {
     {
-        await JsRuntime.InvokeVoidAsync("filemanager.updateUrl", urlId, url);
+        try
+        {
+            await JsRuntime.InvokeVoidAsync("filemanager.updateUrl", urlId, url);
+        }
+        catch (TaskCanceledException) { /* ignored */ }
     }
     }
 
 
     [JSInvokable]
     [JSInvokable]

+ 9 - 0
Moonlight/Features/FileManager/UI/Components/FileView.razor

@@ -209,6 +209,15 @@
         }
         }
         </tbody>
         </tbody>
     </table>
     </table>
+    
+    @if (Entries.Length == 0)
+    {
+        <div class="py-4">
+            <IconAlert Color="primary" Title="No files and folders found" Icon="bx-cloud-upload">
+                Drag and drop files and folders here to start uploading them or click on the upload button on the top
+            </IconAlert>
+        </div>
+    }
 </div>
 </div>
 
 
 @if (EnableContextMenu && ContextMenuTemplate != null)
 @if (EnableContextMenu && ContextMenuTemplate != null)

+ 6 - 1
Moonlight/Features/Servers/Helpers/ServerApiFileActions.cs

@@ -4,7 +4,7 @@ using Moonlight.Features.Servers.Exceptions;
 
 
 namespace Moonlight.Features.Servers.Helpers;
 namespace Moonlight.Features.Servers.Helpers;
 
 
-public class ServerApiFileActions : IFileActions
+public class ServerApiFileActions : IFileActions, IArchiveFileActions
 {
 {
     private readonly string Endpoint;
     private readonly string Endpoint;
     private readonly string Token;
     private readonly string Token;
@@ -43,6 +43,11 @@ public class ServerApiFileActions : IFileActions
     public async Task WriteFileStream(string path, Stream dataStream) =>
     public async Task WriteFileStream(string path, Stream dataStream) =>
         await ApiClient.PostFile($"writeFileStream?path={path}", dataStream, "upload");
         await ApiClient.PostFile($"writeFileStream?path={path}", dataStream, "upload");
 
 
+    public async Task Archive(string path, string[] files)
+    {
+        await ApiClient.Post($"archive?path={path}&provider=tar.gz", files);
+    }
+    
     public IFileActions Clone() => new ServerApiFileActions(Endpoint, Token, ServerId);
     public IFileActions Clone() => new ServerApiFileActions(Endpoint, Token, ServerId);
 
 
     public void Dispose() => ApiClient.Dispose();
     public void Dispose() => ApiClient.Dispose();

Some files were not shown because too many files changed in this diff