mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-11 19:52:10 +00:00
added possibility to open log file in file manager
This commit is contained in:
parent
11dd357a05
commit
d72b7c558e
@ -1648,6 +1648,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T174782740
|
|||||||
-- The log file does not exist: {0}
|
-- The log file does not exist: {0}
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1807514273"] = "The log file does not exist: {0}"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1807514273"] = "The log file does not exist: {0}"
|
||||||
|
|
||||||
|
-- Could not open the log file location.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1828231197"] = "Could not open the log file location."
|
||||||
|
|
||||||
-- Other
|
-- Other
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1849229205"] = "Other"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1849229205"] = "Other"
|
||||||
|
|
||||||
@ -1666,6 +1669,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T237835357
|
|||||||
-- No matching log lines.
|
-- No matching log lines.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2511997530"] = "No matching log lines."
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2511997530"] = "No matching log lines."
|
||||||
|
|
||||||
|
-- Could not open the log file location: {0}
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2533784927"] = "Could not open the log file location: {0}"
|
||||||
|
|
||||||
-- Source details
|
-- Source details
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2686813966"] = "Source details"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2686813966"] = "Source details"
|
||||||
|
|
||||||
@ -1678,6 +1684,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T315262563
|
|||||||
-- Loading log file...
|
-- Loading log file...
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T333036481"] = "Loading log file..."
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T333036481"] = "Loading log file..."
|
||||||
|
|
||||||
|
-- Unknown error
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T3461425987"] = "Unknown error"
|
||||||
|
|
||||||
-- The log file path is not available yet.
|
-- The log file path is not available yet.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T3686775689"] = "The log file path is not available yet."
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T3686775689"] = "The log file path is not available yet."
|
||||||
|
|
||||||
@ -1696,12 +1705,18 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T397479987
|
|||||||
-- Usage log
|
-- Usage log
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4031747274"] = "Usage log"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4031747274"] = "Usage log"
|
||||||
|
|
||||||
|
-- Open in folder
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4048746540"] = "Open in folder"
|
||||||
|
|
||||||
-- Log file
|
-- Log file
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4129341821"] = "Log file"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4129341821"] = "Log file"
|
||||||
|
|
||||||
-- Log Viewer
|
-- Log Viewer
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4130241777"] = "Log Viewer"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4130241777"] = "Log Viewer"
|
||||||
|
|
||||||
|
-- Opened the log file location.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4162897654"] = "Opened the log file location."
|
||||||
|
|
||||||
-- Show timestamps
|
-- Show timestamps
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T469116133"] = "Show timestamps"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T469116133"] = "Show timestamps"
|
||||||
|
|
||||||
@ -8584,24 +8599,42 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T1110203516"] = "Failed
|
|||||||
-- Failed to store the API key due to an API issue.
|
-- Failed to store the API key due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T1704298921"] = "Failed to store the API key due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T1704298921"] = "Failed to store the API key due to an API issue."
|
||||||
|
|
||||||
|
-- The runtime file manager endpoint returned '{0}'.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2158262203"] = "The runtime file manager endpoint returned '{0}'."
|
||||||
|
|
||||||
-- Failed to delete the secret data due to an API issue.
|
-- Failed to delete the secret data due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2303057928"] = "Failed to delete the secret data due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2303057928"] = "Failed to delete the secret data due to an API issue."
|
||||||
|
|
||||||
|
-- The runtime file manager endpoint is not available.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2486847754"] = "The runtime file manager endpoint is not available."
|
||||||
|
|
||||||
|
-- The runtime file manager endpoint failed without details.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3082220817"] = "The runtime file manager endpoint failed without details."
|
||||||
|
|
||||||
-- Successfully copied the text to your clipboard
|
-- Successfully copied the text to your clipboard
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3351807428"] = "Successfully copied the text to your clipboard"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3351807428"] = "Successfully copied the text to your clipboard"
|
||||||
|
|
||||||
|
-- The path does not exist and its parent folder could not be found.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3606079336"] = "The path does not exist and its parent folder could not be found."
|
||||||
|
|
||||||
-- Failed to delete the API key due to an API issue.
|
-- Failed to delete the API key due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3658273365"] = "Failed to delete the API key due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3658273365"] = "Failed to delete the API key due to an API issue."
|
||||||
|
|
||||||
-- Failed to copy the text to your clipboard.
|
-- Failed to copy the text to your clipboard.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3724548108"] = "Failed to copy the text to your clipboard."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3724548108"] = "Failed to copy the text to your clipboard."
|
||||||
|
|
||||||
|
-- The local file manager command failed: {0}
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T381756374"] = "The local file manager command failed: {0}"
|
||||||
|
|
||||||
-- Failed to get the API key due to an API issue.
|
-- Failed to get the API key due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3875720022"] = "Failed to get the API key due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3875720022"] = "Failed to get the API key due to an API issue."
|
||||||
|
|
||||||
-- Failed to get the secret data due to an API issue.
|
-- Failed to get the secret data due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T4007657575"] = "Failed to get the secret data due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T4007657575"] = "Failed to get the secret data due to an API issue."
|
||||||
|
|
||||||
|
-- The local file manager command did not start.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T613631541"] = "The local file manager command did not start."
|
||||||
|
|
||||||
-- No update found.
|
-- No update found.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found."
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,9 @@
|
|||||||
</MudButton>
|
</MudButton>
|
||||||
}
|
}
|
||||||
<MudNumericField T="int" Value="@this.maxLines" ValueChanged="@this.MaxLinesChanged" Label="@T("Max lines")" Variant="Variant.Outlined" Margin="Margin.Dense" Min="@MIN_MAX_LINES" Max="@MAX_MAX_LINES" Step="500" Class="log-viewer-number" />
|
<MudNumericField T="int" Value="@this.maxLines" ValueChanged="@this.MaxLinesChanged" Label="@T("Max lines")" Variant="Variant.Outlined" Margin="Margin.Dense" Min="@MIN_MAX_LINES" Max="@MAX_MAX_LINES" Step="500" Class="log-viewer-number" />
|
||||||
|
<MudButton Variant="Variant.Outlined" Color="Color.Default" StartIcon="@Icons.Material.Filled.FolderOpen" OnClick="@this.OpenCurrentLogInFileManager" Disabled="@(!this.CanOpenCurrentLogPath)">
|
||||||
|
@T("Open in folder")
|
||||||
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<MudStack Row="@true" Wrap="@Wrap.Wrap" AlignItems="@AlignItems.Center" Spacing="2" Class="mb-1">
|
<MudStack Row="@true" Wrap="@Wrap.Wrap" AlignItems="@AlignItems.Center" Spacing="2" Class="mb-1">
|
||||||
|
|||||||
@ -34,6 +34,9 @@ public partial class AssistantLogViewer : MSGComponentBase
|
|||||||
[Inject]
|
[Inject]
|
||||||
private RustService RustService { get; init; } = null!;
|
private RustService RustService { get; init; } = null!;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private ISnackbar Snackbar { get; init; } = null!;
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private NavigationManager NavigationManager { get; init; } = null!;
|
private NavigationManager NavigationManager { get; init; } = null!;
|
||||||
|
|
||||||
@ -65,6 +68,8 @@ public partial class AssistantLogViewer : MSGComponentBase
|
|||||||
|
|
||||||
private string CurrentLogPath => this.selectedLogFile is LogFileKind.APP ? this.logPaths.LogAppPath : this.logPaths.LogStartupPath;
|
private string CurrentLogPath => this.selectedLogFile is LogFileKind.APP ? this.logPaths.LogAppPath : this.logPaths.LogStartupPath;
|
||||||
|
|
||||||
|
private bool CanOpenCurrentLogPath => !string.IsNullOrWhiteSpace(this.CurrentLogPath);
|
||||||
|
|
||||||
private bool HasDropdownFilter => this.selectedLogLevels.Count > 0 || this.selectedLoggers.Count > 0 || this.selectedSourceDetails.Count > 0;
|
private bool HasDropdownFilter => this.selectedLogLevels.Count > 0 || this.selectedLoggers.Count > 0 || this.selectedSourceDetails.Count > 0;
|
||||||
|
|
||||||
private bool HasActiveFilter => !string.IsNullOrWhiteSpace(this.filterText) || this.HasDropdownFilter;
|
private bool HasActiveFilter => !string.IsNullOrWhiteSpace(this.filterText) || this.HasDropdownFilter;
|
||||||
@ -203,6 +208,68 @@ public partial class AssistantLogViewer : MSGComponentBase
|
|||||||
await this.RefreshLogAsync();
|
await this.RefreshLogAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task OpenCurrentLogInFileManager()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.logPaths = await this.RustService.GetLogPaths();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
this.Logger.LogWarning(e, "Could not refresh the log file paths before opening the file manager.");
|
||||||
|
this.Snackbar.Add(T("The log file path is not available yet."), Severity.Warning, config =>
|
||||||
|
{
|
||||||
|
config.Icon = Icons.Material.Filled.Folder;
|
||||||
|
config.IconSize = Size.Large;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = this.CurrentLogPath;
|
||||||
|
if (string.IsNullOrWhiteSpace(path))
|
||||||
|
{
|
||||||
|
this.Snackbar.Add(T("The log file path is not available yet."), Severity.Warning, config =>
|
||||||
|
{
|
||||||
|
config.Icon = Icons.Material.Filled.Folder;
|
||||||
|
config.IconSize = Size.Large;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenPathResponse response;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response = await this.RustService.OpenPathInFileManager(path);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
this.Logger.LogWarning(e, "Could not open the log file location in the file manager.");
|
||||||
|
this.Snackbar.Add(T("Could not open the log file location."), Severity.Error, config =>
|
||||||
|
{
|
||||||
|
config.Icon = Icons.Material.Filled.Folder;
|
||||||
|
config.IconSize = Size.Large;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.Success)
|
||||||
|
{
|
||||||
|
this.Snackbar.Add(T("Opened the log file location."), Severity.Success, config =>
|
||||||
|
{
|
||||||
|
config.Icon = Icons.Material.Filled.FolderOpen;
|
||||||
|
config.IconSize = Size.Large;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var issue = string.IsNullOrWhiteSpace(response.Issue) ? T("Unknown error") : response.Issue;
|
||||||
|
this.Snackbar.Add(string.Format(T("Could not open the log file location: {0}"), issue), Severity.Error, config =>
|
||||||
|
{
|
||||||
|
config.Icon = Icons.Material.Filled.Folder;
|
||||||
|
config.IconSize = Size.Large;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void ClearFilters()
|
private void ClearFilters()
|
||||||
{
|
{
|
||||||
this.filterText = string.Empty;
|
this.filterText = string.Empty;
|
||||||
|
|||||||
@ -1650,6 +1650,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T174782740
|
|||||||
-- The log file does not exist: {0}
|
-- The log file does not exist: {0}
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1807514273"] = "Die Protokolldatei existiert nicht: {0}"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1807514273"] = "Die Protokolldatei existiert nicht: {0}"
|
||||||
|
|
||||||
|
-- Could not open the log file location.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1828231197"] = "Konnte den Speicherort der Protokolldatei nicht öffnen."
|
||||||
|
|
||||||
-- Other
|
-- Other
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1849229205"] = "Andere"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1849229205"] = "Andere"
|
||||||
|
|
||||||
@ -1668,6 +1671,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T237835357
|
|||||||
-- No matching log lines.
|
-- No matching log lines.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2511997530"] = "Keine passenden Protokollzeilen."
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2511997530"] = "Keine passenden Protokollzeilen."
|
||||||
|
|
||||||
|
-- Could not open the log file location: {0}
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2533784927"] = "Konnte den Speicherort der Protokolldatei nicht öffnen: {0}"
|
||||||
|
|
||||||
-- Source details
|
-- Source details
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2686813966"] = "Quellendetails"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2686813966"] = "Quellendetails"
|
||||||
|
|
||||||
@ -1680,6 +1686,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T315262563
|
|||||||
-- Loading log file...
|
-- Loading log file...
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T333036481"] = "Lade Protokolldatei..."
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T333036481"] = "Lade Protokolldatei..."
|
||||||
|
|
||||||
|
-- Unknown error
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T3461425987"] = "Unbekannter Fehler"
|
||||||
|
|
||||||
-- The log file path is not available yet.
|
-- The log file path is not available yet.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T3686775689"] = "Der Pfad zur Protokolldatei ist noch nicht verfügbar."
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T3686775689"] = "Der Pfad zur Protokolldatei ist noch nicht verfügbar."
|
||||||
|
|
||||||
@ -1698,12 +1707,18 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T397479987
|
|||||||
-- Usage log
|
-- Usage log
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4031747274"] = "Nutzungsprotokoll"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4031747274"] = "Nutzungsprotokoll"
|
||||||
|
|
||||||
|
-- Open in folder
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4048746540"] = "Im Ordner öffnen"
|
||||||
|
|
||||||
-- Log file
|
-- Log file
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4129341821"] = "Protokolldatei"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4129341821"] = "Protokolldatei"
|
||||||
|
|
||||||
-- Log Viewer
|
-- Log Viewer
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4130241777"] = "Protokollanzeige"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4130241777"] = "Protokollanzeige"
|
||||||
|
|
||||||
|
-- Opened the log file location.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4162897654"] = "Der Speicherort der Protokolldatei wurde geöffnet."
|
||||||
|
|
||||||
-- Show timestamps
|
-- Show timestamps
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T469116133"] = "Zeitstempel anzeigen"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T469116133"] = "Zeitstempel anzeigen"
|
||||||
|
|
||||||
@ -8586,24 +8601,42 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T1110203516"] = "Fehler
|
|||||||
-- Failed to store the API key due to an API issue.
|
-- Failed to store the API key due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T1704298921"] = "Fehler beim Speichern des API-Schlüssels aufgrund eines API-Problems."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T1704298921"] = "Fehler beim Speichern des API-Schlüssels aufgrund eines API-Problems."
|
||||||
|
|
||||||
|
-- The runtime file manager endpoint returned '{0}'.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2158262203"] = "Der Laufzeit-Dateimanager-Endpunkt hat '{0}' zurückgegeben."
|
||||||
|
|
||||||
-- Failed to delete the secret data due to an API issue.
|
-- Failed to delete the secret data due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2303057928"] = "Das Löschen der geheimen Daten ist aufgrund eines API-Problems fehlgeschlagen."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2303057928"] = "Das Löschen der geheimen Daten ist aufgrund eines API-Problems fehlgeschlagen."
|
||||||
|
|
||||||
|
-- The runtime file manager endpoint is not available.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2486847754"] = "Der Laufzeit-Dateimanager-Endpunkt ist nicht verfügbar."
|
||||||
|
|
||||||
|
-- The runtime file manager endpoint failed without details.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3082220817"] = "Der Laufzeit-Dateimanager-Endpunkt ist ohne Details fehlgeschlagen."
|
||||||
|
|
||||||
-- Successfully copied the text to your clipboard
|
-- Successfully copied the text to your clipboard
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3351807428"] = "Der Text wurde erfolgreich in die Zwischenablage kopiert."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3351807428"] = "Der Text wurde erfolgreich in die Zwischenablage kopiert."
|
||||||
|
|
||||||
|
-- The path does not exist and its parent folder could not be found.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3606079336"] = "Der Pfad existiert nicht, und der übergeordnete Ordner konnte nicht gefunden werden."
|
||||||
|
|
||||||
-- Failed to delete the API key due to an API issue.
|
-- Failed to delete the API key due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3658273365"] = "Das API-Schlüssel konnte aufgrund eines API-Problems nicht gelöscht werden."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3658273365"] = "Das API-Schlüssel konnte aufgrund eines API-Problems nicht gelöscht werden."
|
||||||
|
|
||||||
-- Failed to copy the text to your clipboard.
|
-- Failed to copy the text to your clipboard.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3724548108"] = "Der Text konnte nicht in die Zwischenablage kopiert werden."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3724548108"] = "Der Text konnte nicht in die Zwischenablage kopiert werden."
|
||||||
|
|
||||||
|
-- The local file manager command failed: {0}
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T381756374"] = "Der Befehl des lokalen Dateimanagers ist fehlgeschlagen: {0}"
|
||||||
|
|
||||||
-- Failed to get the API key due to an API issue.
|
-- Failed to get the API key due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3875720022"] = "Der API-Schlüssel konnte aufgrund eines API-Problems nicht abgerufen werden."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3875720022"] = "Der API-Schlüssel konnte aufgrund eines API-Problems nicht abgerufen werden."
|
||||||
|
|
||||||
-- Failed to get the secret data due to an API issue.
|
-- Failed to get the secret data due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T4007657575"] = "Abrufen der geheimen Daten aufgrund eines API-Problems fehlgeschlagen."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T4007657575"] = "Abrufen der geheimen Daten aufgrund eines API-Problems fehlgeschlagen."
|
||||||
|
|
||||||
|
-- The local file manager command did not start.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T613631541"] = "Der Befehl des lokalen Dateimanagers wurde nicht gestartet."
|
||||||
|
|
||||||
-- No update found.
|
-- No update found.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "Kein Update gefunden."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "Kein Update gefunden."
|
||||||
|
|
||||||
|
|||||||
@ -1650,6 +1650,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T174782740
|
|||||||
-- The log file does not exist: {0}
|
-- The log file does not exist: {0}
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1807514273"] = "The log file does not exist: {0}"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1807514273"] = "The log file does not exist: {0}"
|
||||||
|
|
||||||
|
-- Could not open the log file location.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1828231197"] = "Could not open the log file location."
|
||||||
|
|
||||||
-- Other
|
-- Other
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1849229205"] = "Other"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T1849229205"] = "Other"
|
||||||
|
|
||||||
@ -1668,6 +1671,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T237835357
|
|||||||
-- No matching log lines.
|
-- No matching log lines.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2511997530"] = "No matching log lines."
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2511997530"] = "No matching log lines."
|
||||||
|
|
||||||
|
-- Could not open the log file location: {0}
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2533784927"] = "Could not open the log file location: {0}"
|
||||||
|
|
||||||
-- Source details
|
-- Source details
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2686813966"] = "Source details"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T2686813966"] = "Source details"
|
||||||
|
|
||||||
@ -1680,6 +1686,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T315262563
|
|||||||
-- Loading log file...
|
-- Loading log file...
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T333036481"] = "Loading log file..."
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T333036481"] = "Loading log file..."
|
||||||
|
|
||||||
|
-- Unknown error
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T3461425987"] = "Unknown error"
|
||||||
|
|
||||||
-- The log file path is not available yet.
|
-- The log file path is not available yet.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T3686775689"] = "The log file path is not available yet."
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T3686775689"] = "The log file path is not available yet."
|
||||||
|
|
||||||
@ -1698,12 +1707,18 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T397479987
|
|||||||
-- Usage log
|
-- Usage log
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4031747274"] = "Usage log"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4031747274"] = "Usage log"
|
||||||
|
|
||||||
|
-- Open in folder
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4048746540"] = "Open in folder"
|
||||||
|
|
||||||
-- Log file
|
-- Log file
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4129341821"] = "Log file"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4129341821"] = "Log file"
|
||||||
|
|
||||||
-- Log Viewer
|
-- Log Viewer
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4130241777"] = "Log Viewer"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4130241777"] = "Log Viewer"
|
||||||
|
|
||||||
|
-- Opened the log file location.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T4162897654"] = "Opened the log file location."
|
||||||
|
|
||||||
-- Show timestamps
|
-- Show timestamps
|
||||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T469116133"] = "Show timestamps"
|
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::LOGVIEWER::ASSISTANTLOGVIEWER::T469116133"] = "Show timestamps"
|
||||||
|
|
||||||
@ -8586,24 +8601,42 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T1110203516"] = "Failed
|
|||||||
-- Failed to store the API key due to an API issue.
|
-- Failed to store the API key due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T1704298921"] = "Failed to store the API key due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T1704298921"] = "Failed to store the API key due to an API issue."
|
||||||
|
|
||||||
|
-- The runtime file manager endpoint returned '{0}'.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2158262203"] = "The runtime file manager endpoint returned '{0}'."
|
||||||
|
|
||||||
-- Failed to delete the secret data due to an API issue.
|
-- Failed to delete the secret data due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2303057928"] = "Failed to delete the secret data due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2303057928"] = "Failed to delete the secret data due to an API issue."
|
||||||
|
|
||||||
|
-- The runtime file manager endpoint is not available.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T2486847754"] = "The runtime file manager endpoint is not available."
|
||||||
|
|
||||||
|
-- The runtime file manager endpoint failed without details.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3082220817"] = "The runtime file manager endpoint failed without details."
|
||||||
|
|
||||||
-- Successfully copied the text to your clipboard
|
-- Successfully copied the text to your clipboard
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3351807428"] = "Successfully copied the text to your clipboard"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3351807428"] = "Successfully copied the text to your clipboard"
|
||||||
|
|
||||||
|
-- The path does not exist and its parent folder could not be found.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3606079336"] = "The path does not exist and its parent folder could not be found."
|
||||||
|
|
||||||
-- Failed to delete the API key due to an API issue.
|
-- Failed to delete the API key due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3658273365"] = "Failed to delete the API key due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3658273365"] = "Failed to delete the API key due to an API issue."
|
||||||
|
|
||||||
-- Failed to copy the text to your clipboard.
|
-- Failed to copy the text to your clipboard.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3724548108"] = "Failed to copy the text to your clipboard."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3724548108"] = "Failed to copy the text to your clipboard."
|
||||||
|
|
||||||
|
-- The local file manager command failed: {0}
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T381756374"] = "The local file manager command failed: {0}"
|
||||||
|
|
||||||
-- Failed to get the API key due to an API issue.
|
-- Failed to get the API key due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3875720022"] = "Failed to get the API key due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T3875720022"] = "Failed to get the API key due to an API issue."
|
||||||
|
|
||||||
-- Failed to get the secret data due to an API issue.
|
-- Failed to get the secret data due to an API issue.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T4007657575"] = "Failed to get the secret data due to an API issue."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T4007657575"] = "Failed to get the secret data due to an API issue."
|
||||||
|
|
||||||
|
-- The local file manager command did not start.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::T613631541"] = "The local file manager command did not start."
|
||||||
|
|
||||||
-- No update found.
|
-- No update found.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found."
|
||||||
|
|
||||||
|
|||||||
3
app/MindWork AI Studio/Tools/Rust/OpenPathRequest.cs
Normal file
3
app/MindWork AI Studio/Tools/Rust/OpenPathRequest.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace AIStudio.Tools.Rust;
|
||||||
|
|
||||||
|
public readonly record struct OpenPathRequest(string Path);
|
||||||
3
app/MindWork AI Studio/Tools/Rust/OpenPathResponse.cs
Normal file
3
app/MindWork AI Studio/Tools/Rust/OpenPathResponse.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace AIStudio.Tools.Rust;
|
||||||
|
|
||||||
|
public readonly record struct OpenPathResponse(bool Success, string Issue);
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
using AIStudio.Tools.Rust;
|
using AIStudio.Tools.Rust;
|
||||||
|
|
||||||
namespace AIStudio.Tools.Services;
|
namespace AIStudio.Tools.Services;
|
||||||
@ -84,4 +86,109 @@ public sealed partial class RustService
|
|||||||
|
|
||||||
return await result.Content.ReadFromJsonAsync<FileSaveResponse>(this.jsonRustSerializerOptions);
|
return await result.Content.ReadFromJsonAsync<FileSaveResponse>(this.jsonRustSerializerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<OpenPathResponse> OpenPathInFileManager(string path)
|
||||||
|
{
|
||||||
|
var runtimeResponse = await this.TryOpenPathInRuntimeFileManager(path);
|
||||||
|
if (runtimeResponse.Success)
|
||||||
|
return runtimeResponse;
|
||||||
|
|
||||||
|
var localResponse = this.TryOpenPathInLocalFileManager(path);
|
||||||
|
if (localResponse.Success)
|
||||||
|
return localResponse;
|
||||||
|
|
||||||
|
var issue = string.IsNullOrWhiteSpace(runtimeResponse.Issue)
|
||||||
|
? localResponse.Issue
|
||||||
|
: $"{runtimeResponse.Issue} {localResponse.Issue}";
|
||||||
|
|
||||||
|
return new OpenPathResponse(false, issue.Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<OpenPathResponse> TryOpenPathInRuntimeFileManager(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await this.http.PostAsJsonAsync("/open/path", new OpenPathRequest(path), this.jsonRustSerializerOptions);
|
||||||
|
if (!result.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
this.logger!.LogWarning("Failed to open a path in the file manager through the Rust runtime: '{StatusCode}'", result.StatusCode);
|
||||||
|
return new OpenPathResponse(false, string.Format(TB("The runtime file manager endpoint returned '{0}'."), result.StatusCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = await result.Content.ReadFromJsonAsync<OpenPathResponse>(this.jsonRustSerializerOptions);
|
||||||
|
return response.Success
|
||||||
|
? response
|
||||||
|
: new OpenPathResponse(false, string.IsNullOrWhiteSpace(response.Issue) ? TB("The runtime file manager endpoint failed without details.") : response.Issue);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
this.logger!.LogWarning(e, "Failed to open a path in the file manager through the Rust runtime.");
|
||||||
|
return new OpenPathResponse(false, TB("The runtime file manager endpoint is not available."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OpenPathResponse TryOpenPathInLocalFileManager(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var target = ResolveFileManagerTarget(path);
|
||||||
|
if (target is null)
|
||||||
|
return new OpenPathResponse(false, TB("The path does not exist and its parent folder could not be found."));
|
||||||
|
|
||||||
|
using var process = Process.Start(CreateFileManagerStartInfo(target.Value));
|
||||||
|
return process is null
|
||||||
|
? new OpenPathResponse(false, TB("The local file manager command did not start."))
|
||||||
|
: new OpenPathResponse(true, string.Empty);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
this.logger!.LogWarning(e, "Failed to open a path in the local file manager.");
|
||||||
|
return new OpenPathResponse(false, string.Format(TB("The local file manager command failed: {0}"), e.Message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileManagerTarget? ResolveFileManagerTarget(string path)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(path))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var requestedPath = path.Trim();
|
||||||
|
if (File.Exists(requestedPath))
|
||||||
|
return new FileManagerTarget(requestedPath, true);
|
||||||
|
|
||||||
|
if (Directory.Exists(requestedPath))
|
||||||
|
return new FileManagerTarget(requestedPath, false);
|
||||||
|
|
||||||
|
var parent = Directory.GetParent(requestedPath)?.FullName;
|
||||||
|
return !string.IsNullOrWhiteSpace(parent) && Directory.Exists(parent)
|
||||||
|
? new FileManagerTarget(parent, false)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ProcessStartInfo CreateFileManagerStartInfo(FileManagerTarget target)
|
||||||
|
{
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
var windowsInfo = new ProcessStartInfo("explorer.exe") { UseShellExecute = false };
|
||||||
|
windowsInfo.ArgumentList.Add(target.RevealFile ? $"/select,{target.Path}" : target.Path);
|
||||||
|
return windowsInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
var macOsInfo = new ProcessStartInfo("open") { UseShellExecute = false };
|
||||||
|
if (target.RevealFile)
|
||||||
|
macOsInfo.ArgumentList.Add("-R");
|
||||||
|
|
||||||
|
macOsInfo.ArgumentList.Add(target.Path);
|
||||||
|
return macOsInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
var linuxInfo = new ProcessStartInfo("xdg-open") { UseShellExecute = false };
|
||||||
|
var directory = target.RevealFile ? Path.GetDirectoryName(target.Path) ?? target.Path : target.Path;
|
||||||
|
linuxInfo.ArgumentList.Add(directory);
|
||||||
|
return linuxInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly record struct FileManagerTarget(string Path, bool RevealFile);
|
||||||
}
|
}
|
||||||
@ -5,6 +5,7 @@
|
|||||||
- Improved update guidance for Flatpak installations and added an enterprise option that lets organizations manage updates entirely through their IT department.
|
- Improved update guidance for Flatpak installations and added an enterprise option that lets organizations manage updates entirely through their IT department.
|
||||||
- Fixed an issue that could leave AI Studio unresponsive after waking the computer from sleep.
|
- Fixed an issue that could leave AI Studio unresponsive after waking the computer from sleep.
|
||||||
- Fixed enterprise configuration plugins from Windows-created ZIP files not loading correctly on Linux when the ZIP contained plugin files inside a folder.
|
- Fixed enterprise configuration plugins from Windows-created ZIP files not loading correctly on Linux when the ZIP contained plugin files inside a folder.
|
||||||
|
- Fixed file extension handling so files are recognized correctly regardless of uppercase or lowercase letters in their extensions.
|
||||||
- Fixed voice recording not starting on Linux.
|
- Fixed voice recording not starting on Linux.
|
||||||
- Upgraded Rust to v1.97.0.
|
- Upgraded Rust to v1.97.0.
|
||||||
- Upgraded Tauri to v2.11.5.
|
- Upgraded Tauri to v2.11.5.
|
||||||
|
|||||||
@ -2,10 +2,18 @@
|
|||||||
use axum::extract::Query;
|
use axum::extract::Query;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::Command;
|
||||||
|
#[cfg(windows)]
|
||||||
|
use std::os::windows::process::CommandExt;
|
||||||
use tauri_plugin_dialog::{DialogExt, FileDialogBuilder};
|
use tauri_plugin_dialog::{DialogExt, FileDialogBuilder};
|
||||||
use crate::api_token::APIToken;
|
use crate::api_token::APIToken;
|
||||||
use crate::app_window::MAIN_WINDOW;
|
use crate::app_window::MAIN_WINDOW;
|
||||||
|
|
||||||
|
/// Microsoft documents CREATE_NO_WINDOW as a process creation flag with value 0x08000000.
|
||||||
|
#[cfg(windows)]
|
||||||
|
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||||
|
|
||||||
#[derive(Clone, Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
pub struct PreviousDirectory {
|
pub struct PreviousDirectory {
|
||||||
path: String,
|
path: String,
|
||||||
@ -36,6 +44,11 @@ pub struct SaveFileOptions {
|
|||||||
filter: Option<FileTypeFilter>,
|
filter: Option<FileTypeFilter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize)]
|
||||||
|
pub struct OpenPathOptions {
|
||||||
|
path: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct DirectorySelectionResponse {
|
pub struct DirectorySelectionResponse {
|
||||||
user_cancelled: bool,
|
user_cancelled: bool,
|
||||||
@ -60,6 +73,12 @@ pub struct FileSaveResponse {
|
|||||||
save_file_path: String,
|
save_file_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct OpenPathResponse {
|
||||||
|
success: bool,
|
||||||
|
issue: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
pub struct PreviousFile {
|
pub struct PreviousFile {
|
||||||
file_path: String,
|
file_path: String,
|
||||||
@ -286,6 +305,55 @@ pub async fn save_file(_token: APIToken, payload: Json<SaveFileOptions>) -> Json
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn open_path_in_file_manager(
|
||||||
|
_token: APIToken,
|
||||||
|
payload: Json<OpenPathOptions>,
|
||||||
|
) -> Json<OpenPathResponse> {
|
||||||
|
let requested_path = PathBuf::from(payload.path.trim());
|
||||||
|
if requested_path.as_os_str().is_empty() {
|
||||||
|
return Json(OpenPathResponse {
|
||||||
|
success: false,
|
||||||
|
issue: String::from("The path is empty."),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(target) = resolve_file_manager_target(&requested_path) else {
|
||||||
|
let issue = format!(
|
||||||
|
"The path does not exist and its parent folder could not be found: {}",
|
||||||
|
requested_path.to_string_lossy(),
|
||||||
|
);
|
||||||
|
error!(Source = "Tauri"; "{issue}");
|
||||||
|
return Json(OpenPathResponse {
|
||||||
|
success: false,
|
||||||
|
issue,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut command = create_file_manager_command(&target);
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
command.creation_flags(CREATE_NO_WINDOW);
|
||||||
|
|
||||||
|
match command.spawn() {
|
||||||
|
Ok(_) => {
|
||||||
|
info!("Opened file manager for path: {:?}", target.path);
|
||||||
|
Json(OpenPathResponse {
|
||||||
|
success: true,
|
||||||
|
issue: String::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(error) => {
|
||||||
|
let issue = format!("Failed to open the file manager: {error}");
|
||||||
|
error!(Source = "Tauri"; "{issue}");
|
||||||
|
Json(OpenPathResponse {
|
||||||
|
success: false,
|
||||||
|
issue,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Applies an optional file type filter to a FileDialogBuilder.
|
/// Applies an optional file type filter to a FileDialogBuilder.
|
||||||
fn apply_filter<R: tauri::Runtime>(file_dialog: FileDialogBuilder<R>, filter: &Option<FileTypeFilter>) -> FileDialogBuilder<R> {
|
fn apply_filter<R: tauri::Runtime>(file_dialog: FileDialogBuilder<R>, filter: &Option<FileTypeFilter>) -> FileDialogBuilder<R> {
|
||||||
match filter {
|
match filter {
|
||||||
@ -297,3 +365,67 @@ fn apply_filter<R: tauri::Runtime>(file_dialog: FileDialogBuilder<R>, filter: &O
|
|||||||
None => file_dialog,
|
None => file_dialog,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FileManagerTarget {
|
||||||
|
path: PathBuf,
|
||||||
|
reveal_file: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_file_manager_target(requested_path: &Path) -> Option<FileManagerTarget> {
|
||||||
|
if requested_path.is_file() {
|
||||||
|
return Some(FileManagerTarget {
|
||||||
|
path: requested_path.to_path_buf(),
|
||||||
|
reveal_file: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if requested_path.is_dir() {
|
||||||
|
return Some(FileManagerTarget {
|
||||||
|
path: requested_path.to_path_buf(),
|
||||||
|
reveal_file: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
requested_path.parent()
|
||||||
|
.filter(|parent| parent.is_dir())
|
||||||
|
.map(|parent| FileManagerTarget {
|
||||||
|
path: parent.to_path_buf(),
|
||||||
|
reveal_file: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn create_file_manager_command(target: &FileManagerTarget) -> Command {
|
||||||
|
let mut command = Command::new("explorer.exe");
|
||||||
|
if target.reveal_file {
|
||||||
|
command.arg(format!("/select,{}", target.path.to_string_lossy()));
|
||||||
|
} else {
|
||||||
|
command.arg(&target.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
command
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn create_file_manager_command(target: &FileManagerTarget) -> Command {
|
||||||
|
let mut command = Command::new("open");
|
||||||
|
if target.reveal_file {
|
||||||
|
command.arg("-R");
|
||||||
|
}
|
||||||
|
|
||||||
|
command.arg(&target.path);
|
||||||
|
command
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(unix, not(target_os = "macos")))]
|
||||||
|
fn create_file_manager_command(target: &FileManagerTarget) -> Command {
|
||||||
|
let mut command = Command::new("xdg-open");
|
||||||
|
let directory = if target.reveal_file {
|
||||||
|
target.path.parent().unwrap_or(&target.path)
|
||||||
|
} else {
|
||||||
|
&target.path
|
||||||
|
};
|
||||||
|
|
||||||
|
command.arg(directory);
|
||||||
|
command
|
||||||
|
}
|
||||||
|
|||||||
@ -46,6 +46,7 @@ pub fn start_runtime_api() {
|
|||||||
.route("/select/file", post(crate::file_actions::select_file))
|
.route("/select/file", post(crate::file_actions::select_file))
|
||||||
.route("/select/files", post(crate::file_actions::select_files))
|
.route("/select/files", post(crate::file_actions::select_files))
|
||||||
.route("/save/file", post(crate::file_actions::save_file))
|
.route("/save/file", post(crate::file_actions::save_file))
|
||||||
|
.route("/open/path", post(crate::file_actions::open_path_in_file_manager))
|
||||||
.route("/secrets/get", post(crate::secret::get_secret))
|
.route("/secrets/get", post(crate::secret::get_secret))
|
||||||
.route("/secrets/store", post(crate::secret::store_secret))
|
.route("/secrets/store", post(crate::secret::store_secret))
|
||||||
.route("/secrets/delete", post(crate::secret::delete_secret))
|
.route("/secrets/delete", post(crate::secret::delete_secret))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user