Improved download speed and started using Spectre.Console package

This commit is contained in:
2023-09-18 23:13:44 +03:00
parent c9249dc71b
commit 58624f4037
7 changed files with 167 additions and 117 deletions

View File

@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using DiscordBot.Utilities; using DiscordBot.Utilities;
using PluginManager; using PluginManager;
@@ -7,6 +9,7 @@ using PluginManager.Interfaces;
using PluginManager.Loaders; using PluginManager.Loaders;
using PluginManager.Online; using PluginManager.Online;
using PluginManager.Others; using PluginManager.Others;
using Spectre.Console;
namespace DiscordBot.Bot.Actions; namespace DiscordBot.Bot.Actions;
@@ -151,11 +154,28 @@ public class Plugin : ICommandAction
} }
} }
await DownloadPlugin(manager, pluginName);
break;
}
}
private async Task RefreshPlugins()
{
Console.WriteLine("Reloading plugins list...");
await Program.internalActionManager.Execute("plugin", "load");
await Program.internalActionManager.Refresh();
Console.WriteLine("Finished reloading plugins list");
}
public async Task DownloadPlugin(PluginsManager manager, string pluginName)
{
var pluginData = await manager.GetPluginLinkByName(pluginName); var pluginData = await manager.GetPluginLinkByName(pluginName);
if (pluginData == null || pluginData.Length == 0) if (pluginData.Length == 0)
{ {
Console.WriteLine($"Plugin {pluginName} not found. Please check the spelling and try again."); Console.WriteLine($"Plugin {pluginName} not found. Please check the spelling and try again.");
break; return;
} }
var pluginType = pluginData[0]; var pluginType = pluginData[0];
@@ -163,55 +183,86 @@ public class Plugin : ICommandAction
var pluginRequirements = pluginData[2]; var pluginRequirements = pluginData[2];
Console.WriteLine("Downloading plugin..."); await AnsiConsole.Progress()
//download plugin progress bar for linux and windows terminals .Columns(new ProgressColumn[]
var spinner = new ConsoleUtilities.Spinner(); {
spinner.Start(); new TaskDescriptionColumn(),
IProgress<float> progress = new Progress<float>(p => { spinner.Message = $"Downloading {pluginName}... {Math.Round(p, 2)}% "; }); new ProgressBarColumn(),
new PercentageColumn()
})
.StartAsync(async ctx =>
{
var downloadTask = ctx.AddTask("Downloading plugin...");
IProgress<float> progress = new Progress<float>(p => { downloadTask.Value = p; });
await ServerCom.DownloadFileAsync(pluginLink, $"./Data/{pluginType}s/{pluginName}.dll", progress); await ServerCom.DownloadFileAsync(pluginLink, $"./Data/{pluginType}s/{pluginName}.dll", progress);
spinner.Stop();
Console.WriteLine(); downloadTask.Increment(100);
ctx.Refresh();
});
if (pluginRequirements == string.Empty) if (pluginRequirements == string.Empty)
{ {
Console.WriteLine("Finished installing " + pluginName + " successfully"); Console.WriteLine("Finished installing " + pluginName + " successfully");
Console.WriteLine("Reloading plugins list..."); await RefreshPlugins();
await Program.internalActionManager.Execute("plugin", "load"); return;
await Program.internalActionManager.Refresh();
Console.WriteLine("Finished reloading plugins list");
break;
} }
Console.WriteLine("Downloading plugin requirements..."); List<string> requirementsUrLs = new();
var requirementsURLs = await ServerCom.ReadTextFromURL(pluginRequirements);
foreach (var requirement in requirementsURLs) await AnsiConsole.Progress()
.Columns(new ProgressColumn[]
{ {
if (requirement.Length < 2) new TaskDescriptionColumn(),
continue; new ProgressBarColumn(),
var reqdata = requirement.Split(','); new PercentageColumn()
var url = reqdata[0]; })
var filename = reqdata[1]; .StartAsync(async ctx =>
{
var gatherInformationTask = ctx.AddTask("Gathering info...");
gatherInformationTask.IsIndeterminate = true;
requirementsUrLs = await ServerCom.ReadTextFromURL(pluginRequirements);
await Task.Delay(2000);
gatherInformationTask.Increment(100);
});
Console.WriteLine($"Downloading {filename}... "); await AnsiConsole.Progress()
progress = new Progress<float>(p => { spinner.Message = $"Downloading {filename}... {Math.Round(p, 2)}% "; }); .Columns(new ProgressColumn[]
spinner.Start(); {
await ServerCom.DownloadFileAsync(url, $"./{filename}", progress); new TaskDescriptionColumn(),
spinner.Stop(); new ProgressBarColumn(),
progress.Report(1); new PercentageColumn()
await Task.Delay(1000); })
Console.WriteLine("Downloaded " + filename + " successfully"); .StartAsync(async ctx =>
{
List<Tuple<ProgressTask, IProgress<float>, Task>> downloadTasks = new();
foreach (var info in requirementsUrLs)
{
if (info.Length < 2) continue;
string[] data = info.Split(',');
string url = data[0];
string fileName = data[1];
var task = ctx.AddTask($"Downloading {fileName}...");
IProgress<float> progress = new Progress<float>(p =>
{
task.Value = p;
});
var downloadTask = ServerCom.DownloadFileAsync(url, $"./{fileName}", progress);
downloadTasks.Add(new Tuple<ProgressTask, IProgress<float>, Task>(task, progress, downloadTask));
} }
Console.WriteLine("Finished installing " + pluginName + " successfully"); foreach (var task in downloadTasks)
{
await task.Item3;
}
Console.WriteLine("Reloading plugins list..."); });
await Program.internalActionManager.Execute("plugin", "load", "-q");
await Program.internalActionManager.Refresh();
Console.WriteLine("Finished reloading plugins list"); await RefreshPlugins();
break;
}
} }
} }

