mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-01 22:07:20 +00:00
Changed the changelog and the ERI specifications to load without a request to the app server
This commit is contained in:
7 files changed
+92
-34
No files matched your search
@@ -13,7 +13,7 @@ namespace AIStudio.Assistants.ERI;
|
||||
public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
||||
{
|
||||
[Inject]
|
||||
private HttpClient HttpClient { get; set; } = null!;
|
||||
private WebRootFiles WebRootFiles { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
private IDialogService DialogService { get; init; } = null!;
|
||||
@@ -843,7 +843,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
||||
var baseDirectorySnapshot = this.baseDirectory;
|
||||
var previouslyGeneratedFilesSnapshot = this.previouslyGeneratedFiles.ToArray();
|
||||
|
||||
this.eriSpecification = await this.selectedERIVersion.ReadSpecification(this.HttpClient);
|
||||
this.eriSpecification = await this.selectedERIVersion.ReadSpecification(this.WebRootFiles);
|
||||
if (string.IsNullOrWhiteSpace(this.eriSpecification))
|
||||
{
|
||||
this.AddInputIssue(T("The ERI specification could not be loaded. Please try again later."));
|
||||
|
||||
@@ -2,26 +2,14 @@ namespace AIStudio.Assistants.ERI;
|
||||
|
||||
public static class ERIVersionExtensions
|
||||
{
|
||||
public static async Task<string> ReadSpecification(this ERIVersion version, HttpClient httpClient)
|
||||
{
|
||||
try
|
||||
{
|
||||
var url = version.SpecificationURL();
|
||||
using var response = await httpClient.GetAsync(url);
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static Task<string> ReadSpecification(this ERIVersion version, WebRootFiles webRootFiles) => webRootFiles.ReadTextAsync(version.SpecificationURL());
|
||||
|
||||
public static string SpecificationURL(this ERIVersion version)
|
||||
{
|
||||
var nameLower = version.ToString().ToLowerInvariant();
|
||||
var filename = $"{nameLower}.json";
|
||||
return $"specs/eri/{filename}";
|
||||
}
|
||||
|
||||
|
||||
public static bool WasSpecificationSelected(this ERIVersion version) => version != ERIVersion.NONE;
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace AIStudio.Components;
|
||||
public partial class Changelog : MSGComponentBase
|
||||
{
|
||||
[Inject]
|
||||
private HttpClient HttpClient { get; set; } = null!;
|
||||
private WebRootFiles WebRootFiles { get; set; } = null!;
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
@@ -23,7 +23,6 @@ public partial class Changelog : MSGComponentBase
|
||||
|
||||
private async Task ReadLogAsync()
|
||||
{
|
||||
using var response = await this.HttpClient.GetAsync($"changelog/{this.SelectedLog.Filename}");
|
||||
this.LogContent = await response.Content.ReadAsStringAsync();
|
||||
this.LogContent = await this.WebRootFiles.ReadTextAsync($"changelog/{this.SelectedLog.Filename}");
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ namespace AIStudio.Pages;
|
||||
public partial class Home : MSGComponentBase
|
||||
{
|
||||
[Inject]
|
||||
private HttpClient HttpClient { get; init; } = null!;
|
||||
private WebRootFiles WebRootFiles { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private NavigationManager NavigationManager { get; init; } = null!;
|
||||
@@ -222,8 +222,7 @@ public partial class Home : MSGComponentBase
|
||||
private async Task ReadLastChangeAsync()
|
||||
{
|
||||
var latest = Changelog.LOGS.MaxBy(n => n.Build);
|
||||
using var response = await this.HttpClient.GetAsync($"changelog/{latest.Filename}");
|
||||
this.LastChangeContent = await response.Content.ReadAsStringAsync();
|
||||
this.LastChangeContent = await this.WebRootFiles.ReadTextAsync($"changelog/{latest.Filename}");
|
||||
|
||||
await this.InvokeAsync(this.StateHasChanged);
|
||||
}
|
||||
|
||||
@@ -32,11 +32,6 @@ using MudBlazor.Services;
|
||||
|
||||
using MudExtensions.Services;
|
||||
|
||||
#if !DEBUG
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
#endif
|
||||
|
||||
namespace AIStudio;
|
||||
|
||||
internal sealed class Program
|
||||
@@ -283,10 +278,9 @@ internal sealed class Program
|
||||
options.KeepAliveInterval = TimeSpan.FromSeconds(30);
|
||||
});
|
||||
|
||||
builder.Services.AddSingleton(new HttpClient
|
||||
{
|
||||
BaseAddress = new Uri($"http://127.0.0.1:{appPort}")
|
||||
});
|
||||
// For absolute URLs only. The app reads its own files through WebRootFiles:
|
||||
builder.Services.AddSingleton(new HttpClient());
|
||||
builder.Services.AddSingleton<WebRootFiles>();
|
||||
|
||||
//
|
||||
// We listen on the IPv4 loopback address only, where the app window goes. With localhost, the
|
||||
@@ -356,10 +350,9 @@ internal sealed class Program
|
||||
app.UseStaticFiles();
|
||||
app.UseDeveloperExceptionPage();
|
||||
#else
|
||||
var fileProvider = new ManifestEmbeddedFileProvider(Assembly.GetAssembly(type: typeof(Program))!, "wwwroot");
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
FileProvider = fileProvider,
|
||||
FileProvider = app.Services.GetRequiredService<WebRootFiles>().FileProvider,
|
||||
RequestPath = string.Empty,
|
||||
});
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
|
||||
namespace AIStudio.Tools;
|
||||
|
||||
/// <summary>
|
||||
/// Reads the files below wwwroot, which every build embeds into the app.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The app reads files such as its changelogs directly instead of requesting them over HTTP from
|
||||
/// its own server. The release build serves its static files from the same provider.
|
||||
/// </remarks>
|
||||
public sealed class WebRootFiles
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the files below wwwroot.
|
||||
/// </summary>
|
||||
public IFileProvider FileProvider { get; } = new ManifestEmbeddedFileProvider(Assembly.GetAssembly(type: typeof(Program))!, "wwwroot");
|
||||
|
||||
/// <summary>
|
||||
/// Reads a text file below wwwroot.
|
||||
/// </summary>
|
||||
/// <param name="path">The path below wwwroot, such as <c>changelog/v26.10.1.md</c>.</param>
|
||||
/// <returns>The text of the file, or an empty string when there is no such file.</returns>
|
||||
public async Task<string> ReadTextAsync(string path)
|
||||
{
|
||||
var file = this.FileProvider.GetFileInfo(path);
|
||||
if (!file.Exists)
|
||||
return string.Empty;
|
||||
|
||||
await using var fileStream = file.CreateReadStream();
|
||||
using var reader = new StreamReader(fileStream);
|
||||
return await reader.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using AIStudio.Assistants.ERI;
|
||||
using AIStudio.Tools;
|
||||
|
||||
using Changelog = AIStudio.Components.Changelog;
|
||||
|
||||
namespace AIStudio.Tests.Tools.AppAccess;
|
||||
|
||||
/// <summary>
|
||||
/// Checks that the app reads the files below wwwroot which it shows itself.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The changelogs and the ERI specifications come from the files embedded into the app, not from a
|
||||
/// request to its own server. A file which is missing there would leave the changelog or the ERI
|
||||
/// assistant empty without any error.
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
public sealed class WebRootFilesTests
|
||||
{
|
||||
private static IEnumerable<string> ChangelogFiles() => Changelog.LOGS.Select(log => log.Filename);
|
||||
|
||||
private static IEnumerable<ERIVersion> SpecificationVersions() => Enum.GetValues<ERIVersion>().Where(version => version.WasSpecificationSelected());
|
||||
|
||||
[TestCaseSource(nameof(ChangelogFiles))]
|
||||
public async Task EveryChangelogCanBeRead(string filename)
|
||||
{
|
||||
var text = await new WebRootFiles().ReadTextAsync($"changelog/{filename}");
|
||||
Assert.That(text, Is.Not.Empty);
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(SpecificationVersions))]
|
||||
public async Task EveryERISpecificationCanBeRead(ERIVersion version)
|
||||
{
|
||||
var text = await version.ReadSpecification(new WebRootFiles());
|
||||
Assert.That(text, Is.Not.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task AMissingFileReadsAsEmptyText()
|
||||
{
|
||||
var text = await new WebRootFiles().ReadTextAsync("changelog/does-not-exist.md");
|
||||
Assert.That(text, Is.Empty);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user