OF-DL/Cajetan.OF-DL/ProgramCajetan.cs

192 lines
7.0 KiB
C#

using System.Diagnostics;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
AnsiConsole.Write(new FigletText("Welcome to OF-DL").Color(Color.Red));
await RunAsync(args);
static async Task RunAsync(string[] args)
{
ServiceCollection services = await ConfigureServices(args);
ServiceProvider serviceProvider = services.BuildServiceProvider();
ExitIfOtherProcess(serviceProvider);
Worker worker = serviceProvider.GetRequiredService<Worker>();
await worker.RunAsync();
}
static async Task<ServiceCollection> ConfigureServices(string[] args)
{
// Set up dependency injection with LoggingService and ConfigService
ServiceCollection services = new();
services.AddSingleton<ILoggingService, CajetanLoggingService>();
services.AddSingleton<IConfigService, ConfigService>();
services.AddSingleton(new ExitHelper(new SpectreDownloadEventHandler()));
ServiceProvider tempServiceProvider = services.BuildServiceProvider();
ILoggingService loggingService = tempServiceProvider.GetRequiredService<ILoggingService>();
IConfigService configService = tempServiceProvider.GetRequiredService<IConfigService>();
ExitHelper exitHelper = tempServiceProvider.GetRequiredService<ExitHelper>();
if (!await configService.LoadConfigurationAsync(args))
{
AnsiConsole.MarkupLine("\n[red]config.conf is not valid, check your syntax![/]\n");
AnsiConsole.MarkupLine("[red]Press any key to exit.[/]");
Console.ReadKey();
exitHelper.ExitWithCode(3);
}
if (configService.CurrentConfig.NonInteractiveMode is false)
{
AnsiConsole.MarkupLine("\n[red]Cannot run in Interactive Mode![/]\n");
AnsiConsole.MarkupLine("[red]Press any key to exit.[/]");
Console.ReadKey();
exitHelper.ExitWithCode(3);
}
AnsiConsole.Markup("[green]config.conf located successfully!\n[/]");
if (!ParseCommandlineArgs(args, configService.CurrentConfig, out CajetanConfig cajetanConfig))
{
AnsiConsole.MarkupLine($"\n[red]{cajetanConfig.ErrorMessage}[/]\n");
AnsiConsole.MarkupLine("[red]Press any key to exit.[/]");
Console.ReadKey();
exitHelper.ExitWithCode(3);
}
// Set up full dependency injection with loaded config
services = [];
services.AddSingleton(loggingService);
services.AddSingleton(configService);
services.AddSingleton(exitHelper);
services.AddSingleton(cajetanConfig);
services.AddSingleton<IAuthService, AuthService>();
services.AddSingleton<IStartupService, StartupService>();
services.AddSingleton<IFileNameService, FileNameService>();
services.AddSingleton<ICajetanDownloadService, CajetanDownloadService>();
services.AddSingleton<IDownloadService>(sp => sp.GetRequiredService<ICajetanDownloadService>());
services.AddSingleton<ICajetanApiService, CajetanApiService>();
services.AddSingleton<IApiService>(sp => sp.GetRequiredService<ICajetanApiService>());
services.AddSingleton<ICajetanDbService, CajetanDbService>();
services.AddSingleton<IDbService>(sp => sp.GetRequiredService<ICajetanDbService>());
services.AddSingleton<ICajetanDownloadOrchestrationService, CajetanDownloadOrchestrationService>();
services.AddSingleton<IDownloadOrchestrationService>(sp => sp.GetRequiredService<ICajetanDownloadOrchestrationService>());
services.AddSingleton<ICajetanDownloadEventHandler, CajetanDownloadEventHandler>();
services.AddSingleton<IDownloadEventHandler>(sp => sp.GetRequiredService<ICajetanDownloadEventHandler>());
services.AddSingleton<Worker>();
return services;
}
static bool ParseCommandlineArgs(string[] args, Config currentConfig, out CajetanConfig parsedConfig)
{
const string SPECIFIC_LISTS_ARG = "--specific-lists";
const string SPECIFIC_USERS_ARG = "--specific-users";
const string OUTPUT_BLOCKED_USERS_ARG = "--output-blocked";
const string UPDATE_ALL_USER_INFO_ARG = "--update-userinfo";
parsedConfig = new();
if (ParseListAndUserArguments(ref parsedConfig))
return true;
if (ParseFlagArgument(OUTPUT_BLOCKED_USERS_ARG, EMode.OutputBlockedUsers, ref parsedConfig))
return true;
if (ParseFlagArgument(UPDATE_ALL_USER_INFO_ARG, EMode.UpdateAllUserInfo, ref parsedConfig))
return true;
parsedConfig.ErrorMessage = "No mode argument provided!";
return false;
bool ParseListAndUserArguments(ref CajetanConfig parsedConfig)
{
bool hasSpecificListsArg = ParseCommaSeparatedListArgument(SPECIFIC_LISTS_ARG, ref parsedConfig, (c, v) =>
{
c.NonInteractiveSpecificLists = v;
Log.Logger = Log.Logger.ForContext(nameof(CajetanConfig.NonInteractiveSpecificLists), string.Join(",", v));
});
if (hasSpecificListsArg)
return true;
bool hasSpecificUsersArg = ParseCommaSeparatedListArgument(SPECIFIC_USERS_ARG, ref parsedConfig, (c, v) =>
{
c.NonInteractiveSpecificUsers = v;
Log.Logger = Log.Logger.ForContext(nameof(CajetanConfig.NonInteractiveSpecificUsers), string.Join(",", v));
});
if (hasSpecificUsersArg)
return true;
return false;
}
bool ParseCommaSeparatedListArgument(string argName, ref CajetanConfig parsedConfig, Action<CajetanConfig, string[]> assignmentFunc)
{
char[] separator = [','];
int indexOfArg = Array.FindIndex(args, a => argName.Equals(a, StringComparison.OrdinalIgnoreCase));
if (indexOfArg < 0)
return false;
int indexOfListValues = indexOfArg + 1;
string[] strListValues = args.ElementAtOrDefault(indexOfListValues)?.Split(separator, StringSplitOptions.RemoveEmptyEntries) ?? [];
if (strListValues.Length == 0)
return false;
assignmentFunc(parsedConfig, strListValues);
parsedConfig.Mode = EMode.DownloadCreatorContent;
Log.Logger = Log.Logger.ForContext("Mode", $"{EMode.DownloadCreatorContent}");
return true;
}
bool ParseFlagArgument(string argName, EMode modeIfArgIsSet, ref CajetanConfig parsedConfig)
{
if (!args.Any(a => argName.Equals(a, StringComparison.OrdinalIgnoreCase)))
return false;
currentConfig.NonInteractiveMode = true;
parsedConfig.Mode = modeIfArgIsSet;
Log.Logger = Log.Logger.ForContext("Mode", $"{modeIfArgIsSet}");
return true;
}
}
static void ExitIfOtherProcess(ServiceProvider serviceProvider)
{
Assembly? entryAssembly = Assembly.GetEntryAssembly();
AssemblyName? entryAssemblyName = entryAssembly?.GetName();
if (entryAssemblyName?.Name is null)
return;
Process thisProcess = Process.GetCurrentProcess();
Process[] otherProcesses = [.. Process.GetProcessesByName(entryAssemblyName.Name).Where(p => p.Id != thisProcess.Id)];
if (otherProcesses.Length <= 0)
return;
AnsiConsole.Markup($"[green]Other OF DL process detected, exiting..\n[/]");
Log.Warning("Other OF DL process detected, exiting..");
serviceProvider.GetRequiredService<ExitHelper>().ExitWithCode(0);
}