View File

@@ -35,6 +35,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Discord.Net" Version="3.11.0"/> <PackageReference Include="Discord.Net" Version="3.11.0"/>
<PackageReference Include="pythonnet" Version="3.0.1" /> <PackageReference Include="pythonnet" Version="3.0.1" />
<PackageReference Include="Spectre.Console" Version="0.47.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\PluginManager\PluginManager.csproj"/> <ProjectReference Include="..\PluginManager\PluginManager.csproj"/>

View File

@@ -8,6 +8,18 @@ public class Entry
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
#if DEBUG
if (args.Length == 1 && args[0] == "/purge_plugins")
{
foreach (var plugin in Directory.GetFiles("./Data/Plugins", "*.dll", SearchOption.AllDirectories))
{
File.Delete(plugin);
}
}
#endif
var currentDomain = AppDomain.CurrentDomain; var currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += LoadFromSameFolder; currentDomain.AssemblyResolve += LoadFromSameFolder;

View File

@@ -1,8 +1,6 @@
using System; using System;
using System.IO;
using System.Threading.Tasks;
using PluginManager; using PluginManager;
using PluginManager.Online; using Spectre.Console;
namespace DiscordBot; namespace DiscordBot;
@@ -10,36 +8,21 @@ public static class Installer
{ {
public static void GenerateStartupConfig() public static void GenerateStartupConfig()
{ {
Console.WriteLine("Welcome to the SethBot installer !"); AnsiConsole.WriteLine("Welcome to the [bold]SethBot[/] installer !");
Console.WriteLine("First, we need to configure the bot. Don't worry, it will be quick !"); AnsiConsole.WriteLine("First, we need to configure the bot. Don't worry, it will be quick !");
Console.WriteLine("The following information will be stored in the config.json file in the ./Data/Resources folder. You can change it later from there.");
Console.WriteLine("The bot token is required to run the bot. You can get it from the Discord Developer Portal. (https://discord.com/developers/applications)"); var token = AnsiConsole.Ask<string>("Please enter the bot token :");
var prefix = AnsiConsole.Ask<string>("Please enter the bot prefix :");
var serverId = AnsiConsole.Ask<string>("Please enter the Server ID :");
if (!Config.AppSettings.ContainsKey("token"))
{
Console.WriteLine("Please enter the bot token :");
var token = Console.ReadLine();
Config.AppSettings.Add("token", token); Config.AppSettings.Add("token", token);
}
if (!Config.AppSettings.ContainsKey("prefix"))
{
Console.WriteLine("Please enter the bot prefix :");
var prefix = Console.ReadLine();
Config.AppSettings.Add("prefix", prefix); Config.AppSettings.Add("prefix", prefix);
}
if (!Config.AppSettings.ContainsKey("ServerID"))
{
Console.WriteLine("Please enter the Server ID :");
var serverId = Console.ReadLine();
Config.AppSettings.Add("ServerID", serverId); Config.AppSettings.Add("ServerID", serverId);
}
Config.Logger.Log("Config Saved", "Installer", isInternal: true);
Config.AppSettings.SaveToFile(); Config.AppSettings.SaveToFile();
Console.WriteLine("Config saved !"); AnsiConsole.MarkupLine("[bold]Config saved ![/]");
Config.Logger.Log("Config Saved", "Installer", isInternal: true);
} }
} }

