]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Allow admins to export round logs to CSV files (#38206)
authorbeck-thompson <107373427+beck-thompson@users.noreply.github.com>
Sun, 22 Jun 2025 19:28:21 +0000 (12:28 -0700)
committerGitHub <noreply@github.com>
Sun, 22 Jun 2025 19:28:21 +0000 (21:28 +0200)
Content.Client/Administration/UI/Logs/AdminLogsControl.xaml
Content.Client/Administration/UI/Logs/AdminLogsEui.cs
Resources/Locale/en-US/administration/ui/admin-logs.ftl

index fc4d3ee3aca75fcc92f22fbbeb188564c3551024..cd93ffeb0a80e59307ebc71509cdc255f8a941b4 100644 (file)
@@ -49,6 +49,7 @@
                     <Control HorizontalExpand="True"/>
                     <Label Name="Count" Access="Public"/>
                     <Control HorizontalExpand="True"/>
+                    <Button Name="ExportLogs" Access="Public" Text="{Loc admin-logs-export}"/>
                     <Button Name="PopOutButton" Access="Public" Text="{Loc admin-logs-pop-out}"/>
                 </BoxContainer>
                 <BoxContainer Orientation="Horizontal">
index be1bddcd3707bb2e3584b0a47144510834165f2b..2c64b82d20b13a03b1d737fafd9973a948a1102d 100644 (file)
@@ -1,4 +1,6 @@
-using System.Linq;
+using System.IO;
+using System.Linq;
+using Content.Client.Administration.UI.CustomControls;
 using Content.Client.Eui;
 using Content.Shared.Administration.Logs;
 using Content.Shared.Eui;
@@ -15,6 +17,12 @@ public sealed class AdminLogsEui : BaseEui
 {
     [Dependency] private readonly IClyde _clyde = default!;
     [Dependency] private readonly IUserInterfaceManager _uiManager = default!;
+    [Dependency] private readonly IFileDialogManager _dialogManager = default!;
+    [Dependency] private readonly ILogManager _log = default!;
+
+    private ISawmill _sawmill;
+
+    private bool _currentlyExportingLogs = false;
 
     public AdminLogsEui()
     {
@@ -26,6 +34,9 @@ public sealed class AdminLogsEui : BaseEui
         LogsControl.RefreshButton.OnPressed += _ => RequestLogs();
         LogsControl.NextButton.OnPressed += _ => NextLogs();
         LogsControl.PopOutButton.OnPressed += _ => PopOut();
+        LogsControl.ExportLogs.OnPressed += _ => ExportLogs();
+
+        _sawmill = _log.GetSawmill("admin.logs.ui");
     }
 
     private WindowRoot? Root { get; set; }
@@ -74,6 +85,66 @@ public sealed class AdminLogsEui : BaseEui
         SendMessage(request);
     }
 
+    private async void ExportLogs()
+    {
+        if (_currentlyExportingLogs)
+            return;
+
+        _currentlyExportingLogs = true;
+        LogsControl.ExportLogs.Disabled = true;
+
+        var file = await _dialogManager.SaveFile(new FileDialogFilters(new FileDialogFilters.Group("csv")));
+
+        if (file == null)
+            return;
+
+        try
+        {
+            await using var writer = new StreamWriter(file.Value.fileStream);
+            foreach (var child in LogsControl.LogsContainer.Children)
+            {
+                if (child is not AdminLogLabel logLabel || !child.Visible)
+                    continue;
+
+                var log = logLabel.Log;
+
+                // I swear to god if someone adds ,s or "s to the other fields...
+                await writer.WriteAsync(log.Date.ToString("s", System.Globalization.CultureInfo.InvariantCulture));
+                await writer.WriteAsync(',');
+                await writer.WriteAsync(log.Id.ToString());
+                await writer.WriteAsync(',');
+                await writer.WriteAsync(log.Impact.ToString());
+                await writer.WriteAsync(',');
+                // Message
+                await writer.WriteAsync('"');
+                await writer.WriteAsync(log.Message.Replace("\"", "\"\""));
+                await writer.WriteAsync('"');
+                // End of message
+                await writer.WriteAsync(',');
+
+                var players = log.Players;
+                for (var i = 0; i < players.Length; i++)
+                {
+                    await writer.WriteAsync(players[i] + (i == players.Length - 1 ? "" : " "));
+                }
+
+                await writer.WriteAsync(',');
+                await writer.WriteAsync(log.Type.ToString());
+                await writer.WriteLineAsync();
+            }
+        }
+        catch (Exception exc)
+        {
+            _sawmill.Error($"Error when exporting admin log:\n{exc.StackTrace}");
+        }
+        finally
+        {
+            await file.Value.fileStream.DisposeAsync();
+            _currentlyExportingLogs = false;
+            LogsControl.ExportLogs.Disabled = false;
+        }
+    }
+
     private void PopOut()
     {
         if (LogsWindow == null)
index 377bea6e84ab34c7c582a46b8852f38af8d71e1e..25e09433109ce07e6f9357dd0b305ae191db201a 100644 (file)
@@ -1,5 +1,6 @@
 admin-logs-title = Admin Logs Panel
 admin-logs-count = Showing {$showing}/{$total} of {$round}
+admin-logs-export = Export
 admin-logs-pop-out = Pop Out
 
 # Round