Updated the WebUI by creating new page for viewing the installed plugins

This commit is contained in:
2025-04-05 17:02:22 +03:00
parent a4afb28f36
commit 8aaefac706
9 changed files with 117 additions and 34 deletions

View File

@@ -39,7 +39,7 @@ public class LocalPlugin
public static LocalPlugin FromOnlineInfo(OnlinePlugin plugin, List<OnlineDependencyInfo> dependencies, string downloadLocation)
{
LocalPlugin localPlugin = new LocalPlugin(
plugin.PluginName, plugin.LatestVersion, downloadLocation,
plugin.Name, plugin.Version, downloadLocation,
dependencies.Where(dependency => dependency.IsExecutable)
.ToDictionary(dependency => dependency.DependencyName, dependency => dependency.DownloadLocation)
);

View File

@@ -4,24 +4,26 @@ namespace DiscordBotCore.PluginManagement.Models;
public class OnlinePlugin
{
public int PluginId { get; private set; }
public string PluginName { get; private set; }
public string PluginDescription { get; private set; }
public string LatestVersion { get; private set; }
public string PluginAuthor { get; private set; }
public string PluginLink { get; private set; }
public int Id { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public string Version { get; private set; }
public string Author { get; private set; }
public string DownloadLink { get; private set; }
public int OperatingSystem { get; private set; }
public bool IsApproved { get; private set; }
[JsonConstructor]
public OnlinePlugin(int pluginId, string pluginName, string pluginDescription, string latestVersion,
string pluginAuthor, string pluginLink, int operatingSystem)
public OnlinePlugin(int id, string name, string description, string version,
string author, string downloadLink, int operatingSystem, bool isApproved)
{
PluginId = pluginId;
PluginName = pluginName;
PluginDescription = pluginDescription;
LatestVersion = latestVersion;
PluginAuthor = pluginAuthor;
PluginLink = pluginLink;
Id = id;
Name = name;
Description = description;
Version = version;
Author = author;
DownloadLink = downloadLink;
OperatingSystem = operatingSystem;
IsApproved = isApproved;
}
}

View File

@@ -88,7 +88,14 @@ public sealed class PluginManager : IPluginManager
string? pluginDatabaseFile = _Configuration.Get<string>("PluginDatabase");
if (pluginDatabaseFile is null)
{
throw new Exception("Plugin database file not found");
_Logger.Log("Plugin database file path is not present in the config file", this, LogType.Warning);
return [];
}
if (!File.Exists(pluginDatabaseFile))
{
_Logger.Log("Plugin database file not found", this, LogType.Warning);
return [];
}
return await JsonManager.ConvertFromJson<List<LocalPlugin>>(await File.ReadAllTextAsync(pluginDatabaseFile));
@@ -189,31 +196,31 @@ public sealed class PluginManager : IPluginManager
public async Task InstallPlugin(OnlinePlugin plugin, IProgress<InstallationProgressIndicator> progress)
{
List<OnlineDependencyInfo> dependencies = await _PluginRepository.GetDependenciesForPlugin(plugin.PluginId);
List<OnlineDependencyInfo> dependencies = await _PluginRepository.GetDependenciesForPlugin(plugin.Id);
string? pluginsFolder = _Configuration.Get<string>("PluginFolder");
if (pluginsFolder is null)
{
throw new Exception("Plugin folder not found");
}
string downloadLocation = $"{pluginsFolder}/{plugin.PluginName}.dll";
string downloadLocation = $"{pluginsFolder}/{plugin.Name}.dll";
InstallationProgressIndicator installationProgressIndicator = new InstallationProgressIndicator();
IProgress<float> downloadProgress = new Progress<float>(fileProgress =>
{
installationProgressIndicator.SetProgress(plugin.PluginName, fileProgress);
installationProgressIndicator.SetProgress(plugin.Name, fileProgress);
progress.Report(installationProgressIndicator);
});
FileDownloader fileDownloader = new FileDownloader(plugin.PluginLink, downloadLocation);
FileDownloader fileDownloader = new FileDownloader(plugin.DownloadLink, downloadLocation);
await fileDownloader.DownloadFile(downloadProgress.Report);
ParallelDownloadExecutor executor = new ParallelDownloadExecutor();
foreach (var dependency in dependencies)
{
string dependencyLocation = GenerateDependencyRelativePath(plugin.PluginName, dependency.DownloadLocation);
string dependencyLocation = GenerateDependencyRelativePath(plugin.Name, dependency.DownloadLocation);
Action<float> dependencyProgress = new Action<float>(fileProgress =>
{
installationProgressIndicator.SetProgress(dependency.DependencyName, fileProgress);
@@ -228,17 +235,17 @@ public sealed class PluginManager : IPluginManager
public async Task<Tuple<Dictionary<string, string>, List<OnlineDependencyInfo>>> GatherInstallDataForPlugin(OnlinePlugin plugin)
{
List<OnlineDependencyInfo> dependencies = await _PluginRepository.GetDependenciesForPlugin(plugin.PluginId);
List<OnlineDependencyInfo> dependencies = await _PluginRepository.GetDependenciesForPlugin(plugin.Id);
string? pluginsFolder = _Configuration.Get<string>("PluginFolder");
if (pluginsFolder is null)
{
throw new Exception("Plugin folder not found");
}
string downloadLocation = $"{pluginsFolder}/{plugin.PluginName}.dll";
var downloads = new Dictionary<string, string> { { downloadLocation, plugin.PluginLink } };
string downloadLocation = $"{pluginsFolder}/{plugin.Name}.dll";
var downloads = new Dictionary<string, string> { { downloadLocation, plugin.DownloadLink } };
foreach(var dependency in dependencies)
{
string dependencyLocation = GenerateDependencyRelativePath(plugin.PluginName, dependency.DownloadLocation);
string dependencyLocation = GenerateDependencyRelativePath(plugin.Name, dependency.DownloadLocation);
downloads.Add(dependencyLocation, dependency.DownloadLink);
}

View File

@@ -27,12 +27,43 @@ public class PluginsController : Controller
foreach (var plugin in plugins)
{
OnlinePluginViewModel pluginViewModel = new OnlinePluginViewModel();
pluginViewModel.Name = plugin.PluginName;
pluginViewModel.Description = plugin.PluginDescription;
pluginViewModel.Author = plugin.PluginAuthor;
pluginViewModel.Version = plugin.LatestVersion;
pluginViewModel.DownloadUrl = plugin.PluginLink;
pluginViewModel.Name = plugin.Name;
pluginViewModel.Description = plugin.Description;
pluginViewModel.Author = plugin.Author;
pluginViewModel.Version = plugin.Version;
pluginViewModel.DownloadUrl = plugin.DownloadLink;
pluginViewModels.Add(pluginViewModel);
}
return View(pluginViewModels);
}
[HttpGet]
public async Task<IActionResult> InstalledPlugins()
{
_logger.Log("Getting plugins page", this);
var plugins = await _pluginManager.GetInstalledPlugins();
_logger.Log($"{plugins.Count} Plugins loaded", this);
List<InstalledPluginViewModel> pluginViewModels = new List<InstalledPluginViewModel>();
foreach (var plugin in plugins)
{
InstalledPluginViewModel pluginViewModel = new InstalledPluginViewModel();
pluginViewModel.Name = plugin.PluginName;
pluginViewModel.Version = plugin.PluginVersion;
pluginViewModel.IsOfflineAdded = plugin.IsOfflineAdded;
pluginViewModels.Add(pluginViewModel);
}
return View(pluginViewModels);
}
[HttpPost]
public async Task<IActionResult> DeletePlugin(string pluginName)
{
_logger.Log($"Deleting plugin {pluginName}", this);
//TODO: Implement delete plugin
return RedirectToAction("InstalledPlugins");
}
}

View File

@@ -23,7 +23,7 @@ public class SettingsController : Controller
{
Token = _configuration.Get<string>("token", string.Empty),
Prefix = _configuration.Get<string>("prefix", string.Empty),
ServerIds = _configuration.Get<List<ulong>>("serverIds", new List<ulong>()),
ServerIds = _configuration.Get<List<ulong>>("ServerIds", new List<ulong>()),
};
return View(model);

View File

@@ -0,0 +1,8 @@
namespace WebUI.Models;
public class InstalledPluginViewModel
{
public string Name { get; set; }
public string Version { get; set; }
public bool IsOfflineAdded { get; set; }
}

View File

@@ -136,7 +136,7 @@ builder.Services.AddSingleton<IPluginManager>(sp =>
IConfiguration configuration = sp.GetRequiredService<IConfiguration>();
Directory.CreateDirectory(configuration.Get<string>("PluginFolder", defaultPluginFolder));
string pluginDatabaseFile = configuration.Get<string>("PluginDatabaseFile", defaultPluginDatabaseFile);
string pluginDatabaseFile = configuration.Get<string>("PluginDatabase", defaultPluginDatabaseFile);
Directory.CreateDirectory(new FileInfo(pluginDatabaseFile).DirectoryName);
IPluginManager pluginManager = new PluginManager(pluginRepository, logger, configuration);

View File

@@ -0,0 +1,32 @@
@model List<InstalledPluginViewModel>
@{
ViewData["Title"] = "Installed Plugins";
}
<h2>@ViewData["Title"]</h2>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Version</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var plugin in Model)
{
<tr>
<td>@plugin.Name</td>
<td>@plugin.Version</td>
<td>
<form method="post" asp-action="DeletePlugin" asp-route-pluginName="@plugin.Name">
<button type="submit" class="btn btn-danger btn-sm">Delete</button>
</form>
<button type="button" class="btn btn-info btn-sm" data-toggle="modal" data-target="#pluginDetailsModal-@plugin.Name">Details</button>
</td>
</tr>
}
</tbody>
</table>

View File

@@ -20,10 +20,13 @@
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Settings" asp-action="Index">Settings</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Plugins" asp-action="OnlinePlugins">View Online Repository</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Plugins" asp-action="InstalledPlugins">View Installed Plugins</a>
</li>
</ul>
</div>