Linked Plugin List and Plugin Install endpoints between web and console

This commit is contained in:
2024-12-15 22:49:45 +02:00
parent a12aa66660
commit 424bf2196f
13 changed files with 180 additions and 19 deletions

View File

@@ -10,7 +10,7 @@ namespace DiscordBotCore.API.Endpoints.PluginManagement;
public class PluginInstallEndpoint : IEndpoint
{
public string Path => "/api/plugin/install";
public EndpointType HttpMethod => EndpointType.Put;
public EndpointType HttpMethod => EndpointType.Post;
public async Task<ApiResponse> HandleRequest(string? jsonRequest)
{
Dictionary<string, string> jsonDict = await JsonManager.ConvertFromJson<Dictionary<string, string>>(jsonRequest);

View File

@@ -13,7 +13,11 @@ public class PluginListEndpoint : IEndpoint
{
var onlineInfos = await Application.CurrentApplication.PluginManager.GetPluginsList();
var response = await JsonManager.ConvertToJson(onlineInfos, [nameof(PluginOnlineInfo.Name), nameof(PluginOnlineInfo.Author), nameof(PluginOnlineInfo.Version)]);
var response = await JsonManager.ConvertToJson(onlineInfos, [
nameof(PluginOnlineInfo.Name),
nameof(PluginOnlineInfo.Author),
nameof(PluginOnlineInfo.Description)
]);
return ApiResponse.From(response, true);
}

View File

@@ -21,7 +21,7 @@ public sealed class PluginManager
_PluginRepository = pluginRepository;
}
public async Task<List<PluginOnlineInfo>?> GetPluginsList()
public async Task<List<PluginOnlineInfo>> GetPluginsList()
{
var jsonText = await _PluginRepository.JsonGetAllPlugins();
List<PluginOnlineInfo> result = await JsonManager.ConvertFromJson<List<PluginOnlineInfo>>(jsonText);

View File

@@ -2,12 +2,12 @@
<RadzenCard>
<RadzenDataGrid Data="PluginModels" AllowPaging="true" AllowColumnResize="true" PageSize="5">
<Columns>
<RadzenDataGridColumn Property="@nameof(PluginModel.PluginName)" Title="Plugin Name"/>
<RadzenDataGridColumn Property="@nameof(PluginModel.PluginAuthor)" Title="Author"/>
<RadzenDataGridColumn Property="@nameof(PluginModel.PluginDescription)" Title="Version"/>
<RadzenDataGridColumn Property="@nameof(PluginModel.Name)" Title="Plugin Name"/>
<RadzenDataGridColumn Property="@nameof(PluginModel.Author)" Title="Author"/>
<RadzenDataGridColumn Property="@nameof(PluginModel.Description)" Title="Version"/>
<RadzenDataGridColumn Title="Download">
<Template Context="item">
<RadzenButton Click="() => OnPluginDownloadClick!(item.PluginName)" Text="Download"/>
<RadzenButton Click="() => OnPluginDownloadClick!(item.Name)" Text="Download"/>
</Template>
</RadzenDataGridColumn>
</Columns>

View File

@@ -1,24 +1,48 @@
@page "/plugins"
@using DiscordBotWebUI.Components.CustomTags
@using DiscordBotWebUI.Models
@using DiscordBotWebUI.ServerCommunication
<Marketplace PluginModels="_PluginModels" OnPluginDownloadClick="OnModelSelected"/>
@code {
private List<PluginModel> _PluginModels;
[Inject]
public ApiHandler ApiHandler { get; set; }
private async void OnModelSelected(string itemName)
{
Console.WriteLine(itemName);
}
ApiResponse response = await ApiHandler.PostAsync("/api/plugin/install", new Dictionary<string, string>()
{
{"pluginName", itemName}
});
if(!response.Success)
{
Console.WriteLine(response.Message);
return;
}
Console.WriteLine("Plugin installed");
}
protected override async Task OnInitializedAsync()
{
_PluginModels = new List<PluginModel>()
ApiResponse response = await ApiHandler.GetAsync("/api/plugin/list/online");
if (!response.Success)
{
new PluginModel() {PluginName = "Test", PluginAuthor = "Andrei", PluginDescription = "Interesting plugin"}
};
return;
}
string jsonStr = response.Message;
var result = await JsonManager.ConvertFromJson<List<PluginModel>>(jsonStr);
if (result != null)
{
_PluginModels = result;
}
}
}

View File

