diff --git a/DiscordChatExporter.Cli/Program.cs b/DiscordChatExporter.Cli/Program.cs index af44822..dca6c27 100644 --- a/DiscordChatExporter.Cli/Program.cs +++ b/DiscordChatExporter.Cli/Program.cs @@ -37,7 +37,8 @@ namespace DiscordChatExporter.Cli // Get all verb types var verbTypes = new[] { - typeof(ExportChatOptions), + typeof(ExportChannelOptions), + typeof(ExportDirectMessagesOptions), typeof(ExportGuildOptions), typeof(GetChannelsOptions), typeof(GetDirectMessageChannelsOptions), @@ -48,7 +49,8 @@ namespace DiscordChatExporter.Cli var parsedArgs = Parser.Default.ParseArguments(args, verbTypes); // Execute commands - parsedArgs.WithParsed(o => new ExportChatVerb(o).Execute()); + parsedArgs.WithParsed(o => new ExportChannelVerb(o).Execute()); + parsedArgs.WithParsed(o => new ExportDirectMessagesVerb(o).Execute()); parsedArgs.WithParsed(o => new ExportGuildVerb(o).Execute()); parsedArgs.WithParsed(o => new GetChannelsVerb(o).Execute()); parsedArgs.WithParsed(o => new GetDirectMessageChannelsVerb(o).Execute()); diff --git a/DiscordChatExporter.Cli/Verbs/ExportChatVerb.cs b/DiscordChatExporter.Cli/Verbs/ExportChannelVerb.cs similarity index 93% rename from DiscordChatExporter.Cli/Verbs/ExportChatVerb.cs rename to DiscordChatExporter.Cli/Verbs/ExportChannelVerb.cs index 91b31ab..56b6c2f 100644 --- a/DiscordChatExporter.Cli/Verbs/ExportChatVerb.cs +++ b/DiscordChatExporter.Cli/Verbs/ExportChannelVerb.cs @@ -7,9 +7,9 @@ using Tyrrrz.Extensions; namespace DiscordChatExporter.Cli.Verbs { - public class ExportChatVerb : Verb + public class ExportChannelVerb : Verb { - public ExportChatVerb(ExportChatOptions options) + public ExportChannelVerb(ExportChannelOptions options) : base(options) { } diff --git a/DiscordChatExporter.Cli/Verbs/ExportDirectMessagesVerb.cs b/DiscordChatExporter.Cli/Verbs/ExportDirectMessagesVerb.cs new file mode 100644 index 0000000..6695130 --- /dev/null +++ b/DiscordChatExporter.Cli/Verbs/ExportDirectMessagesVerb.cs @@ -0,0 +1,80 @@ +using System; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using DiscordChatExporter.Cli.Verbs.Options; +using DiscordChatExporter.Core.Exceptions; +using DiscordChatExporter.Core.Helpers; +using DiscordChatExporter.Core.Services; +using Tyrrrz.Extensions; + +namespace DiscordChatExporter.Cli.Verbs +{ + public class ExportDirectMessagesVerb : Verb + { + public ExportDirectMessagesVerb(ExportDirectMessagesOptions options) + : base(options) + { + } + + public override async Task ExecuteAsync() + { + // Get services + var settingsService = Container.Instance.Get(); + var dataService = Container.Instance.Get(); + var exportService = Container.Instance.Get(); + + // Configure settings + if (Options.DateFormat.IsNotBlank()) + settingsService.DateFormat = Options.DateFormat; + if (Options.MessageGroupLimit > 0) + settingsService.MessageGroupLimit = Options.MessageGroupLimit; + + // Get channels + var channels = await dataService.GetDirectMessageChannelsAsync(Options.GetToken()); + + // Order channels + channels = channels.OrderBy(c => c.Name).ToArray(); + + // Loop through channels + foreach (var channel in channels) + { + try + { + // Print current channel name + Console.WriteLine($"Exporting chat from [{channel.Name}]..."); + + // Get chat log + var chatLog = await dataService.GetChatLogAsync(Options.GetToken(), channel, + Options.After, Options.Before); + + // Generate file path if not set or is a directory + var filePath = Options.FilePath; + if (filePath == null || filePath.EndsWith("/") || filePath.EndsWith("\\")) + { + // Generate default file name + var defaultFileName = ExportHelper.GetDefaultExportFileName(Options.ExportFormat, chatLog.Guild, + chatLog.Channel, Options.After, Options.Before); + + // Append the file name to the file path + filePath += defaultFileName; + } + + // Export + exportService.ExportChatLog(chatLog, filePath, Options.ExportFormat, Options.PartitionLimit); + + // Print result + Console.WriteLine($"Exported chat to [{filePath}]"); + } + catch (HttpErrorStatusCodeException ex) when (ex.StatusCode == HttpStatusCode.Forbidden) + { + Console.Error.WriteLine("You don't have access to this channel"); + } + catch (HttpErrorStatusCodeException ex) when (ex.StatusCode == HttpStatusCode.NotFound) + { + Console.Error.WriteLine("This channel doesn't exist"); + } + } + } + } +} \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Verbs/Options/ExportChatOptions.cs b/DiscordChatExporter.Cli/Verbs/Options/ExportChannelOptions.cs similarity index 62% rename from DiscordChatExporter.Cli/Verbs/Options/ExportChatOptions.cs rename to DiscordChatExporter.Cli/Verbs/Options/ExportChannelOptions.cs index 132d834..5278a2d 100644 --- a/DiscordChatExporter.Cli/Verbs/Options/ExportChatOptions.cs +++ b/DiscordChatExporter.Cli/Verbs/Options/ExportChannelOptions.cs @@ -2,8 +2,8 @@ namespace DiscordChatExporter.Cli.Verbs.Options { - [Verb("export", HelpText = "Export channel chat log to a file.")] - public class ExportChatOptions : ExportOptions + [Verb("export", HelpText = "Export channel.")] + public class ExportChannelOptions : ExportOptions { [Option('c', "channel", Required = true, HelpText = "Channel ID.")] public string ChannelId { get; set; } diff --git a/DiscordChatExporter.Cli/Verbs/Options/ExportDirectMessagesOptions.cs b/DiscordChatExporter.Cli/Verbs/Options/ExportDirectMessagesOptions.cs new file mode 100644 index 0000000..a29cedf --- /dev/null +++ b/DiscordChatExporter.Cli/Verbs/Options/ExportDirectMessagesOptions.cs @@ -0,0 +1,9 @@ +using CommandLine; + +namespace DiscordChatExporter.Cli.Verbs.Options +{ + [Verb("exportdm", HelpText = "Export all direct message channels.")] + public class ExportDirectMessagesOptions : ExportOptions + { + } +} \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Verbs/Options/ExportGuildOptions.cs b/DiscordChatExporter.Cli/Verbs/Options/ExportGuildOptions.cs index 3d51a75..0392184 100644 --- a/DiscordChatExporter.Cli/Verbs/Options/ExportGuildOptions.cs +++ b/DiscordChatExporter.Cli/Verbs/Options/ExportGuildOptions.cs @@ -2,7 +2,7 @@ namespace DiscordChatExporter.Cli.Verbs.Options { - [Verb("exportguild", HelpText = "Export all available channels within a given guild.")] + [Verb("exportguild", HelpText = "Export all channels within a given guild.")] public class ExportGuildOptions : ExportOptions { [Option('g', "guild", Required = true, HelpText = "Guild ID.")] diff --git a/DiscordChatExporter.Cli/Verbs/Options/ExportOptions.cs b/DiscordChatExporter.Cli/Verbs/Options/ExportOptions.cs index cab470b..436535a 100644 --- a/DiscordChatExporter.Cli/Verbs/Options/ExportOptions.cs +++ b/DiscordChatExporter.Cli/Verbs/Options/ExportOptions.cs @@ -4,7 +4,7 @@ using DiscordChatExporter.Core.Models; namespace DiscordChatExporter.Cli.Verbs.Options { - public class ExportOptions : TokenOptions + public abstract class ExportOptions : TokenOptions { [Option('f', "format", Default = ExportFormat.HtmlDark, HelpText = "Output file format.")] public ExportFormat ExportFormat { get; set; } diff --git a/DiscordChatExporter.Cli/Verbs/Options/TokenOptions.cs b/DiscordChatExporter.Cli/Verbs/Options/TokenOptions.cs index 6262a3f..350417e 100644 --- a/DiscordChatExporter.Cli/Verbs/Options/TokenOptions.cs +++ b/DiscordChatExporter.Cli/Verbs/Options/TokenOptions.cs @@ -3,7 +3,7 @@ using DiscordChatExporter.Core.Models; namespace DiscordChatExporter.Cli.Verbs.Options { - public class TokenOptions + public abstract class TokenOptions { [Option('t', "token", Required = true, HelpText = "Authorization token.")] public string TokenValue { get; set; }