Implemented archiving and extracting for users

This commit is contained in:
Marcel Baumgartner 2024-05-14 14:08:07 +02:00
parent 923a3c18b8
commit fda972a90e
7 changed files with 145 additions and 9 deletions

View file

@ -7,7 +7,7 @@
@inherits ErrorBoundaryBase
@if (Crashed || CurrentException != null)
@if (Crashed || Exception != null)
{
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" || (IdentityService.IsLoggedIn && IdentityService.CurrentUser.Permissions >= 9000))
{

View file

@ -54,6 +54,8 @@ public class FileManagerFeature : MoonlightFeature
await pluginService.RegisterImplementation<IFileManagerContextAction>(new RenameContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new MoveContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new DownloadContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new ArchiveContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new ExtractContextAction());
await pluginService.RegisterImplementation<IFileManagerContextAction>(new DeleteContextAction());
await pluginService.RegisterImplementation<IFileManagerSelectionAction>(new MoveSelectionAction());

View file

@ -0,0 +1,59 @@
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 ArchiveContextAction : IFileManagerContextAction
{
public string Name => "Archive";
public string Icon => "bxs-archive-in";
public string Color => "warning";
public Func<FileEntry, bool> Filter => _ => true;
public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry entry,
IServiceProvider provider)
{
var archiveAccess = access.Actions 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;
var toastService = provider.GetRequiredService<ToastService>();
await toastService.CreateProgress("fileManagerArchive", "Archiving... Please be patient");
try
{
await archiveAccess.Archive(
access.CurrentDirectory + fileName,
new[] { access.CurrentDirectory + entry.Name }
);
await toastService.Success("Successfully created archive");
}
catch (Exception e)
{
Logger.Warn($"An error occured while archiving item ({entry.Name}):");
Logger.Warn(e);
await toastService.Danger("An unknown error occured while creating archive");
}
finally
{
await toastService.RemoveProgress("fileManagerArchive");
}
await fileManager.View.Refresh();
}
}

View file

@ -14,10 +14,7 @@ public class ArchiveSelectionAction : IFileManagerSelectionAction
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;
var archiveAccess = access.Actions as IArchiveFileActions;
if (archiveAccess == null)
throw new DisplayException("This file access does not support archiving");
@ -30,9 +27,29 @@ public class ArchiveSelectionAction : IFileManagerSelectionAction
if (string.IsNullOrEmpty(fileName) || fileName.Contains("..")) // => canceled
return;
await archiveAccess.Archive(
access.CurrentDirectory + fileName,
entries.Select(x => access.CurrentDirectory + x.Name).ToArray()
);
var toastService = provider.GetRequiredService<ToastService>();
await toastService.CreateProgress("fileManagerArchive", "Archiving... Please be patient");
try
{
await archiveAccess.Archive(
access.CurrentDirectory + fileName,
entries.Select(x => access.CurrentDirectory + x.Name).ToArray()
);
await toastService.Success("Successfully created archive");
}
catch (Exception e)
{
Logger.Warn($"An error occured while archiving items ({entries.Length}):");
Logger.Warn(e);
await toastService.Danger("An unknown error occured while creating archive");
}
finally
{
await toastService.RemoveProgress("fileManagerArchive");
}
}
}

View file

@ -0,0 +1,52 @@
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 ExtractContextAction : IFileManagerContextAction
{
public string Name => "Extract";
public string Icon => "bxs-archive-out";
public string Color => "warning";
public Func<FileEntry, bool> Filter => entry => entry.IsFile && entry.Name.EndsWith(".tar.gz");
public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry entry, IServiceProvider provider)
{
var archiveAccess = access.Actions as IArchiveFileActions;
if (archiveAccess == null)
throw new DisplayException("This file access does not support archiving");
await fileManager.OpenFolderSelect("Select where you want to extract the content of the archive", async destination =>
{
var toastService = provider.GetRequiredService<ToastService>();
await toastService.CreateProgress("fileManagerExtract", "Extracting... Please be patient");
try
{
await archiveAccess.Extract(
access.CurrentDirectory + entry.Name,
destination
);
await toastService.Success("Successfully extracted archive");
}
catch (Exception e)
{
Logger.Warn($"An error occured while extracting archive ({entry.Name}):");
Logger.Warn(e);
await toastService.Danger("An unknown error occured while extracting archive");
}
finally
{
await toastService.RemoveProgress("fileManagerExtract");
}
await fileManager.View.Refresh();
});
}
}

View file

@ -3,4 +3,5 @@ namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
public interface IArchiveFileActions
{
public Task Archive(string path, string[] files);
public Task Extract(string path, string destination);
}

View file

@ -48,6 +48,11 @@ public class ServerApiFileActions : IFileActions, IArchiveFileActions
await ApiClient.Post($"archive?path={path}&provider=tar.gz", files);
}
public async Task Extract(string path, string destination)
{
await ApiClient.Post($"extract?path={path}&destination={destination}&provider=tar.gz");
}
public IFileActions Clone() => new ServerApiFileActions(Endpoint, Token, ServerId);
public void Dispose() => ApiClient.Dispose();