@@ -38,8 +38,4 @@
<_ContentIncludedByDefault Remove="Components\Pages\Setup\SetupWizard.razor" />
</ItemGroup>
<ItemGroup>
<Folder Include="ServerCommunication\" />
</ItemGroup>
</Project>

View File

@@ -1,8 +1,18 @@
using System.Text.Json.Serialization;
namespace DiscordBotWebUI.Models;
public class PluginModel
{
public string PluginName { get; set; }
public string PluginAuthor { get; set; }
public string PluginDescription { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public string Description { get; set; }
[JsonConstructor]
public PluginModel(string name, string author, string description)
{
Name = name;
Author = author;
Description = description;
}
}

View File

@@ -1,4 +1,6 @@
using DiscordBotWebUI.Components;
using DiscordBotWebUI.ServerCommunication;
using DiscordBotWebUI.ServerCommunication.ApiSettings;
using Radzen;
@@ -33,6 +35,9 @@ builder.Services.AddRadzenCookieThemeService(options =>
options.Duration = TimeSpan.FromDays(365); // The duration of the cookie
});
builder.Services.AddSingleton<IApiSettings>(new ApiSettings("http://localhost", "5000"));
builder.Services.AddSingleton<ApiHandler>();
builder.Services.AddRadzenComponents();
var app = builder.Build();

View File

@@ -0,0 +1,55 @@
using System.Net.Http.Headers;
using System.Text;
using DiscordBotWebUI.ServerCommunication.ApiSettings;
namespace DiscordBotWebUI.ServerCommunication;
public class ApiHandler
{
private IApiSettings ApiSettings { get; }
public ApiHandler(IApiSettings apiSettings)
{
ApiSettings = apiSettings;
}
public async Task<ApiResponse> GetAsync(string endpoint)
{
using HttpClient client = new HttpClient();
client.BaseAddress = new Uri($"{ApiSettings.BaseUrl}:{ApiSettings.BasePort}");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(endpoint);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
return await JsonManager.ConvertFromJson<ApiResponse>(content);
}
return new ApiResponse("Failed to get response", false);
}
public async Task<ApiResponse> PostAsync(string endpoint, Dictionary<string, string> jsonValues)
{
if (jsonValues.Count <= 0)
{
return new ApiResponse("No values to post", false);
}
string jsonString = await JsonManager.ConvertToJsonString(jsonValues);
return await PostAsync(endpoint, jsonString);
}
public async Task<ApiResponse> PostAsync(string endpoint, string json)
{
using HttpClient client = new HttpClient();
client.BaseAddress = new Uri($"{ApiSettings.BaseUrl}:{ApiSettings.BasePort}");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(endpoint, content);
if (response.IsSuccessStatusCode)
{
string responseContent = await response.Content.ReadAsStringAsync();
return await JsonManager.ConvertFromJson<ApiResponse>(responseContent);
}
return new ApiResponse("Failed to get response", false);
}
}

View File

@@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
namespace DiscordBotWebUI.ServerCommunication;
public class ApiResponse
{
public bool Success { get; }
public string Message { get; }
[JsonConstructor]
public ApiResponse(string message, bool success)
{
Message = message;
Success = success;
}
}

View File

@@ -0,0 +1,13 @@
namespace DiscordBotWebUI.ServerCommunication.ApiSettings;
public class ApiSettings : IApiSettings
{
public string BaseUrl { get; }
public string BasePort { get; }
public ApiSettings(string baseUrl, string basePort)
{
BaseUrl = baseUrl;
BasePort = basePort;
}
}

View File

@@ -0,0 +1,7 @@
namespace DiscordBotWebUI.ServerCommunication.ApiSettings;
public interface IApiSettings
{
public string BaseUrl { get; }
public string BasePort { get; }
}

View File

@@ -0,0 +1,31 @@
using System.Text;
using System.Text.Json;
namespace DiscordBotWebUI.ServerCommunication;
public class JsonManager
{
public static async Task<T?> ConvertFromJson<T>(string jsonString)
{
if (string.IsNullOrWhiteSpace(jsonString))
throw new ArgumentException("JSON string cannot be null or empty.", nameof(jsonString));
using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
try
{
return await JsonSerializer.DeserializeAsync<T>(stream);
}
catch (JsonException ex)
{
throw new InvalidOperationException("Failed to deserialize JSON.", ex);
}
}
public static async Task<string> ConvertToJsonString<T>(T data)
{
using MemoryStream stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, data);
return Encoding.UTF8.GetString(stream.ToArray());
}
}