DiscordChatExporter/DiscordChatExporter.Core.Rendering/FacadeMessageRenderer.cs
2020-01-11 14:18:04 +02:00

125 lines
4.1 KiB
C#

using System;
using System.IO;
using System.Threading.Tasks;
using DiscordChatExporter.Core.Models;
namespace DiscordChatExporter.Core.Rendering
{
public partial class FacadeMessageRenderer : IMessageRenderer
{
private readonly string _baseFilePath;
private readonly ExportFormat _format;
private readonly RenderContext _context;
private readonly int? _partitionLimit;
private long _renderedMessageCount;
private int _partitionIndex;
private TextWriter _writer;
private IMessageRenderer _innerRenderer;
public FacadeMessageRenderer(string baseFilePath, ExportFormat format, RenderContext context, int? partitionLimit)
{
_baseFilePath = baseFilePath;
_format = format;
_context = context;
_partitionLimit = partitionLimit;
}
private void EnsureInnerRendererInitialized()
{
if (_writer != null && _innerRenderer != null)
return;
// Get partition file path
var filePath = GetPartitionFilePath(_baseFilePath, _partitionIndex);
// Create output directory
var dirPath = Path.GetDirectoryName(_baseFilePath);
if (!string.IsNullOrWhiteSpace(dirPath))
Directory.CreateDirectory(dirPath);
// Create writer
_writer = File.CreateText(filePath);
// Create inner renderer
if (_format == ExportFormat.PlainText)
{
_innerRenderer = new PlainTextMessageRenderer(_writer, _context);
}
else if (_format == ExportFormat.Csv)
{
_innerRenderer = new CsvMessageRenderer(_writer, _context);
}
else if (_format == ExportFormat.HtmlDark)
{
_innerRenderer = new HtmlMessageRenderer(_writer, _context, "Dark");
}
else if (_format == ExportFormat.HtmlLight)
{
_innerRenderer = new HtmlMessageRenderer(_writer, _context, "Light");
}
else
{
throw new InvalidOperationException($"Unknown export format [{_format}].");
}
}
private async Task ResetInnerRendererAsync()
{
if (_innerRenderer != null)
{
await _innerRenderer.DisposeAsync();
_innerRenderer = null;
}
if (_writer != null)
{
await _writer.DisposeAsync();
_writer = null;
}
}
public async Task RenderMessageAsync(Message message)
{
// Ensure underlying writer and renderer are initialized
EnsureInnerRendererInitialized();
// Render the actual message
await _innerRenderer.RenderMessageAsync(message);
// Increment count
_renderedMessageCount++;
// Update partition if necessary
if (_partitionLimit != null && _partitionLimit != 0 && _renderedMessageCount % _partitionLimit == 0)
{
await ResetInnerRendererAsync();
_partitionIndex++;
}
}
public async ValueTask DisposeAsync() => await ResetInnerRendererAsync();
}
public partial class FacadeMessageRenderer
{
private static string GetPartitionFilePath(string baseFilePath, int partitionIndex)
{
// First partition - no changes
if (partitionIndex <= 0)
return baseFilePath;
// Inject partition index into file name
var fileNameWithoutExt = Path.GetFileNameWithoutExtension(baseFilePath);
var fileExt = Path.GetExtension(baseFilePath);
var fileName = $"{fileNameWithoutExt} [part {partitionIndex + 1}]{fileExt}";
// Generate new path
var dirPath = Path.GetDirectoryName(baseFilePath);
if (!string.IsNullOrWhiteSpace(dirPath))
return Path.Combine(dirPath, fileName);
return fileName;
}
}
}