using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using Logging; using Spectre.Console; using Spectre.Console.Cli; using Tranga; var app = new CommandApp(); return app.Run(args); internal sealed class TrangaCli : Command { public sealed class Settings : CommandSettings { [Description("Directory to which downloaded Manga are saved")] [CommandOption("-d|--downloadLocation")] [DefaultValue(null)] public string? downloadLocation { get; init; } [Description("Directory in which application-data is saved")] [CommandOption("-w|--workingDirectory")] [DefaultValue(null)] public string? workingDirectory { get; init; } [Description("Enables the file-logger")] [CommandOption("-f")] [DefaultValue(null)] public bool? fileLogger { get; init; } [Description("Path to save logfile to")] [CommandOption("-l|--fPath")] [DefaultValue(null)] public string? fileLoggerPath { get; init; } [Description("Port on which to run API on")] [CommandOption("-p|--port")] [DefaultValue(null)] public int? apiPort { get; init; } } public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings) { List enabledLoggers = new(); if(settings.fileLogger.HasValue && settings.fileLogger.Value == true) enabledLoggers.Add(Logger.LoggerType.FileLogger); string? logFilePath = settings.fileLoggerPath ?? "";//TODO path Logger logger = new(enabledLoggers.ToArray(), Console.Out, Console.OutputEncoding, logFilePath); TrangaSettings trangaSettings = new (settings.downloadLocation, settings.workingDirectory, settings.apiPort); Directory.CreateDirectory(trangaSettings.downloadLocation); Directory.CreateDirectory(trangaSettings.workingDirectory); Tranga.Tranga? api = null; Thread trangaApi = new Thread(() => { api = new(logger, trangaSettings); }); trangaApi.Start(); HttpClient client = new(); bool exit = false; while (!exit) { string menuSelect = AnsiConsole.Prompt( new SelectionPrompt() .Title("Menu") .PageSize(10) .MoreChoicesText("Up/Down") .AddChoices(new[] { "CustomRequest", "Log", "Exit" })); switch (menuSelect) { case "CustomRequest": string requestType = AnsiConsole.Prompt( new SelectionPrompt() .Title("Request Type") .AddChoices(new[] { "GET", "POST", "DELETE" })); HttpMethod method = requestType == "GET" ? HttpMethod.Get : requestType == "DELETE" ? HttpMethod.Delete : HttpMethod.Post; string requestPath = AnsiConsole.Prompt( new TextPrompt("Request Path:")); List> parameters = new(); while (AnsiConsole.Confirm("Add Parameter?")) { string name = AnsiConsole.Ask("Parameter Name:"); string value = AnsiConsole.Ask("Parameter Value:"); parameters.Add(new ValueTuple(name, value)); } string requestString = $"http://localhost:{trangaSettings.apiPortNumber}/{requestPath}"; if (parameters.Any()) { requestString += "?"; foreach (ValueTuple parameter in parameters) requestString += $"{parameter.Item1}={parameter.Item2}&"; } HttpRequestMessage request = new HttpRequestMessage(method, requestString); AnsiConsole.WriteLine($"Request: {request.Method} {request.RequestUri}"); HttpResponseMessage response; if (AnsiConsole.Confirm("Send Request?")) response = client.Send(request); else break; AnsiConsole.WriteLine(response.Content.ReadAsStringAsync().Result); break; case "Log": List lines = logger.Tail(10).ToList(); Rows rows = new Rows(lines.Select(line => new Text(line))); AnsiConsole.Live(rows).Start(context => { bool running = true; while (running) { string[] newLines = logger.GetNewLines(); if (newLines.Length > 0) { lines.AddRange(newLines); rows = new Rows(lines.Select(line => new Text(line))); context.UpdateTarget(rows); } Thread.Sleep(100); if (Console.KeyAvailable) running = false; } }); break; case "Exit": exit = true; break; } } if (api is not null) api.keepRunning = false; return 0; } }