View File

@@ -1,13 +1,10 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using DiscordBot.Utilities; using DiscordBot.Utilities;
using PluginManager.Bot; using PluginManager.Bot;
using PluginManager.Online;
using PluginManager.Online.Helpers;
using PluginManager.Others; using PluginManager.Others;
using PluginManager.Others.Actions; using PluginManager.Others.Actions;
using static PluginManager.Config; using static PluginManager.Config;
@@ -137,6 +134,7 @@ public class Program
Console.WriteLine($"[{type.ToString()}] {message}"); Console.WriteLine($"[{type.ToString()}] {message}");
Console.ResetColor(); Console.ResetColor();
}; };
AppSettings["Version"] = Assembly.GetExecutingAssembly().GetName().Version.ToString(); AppSettings["Version"] = Assembly.GetExecutingAssembly().GetName().Version.ToString();
} }
} }

View File

@@ -35,21 +35,25 @@ internal static class OnlineFunctions
if (progress == null || !contentLength.HasValue) if (progress == null || !contentLength.HasValue)
{ {
await download.CopyToAsync(destination, cancellation); await download.CopyToAsync(destination, cancellation);
if(!contentLength.HasValue)
progress?.Report(100f);
return; return;
} }
// Convert absolute progress (bytes downloaded) into relative progress (0% - 100%) // Convert absolute progress (bytes downloaded) into relative progress (0% - 100%)
var relativeProgress = new Progress<long>(totalBytes => // total ... 100%
// downloaded ... x%
// x = downloaded * 100 / total => x = downloaded / total * 100
var relativeProgress = new Progress<long>(totalBytesDownloaded =>
{ {
progress?.Report((float)totalBytes / contentLength.Value * progress?.Report(totalBytesDownloaded / (float)contentLength.Value * 100);
100); downloadedBytes?.Report(totalBytesDownloaded);
downloadedBytes?.Report(totalBytes);
} }
); );
// Use extension method to report progress while downloading // Use extension method to report progress while downloading
await download.CopyToOtherStreamAsync(destination, bufferSize, relativeProgress, cancellation); await download.CopyToOtherStreamAsync(destination, bufferSize, relativeProgress, cancellation);
progress.Report(100); progress.Report(100f);
} }
} }
} }

View File

@@ -48,4 +48,5 @@ public static class ServerCom
{ {
await DownloadFileAsync(URl, location, progress, null); await DownloadFileAsync(URl, location, progress, null);
} }
} }