mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-28 13:44:12 -04:00
Refactor more
This commit is contained in:
parent
dc79813ad7
commit
88a4fa792b
26 changed files with 117 additions and 99 deletions
|
@ -29,14 +29,14 @@ namespace DiscordChatExporter.Cli.Commands.Base
|
|||
[CommandOption("dateformat", Description = "Date format used in output.")]
|
||||
public string DateFormat { get; set; } = "dd-MMM-yy hh:mm tt";
|
||||
|
||||
protected Exporter GetExporter() => new Exporter(GetDiscordClient());
|
||||
protected ChannelExporter GetChannelExporter() => new ChannelExporter(GetDiscordClient());
|
||||
|
||||
protected async ValueTask ExportAsync(IConsole console, Guild guild, Channel channel)
|
||||
{
|
||||
console.Output.Write($"Exporting channel '{channel.Name}'... ");
|
||||
var progress = console.CreateProgressTicker();
|
||||
|
||||
await GetExporter().ExportChatLogAsync(guild, channel,
|
||||
await GetChannelExporter().ExportAsync(guild, channel,
|
||||
OutputPath, ExportFormat, DateFormat, PartitionLimit,
|
||||
After, Before, progress);
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace DiscordChatExporter.Cli.Commands.Base
|
|||
{
|
||||
var guild = await GetDiscordClient().GetGuildAsync(channel.GuildId);
|
||||
|
||||
await GetExporter().ExportChatLogAsync(guild, channel,
|
||||
await GetChannelExporter().ExportAsync(guild, channel,
|
||||
OutputPath, ExportFormat, DateFormat, PartitionLimit,
|
||||
After, Before, operation);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Drawing;
|
|||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using DiscordChatExporter.Domain.Discord.Models;
|
||||
using DiscordChatExporter.Domain.Discord.Models.Common;
|
||||
using DiscordChatExporter.Domain.Internal;
|
||||
using Tyrrrz.Extensions;
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@ namespace DiscordChatExporter.Domain.Discord
|
|||
_token = token;
|
||||
_httpClient = httpClient;
|
||||
|
||||
_httpClient.BaseAddress = new Uri("https://discordapp.com/api/v6");
|
||||
|
||||
// Discord seems to always respond with 429 on the first request with unreasonable wait time (10+ minutes).
|
||||
// For that reason the policy will start respecting their retry-after header only after Nth failed response.
|
||||
_httpRequestPolicy = Policy
|
||||
|
@ -53,7 +51,9 @@ namespace DiscordChatExporter.Domain.Discord
|
|||
{
|
||||
using var response = await _httpRequestPolicy.ExecuteAsync(async () =>
|
||||
{
|
||||
using var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
var uri = new Uri(new Uri("https://discordapp.com/api/v6"), url);
|
||||
|
||||
using var request = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
request.Headers.Authorization = _token.GetAuthenticationHeader();
|
||||
|
||||
return await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using DiscordChatExporter.Domain.Discord.Models.Common;
|
||||
|
||||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
{
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
using DiscordChatExporter.Domain.Discord.Models.Common;
|
||||
|
||||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
{
|
||||
// https://discordapp.com/developers/docs/resources/channel#channel-object-channel-types
|
||||
// Order of enum fields needs to match the order in the docs.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
namespace DiscordChatExporter.Domain.Discord.Models.Common
|
||||
{
|
||||
// Loosely based on https://github.com/omar/ByteSize (MIT license)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
namespace DiscordChatExporter.Domain.Discord.Models.Common
|
||||
{
|
||||
public interface IHasId
|
||||
{
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
namespace DiscordChatExporter.Domain.Discord.Models.Common
|
||||
{
|
||||
public partial class IdBasedEqualityComparer : IEqualityComparer<IHasId>
|
||||
{
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DiscordChatExporter.Domain.Discord.Models.Common;
|
||||
using DiscordChatExporter.Domain.Internal;
|
||||
|
||||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DiscordChatExporter.Domain.Discord.Models.Common;
|
||||
|
||||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Drawing;
|
||||
using DiscordChatExporter.Domain.Discord.Models.Common;
|
||||
|
||||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using DiscordChatExporter.Domain.Discord.Models.Common;
|
||||
|
||||
namespace DiscordChatExporter.Domain.Discord.Models
|
||||
{
|
||||
|
|
|
@ -5,39 +5,47 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using DiscordChatExporter.Domain.Discord;
|
||||
using DiscordChatExporter.Domain.Discord.Models;
|
||||
using DiscordChatExporter.Domain.Discord.Models.Common;
|
||||
using DiscordChatExporter.Domain.Exceptions;
|
||||
using Tyrrrz.Extensions;
|
||||
|
||||
namespace DiscordChatExporter.Domain.Exporting
|
||||
{
|
||||
public partial class Exporter
|
||||
public partial class ChannelExporter
|
||||
{
|
||||
private readonly DiscordClient _discord;
|
||||
|
||||
public Exporter(DiscordClient discord) => _discord = discord;
|
||||
public ChannelExporter(DiscordClient discord) => _discord = discord;
|
||||
|
||||
public async Task ExportChatLogAsync(Guild guild, Channel channel,
|
||||
string outputPath, ExportFormat format, string dateFormat, int? partitionLimit,
|
||||
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double>? progress = null)
|
||||
public async Task ExportAsync(
|
||||
Guild guild,
|
||||
Channel channel,
|
||||
string outputPath,
|
||||
ExportFormat format,
|
||||
string dateFormat,
|
||||
int? partitionLimit,
|
||||
DateTimeOffset? after = null,
|
||||
DateTimeOffset? before = null,
|
||||
IProgress<double>? progress = null)
|
||||
{
|
||||
// Get base file path from output path
|
||||
var baseFilePath = GetFilePathFromOutputPath(outputPath, format, guild, channel, after, before);
|
||||
var baseFilePath = GetFilePathFromOutputPath(guild, channel, outputPath, format, after, before);
|
||||
|
||||
// Create options
|
||||
var options = new RenderOptions(baseFilePath, format, partitionLimit);
|
||||
var options = new ExportOptions(baseFilePath, format, partitionLimit);
|
||||
|
||||
// Create context
|
||||
var mentionableUsers = new HashSet<User>(IdBasedEqualityComparer.Instance);
|
||||
var mentionableChannels = await _discord.GetGuildChannelsAsync(guild.Id);
|
||||
var mentionableRoles = guild.Roles;
|
||||
|
||||
var context = new RenderContext(
|
||||
var context = new ExportContext(
|
||||
guild, channel, after, before, dateFormat,
|
||||
mentionableUsers, mentionableChannels, mentionableRoles
|
||||
);
|
||||
|
||||
// Create renderer
|
||||
await using var renderer = new MessageRenderer(options, context);
|
||||
await using var renderer = new MessageExporter(options, context);
|
||||
|
||||
// Render messages
|
||||
var renderedAnything = false;
|
||||
|
@ -52,14 +60,13 @@ namespace DiscordChatExporter.Domain.Exporting
|
|||
|
||||
foreach (User u in encounteredUsers)
|
||||
{
|
||||
if(!guild.Members.ContainsKey(u.Id))
|
||||
if (!guild.Members.ContainsKey(u.Id))
|
||||
{
|
||||
var member = await _discord.GetGuildMemberAsync(guild.Id, u.Id);
|
||||
guild.Members[u.Id] = member;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Render message
|
||||
await renderer.RenderMessageAsync(message);
|
||||
renderedAnything = true;
|
||||
|
@ -71,18 +78,21 @@ namespace DiscordChatExporter.Domain.Exporting
|
|||
}
|
||||
}
|
||||
|
||||
public partial class Exporter
|
||||
public partial class ChannelExporter
|
||||
{
|
||||
public static string GetDefaultExportFileName(ExportFormat format,
|
||||
Guild guild, Channel channel,
|
||||
DateTimeOffset? after = null, DateTimeOffset? before = null)
|
||||
public static string GetDefaultExportFileName(
|
||||
Guild guild,
|
||||
Channel channel,
|
||||
ExportFormat format,
|
||||
DateTimeOffset? after = null,
|
||||
DateTimeOffset? before = null)
|
||||
{
|
||||
var buffer = new StringBuilder();
|
||||
|
||||
// Append guild and channel names
|
||||
// Guild and channel names
|
||||
buffer.Append($"{guild.Name} - {channel.Name} [{channel.Id}]");
|
||||
|
||||
// Append date range
|
||||
// Date range
|
||||
if (after != null || before != null)
|
||||
{
|
||||
buffer.Append(" (");
|
||||
|
@ -106,7 +116,7 @@ namespace DiscordChatExporter.Domain.Exporting
|
|||
buffer.Append(")");
|
||||
}
|
||||
|
||||
// Append extension
|
||||
// File extension
|
||||
buffer.Append($".{format.GetFileExtension()}");
|
||||
|
||||
// Replace invalid chars
|
||||
|
@ -116,13 +126,18 @@ namespace DiscordChatExporter.Domain.Exporting
|
|||
return buffer.ToString();
|
||||
}
|
||||
|
||||
private static string GetFilePathFromOutputPath(string outputPath, ExportFormat format, Guild guild, Channel channel,
|
||||
DateTimeOffset? after, DateTimeOffset? before)
|
||||
private static string GetFilePathFromOutputPath(
|
||||
Guild guild,
|
||||
Channel channel,
|
||||
string outputPath,
|
||||
ExportFormat format,
|
||||
DateTimeOffset? after = null,
|
||||
DateTimeOffset? before = null)
|
||||
{
|
||||
// Output is a directory
|
||||
if (Directory.Exists(outputPath) || string.IsNullOrWhiteSpace(Path.GetExtension(outputPath)))
|
||||
{
|
||||
var fileName = GetDefaultExportFileName(format, guild, channel, after, before);
|
||||
var fileName = GetDefaultExportFileName(guild, channel, format, after, before);
|
||||
return Path.Combine(outputPath, fileName);
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ using DiscordChatExporter.Domain.Discord.Models;
|
|||
|
||||
namespace DiscordChatExporter.Domain.Exporting
|
||||
{
|
||||
public class RenderContext
|
||||
public class ExportContext
|
||||
{
|
||||
public Guild Guild { get; }
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace DiscordChatExporter.Domain.Exporting
|
|||
|
||||
public IReadOnlyCollection<Role> MentionableRoles { get; }
|
||||
|
||||
public RenderContext(
|
||||
public ExportContext(
|
||||
Guild guild,
|
||||
Channel channel,
|
||||
DateTimeOffset? after,
|
|
@ -1,6 +1,6 @@
|
|||
namespace DiscordChatExporter.Domain.Exporting
|
||||
{
|
||||
public class RenderOptions
|
||||
public class ExportOptions
|
||||
{
|
||||
public string BaseFilePath { get; }
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
|||
|
||||
public int? PartitionLimit { get; }
|
||||
|
||||
public RenderOptions(string baseFilePath, ExportFormat format, int? partitionLimit)
|
||||
public ExportOptions(string baseFilePath, ExportFormat format, int? partitionLimit)
|
||||
{
|
||||
BaseFilePath = baseFilePath;
|
||||
Format = format;
|
|
@ -6,82 +6,77 @@ using DiscordChatExporter.Domain.Exporting.Writers;
|
|||
|
||||
namespace DiscordChatExporter.Domain.Exporting
|
||||
{
|
||||
internal partial class MessageRenderer : IAsyncDisposable
|
||||
internal partial class MessageExporter : IAsyncDisposable
|
||||
{
|
||||
private readonly RenderOptions _options;
|
||||
private readonly RenderContext _context;
|
||||
private readonly ExportOptions _options;
|
||||
private readonly ExportContext _context;
|
||||
|
||||
private long _renderedMessageCount;
|
||||
private int _partitionIndex;
|
||||
private MessageWriterBase? _writer;
|
||||
private MessageWriter? _writer;
|
||||
|
||||
public MessageRenderer(RenderOptions options, RenderContext context)
|
||||
public MessageExporter(ExportOptions options, ExportContext context)
|
||||
{
|
||||
_options = options;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private async Task<MessageWriterBase> InitializeWriterAsync()
|
||||
{
|
||||
// Get partition file path
|
||||
var filePath = GetPartitionFilePath(_options.BaseFilePath, _partitionIndex);
|
||||
|
||||
// Create output directory
|
||||
var dirPath = Path.GetDirectoryName(_options.BaseFilePath);
|
||||
if (!string.IsNullOrWhiteSpace(dirPath))
|
||||
Directory.CreateDirectory(dirPath);
|
||||
|
||||
// Create writer
|
||||
var writer = CreateMessageWriter(filePath, _options.Format, _context);
|
||||
|
||||
// Write preamble
|
||||
await writer.WritePreambleAsync();
|
||||
|
||||
return _writer = writer;
|
||||
}
|
||||
private bool IsPartitionLimitReached() =>
|
||||
_renderedMessageCount > 0 &&
|
||||
_options.PartitionLimit != null &&
|
||||
_options.PartitionLimit != 0 &&
|
||||
_renderedMessageCount % _options.PartitionLimit == 0;
|
||||
|
||||
private async Task ResetWriterAsync()
|
||||
{
|
||||
if (_writer != null)
|
||||
{
|
||||
// Write postamble
|
||||
await _writer.WritePostambleAsync();
|
||||
|
||||
// Flush
|
||||
await _writer.DisposeAsync();
|
||||
_writer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RenderMessageAsync(Message message)
|
||||
private async Task<MessageWriter> GetWriterAsync()
|
||||
{
|
||||
// Ensure underlying writer is initialized
|
||||
_writer ??= await InitializeWriterAsync();
|
||||
|
||||
// Render the actual message
|
||||
await _writer!.WriteMessageAsync(message);
|
||||
|
||||
// Increment count
|
||||
_renderedMessageCount++;
|
||||
|
||||
// Shift partition if necessary
|
||||
if (_options.PartitionLimit != null &&
|
||||
_options.PartitionLimit != 0 &&
|
||||
_renderedMessageCount % _options.PartitionLimit == 0)
|
||||
// Ensure partition limit is not exceeded
|
||||
if (IsPartitionLimitReached())
|
||||
{
|
||||
await ResetWriterAsync();
|
||||
_partitionIndex++;
|
||||
}
|
||||
|
||||
// Writer is still valid - return
|
||||
if (_writer != null)
|
||||
return _writer;
|
||||
|
||||
var filePath = GetPartitionFilePath(_options.BaseFilePath, _partitionIndex);
|
||||
|
||||
var dirPath = Path.GetDirectoryName(_options.BaseFilePath);
|
||||
if (!string.IsNullOrWhiteSpace(dirPath))
|
||||
Directory.CreateDirectory(dirPath);
|
||||
|
||||
var writer = CreateMessageWriter(filePath, _options.Format, _context);
|
||||
await writer.WritePreambleAsync();
|
||||
|
||||
return _writer = writer;
|
||||
}
|
||||
|
||||
public async Task RenderMessageAsync(Message message)
|
||||
{
|
||||
var writer = await GetWriterAsync();
|
||||
await writer.WriteMessageAsync(message);
|
||||
_renderedMessageCount++;
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync() => await ResetWriterAsync();
|
||||
}
|
||||
|
||||
internal partial class MessageRenderer
|
||||
internal partial class MessageExporter
|
||||
{
|
||||
private static string GetPartitionFilePath(string baseFilePath, int partitionIndex)
|
||||
{
|
||||
// First partition - no changes
|
||||
// First partition - don't change file name
|
||||
if (partitionIndex <= 0)
|
||||
return baseFilePath;
|
||||
|
||||
|
@ -98,9 +93,9 @@ namespace DiscordChatExporter.Domain.Exporting
|
|||
return fileName;
|
||||
}
|
||||
|
||||
private static MessageWriterBase CreateMessageWriter(string filePath, ExportFormat format, RenderContext context)
|
||||
private static MessageWriter CreateMessageWriter(string filePath, ExportFormat format, ExportContext context)
|
||||
{
|
||||
// Create a stream (it will get disposed by the writer)
|
||||
// Stream will be disposed by the underlying writer
|
||||
var stream = File.Create(filePath);
|
||||
|
||||
return format switch
|
|
@ -9,11 +9,11 @@ using Tyrrrz.Extensions;
|
|||
|
||||
namespace DiscordChatExporter.Domain.Exporting.Writers
|
||||
{
|
||||
internal partial class CsvMessageWriter : MessageWriterBase
|
||||
internal partial class CsvMessageWriter : MessageWriter
|
||||
{
|
||||
private readonly TextWriter _writer;
|
||||
|
||||
public CsvMessageWriter(Stream stream, RenderContext context)
|
||||
public CsvMessageWriter(Stream stream, ExportContext context)
|
||||
: base(stream, context)
|
||||
{
|
||||
_writer = new StreamWriter(stream);
|
||||
|
|
|
@ -13,7 +13,7 @@ using Tyrrrz.Extensions;
|
|||
|
||||
namespace DiscordChatExporter.Domain.Exporting.Writers
|
||||
{
|
||||
internal partial class HtmlMessageWriter : MessageWriterBase
|
||||
internal partial class HtmlMessageWriter : MessageWriter
|
||||
{
|
||||
private readonly TextWriter _writer;
|
||||
private readonly string _themeName;
|
||||
|
@ -25,7 +25,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
|
|||
|
||||
private long _messageCount;
|
||||
|
||||
public HtmlMessageWriter(Stream stream, RenderContext context, string themeName)
|
||||
public HtmlMessageWriter(Stream stream, ExportContext context, string themeName)
|
||||
: base(stream, context)
|
||||
{
|
||||
_writer = new StreamWriter(stream);
|
||||
|
|
|
@ -7,13 +7,13 @@ using DiscordChatExporter.Domain.Internal;
|
|||
|
||||
namespace DiscordChatExporter.Domain.Exporting.Writers
|
||||
{
|
||||
internal class JsonMessageWriter : MessageWriterBase
|
||||
internal class JsonMessageWriter : MessageWriter
|
||||
{
|
||||
private readonly Utf8JsonWriter _writer;
|
||||
|
||||
private long _messageCount;
|
||||
|
||||
public JsonMessageWriter(Stream stream, RenderContext context)
|
||||
public JsonMessageWriter(Stream stream, ExportContext context)
|
||||
: base(stream, context)
|
||||
{
|
||||
_writer = new Utf8JsonWriter(stream, new JsonWriterOptions
|
||||
|
|
|
@ -12,11 +12,11 @@ namespace DiscordChatExporter.Domain.Exporting.Writers.MarkdownVisitors
|
|||
{
|
||||
internal partial class HtmlMarkdownVisitor : MarkdownVisitor
|
||||
{
|
||||
private readonly RenderContext _context;
|
||||
private readonly ExportContext _context;
|
||||
private readonly StringBuilder _buffer;
|
||||
private readonly bool _isJumbo;
|
||||
|
||||
public HtmlMarkdownVisitor(RenderContext context, StringBuilder buffer, bool isJumbo)
|
||||
public HtmlMarkdownVisitor(ExportContext context, StringBuilder buffer, bool isJumbo)
|
||||
{
|
||||
_context = context;
|
||||
_buffer = buffer;
|
||||
|
@ -162,7 +162,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers.MarkdownVisitors
|
|||
{
|
||||
private static string HtmlEncode(string text) => WebUtility.HtmlEncode(text);
|
||||
|
||||
public static string Format(RenderContext context, string markdown)
|
||||
public static string Format(ExportContext context, string markdown)
|
||||
{
|
||||
var nodes = MarkdownParser.Parse(markdown);
|
||||
var isJumbo = nodes.All(n => n is EmojiNode || n is TextNode textNode && string.IsNullOrWhiteSpace(textNode.Text));
|
||||
|
|
|
@ -8,10 +8,10 @@ namespace DiscordChatExporter.Domain.Exporting.Writers.MarkdownVisitors
|
|||
{
|
||||
internal partial class PlainTextMarkdownVisitor : MarkdownVisitor
|
||||
{
|
||||
private readonly RenderContext _context;
|
||||
private readonly ExportContext _context;
|
||||
private readonly StringBuilder _buffer;
|
||||
|
||||
public PlainTextMarkdownVisitor(RenderContext context, StringBuilder buffer)
|
||||
public PlainTextMarkdownVisitor(ExportContext context, StringBuilder buffer)
|
||||
{
|
||||
_context = context;
|
||||
_buffer = buffer;
|
||||
|
@ -64,7 +64,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers.MarkdownVisitors
|
|||
|
||||
internal partial class PlainTextMarkdownVisitor
|
||||
{
|
||||
public static string Format(RenderContext context, string markdown)
|
||||
public static string Format(ExportContext context, string markdown)
|
||||
{
|
||||
var nodes = MarkdownParser.ParseMinimal(markdown);
|
||||
var buffer = new StringBuilder();
|
||||
|
|
|
@ -5,13 +5,13 @@ using DiscordChatExporter.Domain.Discord.Models;
|
|||
|
||||
namespace DiscordChatExporter.Domain.Exporting.Writers
|
||||
{
|
||||
internal abstract class MessageWriterBase : IAsyncDisposable
|
||||
internal abstract class MessageWriter : IAsyncDisposable
|
||||
{
|
||||
protected Stream Stream { get; }
|
||||
|
||||
protected RenderContext Context { get; }
|
||||
protected ExportContext Context { get; }
|
||||
|
||||
protected MessageWriterBase(Stream stream, RenderContext context)
|
||||
protected MessageWriter(Stream stream, ExportContext context)
|
||||
{
|
||||
Stream = stream;
|
||||
Context = context;
|
|
@ -10,13 +10,13 @@ using DiscordChatExporter.Domain.Internal;
|
|||
|
||||
namespace DiscordChatExporter.Domain.Exporting.Writers
|
||||
{
|
||||
internal class PlainTextMessageWriter : MessageWriterBase
|
||||
internal class PlainTextMessageWriter : MessageWriter
|
||||
{
|
||||
private readonly TextWriter _writer;
|
||||
|
||||
private long _messageCount;
|
||||
|
||||
public PlainTextMessageWriter(Stream stream, RenderContext context)
|
||||
public PlainTextMessageWriter(Stream stream, ExportContext context)
|
||||
: base(stream, context)
|
||||
{
|
||||
_writer = new StreamWriter(stream);
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
|||
var channel = Channels.Single();
|
||||
|
||||
// Generate default file name
|
||||
var defaultFileName = Exporter.GetDefaultExportFileName(SelectedFormat, Guild!, channel!, After, Before);
|
||||
var defaultFileName = ChannelExporter.GetDefaultExportFileName(Guild!, channel!, SelectedFormat, After, Before);
|
||||
|
||||
// Generate filter
|
||||
var ext = SelectedFormat.GetFileExtension();
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
|
||||
private DiscordClient GetDiscordClient(AuthToken token) => new DiscordClient(token);
|
||||
|
||||
private Exporter GetExporter(AuthToken token) => new Exporter(GetDiscordClient(token));
|
||||
private ChannelExporter GetChannelExporter(AuthToken token) => new ChannelExporter(GetDiscordClient(token));
|
||||
|
||||
private async Task HandleAutoUpdateAsync()
|
||||
{
|
||||
|
@ -261,7 +261,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
|
||||
try
|
||||
{
|
||||
await GetExporter(token).ExportChatLogAsync(dialog.Guild!, channel!,
|
||||
await GetChannelExporter(token).ExportAsync(dialog.Guild!, channel!,
|
||||
dialog.OutputPath!, dialog.SelectedFormat, _settingsService.DateFormat,
|
||||
dialog.PartitionLimit, dialog.After, dialog.Before, operation);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue