moved diagnose to own controller, added advanced diagnose building, ui for advanced still missing

This commit is contained in:
mxritzdev
2025-05-13 17:22:47 +02:00
parent 0743bad93c
commit 609a0297d5
6 changed files with 155 additions and 35 deletions

View File

@@ -0,0 +1,44 @@
using Microsoft.AspNetCore.Mvc;
using MoonCore.Attributes;
using Moonlight.ApiServer.Services;
using Moonlight.Shared.Http.Requests.Admin.Sys;
using Moonlight.Shared.Http.Responses.Admin.Sys;
using Moonlight.Shared.Misc;
namespace Moonlight.ApiServer.Http.Controllers.Admin.Sys;
[ApiController]
[Route("api/admin/system/diagnose")]
public class DiagnoseController : Controller
{
private readonly DiagnoseService DiagnoseService;
public DiagnoseController(DiagnoseService diagnoseService)
{
DiagnoseService = diagnoseService;
}
[HttpPost]
[RequirePermission("admin.system.diagnose")]
public async Task<IActionResult> Diagnose([FromBody] string[]? requestedDiagnoseProviders = null)
{
var stream = new MemoryStream();
await DiagnoseService.GenerateDiagnose(stream, requestedDiagnoseProviders);
return File(stream, "application/zip", "diagnose.zip");
}
[HttpGet("available")]
[RequirePermission("admin.system.diagnose")]
public async Task<SystemAvailableDiagnoseProviderResponse> GetAvailable()
{
var availableProviders = await DiagnoseService.GetAvailable();
return new SystemAvailableDiagnoseProviderResponse()
{
AvailableProviders = availableProviders
};
}
}

View File

@@ -18,13 +18,12 @@ public class SystemController : Controller
{ {
private readonly ApplicationService ApplicationService; private readonly ApplicationService ApplicationService;
private readonly IEnumerable<IDiagnoseProvider> DiagnoseProviders; private readonly IEnumerable<IDiagnoseProvider> DiagnoseProviders;
private readonly DiagnoseService DiagnoseService;
public SystemController(ApplicationService applicationService, IEnumerable<IDiagnoseProvider> diagnoseProviders, DiagnoseService diagnoseService)
public SystemController(ApplicationService applicationService, IEnumerable<IDiagnoseProvider> diagnoseProviders)
{ {
ApplicationService = applicationService; ApplicationService = applicationService;
DiagnoseProviders = diagnoseProviders; DiagnoseProviders = diagnoseProviders;
DiagnoseService = diagnoseService;
} }
[HttpGet] [HttpGet]
@@ -46,15 +45,4 @@ public class SystemController : Controller
{ {
await ApplicationService.Shutdown(); await ApplicationService.Shutdown();
} }
[HttpGet("diagnose")]
[RequirePermission("admin.system.diagnose")]
public async Task<IActionResult> Diagnose()
{
var stream = new MemoryStream();
await DiagnoseService.GenerateDiagnose(stream);
return File(stream, "application/zip", "diagnose.zip");
}
} }

View File

@@ -3,13 +3,14 @@ using Moonlight.ApiServer.Interfaces;
using Moonlight.ApiServer.Models.Diagnose; using Moonlight.ApiServer.Models.Diagnose;
using System.IO.Compression; using System.IO.Compression;
using MoonCore.Attributes; using MoonCore.Attributes;
using Moonlight.Shared.Http.Responses.Admin.Sys;
using Moonlight.Shared.Misc;
namespace Moonlight.ApiServer.Services; namespace Moonlight.ApiServer.Services;
[Scoped] [Scoped]
public class DiagnoseService public class DiagnoseService
{ {
private readonly IEnumerable<IDiagnoseProvider> DiagnoseProviders; private readonly IEnumerable<IDiagnoseProvider> DiagnoseProviders;
public DiagnoseService(IEnumerable<IDiagnoseProvider> diagnoseProviders) public DiagnoseService(IEnumerable<IDiagnoseProvider> diagnoseProviders)
@@ -17,9 +18,51 @@ public class DiagnoseService
DiagnoseProviders = diagnoseProviders; DiagnoseProviders = diagnoseProviders;
} }
public async Task GenerateDiagnose(Stream outputStream) public async Task<DiagnoseProvider[]> GetAvailable()
{ {
var tasks = DiagnoseProviders var availableProviders = new List<DiagnoseProvider>();
foreach (var diagnoseProvider in DiagnoseProviders)
{
var name = diagnoseProvider.GetType().Name;
var type = diagnoseProvider.GetType().FullName;
// The type name is null if the type is a generic type, unlikely, but still could happen
if (type != null)
availableProviders.Add(new DiagnoseProvider()
{
Name = name,
Type = type
});
}
return availableProviders.ToArray();
}
public async Task GenerateDiagnose(Stream outputStream, string[]? requestedProviders)
{
List<IDiagnoseProvider> providers;
if (requestedProviders != null && requestedProviders.Length > 0)
{
providers = new List<IDiagnoseProvider>();
foreach (var requestedProvider in requestedProviders)
{
var provider = DiagnoseProviders.FirstOrDefault(x => x.GetType().FullName == requestedProvider);
if (provider != null)
providers.Add(provider);
}
}
else
{
providers = DiagnoseProviders.ToList();
}
var tasks = providers
.SelectMany(x => x.GetFiles()) .SelectMany(x => x.GetFiles())
.Select(async x => await ProcessDiagnoseEntry(null, x)); .Select(async x => await ProcessDiagnoseEntry(null, x));
@@ -31,7 +74,6 @@ public class DiagnoseService
try try
{ {
using (var zip = new ZipArchive(outputStream, ZipArchiveMode.Create, leaveOpen: true)) using (var zip = new ZipArchive(outputStream, ZipArchiveMode.Create, leaveOpen: true))
{ {
foreach (var kv in fileEntries) foreach (var kv in fileEntries)
@@ -92,7 +134,7 @@ public class DiagnoseService
{ {
var result = new Dictionary<string, byte[]>(); var result = new Dictionary<string, byte[]>();
var directoryPath = path != null ? string.Join("/", path, directory.Name) : directory.Name; var directoryPath = path != null ? string.Join("/", path, directory.Name) : directory.Name;
foreach (var entry in directory.Children) foreach (var entry in directory.Children)
{ {
@@ -109,8 +151,7 @@ public class DiagnoseService
private async Task<KeyValuePair<string, byte[]>> ProcessDiagnoseFile(string? path, DiagnoseFile file) private async Task<KeyValuePair<string, byte[]>> ProcessDiagnoseFile(string? path, DiagnoseFile file)
{ {
var filePath = path != null ? string.Join("/", path, file.Name) : file.Name;
var filePath = path != null ? string.Join("/", path, file.Name) : file.Name;
var bytes = file.GetContent(); var bytes = file.GetContent();

View File

@@ -2,6 +2,8 @@
@using MoonCore.Attributes @using MoonCore.Attributes
@using MoonCore.Helpers @using MoonCore.Helpers
@using Moonlight.Shared.Http.Responses.Admin.Sys
@using Moonlight.Shared.Misc
@attribute [RequirePermission("admin.system.diagnose")] @attribute [RequirePermission("admin.system.diagnose")]
@@ -25,22 +27,51 @@
The report includes useful information about your system, plugins, and environment, making it easier to identify problems or share with support. The report includes useful information about your system, plugins, and environment, making it easier to identify problems or share with support.
</p> </p>
<WButton OnClick="GenerateFrontend" CssClasses="btn btn-primary mt-5">Generate diagnose</WButton> <WButton OnClick="GenerateDiagnose" CssClasses="btn btn-primary my-5">Generate diagnose</WButton>
@* <div> *@
@* <a class="text-primary cursor-pointer" @onclick:preventDefault @onclick="ToggleDropDown">Advanced <i class="icon-chevron-@(DropdownOpen ? "up" : "down")"></i></a> *@
@* *@
@* <div class="@(DropdownOpen ? "" : "hidden")"> *@
@* *@
@* *@
@* <LazyLoader Load="Load"> *@
@* *@
@* @for (int i = 0; i < AvailableProviders.Length; i++) *@
@* { *@
@* <div> *@
@* <input type="checkbox" @bind="@CheckedProviders[i]"/> @Formatter.ConvertCamelCaseToSpaces(AvailableProviders[i].Name) *@
@* </div> *@
@* } *@
@* *@
@* </LazyLoader> *@
@* *@
@* *@
@* </div> *@
@* *@
@* </div> *@
</div> </div>
</div> </div>
</div> </div>
@code @code
{ {
private async Task GenerateFrontend(WButton _)
private async Task GenerateDiagnose(WButton _)
{ {
var stream = await ApiClient.GetStream("api/admin/system/diagnose"); var stream = await ApiClient.PostStream("api/admin/system/diagnose");
await DownloadService.DownloadStream("diagnose.zip", stream); await DownloadService.DownloadStream("diagnose.zip", stream);
} }
}
@code { private async Task Load(LazyLoader arg)
{
// AvailableProviders = (await ApiClient.GetJson<SystemAvailableDiagnoseProviderResponse>("api/admin/system/diagnose/available")).AvailableProviders;
}
} }

View File

@@ -0,0 +1,8 @@
using Moonlight.Shared.Misc;
namespace Moonlight.Shared.Http.Responses.Admin.Sys;
public class SystemAvailableDiagnoseProviderResponse
{
public DiagnoseProvider[] AvailableProviders { get; set; }= [];
}

View File

@@ -0,0 +1,8 @@
namespace Moonlight.Shared.Misc;
public class DiagnoseProvider
{
public string Name { get; set; }
public string Type { get; set; }
}