diff --git a/Moonlight/App/Helpers/Files/FtpFileAccess.cs b/Moonlight/App/Helpers/Files/FtpFileAccess.cs new file mode 100644 index 00000000..0b6a9de4 --- /dev/null +++ b/Moonlight/App/Helpers/Files/FtpFileAccess.cs @@ -0,0 +1,184 @@ +using System.Net; +using System.Text; +using FluentFTP; + +namespace Moonlight.App.Helpers.Files; + +public class FtpFileAccess : FileAccess +{ + private string FtpHost, FtpUser, FtpPassword; + private int FtpPort; + + private AsyncFtpClient Client; + + public FtpFileAccess(string ftpHost, int ftpPort, string ftpUser, string ftpPassword) + { + FtpHost = ftpHost; + FtpPort = ftpPort; + FtpUser = ftpUser; + FtpPassword = ftpPassword; + + Client = new AsyncFtpClient(FtpHost, FtpUser, FtpPassword, FtpPort); + } + + private async Task EnsureConnect() + { + if (!Client.IsConnected) + await Client.AutoConnect(); + } + + public override async Task Ls() + { + await EnsureConnect(); + + var x = new List(); + + foreach (FtpListItem item in (await Client.GetListing(CurrentPath)).OrderBy(x => x.Type + " " + x.Name)) + { + long size = 0; + + if (item.Type == FtpObjectType.File) + { + size = await Client.GetFileSize(item.FullName); + } + + x.Add(new() + { + Name = item.Name, + Size = size, + IsFile = item.Type == FtpObjectType.File, + }); + } + + return x.ToArray(); + } + + public override Task Cd(string dir) + { + var x = Path.Combine(CurrentPath, dir).Replace("\\", "/") + "/"; + x = x.Replace("//", "/"); + CurrentPath = x; + + return Task.CompletedTask; + } + + public override Task Up() + { + CurrentPath = Path.GetFullPath(Path.Combine(CurrentPath, "..")).Replace("\\", "/").Replace("C:", ""); + return Task.CompletedTask; + } + + public override Task SetDir(string dir) + { + CurrentPath = dir; + return Task.CompletedTask; + } + + public override async Task Read(FileData fileData) + { + await EnsureConnect(); + + var s = new MemoryStream(); + await Client.DownloadStream(s, CurrentPath.TrimEnd('/') + "/" + fileData.Name); + var data = s.ToArray(); + s.Dispose(); + var str = Encoding.UTF8.GetString(data); + return str; + } + + public override async Task Write(FileData fileData, string content) + { + await EnsureConnect(); + + var s = new MemoryStream(); + s.Write(Encoding.UTF8.GetBytes(content)); + s.Position = 0; + await Client.UploadStream(s, CurrentPath.TrimEnd('/') + "/" + fileData.Name, FtpRemoteExists.Overwrite); + s.Dispose(); + } + + public override async Task Upload(string name, Stream dataStream, Action? progressUpdated = null) + { + await EnsureConnect(); + + IProgress progress = new Progress(x => + { + progressUpdated((int) x.Progress); + }); + await Client.UploadStream(dataStream, CurrentPath.TrimEnd('/') + "/" + name, FtpRemoteExists.Overwrite, false, progress); + dataStream.Dispose(); + } + + public override async Task MkDir(string name) + { + await EnsureConnect(); + + await Client.CreateDirectory(CurrentPath.TrimEnd('/') + "/" + name + "/"); + } + + public override Task Pwd() + { + return Task.FromResult(CurrentPath); + } + + public override async Task DownloadUrl(FileData fileData) + { + await EnsureConnect(); + + throw new NotImplementedException(); + } + + public override async Task DownloadStream(FileData fileData) + { + await EnsureConnect(); + + var s = new MemoryStream(); + await Client.DownloadStream(s, CurrentPath.TrimEnd('/') + "/" + fileData.Name); + return s; + } + + public override async Task Delete(FileData fileData) + { + await EnsureConnect(); + + if (fileData.IsFile) + await Client.DeleteFile(CurrentPath.TrimEnd('/') + "/" + fileData.Name); + else + await Client.DeleteDirectory(CurrentPath.TrimEnd('/') + "/" + fileData.Name); + } + + public override async Task Move(FileData fileData, string newPath) + { + await EnsureConnect(); + + if (fileData.IsFile) + await Client.MoveFile(CurrentPath.TrimEnd('/') + "/" + fileData.Name, newPath); + else + await Client.MoveDirectory(CurrentPath.TrimEnd('/') + "/" + fileData.Name, newPath); + } + + public override async Task Compress(params FileData[] files) + { + await EnsureConnect(); + + throw new NotImplementedException(); + } + + public override async Task Decompress(FileData fileData) + { + await EnsureConnect(); + + throw new NotImplementedException(); + } + + public override Task GetLaunchUrl() + { + return Task.FromResult( + $"ftp://{FtpUser}:{FtpPassword}@{FtpHost}:{FtpPort}/"); + } + + public override object Clone() + { + return new FtpFileAccess(FtpHost, FtpPort, FtpUser, FtpPassword); + } +} \ No newline at end of file diff --git a/Moonlight/Moonlight.csproj b/Moonlight/Moonlight.csproj index 9609e642..2c6662f8 100644 --- a/Moonlight/Moonlight.csproj +++ b/Moonlight/Moonlight.csproj @@ -20,6 +20,7 @@ + diff --git a/Moonlight/Shared/Components/FileManagerPartials/FileManager.razor b/Moonlight/Shared/Components/FileManagerPartials/FileManager.razor index f1f9eea1..2fe4c06b 100644 --- a/Moonlight/Shared/Components/FileManagerPartials/FileManager.razor +++ b/Moonlight/Shared/Components/FileManagerPartials/FileManager.razor @@ -24,7 +24,7 @@ else {
-
+
@@ -59,7 +59,7 @@ else else {
-
+
@(Formatter.FormatSize(file.Size))
-
+
@if (ContextActions.Any()) { diff --git a/Moonlight/Shared/Views/Changelog.razor b/Moonlight/Shared/Views/Changelog.razor new file mode 100644 index 00000000..ad68c1e2 --- /dev/null +++ b/Moonlight/Shared/Views/Changelog.razor @@ -0,0 +1,53 @@ +@page "/changelog" + +@{ + List changelog = new List() + { + new[] {"title", "body1", "body2"}, + new[] {"title2", "body3", "body4", "body5"}, + }; + int i = 0; +} + +
+
+
+ @foreach (var prt in changelog) + { + i++; +
+
+ + + + + + + + +

@prt[0]

+
+ +
+
+
+ @{ + var o = prt[1..]; + } +

Changes

+
    + @foreach (var v in o) + { +
  • + @v +
  • + } +
+
+
+
+
+ } +
+
+
\ No newline at end of file diff --git a/Moonlight/Shared/Views/Profile/Index.razor b/Moonlight/Shared/Views/Profile/Index.razor index b9394503..cb1451ce 100644 --- a/Moonlight/Shared/Views/Profile/Index.razor +++ b/Moonlight/Shared/Views/Profile/Index.razor @@ -13,14 +13,7 @@
-
-
-

- Personal information -

-
-
-
+
diff --git a/Moonlight/Shared/Views/Profile/Security.razor b/Moonlight/Shared/Views/Profile/Security.razor index db0bf9f8..7cd7bff4 100644 --- a/Moonlight/Shared/Views/Profile/Security.razor +++ b/Moonlight/Shared/Views/Profile/Security.razor @@ -22,204 +22,225 @@
-
-
-

- Security -

-
-
- -
-
- @if (TotpEnabled) - { -
- - - - - - -
-
-

- Your account is secured with 2fa -

-
- anyone write a fancy text here? -
-
- -