mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-28 10:39:47 +00:00
Merge 8a890d2ed9
into 3fc15d9789
This commit is contained in:
commit
3fdb4bae7e
@ -3,6 +3,22 @@
|
|||||||
<div class="inner-scrolling-context">
|
<div class="inner-scrolling-context">
|
||||||
<MudText Typo="Typo.h3" Class="mb-2">About MindWork AI Studio</MudText>
|
<MudText Typo="Typo.h3" Class="mb-2">About MindWork AI Studio</MudText>
|
||||||
|
|
||||||
|
<!-- TODO: DELETE FOR DEBUGGING ONLY -->
|
||||||
|
<MudItem>
|
||||||
|
<h3>Pandoc Verfügbarkeit prüfen</h3>
|
||||||
|
<MudButton OnClick="CheckPandoc" Disabled="@isChecking">
|
||||||
|
@(isChecking ? "Überprüfe..." : "Pandoc überprüfen")
|
||||||
|
</MudButton>
|
||||||
|
<p>@statusMessage</p>
|
||||||
|
</MudItem>
|
||||||
|
|
||||||
|
<MudItem Class="my-9">
|
||||||
|
<h3>Pandoc Installation</h3>
|
||||||
|
<MudButton OnClick="InstallPandoc">
|
||||||
|
Install Pandoc
|
||||||
|
</MudButton>
|
||||||
|
</MudItem>
|
||||||
|
|
||||||
<InnerScrolling>
|
<InnerScrolling>
|
||||||
<MudExpansionPanels Class="mb-3" MultiExpansion="@false">
|
<MudExpansionPanels Class="mb-3" MultiExpansion="@false">
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Layers" HeaderText="Versions" IsExpanded="@true">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Layers" HeaderText="Versions" IsExpanded="@true">
|
||||||
|
@ -174,4 +174,30 @@ public partial class About : ComponentBase
|
|||||||
{
|
{
|
||||||
await this.MessageBus.SendMessage<bool>(this, Event.USER_SEARCH_FOR_UPDATE);
|
await this.MessageBus.SendMessage<bool>(this, Event.USER_SEARCH_FOR_UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: DELETE FOR DEBUGGING ONLY
|
||||||
|
private bool isChecking;
|
||||||
|
private string statusMessage = string.Empty;
|
||||||
|
private async Task CheckPandoc()
|
||||||
|
{
|
||||||
|
this.isChecking = true;
|
||||||
|
this.statusMessage = "Überprüfe die Verfügbarkeit von Pandoc...";
|
||||||
|
this.StateHasChanged(); // Aktualisiere die UI
|
||||||
|
var isPandocAvailable = await Pandoc.IsPandocAvailableAsync();
|
||||||
|
if (isPandocAvailable)
|
||||||
|
{
|
||||||
|
this.statusMessage = "Pandoc ist verfügbar und erfüllt die Mindestversion.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.statusMessage = "Pandoc ist nicht verfügbar oder die installierte Version ist zu niedrig.";
|
||||||
|
}
|
||||||
|
this.isChecking = false;
|
||||||
|
this.StateHasChanged(); // Aktualisiere die UI
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task InstallPandoc()
|
||||||
|
{
|
||||||
|
var installPandoc = Pandoc.InstallPandocAsync(this.RustService);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,3 +14,18 @@ public readonly record struct Error(string Icon, string Message)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public readonly record struct Success(string Icon, string Message)
|
||||||
|
{
|
||||||
|
public void Show(ISnackbar snackbar)
|
||||||
|
{
|
||||||
|
var icon = this.Icon;
|
||||||
|
snackbar.Add(this.Message, Severity.Success, config =>
|
||||||
|
{
|
||||||
|
config.Icon = icon;
|
||||||
|
config.IconSize = Size.Large;
|
||||||
|
config.HideTransitionDuration = 600;
|
||||||
|
config.VisibleStateDuration = 10_000;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ public enum Event
|
|||||||
STARTUP_PLUGIN_SYSTEM,
|
STARTUP_PLUGIN_SYSTEM,
|
||||||
PLUGINS_RELOADED,
|
PLUGINS_RELOADED,
|
||||||
SHOW_ERROR,
|
SHOW_ERROR,
|
||||||
|
SHOW_SUCCESS,
|
||||||
|
|
||||||
// Update events:
|
// Update events:
|
||||||
USER_SEARCH_FOR_UPDATE,
|
USER_SEARCH_FOR_UPDATE,
|
||||||
|
@ -68,6 +68,8 @@ public sealed class MessageBus
|
|||||||
|
|
||||||
public Task SendError(Error error) => this.SendMessage(null, Event.SHOW_ERROR, error);
|
public Task SendError(Error error) => this.SendMessage(null, Event.SHOW_ERROR, error);
|
||||||
|
|
||||||
|
public Task SendSuccess(Success success) => this.SendMessage(null, Event.SHOW_SUCCESS, success);
|
||||||
|
|
||||||
public void DeferMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data = default)
|
public void DeferMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data = default)
|
||||||
{
|
{
|
||||||
if (this.deferredMessages.TryGetValue(triggeredEvent, out var queue))
|
if (this.deferredMessages.TryGetValue(triggeredEvent, out var queue))
|
||||||
|
136
app/MindWork AI Studio/Tools/Pandoc.cs
Normal file
136
app/MindWork AI Studio/Tools/Pandoc.cs
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using AIStudio.Components;
|
||||||
|
using AIStudio.Tools.Services;
|
||||||
|
|
||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
public static partial class Pandoc
|
||||||
|
{
|
||||||
|
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger("PluginFactory");
|
||||||
|
private static readonly string DOWNLOAD_URL = "https://github.com/jgm/pandoc/releases/download/3.6.4/pandoc-3.6.4-windows-x86_64.zip";
|
||||||
|
private static readonly Version MINIMUM_REQUIRED_VERSION = new Version(3, 6);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if pandoc is available on the system and can be started as a process
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True, if pandoc is available and the minimum required version is met, else False.</returns>
|
||||||
|
public static async Task<bool> IsPandocAvailableAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var startInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = GetPandocExecutableName(),
|
||||||
|
Arguments = "--version",
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
UseShellExecute = false,
|
||||||
|
CreateNoWindow = true
|
||||||
|
};
|
||||||
|
using var process = Process.Start(startInfo);
|
||||||
|
if (process == null)
|
||||||
|
{
|
||||||
|
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Help, "The pandoc process could not be started."));
|
||||||
|
LOG.LogInformation("The pandoc process was not started, it was null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var output = await process.StandardOutput.ReadToEndAsync();
|
||||||
|
await process.WaitForExitAsync();
|
||||||
|
if (process.ExitCode != 0)
|
||||||
|
{
|
||||||
|
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Error, $"The pandoc process exited unexpectedly."));
|
||||||
|
LOG.LogError("The pandoc process was exited with code {ProcessExitCode}", process.ExitCode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var versionMatch = PandocRegex().Match(output);
|
||||||
|
if (!versionMatch.Success)
|
||||||
|
{
|
||||||
|
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Terminal, $"pandoc --version returned an invalid format."));
|
||||||
|
LOG.LogError("pandoc --version returned an invalid format:\n {Output}", output);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var versions = versionMatch.Groups[1].Value.Split('.');
|
||||||
|
var major = int.Parse(versions[0]);
|
||||||
|
var minor = int.Parse(versions[1]);
|
||||||
|
var installedVersion = new Version(major, minor);
|
||||||
|
|
||||||
|
if (installedVersion >= MINIMUM_REQUIRED_VERSION)
|
||||||
|
{
|
||||||
|
await MessageBus.INSTANCE.SendSuccess(new(Icons.Material.Filled.CheckCircle, $"Pandoc {installedVersion.ToString()} is installed."));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Build, $"Pandoc {installedVersion.ToString()} is installed, but it doesn't match the required version ({MINIMUM_REQUIRED_VERSION.ToString()})."));
|
||||||
|
LOG.LogInformation("Pandoc {Installed} is installed, but it does not match the required version ({Requirement})", installedVersion.ToString(), MINIMUM_REQUIRED_VERSION.ToString());
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await MessageBus.INSTANCE.SendError(new (@Icons.Material.Filled.AppsOutage, "Pandoc is not installed."));
|
||||||
|
LOG.LogError("Pandoc is not installed and threw an exception:\n {Message}", e.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task InstallPandocAsync(RustService rustService)
|
||||||
|
{
|
||||||
|
var dataDir = await rustService.GetDataDirectory();
|
||||||
|
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Help, $"{dataDir}"));
|
||||||
|
var installDir = Path.Join(dataDir, "pandoc");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(installDir))
|
||||||
|
Directory.CreateDirectory(installDir);
|
||||||
|
|
||||||
|
using var client = new HttpClient();
|
||||||
|
var response = await client.GetAsync(DOWNLOAD_URL);
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var fileBytes = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
var tempZipPath = Path.Join(Path.GetTempPath(), "pandoc.zip");
|
||||||
|
await File.WriteAllBytesAsync(tempZipPath, fileBytes);
|
||||||
|
ZipFile.ExtractToDirectory(tempZipPath, installDir);
|
||||||
|
File.Delete(tempZipPath);
|
||||||
|
|
||||||
|
var currentPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine);
|
||||||
|
var pandocDir = Path.Join(currentPath, "pandoc-3.6.4");
|
||||||
|
if (currentPath != null && !currentPath.Contains(pandocDir))
|
||||||
|
{
|
||||||
|
Environment.SetEnvironmentVariable(
|
||||||
|
"PATH",
|
||||||
|
$"{currentPath};{pandocDir}",
|
||||||
|
EnvironmentVariableTarget.Machine);
|
||||||
|
Console.WriteLine("Pandoc-Verzeichnis zum PATH hinzugefügt.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Pandoc-Verzeichnis ist bereits im PATH.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await MessageBus.INSTANCE.SendSuccess(new(Icons.Material.Filled.CheckCircle, $"Pandoc {MINIMUM_REQUIRED_VERSION.ToString()} was installed successfully."));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Fehler beim Herunterladen von Pandoc.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Fehler: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the name of the pandoc executable based on the running operating system
|
||||||
|
/// </summary>
|
||||||
|
private static string GetPandocExecutableName() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "pandoc.exe" : "pandoc";
|
||||||
|
|
||||||
|
[GeneratedRegex(@"pandoc(?:\.exe)?\s*([0-9]+\.[0-9]+)")]
|
||||||
|
private static partial Regex PandocRegex();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user