diff --git a/DiscordChatExporter.Cli/Commands/ExportCommandBase.cs b/DiscordChatExporter.Cli/Commands/ExportCommandBase.cs index b1675d2..ddc5648 100644 --- a/DiscordChatExporter.Cli/Commands/ExportCommandBase.cs +++ b/DiscordChatExporter.Cli/Commands/ExportCommandBase.cs @@ -3,7 +3,7 @@ using System.IO; using System.Threading.Tasks; using CliFx.Attributes; using CliFx.Services; -using DiscordChatExporter.Cli.Internal; +using CliFx.Utilities; using DiscordChatExporter.Core.Models; using DiscordChatExporter.Core.Services; using DiscordChatExporter.Core.Services.Helpers; @@ -50,29 +50,27 @@ namespace DiscordChatExporter.Cli.Commands SettingsService.DateFormat = DateFormat; console.Output.Write($"Exporting channel [{channel.Name}]... "); - using (var progress = new InlineProgress(console)) + var progress = console.CreateProgressTicker(); + + // Get chat log + var chatLog = await DataService.GetChatLogAsync(GetToken(), channel, After, Before, progress); + + // Generate file path if not set or is a directory + var filePath = OutputPath; + if (filePath.IsNullOrWhiteSpace() || ExportHelper.IsDirectoryPath(filePath)) { - // Get chat log - var chatLog = await DataService.GetChatLogAsync(GetToken(), channel, After, Before, progress); - - // Generate file path if not set or is a directory - var filePath = OutputPath; - if (filePath.IsNullOrWhiteSpace() || ExportHelper.IsDirectoryPath(filePath)) - { - // Generate default file name - var fileName = ExportHelper.GetDefaultExportFileName(ExportFormat, chatLog.Guild, - chatLog.Channel, After, Before); - - // Combine paths - filePath = Path.Combine(filePath ?? "", fileName); - } - - // Export - await ExportService.ExportChatLogAsync(chatLog, filePath, ExportFormat, PartitionLimit); - - // Report successful completion - progress.ReportCompletion(); + // Generate default file name + var fileName = ExportHelper.GetDefaultExportFileName(ExportFormat, chatLog.Guild, + chatLog.Channel, After, Before); + + // Combine paths + filePath = Path.Combine(filePath ?? "", fileName); } + + // Export + await ExportService.ExportChatLogAsync(chatLog, filePath, ExportFormat, PartitionLimit); + + console.Output.WriteLine(); } } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Internal/InlineProgress.cs b/DiscordChatExporter.Cli/Internal/InlineProgress.cs deleted file mode 100644 index fd7c8d7..0000000 --- a/DiscordChatExporter.Cli/Internal/InlineProgress.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using CliFx.Services; - -namespace DiscordChatExporter.Cli.Internal -{ - internal class InlineProgress : IProgress, IDisposable - { - private readonly IConsole _console; - - private string _lastOutput = ""; - private bool _isCompleted; - - public InlineProgress(IConsole console) - { - _console = console; - } - - private void ResetCursorPosition() - { - foreach (var c in _lastOutput) - _console.Output.Write('\b'); - } - - public void Report(double progress) - { - // If output is not redirected - reset cursor position and write progress - if (!_console.IsOutputRedirected) - { - ResetCursorPosition(); - _console.Output.Write(_lastOutput = $"{progress:P1}"); - } - } - - public void ReportCompletion() => _isCompleted = true; - - public void Dispose() - { - // If output is not redirected - reset cursor position - if (!_console.IsOutputRedirected) - { - ResetCursorPosition(); - } - - // Inform about completion - _console.Output.WriteLine(_isCompleted ? "Completed ✓" : "Failed X"); - } - } -} \ No newline at end of file diff --git a/DiscordChatExporter.Core.Services/DataService.cs b/DiscordChatExporter.Core.Services/DataService.cs index 6f0010d..3615e38 100644 --- a/DiscordChatExporter.Core.Services/DataService.cs +++ b/DiscordChatExporter.Core.Services/DataService.cs @@ -32,41 +32,37 @@ namespace DiscordChatExporter.Core.Services { // Create request const string apiRoot = "https://discordapp.com/api/v6"; - using (var request = new HttpRequestMessage(HttpMethod.Get, $"{apiRoot}/{resource}/{endpoint}")) + using var request = new HttpRequestMessage(HttpMethod.Get, $"{apiRoot}/{resource}/{endpoint}"); + // Set authorization header + request.Headers.Authorization = token.Type == AuthTokenType.Bot + ? new AuthenticationHeaderValue("Bot", token.Value) + : new AuthenticationHeaderValue(token.Value); + + // Add parameters + foreach (var parameter in parameters) { - // Set authorization header - request.Headers.Authorization = token.Type == AuthTokenType.Bot - ? new AuthenticationHeaderValue("Bot", token.Value) - : new AuthenticationHeaderValue(token.Value); - - // Add parameters - foreach (var parameter in parameters) - { - var key = parameter.SubstringUntil("="); - var value = parameter.SubstringAfter("="); - - // Skip empty values - if (value.IsNullOrWhiteSpace()) - continue; - - request.RequestUri = request.RequestUri.SetQueryParameter(key, value); - } - - // Get response - using (var response = await _httpClient.SendAsync(request)) - { - // Check status code - // We throw our own exception here because default one doesn't have status code - if (!response.IsSuccessStatusCode) - throw new HttpErrorStatusCodeException(response.StatusCode, response.ReasonPhrase); - - // Get content - var raw = await response.Content.ReadAsStringAsync(); - - // Parse - return JToken.Parse(raw); - } + var key = parameter.SubstringUntil("="); + var value = parameter.SubstringAfter("="); + + // Skip empty values + if (value.IsNullOrWhiteSpace()) + continue; + + request.RequestUri = request.RequestUri.SetQueryParameter(key, value); } + + // Get response + using var response = await _httpClient.SendAsync(request); + // Check status code + // We throw our own exception here because default one doesn't have status code + if (!response.IsSuccessStatusCode) + throw new HttpErrorStatusCodeException(response.StatusCode, response.ReasonPhrase); + + // Get content + var raw = await response.Content.ReadAsStringAsync(); + + // Parse + return JToken.Parse(raw); }); } diff --git a/DiscordChatExporter.Core.Services/ExportService.cs b/DiscordChatExporter.Core.Services/ExportService.cs index 5c4b70c..395aa77 100644 --- a/DiscordChatExporter.Core.Services/ExportService.cs +++ b/DiscordChatExporter.Core.Services/ExportService.cs @@ -42,8 +42,8 @@ namespace DiscordChatExporter.Core.Services Directory.CreateDirectory(dirPath); // Render chat log to output file - using (var writer = File.CreateText(filePath)) - await CreateRenderer(chatLog, format).RenderAsync(writer); + await using var writer = File.CreateText(filePath); + await CreateRenderer(chatLog, format).RenderAsync(writer); } public async Task ExportChatLogAsync(ChatLog chatLog, string filePath, ExportFormat format, int? partitionLimit) diff --git a/DiscordChatExporter.Core.Services/Helpers/ExportHelper.cs b/DiscordChatExporter.Core.Services/Helpers/ExportHelper.cs index 142b70d..cd82782 100644 --- a/DiscordChatExporter.Core.Services/Helpers/ExportHelper.cs +++ b/DiscordChatExporter.Core.Services/Helpers/ExportHelper.cs @@ -12,7 +12,7 @@ namespace DiscordChatExporter.Core.Services.Helpers public static bool IsDirectoryPath(string path) => path.Last() == Path.DirectorySeparatorChar || path.Last() == Path.AltDirectorySeparatorChar || - (Path.GetExtension(path).IsNullOrWhiteSpace() && !File.Exists(path)); + Path.GetExtension(path).IsNullOrWhiteSpace() && !File.Exists(path); public static string GetDefaultExportFileName(ExportFormat format, Guild guild, Channel channel, DateTimeOffset? after = null, DateTimeOffset? before = null)