Add CLI command to export all available channels in a guild (#123)

pull/145/head
TVdata 6 years ago committed by Alexey Golub
parent 17b0161ade
commit bf5cedb646

@ -38,6 +38,7 @@ namespace DiscordChatExporter.Cli
var verbTypes = new[] var verbTypes = new[]
{ {
typeof(ExportChatOptions), typeof(ExportChatOptions),
typeof(ExportGuildOptions),
typeof(GetChannelsOptions), typeof(GetChannelsOptions),
typeof(GetDirectMessageChannelsOptions), typeof(GetDirectMessageChannelsOptions),
typeof(GetGuildsOptions) typeof(GetGuildsOptions)
@ -48,6 +49,7 @@ namespace DiscordChatExporter.Cli
// Execute commands // Execute commands
parsedArgs.WithParsed<ExportChatOptions>(o => new ExportChatVerb(o).Execute()); parsedArgs.WithParsed<ExportChatOptions>(o => new ExportChatVerb(o).Execute());
parsedArgs.WithParsed<ExportGuildOptions>(o => new ExportGuildVerb(o).Execute());
parsedArgs.WithParsed<GetChannelsOptions>(o => new GetChannelsVerb(o).Execute()); parsedArgs.WithParsed<GetChannelsOptions>(o => new GetChannelsVerb(o).Execute());
parsedArgs.WithParsed<GetDirectMessageChannelsOptions>(o => new GetDirectMessageChannelsVerb(o).Execute()); parsedArgs.WithParsed<GetDirectMessageChannelsOptions>(o => new GetDirectMessageChannelsVerb(o).Execute());
parsedArgs.WithParsed<GetGuildsOptions>(o => new GetGuildsVerb(o).Execute()); parsedArgs.WithParsed<GetGuildsOptions>(o => new GetGuildsVerb(o).Execute());

@ -0,0 +1,79 @@
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.Models;
using DiscordChatExporter.Core.Services;
using Tyrrrz.Extensions;
namespace DiscordChatExporter.Cli.Verbs
{
public class ExportGuildVerb : Verb<ExportGuildOptions>
{
public ExportGuildVerb(ExportGuildOptions options)
: base(options)
{
}
public override async Task ExecuteAsync()
{
// Get services
var settingsService = Container.Instance.Get<SettingsService>();
var dataService = Container.Instance.Get<DataService>();
var exportService = Container.Instance.Get<ExportService>();
// Configure settings
if (Options.DateFormat.IsNotBlank())
settingsService.DateFormat = Options.DateFormat;
if (Options.MessageGroupLimit > 0)
settingsService.MessageGroupLimit = Options.MessageGroupLimit;
// Get channels
var channels = await dataService.GetGuildChannelsAsync(Options.GetToken(), Options.GuildId);
// Loop through channels
foreach (var channel in channels.Where(c => c.Type.IsEither(ChannelType.GuildTextChat))
.OrderBy(c => c.Name))
{
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");
}
}
}
}
}

@ -1,34 +1,11 @@
using System; using CommandLine;
using CommandLine;
using DiscordChatExporter.Core.Models;
namespace DiscordChatExporter.Cli.Verbs.Options namespace DiscordChatExporter.Cli.Verbs.Options
{ {
[Verb("export", HelpText = "Export channel chat log to a file.")] [Verb("export", HelpText = "Export channel chat log to a file.")]
public class ExportChatOptions : TokenOptions public class ExportChatOptions : ExportOptions
{ {
[Option('c', "channel", Required = true, HelpText = "Channel ID.")] [Option('c', "channel", Required = true, HelpText = "Channel ID.")]
public string ChannelId { get; set; } public string ChannelId { get; set; }
[Option('f', "format", Default = ExportFormat.HtmlDark, HelpText = "Output file format.")]
public ExportFormat ExportFormat { get; set; }
[Option('o', "output", Default = null, HelpText = "Output file path.")]
public string FilePath { get; set; }
[Option("after", Default = null, HelpText = "Limit to messages sent after this date.")]
public DateTime? After { get; set; }
[Option("before", Default = null, HelpText = "Limit to messages sent before this date.")]
public DateTime? Before { get; set; }
[Option('p', "partition", Default = null, HelpText = "Split output into partitions limited to this number of messages.")]
public int? PartitionLimit { get; set; }
[Option("dateformat", Default = null, HelpText = "Date format used in output.")]
public string DateFormat { get; set; }
[Option("grouplimit", Default = 0, HelpText = "Message group limit.")]
public int MessageGroupLimit { get; set; }
} }
} }

@ -0,0 +1,11 @@
using CommandLine;
namespace DiscordChatExporter.Cli.Verbs.Options
{
[Verb("exportguild", HelpText = "Export all available channels within a given guild.")]
public class ExportGuildOptions : ExportOptions
{
[Option('g', "guild", Required = true, HelpText = "Guild ID.")]
public string GuildId { get; set; }
}
}

@ -0,0 +1,30 @@
using System;
using CommandLine;
using DiscordChatExporter.Core.Models;
namespace DiscordChatExporter.Cli.Verbs.Options
{
public class ExportOptions : TokenOptions
{
[Option('f', "format", Default = ExportFormat.HtmlDark, HelpText = "Output file format.")]
public ExportFormat ExportFormat { get; set; }
[Option('o', "output", Default = null, HelpText = "Output file path.")]
public string FilePath { get; set; }
[Option("after", Default = null, HelpText = "Limit to messages sent after this date.")]
public DateTime? After { get; set; }
[Option("before", Default = null, HelpText = "Limit to messages sent before this date.")]
public DateTime? Before { get; set; }
[Option('p', "partition", Default = null, HelpText = "Split output into partitions limited to this number of messages.")]
public int? PartitionLimit { get; set; }
[Option("dateformat", Default = null, HelpText = "Date format used in output.")]
public string DateFormat { get; set; }
[Option("grouplimit", Default = 0, HelpText = "Message group limit.")]
public int MessageGroupLimit { get; set; }
}
}

@ -226,12 +226,9 @@ namespace DiscordChatExporter.Core.Services
return new ChatLog(guild, channel, from, to, messages, mentionables); return new ChatLog(guild, channel, from, to, messages, mentionables);
} }
public async Task<ChatLog> GetChatLogAsync(AuthToken token, string channelId, public async Task<ChatLog> GetChatLogAsync(AuthToken token, Channel channel,
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null) DateTime? from = null, DateTime? to = null, IProgress<double> progress = null)
{ {
// Get channel
var channel = await GetChannelAsync(token, channelId);
// Get guild // Get guild
var guild = channel.GuildId == Guild.DirectMessages.Id var guild = channel.GuildId == Guild.DirectMessages.Id
? Guild.DirectMessages ? Guild.DirectMessages
@ -241,6 +238,16 @@ namespace DiscordChatExporter.Core.Services
return await GetChatLogAsync(token, guild, channel, from, to, progress); return await GetChatLogAsync(token, guild, channel, from, to, progress);
} }
public async Task<ChatLog> GetChatLogAsync(AuthToken token, string channelId,
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null)
{
// Get channel
var channel = await GetChannelAsync(token, channelId);
// Get the chat log
return await GetChatLogAsync(token, channel, from, to, progress);
}
public void Dispose() public void Dispose()
{ {
_httpClient.Dispose(); _httpClient.Dispose();

Loading…
Cancel
Save