File-Explorer: Editor editierbar + Speichern-Button

This commit is contained in:
Meleki committed 2026-02-28 16:49:15 +01:00
1 parent f74409dd89
commit b84dff6d8c
3 files changed
+157 -8

No files matched your search

+53
View File
@@ -38,6 +38,7 @@ public static class WorkspaceEndpoint
{
app.MapGet("/api/workspace/tree", HandleTree);
app.MapGet("/api/workspace/file", HandleFile);
app.MapPut("/api/workspace/file", HandleFileSave);
app.MapGet("/api/workspace/browse", HandleBrowse);
}
@@ -158,6 +159,58 @@ public static class WorkspaceEndpoint
});
}
private static async Task HandleFileSave(HttpContext ctx)
{
var sessionId = ctx.Request.Query["sessionId"].FirstOrDefault();
var filePath = ctx.Request.Query["path"].FirstOrDefault();
if (string.IsNullOrEmpty(filePath))
{
ctx.Response.StatusCode = 400;
return;
}
var db = ctx.RequestServices.GetRequiredService<Gott.Services.DatabaseService>();
var session = await db.GetSession(sessionId ?? "");
if (session == null || string.IsNullOrEmpty(session.Workspace))
{
ctx.Response.StatusCode = 400;
await ctx.Response.WriteAsJsonAsync(new { error = "Kein Workspace konfiguriert" });
return;
}
var basePath = Path.GetFullPath(session.Workspace);
var targetPath = Path.GetFullPath(Path.Combine(basePath, filePath));
if (!targetPath.StartsWith(basePath))
{
ctx.Response.StatusCode = 403;
return;
}
if (!File.Exists(targetPath))
{
ctx.Response.StatusCode = 404;
return;
}
using var reader = new StreamReader(ctx.Request.Body);
var content = await reader.ReadToEndAsync();
await File.WriteAllTextAsync(targetPath, content);
var info = new FileInfo(targetPath);
var lineCount = content.Split('\n').Length;
await ctx.Response.WriteAsJsonAsync(new
{
path = filePath,
name = info.Name,
size = info.Length,
lineCount
});
}
private static async Task HandleBrowse(HttpContext ctx)
{
var path = ctx.Request.Query["path"].FirstOrDefault() ?? "/";