Updated API for plugins to work with database from remote. Added PluginRepository and removed Installation Scripts

This commit is contained in:
2025-01-26 20:34:34 +02:00
parent 8b2169dc7b
commit 84b19e2069
35 changed files with 435 additions and 1056 deletions

View File

@@ -3,56 +3,54 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using DiscordBotCore.Interfaces.PluginManagement;
using DiscordBotCore.Others;
using DiscordBotCore.Plugin;
using DiscordBotCore.Repository;
using DiscordBotCore.Updater.Plugins;
namespace DiscordBotCore.Online;
public sealed class PluginManager
{
private static readonly string _LibrariesBaseFolder = "Libraries";
private readonly PluginRepository _PluginRepository;
private readonly IPluginRepository _PluginRepository;
internal InstallingPluginInformation? InstallingPluginInformation { get; private set; }
public PluginManager(PluginRepository pluginRepository)
internal PluginManager(IPluginRepository pluginRepository)
{
_PluginRepository = pluginRepository;
}
public async Task<List<PluginOnlineInfo>> GetPluginsList()
public async Task<List<OnlinePlugin>> GetPluginsList()
{
var jsonText = await _PluginRepository.JsonGetAllPlugins();
List<PluginOnlineInfo> result = await JsonManager.ConvertFromJson<List<PluginOnlineInfo>>(jsonText);
var currentOs = OperatingSystem.IsWindows() ? OSType.WINDOWS :
OperatingSystem.IsLinux() ? OSType.LINUX :
OperatingSystem.IsMacOS() ? OSType.MACOSX : OSType.NONE;
return result.FindAll(pl => (pl.SupportedOS & currentOs) != 0);
}
public async Task<PluginOnlineInfo?> GetPluginDataByName(string pluginName)
{
List<PluginOnlineInfo>? plugins = await GetPluginsList();
if (plugins is null)
var onlinePlugins = await _PluginRepository.GetAllPlugins();
if (!onlinePlugins.Any())
{
return null;
Application.Log("Failed to get all plugins from the repository", LogType.Warning);
return [];
}
PluginOnlineInfo? result = plugins.Find(pl => pl.Name.Contains(pluginName, StringComparison.CurrentCultureIgnoreCase));
if (result is null)
int os = OS.GetOperatingSystemInt();
var response = onlinePlugins.Where(plugin => plugin.OperatingSystem == os).ToList();
return response;
}
public async Task<OnlinePlugin?> GetPluginDataByName(string pluginName)
{
var plugin = await _PluginRepository.GetPluginByName(pluginName);
if (plugin == null)
{
Application.Log("Failed to get plugin from the repository", LogType.Warning);
return null;
}
return result;
return plugin;
}
public async Task RemovePluginFromDatabase(string pluginName)
private async Task RemovePluginFromDatabase(string pluginName)
{
List<PluginInfo> installedPlugins = await JsonManager.ConvertFromJson<List<PluginInfo>>(await File.ReadAllTextAsync(Application.CurrentApplication.PluginDatabase));
@@ -60,24 +58,6 @@ public sealed class PluginManager
await JsonManager.SaveToJsonFile(Application.CurrentApplication.PluginDatabase, installedPlugins);
}
public async Task ExecutePluginInstallScripts(List<OnlineScriptDependencyInfo> listOfDependencies)
{
string? console = Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("console.terminal");
if (string.IsNullOrEmpty(console))
{
return;
}
string? cmd_prefix = Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("console.cmd_prefix");
if (string.IsNullOrEmpty(cmd_prefix))
{
return;
}
foreach (var script in listOfDependencies)
await ServerCom.RunConsoleCommand(console, $"{cmd_prefix}{script.ScriptContent}");
}
public async Task AppendPluginToDatabase(PluginInfo pluginData)
{
List<PluginInfo> installedPlugins = await JsonManager.ConvertFromJson<List<PluginInfo>>(await File.ReadAllTextAsync(Application.CurrentApplication.PluginDatabase));
@@ -102,26 +82,10 @@ public sealed class PluginManager
return installedPlugins.Any(plugin => plugin.PluginName == pluginName);
}
public async Task CheckForUpdates()
{
var pluginUpdater = new PluginUpdater(this);
List<PluginInfo> installedPlugins = await GetInstalledPlugins();
foreach (var plugin in installedPlugins)
{
if (await pluginUpdater.HasUpdate(plugin.PluginName))
{
Application.CurrentApplication.Logger.Log("Updating plugin: " + plugin.PluginName, this, LogType.Info);
await pluginUpdater.UpdatePlugin(plugin.PluginName);
}
}
}
public async Task<bool> MarkPluginToUninstall(string pluginName)
{
IEnumerable<PluginInfo> installedPlugins = await GetInstalledPlugins();
IEnumerable<PluginInfo> info = installedPlugins.Where(info => info.PluginName == pluginName).AsEnumerable();
List<PluginInfo> installedPlugins = await GetInstalledPlugins();
List<PluginInfo> info = installedPlugins.Where(info => info.PluginName == pluginName).ToList();
if (!info.Any())
return false;
@@ -132,10 +96,8 @@ public sealed class PluginManager
item.IsMarkedToUninstall = true;
await AppendPluginToDatabase(item);
}
return true;
}
public async Task UninstallMarkedPlugins()
@@ -201,137 +163,54 @@ public sealed class PluginManager
return relative;
}
public async Task InstallPluginWithNoProgress(PluginOnlineInfo pluginData)
public async Task InstallPluginNoProgress(OnlinePlugin plugin)
{
InstallingPluginInformation = new InstallingPluginInformation() { PluginName = pluginData.Name };
// Calculate the total number of steps: main file + dependencies
int totalSteps = pluginData.HasFileDependencies ? pluginData.Dependencies.Count + 1 : 1;
// Each step contributes this percentage to the total progress
InstallingPluginInformation = new InstallingPluginInformation() { PluginName = plugin.PluginName };
List<OnlineDependencyInfo> dependencies = await _PluginRepository.GetDependenciesForPlugin(plugin.PluginId);
int totalSteps = dependencies.Count + 1;
float stepFraction = 100f / totalSteps;
// Tracks the current cumulative progress in percentage
float currentProgress = 0f;
InstallingPluginInformation.IsInstalling = true;
// Create a progress updater that maps the file's 0100 progress to its portion of the total progress
var progress = currentProgress;
IProgress<float> downloadProgress = new Progress<float>(fileProgress =>
{
// Map the file progress (0-100) to the total progress
InstallingPluginInformation.InstallationProgress = currentProgress + (fileProgress / 100f) * stepFraction;
InstallingPluginInformation.InstallationProgress = progress + (fileProgress / 100f) * stepFraction;
});
// Download the main plugin file and map its progress
await ServerCom.DownloadFileAsync(pluginData.DownLoadLink,
$"{Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("PluginFolder")}/{pluginData.Name}.dll",
downloadProgress
);
// Update cumulative progress after the main file
await ServerCom.DownloadFileAsync(plugin.PluginLink,
$"{Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("PluginFolder")}/{plugin.PluginName}.dll",
downloadProgress);
currentProgress += stepFraction;
// Download file dependencies if they exist
if (pluginData.HasFileDependencies)
if (dependencies.Count > 0)
{
foreach (var dependency in pluginData.Dependencies)
foreach (var dependency in dependencies)
{
string dependencyLocation =
GenerateDependencyRelativePath(pluginData.Name, dependency.DownloadLocation);
// Download dependency and map its progress
string dependencyLocation = GenerateDependencyRelativePath(plugin.PluginName, dependency.DownloadLocation);
await ServerCom.DownloadFileAsync(dependency.DownloadLink, dependencyLocation, downloadProgress);
// Update cumulative progress after each dependency
currentProgress += stepFraction;
}
}
// Run script dependencies if any (doesn't affect download progress percentage)
if (pluginData.HasScriptDependencies)
{
foreach (var scriptDependency in pluginData.ScriptDependencies)
{
string? console = Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("console.terminal");
if (string.IsNullOrEmpty(console))
{
return;
}
string? cmdPrefix = Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("console.cmd_prefix");
if (string.IsNullOrEmpty(cmdPrefix))
{
return;
}
string arguments = $"{cmdPrefix}{scriptDependency.ScriptContent}";
await ServerCom.RunConsoleCommand(console, arguments);
}
}
// Register the plugin in the database
PluginInfo pluginInfo = PluginInfo.FromOnlineInfo(pluginData);
await AppendPluginToDatabase(pluginInfo);
InstallingPluginInformation.IsInstalling = false; // Mark installation as complete
}
public async Task InstallPluginWithProgressBar(PluginOnlineInfo pluginData, IProgress<float>? installProgress)
{
installProgress?.Report(0f);
int totalSteps = pluginData.HasFileDependencies ? pluginData.Dependencies.Count + 1 : 1;
float stepProgress = 1f / totalSteps;
float currentProgress = 0f;
IProgress<float> progress = new Progress<float>((p) =>
PluginInfo pluginInfo = PluginInfo.FromOnlineInfo(plugin, dependencies);
await AppendPluginToDatabase(pluginInfo);
InstallingPluginInformation.IsInstalling = false;
}
public async Task<Tuple<Dictionary<string, string>, List<OnlineDependencyInfo>>> GatherInstallDataForPlugin(OnlinePlugin plugin)
{
List<OnlineDependencyInfo> dependencies = await _PluginRepository.GetDependenciesForPlugin(plugin.PluginId);
var downloads = new Dictionary<string, string> { { $"{Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("PluginFolder")}/{plugin.PluginName}.dll", plugin.PluginLink } };
foreach(var dependency in dependencies)
{
installProgress?.Report(currentProgress + stepProgress * p);
});
await ServerCom.DownloadFileAsync(pluginData.DownLoadLink, $"{Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("PluginFolder")}/{pluginData.Name}.dll", progress);
if (pluginData.HasFileDependencies)
foreach (var dependency in pluginData.Dependencies)
{
string dependencyLocation = GenerateDependencyRelativePath(pluginData.Name, dependency.DownloadLocation);
await ServerCom.DownloadFileAsync(dependency.DownloadLink, dependencyLocation, progress);
currentProgress += stepProgress;
}
if (pluginData.HasScriptDependencies)
{
foreach (var scriptDependency in pluginData.ScriptDependencies)
{
string? console = Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("console.terminal");
if (string.IsNullOrEmpty(console))
{
return;
}
string? cmdPrefix = Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("console.cmd_prefix");
if (string.IsNullOrEmpty(cmdPrefix))
{
return;
}
string arguments = $"{cmdPrefix}{scriptDependency.ScriptContent}";
await ServerCom.RunConsoleCommand(console, arguments);
}
string dependencyLocation = GenerateDependencyRelativePath(plugin.PluginName, dependency.DownloadLocation);
downloads.Add(dependencyLocation, dependency.DownloadLink);
}
PluginInfo pluginInfo = PluginInfo.FromOnlineInfo(pluginData);
await AppendPluginToDatabase(pluginInfo);
return (downloads, dependencies).ToTuple();
}
public async Task SetEnabledStatus(string pluginName, bool status)