diff --git a/app/MindWork AI Studio/Tools/Pandoc.cs b/app/MindWork AI Studio/Tools/Pandoc.cs
index dba5be66..d14203ea 100644
--- a/app/MindWork AI Studio/Tools/Pandoc.cs
+++ b/app/MindWork AI Studio/Tools/Pandoc.cs
@@ -26,6 +26,11 @@ public static partial class Pandoc
private static readonly Version MINIMUM_REQUIRED_VERSION = new (3, 7, 0, 2);
private static readonly Version FALLBACK_VERSION = new (3, 7, 0, 2);
+ ///
+ /// Tracks whether the first availability check log has been written to avoid log spam on repeated calls.
+ ///
+ private static bool HAS_LOGGED_AVAILABILITY_CHECK_ONCE;
+
///
/// Prepares a Pandoc process by using the Pandoc process builder.
///
@@ -41,18 +46,26 @@ public static partial class Pandoc
/// True, if pandoc is available and the minimum required version is met, else false.
public static async Task CheckAvailabilityAsync(RustService rustService, bool showMessages = true, bool showSuccessMessage = true)
{
+ //
+ // Determine if we should log (only on the first call):
+ //
+ var shouldLog = !HAS_LOGGED_AVAILABILITY_CHECK_ONCE;
+
try
{
var preparedProcess = await PreparePandocProcess().AddArgument("--version").BuildAsync(rustService);
- LOG.LogDebug("Checking Pandoc availability using executable: '{Executable}' (IsLocal: {IsLocal}).", preparedProcess.StartInfo.FileName, preparedProcess.IsLocal);
+ if (shouldLog)
+ LOG.LogInformation("Checking Pandoc availability using executable: '{Executable}' (IsLocal: {IsLocal}).", preparedProcess.StartInfo.FileName, preparedProcess.IsLocal);
using var process = Process.Start(preparedProcess.StartInfo);
if (process == null)
{
if (showMessages)
- await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Help, TB("Was not able to check the Pandoc installation.")));
+ await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Help, TB("Was not able to check the Pandoc installation.")));
- LOG.LogInformation("The Pandoc process was not started, it was null. Executable path: '{Executable}'.", preparedProcess.StartInfo.FileName);
+ if (shouldLog)
+ LOG.LogError("The Pandoc process was not started, it was null. Executable path: '{Executable}'.", preparedProcess.StartInfo.FileName);
+
return new(false, TB("Was not able to check the Pandoc installation."), false, string.Empty, preparedProcess.IsLocal);
}
@@ -68,9 +81,11 @@ public static partial class Pandoc
if (process.ExitCode != 0)
{
if (showMessages)
- await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Error, TB("Pandoc is not available on the system or the process had issues.")));
+ await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Error, TB("Pandoc is not available on the system or the process had issues.")));
- LOG.LogError("The Pandoc process exited with code {ProcessExitCode}. Error output: '{ErrorText}'", process.ExitCode, error);
+ if (shouldLog)
+ LOG.LogError("The Pandoc process exited with code {ProcessExitCode}. Error output: '{ErrorText}'", process.ExitCode, error);
+
return new(false, TB("Pandoc is not available on the system or the process had issues."), false, string.Empty, preparedProcess.IsLocal);
}
@@ -78,39 +93,51 @@ public static partial class Pandoc
if (!versionMatch.Success)
{
if (showMessages)
- await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Terminal, TB("Was not able to validate the Pandoc installation.")));
+ await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Terminal, TB("Was not able to validate the Pandoc installation.")));
+
+ if (shouldLog)
+ LOG.LogError("Pandoc --version returned an invalid format: '{Output}'.", output);
- LOG.LogError("Pandoc --version returned an invalid format: {Output}", output);
return new(false, TB("Was not able to validate the Pandoc installation."), false, string.Empty, preparedProcess.IsLocal);
}
-
+
var versions = versionMatch.Groups[1].Value;
var installedVersion = Version.Parse(versions);
var installedVersionString = installedVersion.ToString();
-
+
if (installedVersion >= MINIMUM_REQUIRED_VERSION)
{
if (showMessages && showSuccessMessage)
await MessageBus.INSTANCE.SendSuccess(new(Icons.Material.Filled.CheckCircle, string.Format(TB("Pandoc v{0} is installed."), installedVersionString)));
-
- LOG.LogInformation("Pandoc v{0} is installed and matches the required version (v{1})", installedVersionString, MINIMUM_REQUIRED_VERSION.ToString());
+
+ if (shouldLog)
+ LOG.LogInformation("Pandoc v{0} is installed and matches the required version (v{1}).", installedVersionString, MINIMUM_REQUIRED_VERSION.ToString());
+
return new(true, string.Empty, true, installedVersionString, preparedProcess.IsLocal);
}
-
+
if (showMessages)
- await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.Build, string.Format(TB("Pandoc v{0} is installed, but it doesn't match the required version (v{1})."), installedVersionString, MINIMUM_REQUIRED_VERSION.ToString())));
+ await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Build, string.Format(TB("Pandoc v{0} is installed, but it doesn't match the required version (v{1})."), installedVersionString, MINIMUM_REQUIRED_VERSION.ToString())));
+
+ if (shouldLog)
+ LOG.LogWarning("Pandoc v{0} is installed, but it does not match the required version (v{1}).", installedVersionString, MINIMUM_REQUIRED_VERSION.ToString());
- LOG.LogWarning("Pandoc v{0} is installed, but it does not match the required version (v{1})", installedVersionString, MINIMUM_REQUIRED_VERSION.ToString());
return new(true, string.Format(TB("Pandoc v{0} is installed, but it does not match the required version (v{1})."), installedVersionString, MINIMUM_REQUIRED_VERSION.ToString()), false, installedVersionString, preparedProcess.IsLocal);
}
catch (Exception e)
{
if (showMessages)
- await MessageBus.INSTANCE.SendError(new (@Icons.Material.Filled.AppsOutage, TB("It seems that Pandoc is not installed.")));
+ await MessageBus.INSTANCE.SendError(new(@Icons.Material.Filled.AppsOutage, TB("It seems that Pandoc is not installed.")));
- LOG.LogError(e, "Pandoc availability check failed. This usually means Pandoc is not installed or not in the system PATH.");
+ if(shouldLog)
+ LOG.LogError(e, "Pandoc availability check failed. This usually means Pandoc is not installed or not in the system PATH.");
+
return new(false, TB("It seems that Pandoc is not installed."), false, string.Empty, false);
}
+ finally
+ {
+ HAS_LOGGED_AVAILABILITY_CHECK_ONCE = true;
+ }
}
///
diff --git a/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs b/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs
index 0b856486..3265351f 100644
--- a/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs
+++ b/app/MindWork AI Studio/Tools/PandocProcessBuilder.cs
@@ -16,6 +16,9 @@ public sealed class PandocProcessBuilder
private static readonly RID CPU_ARCHITECTURE = META_DATA_ARCH.Architecture.ToRID();
private static readonly ILogger LOGGER = Program.LOGGER_FACTORY.CreateLogger(nameof(PandocProcessBuilder));
+ // Tracks whether the first log has been written to avoid log spam on repeated calls:
+ private static bool HAS_LOGGED_ONCE;
+
private string? providedInputFile;
private string? providedOutputFile;
private string? providedInputFormat;
@@ -113,67 +116,94 @@ public sealed class PandocProcessBuilder
private static async Task PandocExecutablePath(RustService rustService)
{
//
- // First, we try to find the pandoc executable in the data directory.
- // Any local installation should be preferred over the system-wide installation.
+ // Determine if we should log (only on the first call):
//
- var localInstallationRootDirectory = await Pandoc.GetPandocDataFolder(rustService);
+ var shouldLog = !HAS_LOGGED_ONCE;
- //
- // Check if the data directory path is valid:
- //
- if (string.IsNullOrWhiteSpace(localInstallationRootDirectory))
- LOGGER.LogWarning("The local data directory path is empty or null. Cannot search for local Pandoc installation.");
-
- else if (!Directory.Exists(localInstallationRootDirectory))
- LOGGER.LogWarning("The local Pandoc installation directory does not exist: '{LocalInstallationRootDirectory}'.", localInstallationRootDirectory);
-
- else
+ try
{
//
- // The directory exists, search for the pandoc executable:
+ // First, we try to find the pandoc executable in the data directory.
+ // Any local installation should be preferred over the system-wide installation.
//
- var executableName = PandocExecutableName;
- LOGGER.LogDebug("Searching for Pandoc executable '{ExecutableName}' in: '{LocalInstallationRootDirectory}'.", executableName, localInstallationRootDirectory);
+ var localInstallationRootDirectory = await Pandoc.GetPandocDataFolder(rustService);
- try
+ //
+ // Check if the data directory path is valid:
+ //
+ if (string.IsNullOrWhiteSpace(localInstallationRootDirectory))
+ {
+ if (shouldLog)
+ LOGGER.LogWarning("The local data directory path is empty or null. Cannot search for local Pandoc installation.");
+ }
+ else if (!Directory.Exists(localInstallationRootDirectory))
+ {
+ if (shouldLog)
+ LOGGER.LogWarning("The local Pandoc installation directory does not exist: '{LocalInstallationRootDirectory}'.", localInstallationRootDirectory);
+ }
+ else
{
//
- // First, check the root directory itself:
+ // The directory exists, search for the pandoc executable:
//
- var rootExecutablePath = Path.Combine(localInstallationRootDirectory, executableName);
- if (File.Exists(rootExecutablePath))
- {
- LOGGER.LogInformation("Found local Pandoc installation at the root path: '{Path}'.", rootExecutablePath);
- return new(rootExecutablePath, true);
- }
+ var executableName = PandocExecutableName;
+ if (shouldLog)
+ LOGGER.LogInformation("Searching for Pandoc executable '{ExecutableName}' in: '{LocalInstallationRootDirectory}'.", executableName, localInstallationRootDirectory);
- //
- // Then, search all subdirectories:
- //
- var subdirectories = Directory.GetDirectories(localInstallationRootDirectory, "*", SearchOption.AllDirectories);
- foreach (var subdirectory in subdirectories)
+ try
{
- var pandocPath = Path.Combine(subdirectory, executableName);
- if (File.Exists(pandocPath))
+ //
+ // First, check the root directory itself:
+ //
+ var rootExecutablePath = Path.Combine(localInstallationRootDirectory, executableName);
+ if (File.Exists(rootExecutablePath))
{
- LOGGER.LogInformation("Found local Pandoc installation at: '{Path}'.", pandocPath);
- return new(pandocPath, true);
+ if (shouldLog)
+ LOGGER.LogInformation("Found local Pandoc installation at the root path: '{Path}'.", rootExecutablePath);
+
+ HAS_LOGGED_ONCE = true;
+ return new(rootExecutablePath, true);
}
+
+ //
+ // Then, search all subdirectories:
+ //
+ var subdirectories = Directory.GetDirectories(localInstallationRootDirectory, "*", SearchOption.AllDirectories);
+ foreach (var subdirectory in subdirectories)
+ {
+ var pandocPath = Path.Combine(subdirectory, executableName);
+ if (File.Exists(pandocPath))
+ {
+ if (shouldLog)
+ LOGGER.LogInformation("Found local Pandoc installation at: '{Path}'.", pandocPath);
+
+ HAS_LOGGED_ONCE = true;
+ return new(pandocPath, true);
+ }
+ }
+
+ if (shouldLog)
+ LOGGER.LogWarning("No Pandoc executable found in local installation directory or its subdirectories.");
}
+ catch (Exception ex)
+ {
+ if (shouldLog)
+ LOGGER.LogWarning(ex, "Error while searching for a local Pandoc installation in: '{LocalInstallationRootDirectory}'.", localInstallationRootDirectory);
+ }
+ }
- LOGGER.LogWarning("No Pandoc executable found in local installation directory or its subdirectories.");
- }
- catch (Exception ex)
- {
- LOGGER.LogWarning(ex, "Error while searching for a local Pandoc installation in: '{LocalInstallationRootDirectory}'.", localInstallationRootDirectory);
- }
+ //
+ // When no local installation was found, we assume that the pandoc executable is in the system PATH:
+ //
+ if (shouldLog)
+ LOGGER.LogWarning("Falling back to system PATH for the Pandoc executable: '{ExecutableName}'.", PandocExecutableName);
+
+ return new(PandocExecutableName, false);
+ }
+ finally
+ {
+ HAS_LOGGED_ONCE = true;
}
-
- //
- // When no local installation was found, we assume that the pandoc executable is in the system PATH:
- //
- LOGGER.LogWarning("Falling back to system PATH for the Pandoc executable: '{ExecutableName}'.", PandocExecutableName);
- return new(PandocExecutableName, false);
}
///