DiscordChatExporter/DiscordChatExporter.Cli.Tests/Infra/ExportWrapper.cs

132 lines
4.2 KiB
C#
Raw Normal View History

2021-09-07 18:18:35 -04:00
using System;
2021-09-14 17:33:53 -04:00
using System.Collections.Generic;
2021-09-07 18:18:35 -04:00
using System.IO;
using System.Linq;
2023-02-11 16:12:15 -05:00
using System.Reflection;
2021-09-07 18:18:35 -04:00
using System.Text.Json;
using System.Threading.Tasks;
using AngleSharp.Dom;
using AngleSharp.Html.Dom;
using AsyncKeyedLock;
2021-09-07 18:18:35 -04:00
using CliFx.Infrastructure;
using DiscordChatExporter.Cli.Commands;
using DiscordChatExporter.Cli.Tests.Utils;
using DiscordChatExporter.Core.Discord;
using DiscordChatExporter.Core.Exporting;
using JsonExtensions;
2023-02-11 16:12:15 -05:00
namespace DiscordChatExporter.Cli.Tests.Infra;
2021-12-08 16:50:21 -05:00
2023-02-11 16:12:15 -05:00
public static class ExportWrapper
2021-09-07 18:18:35 -04:00
{
2024-08-26 10:23:29 -04:00
private static readonly AsyncKeyedLocker<string> Locker = new();
2023-02-11 16:12:15 -05:00
private static readonly string DirPath = Path.Combine(
2023-08-22 14:17:19 -04:00
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
?? Directory.GetCurrentDirectory(),
2023-02-11 16:12:15 -05:00
"ExportCache"
2021-12-08 16:50:21 -05:00
);
2021-09-07 18:18:35 -04:00
2023-02-11 16:12:15 -05:00
static ExportWrapper()
{
2023-02-12 06:13:53 -05:00
try
{
Directory.Delete(DirPath, true);
}
2023-08-22 14:17:19 -04:00
catch (DirectoryNotFoundException) { }
2023-02-12 06:13:53 -05:00
2023-02-11 16:12:15 -05:00
Directory.CreateDirectory(DirPath);
}
2021-09-14 17:33:53 -04:00
2023-02-11 16:12:15 -05:00
private static async ValueTask<string> ExportAsync(Snowflake channelId, ExportFormat format)
2021-12-08 16:50:21 -05:00
{
2023-02-13 09:42:03 -05:00
var fileName = channelId.ToString() + '.' + format.GetFileExtension();
var filePath = Path.Combine(DirPath, fileName);
2023-07-03 11:35:28 -04:00
using var _ = await Locker.LockAsync(filePath);
using var console = new FakeConsole();
// Perform the export only if it hasn't been done before
if (!File.Exists(filePath))
2021-12-08 16:50:21 -05:00
{
2023-07-03 11:35:28 -04:00
await new ExportChannelsCommand
2021-09-07 18:18:35 -04:00
{
2023-07-03 11:35:28 -04:00
Token = Secrets.DiscordToken,
2024-01-11 15:21:53 -05:00
ChannelIds = [channelId],
2023-07-03 11:35:28 -04:00
ExportFormat = format,
OutputPath = filePath,
Locale = "en-US",
IsUtcNormalizationEnabled = true
2023-07-03 11:35:28 -04:00
}.ExecuteAsync(console);
}
2023-07-03 11:35:28 -04:00
return await File.ReadAllTextAsync(filePath);
2021-12-08 16:50:21 -05:00
}
2021-09-07 18:18:35 -04:00
2023-08-22 14:17:19 -04:00
public static async ValueTask<IHtmlDocument> ExportAsHtmlAsync(Snowflake channelId) =>
Html.Parse(await ExportAsync(channelId, ExportFormat.HtmlDark));
2023-08-22 14:17:19 -04:00
public static async ValueTask<JsonElement> ExportAsJsonAsync(Snowflake channelId) =>
Json.Parse(await ExportAsync(channelId, ExportFormat.Json));
2021-09-07 18:18:35 -04:00
2023-02-11 16:12:15 -05:00
public static async ValueTask<string> ExportAsPlainTextAsync(Snowflake channelId) =>
2022-06-30 12:07:11 -04:00
await ExportAsync(channelId, ExportFormat.PlainText);
2021-09-07 18:18:35 -04:00
2023-02-11 16:12:15 -05:00
public static async ValueTask<string> ExportAsCsvAsync(Snowflake channelId) =>
2022-06-30 12:07:11 -04:00
await ExportAsync(channelId, ExportFormat.Csv);
2021-09-07 18:18:35 -04:00
2023-08-22 14:17:19 -04:00
public static async ValueTask<IReadOnlyList<IElement>> GetMessagesAsHtmlAsync(
Snowflake channelId
) => (await ExportAsHtmlAsync(channelId)).QuerySelectorAll("[data-message-id]").ToArray();
2021-12-08 16:50:21 -05:00
2023-08-22 14:17:19 -04:00
public static async ValueTask<IReadOnlyList<JsonElement>> GetMessagesAsJsonAsync(
Snowflake channelId
) => (await ExportAsJsonAsync(channelId)).GetProperty("messages").EnumerateArray().ToArray();
2021-12-08 16:50:21 -05:00
2023-08-22 14:17:19 -04:00
public static async ValueTask<IElement> GetMessageAsHtmlAsync(
Snowflake channelId,
Snowflake messageId
)
2021-12-08 16:50:21 -05:00
{
2024-04-26 21:17:46 -04:00
var message = (await GetMessagesAsHtmlAsync(channelId)).SingleOrDefault(e =>
string.Equals(
e.GetAttribute("data-message-id"),
messageId.ToString(),
StringComparison.OrdinalIgnoreCase
)
2023-05-20 00:09:19 -04:00
);
2021-09-07 18:18:35 -04:00
2021-12-08 16:50:21 -05:00
if (message is null)
{
2021-12-08 16:50:21 -05:00
throw new InvalidOperationException(
2023-11-17 11:37:52 -05:00
$"Message #{messageId} not found in the export of channel #{channelId}."
2021-09-14 17:33:53 -04:00
);
2021-12-08 16:50:21 -05:00
}
2021-12-08 16:50:21 -05:00
return message;
}
2023-08-22 14:17:19 -04:00
public static async ValueTask<JsonElement> GetMessageAsJsonAsync(
Snowflake channelId,
Snowflake messageId
)
2021-12-08 16:50:21 -05:00
{
2024-04-26 21:17:46 -04:00
var message = (await GetMessagesAsJsonAsync(channelId)).SingleOrDefault(j =>
string.Equals(
j.GetProperty("id").GetString(),
messageId.ToString(),
StringComparison.OrdinalIgnoreCase
)
2023-05-20 00:09:19 -04:00
);
2021-09-07 18:18:35 -04:00
2021-12-08 16:50:21 -05:00
if (message.ValueKind == JsonValueKind.Undefined)
2021-09-07 18:18:35 -04:00
{
2021-12-08 16:50:21 -05:00
throw new InvalidOperationException(
2023-11-17 11:37:52 -05:00
$"Message #{messageId} not found in the export of channel #{channelId}."
2021-09-14 17:33:53 -04:00
);
2021-09-07 18:18:35 -04:00
}
2021-12-08 16:50:21 -05:00
return message;
2021-09-07 18:18:35 -04:00
}
2023-08-22 14:17:19 -04:00
}