2022-06-17 15:06:12 -04:00
|
|
|
|
using System;
|
2023-07-29 13:47:43 -04:00
|
|
|
|
using System.Globalization;
|
2022-06-17 15:06:12 -04:00
|
|
|
|
using System.IO;
|
2020-07-18 08:45:09 -04:00
|
|
|
|
using System.Text;
|
2021-01-28 15:01:13 -05:00
|
|
|
|
using System.Text.RegularExpressions;
|
2021-02-21 20:15:09 -05:00
|
|
|
|
using DiscordChatExporter.Core.Discord;
|
|
|
|
|
using DiscordChatExporter.Core.Discord.Data;
|
2021-07-07 15:14:40 -04:00
|
|
|
|
using DiscordChatExporter.Core.Exporting.Filtering;
|
2021-04-16 16:09:08 -04:00
|
|
|
|
using DiscordChatExporter.Core.Exporting.Partitioning;
|
2021-02-21 20:15:09 -05:00
|
|
|
|
using DiscordChatExporter.Core.Utils;
|
2024-01-15 16:58:28 -05:00
|
|
|
|
using DiscordChatExporter.Core.Utils.Extensions;
|
2020-07-18 08:45:09 -04:00
|
|
|
|
|
2021-12-08 16:50:21 -05:00
|
|
|
|
namespace DiscordChatExporter.Core.Exporting;
|
|
|
|
|
|
2023-02-17 14:30:10 -05:00
|
|
|
|
public partial class ExportRequest
|
2020-07-18 08:45:09 -04:00
|
|
|
|
{
|
2023-02-17 14:30:10 -05:00
|
|
|
|
public Guild Guild { get; }
|
|
|
|
|
|
2023-07-16 15:55:36 -04:00
|
|
|
|
public Channel Channel { get; }
|
2023-02-17 14:30:10 -05:00
|
|
|
|
|
|
|
|
|
public string OutputFilePath { get; }
|
|
|
|
|
|
|
|
|
|
public string OutputDirPath { get; }
|
|
|
|
|
|
|
|
|
|
public string AssetsDirPath { get; }
|
|
|
|
|
|
|
|
|
|
public ExportFormat Format { get; }
|
|
|
|
|
|
|
|
|
|
public Snowflake? After { get; }
|
|
|
|
|
|
|
|
|
|
public Snowflake? Before { get; }
|
|
|
|
|
|
|
|
|
|
public PartitionLimit PartitionLimit { get; }
|
|
|
|
|
|
|
|
|
|
public MessageFilter MessageFilter { get; }
|
|
|
|
|
|
|
|
|
|
public bool ShouldFormatMarkdown { get; }
|
|
|
|
|
|
|
|
|
|
public bool ShouldDownloadAssets { get; }
|
|
|
|
|
|
|
|
|
|
public bool ShouldReuseAssets { get; }
|
|
|
|
|
|
2024-01-15 16:58:28 -05:00
|
|
|
|
public string? Locale { get; }
|
2023-09-07 07:34:08 -04:00
|
|
|
|
|
2024-01-15 16:58:28 -05:00
|
|
|
|
public CultureInfo? CultureInfo { get; }
|
2023-09-07 07:34:08 -04:00
|
|
|
|
|
|
|
|
|
public bool IsUtcNormalizationEnabled { get; }
|
2023-02-17 14:30:10 -05:00
|
|
|
|
|
|
|
|
|
public ExportRequest(
|
|
|
|
|
Guild guild,
|
2023-07-16 15:55:36 -04:00
|
|
|
|
Channel channel,
|
2023-02-17 14:30:10 -05:00
|
|
|
|
string outputPath,
|
|
|
|
|
string? assetsDirPath,
|
|
|
|
|
ExportFormat format,
|
|
|
|
|
Snowflake? after,
|
|
|
|
|
Snowflake? before,
|
|
|
|
|
PartitionLimit partitionLimit,
|
|
|
|
|
MessageFilter messageFilter,
|
|
|
|
|
bool shouldFormatMarkdown,
|
|
|
|
|
bool shouldDownloadAssets,
|
|
|
|
|
bool shouldReuseAssets,
|
2024-01-15 16:58:28 -05:00
|
|
|
|
string? locale,
|
2023-09-07 07:34:08 -04:00
|
|
|
|
bool isUtcNormalizationEnabled
|
2023-08-22 14:17:19 -04:00
|
|
|
|
)
|
2023-02-17 14:30:10 -05:00
|
|
|
|
{
|
|
|
|
|
Guild = guild;
|
|
|
|
|
Channel = channel;
|
|
|
|
|
Format = format;
|
|
|
|
|
After = after;
|
|
|
|
|
Before = before;
|
|
|
|
|
PartitionLimit = partitionLimit;
|
|
|
|
|
MessageFilter = messageFilter;
|
|
|
|
|
ShouldFormatMarkdown = shouldFormatMarkdown;
|
|
|
|
|
ShouldDownloadAssets = shouldDownloadAssets;
|
|
|
|
|
ShouldReuseAssets = shouldReuseAssets;
|
2023-09-07 07:34:08 -04:00
|
|
|
|
Locale = locale;
|
|
|
|
|
IsUtcNormalizationEnabled = isUtcNormalizationEnabled;
|
2023-02-17 14:30:10 -05:00
|
|
|
|
|
2023-08-22 14:17:19 -04:00
|
|
|
|
OutputFilePath = GetOutputBaseFilePath(Guild, Channel, outputPath, Format, After, Before);
|
2023-02-17 14:30:10 -05:00
|
|
|
|
|
|
|
|
|
OutputDirPath = Path.GetDirectoryName(OutputFilePath)!;
|
|
|
|
|
|
|
|
|
|
AssetsDirPath = !string.IsNullOrWhiteSpace(assetsDirPath)
|
2023-08-22 14:17:19 -04:00
|
|
|
|
? FormatPath(assetsDirPath, Guild, Channel, After, Before)
|
2023-02-17 14:30:10 -05:00
|
|
|
|
: $"{OutputFilePath}_Files{Path.DirectorySeparatorChar}";
|
2023-09-07 07:34:08 -04:00
|
|
|
|
|
2024-01-15 16:58:28 -05:00
|
|
|
|
CultureInfo = Locale?.Pipe(CultureInfo.GetCultureInfo);
|
2023-02-17 14:30:10 -05:00
|
|
|
|
}
|
2021-12-08 16:50:21 -05:00
|
|
|
|
}
|
2020-07-18 08:45:09 -04:00
|
|
|
|
|
2023-02-17 14:30:10 -05:00
|
|
|
|
public partial class ExportRequest
|
2021-12-08 16:50:21 -05:00
|
|
|
|
{
|
|
|
|
|
public static string GetDefaultOutputFileName(
|
|
|
|
|
Guild guild,
|
2023-07-16 15:55:36 -04:00
|
|
|
|
Channel channel,
|
2021-12-08 16:50:21 -05:00
|
|
|
|
ExportFormat format,
|
|
|
|
|
Snowflake? after = null,
|
2023-08-22 14:17:19 -04:00
|
|
|
|
Snowflake? before = null
|
|
|
|
|
)
|
2021-12-08 16:50:21 -05:00
|
|
|
|
{
|
|
|
|
|
var buffer = new StringBuilder();
|
|
|
|
|
|
2023-09-07 09:36:29 -04:00
|
|
|
|
// Guild name
|
|
|
|
|
buffer.Append(guild.Name);
|
|
|
|
|
|
|
|
|
|
// Parent name
|
|
|
|
|
if (channel.Parent is not null)
|
|
|
|
|
buffer.Append(" - ").Append(channel.Parent.Name);
|
|
|
|
|
|
|
|
|
|
// Channel name and ID
|
|
|
|
|
buffer
|
|
|
|
|
.Append(" - ")
|
|
|
|
|
.Append(channel.Name)
|
|
|
|
|
.Append(' ')
|
|
|
|
|
.Append('[')
|
|
|
|
|
.Append(channel.Id)
|
|
|
|
|
.Append(']');
|
2021-12-08 16:50:21 -05:00
|
|
|
|
|
|
|
|
|
// Date range
|
|
|
|
|
if (after is not null || before is not null)
|
|
|
|
|
{
|
2022-04-06 12:43:10 -04:00
|
|
|
|
buffer.Append(' ').Append('(');
|
2020-07-18 08:45:09 -04:00
|
|
|
|
|
2021-12-08 16:50:21 -05:00
|
|
|
|
// Both 'after' and 'before' are set
|
|
|
|
|
if (after is not null && before is not null)
|
|
|
|
|
{
|
2023-08-22 14:17:19 -04:00
|
|
|
|
buffer.Append(
|
|
|
|
|
$"{after.Value.ToDate():yyyy-MM-dd} to {before.Value.ToDate():yyyy-MM-dd}"
|
|
|
|
|
);
|
2021-12-08 16:50:21 -05:00
|
|
|
|
}
|
|
|
|
|
// Only 'after' is set
|
|
|
|
|
else if (after is not null)
|
2020-07-18 08:45:09 -04:00
|
|
|
|
{
|
2021-12-08 16:50:21 -05:00
|
|
|
|
buffer.Append($"after {after.Value.ToDate():yyyy-MM-dd}");
|
|
|
|
|
}
|
|
|
|
|
// Only 'before' is set
|
|
|
|
|
else if (before is not null)
|
|
|
|
|
{
|
|
|
|
|
buffer.Append($"before {before.Value.ToDate():yyyy-MM-dd}");
|
2020-07-18 08:45:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-06 12:43:10 -04:00
|
|
|
|
buffer.Append(')');
|
2021-12-08 16:50:21 -05:00
|
|
|
|
}
|
2020-07-18 08:45:09 -04:00
|
|
|
|
|
2021-12-08 16:50:21 -05:00
|
|
|
|
// File extension
|
2022-04-06 12:43:10 -04:00
|
|
|
|
buffer.Append('.').Append(format.GetFileExtension());
|
2020-07-18 08:45:09 -04:00
|
|
|
|
|
2021-12-13 14:02:11 -05:00
|
|
|
|
return PathEx.EscapeFileName(buffer.ToString());
|
2020-07-18 08:45:09 -04:00
|
|
|
|
}
|
2023-01-03 03:34:53 -05:00
|
|
|
|
|
2023-02-17 14:30:10 -05:00
|
|
|
|
private static string FormatPath(
|
2023-02-17 13:48:20 -05:00
|
|
|
|
string path,
|
2023-01-03 03:34:53 -05:00
|
|
|
|
Guild guild,
|
2023-07-16 15:55:36 -04:00
|
|
|
|
Channel channel,
|
2023-02-17 13:48:20 -05:00
|
|
|
|
Snowflake? after,
|
2023-08-22 14:17:19 -04:00
|
|
|
|
Snowflake? before
|
2023-09-07 09:36:29 -04:00
|
|
|
|
) =>
|
|
|
|
|
Regex.Replace(
|
2023-02-17 13:48:20 -05:00
|
|
|
|
path,
|
2023-01-03 03:44:31 -05:00
|
|
|
|
"%.",
|
2023-08-22 14:17:19 -04:00
|
|
|
|
m =>
|
|
|
|
|
PathEx.EscapeFileName(
|
|
|
|
|
m.Value switch
|
|
|
|
|
{
|
|
|
|
|
"%g" => guild.Id.ToString(),
|
|
|
|
|
"%G" => guild.Name,
|
2023-09-07 09:36:29 -04:00
|
|
|
|
|
2023-08-22 14:17:19 -04:00
|
|
|
|
"%t" => channel.Parent?.Id.ToString() ?? "",
|
|
|
|
|
"%T" => channel.Parent?.Name ?? "",
|
2023-09-07 09:36:29 -04:00
|
|
|
|
|
2023-08-22 14:17:19 -04:00
|
|
|
|
"%c" => channel.Id.ToString(),
|
|
|
|
|
"%C" => channel.Name,
|
2023-09-07 09:36:29 -04:00
|
|
|
|
|
2023-08-22 14:17:19 -04:00
|
|
|
|
"%p" => channel.Position?.ToString(CultureInfo.InvariantCulture) ?? "0",
|
|
|
|
|
"%P"
|
|
|
|
|
=> channel.Parent?.Position?.ToString(CultureInfo.InvariantCulture)
|
|
|
|
|
?? "0",
|
2023-09-07 09:36:29 -04:00
|
|
|
|
|
2023-08-22 14:17:19 -04:00
|
|
|
|
"%a"
|
|
|
|
|
=> after?.ToDate().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
|
|
|
|
|
?? "",
|
|
|
|
|
"%b"
|
|
|
|
|
=> before?.ToDate().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
|
|
|
|
|
?? "",
|
|
|
|
|
"%d"
|
2023-12-28 17:08:16 -05:00
|
|
|
|
=> DateTimeOffset.Now.ToString(
|
|
|
|
|
"yyyy-MM-dd",
|
|
|
|
|
CultureInfo.InvariantCulture
|
|
|
|
|
),
|
2023-09-07 09:36:29 -04:00
|
|
|
|
|
2023-08-22 14:17:19 -04:00
|
|
|
|
"%%" => "%",
|
|
|
|
|
_ => m.Value
|
|
|
|
|
}
|
|
|
|
|
)
|
2023-02-17 14:30:10 -05:00
|
|
|
|
);
|
2023-02-17 13:48:20 -05:00
|
|
|
|
|
|
|
|
|
private static string GetOutputBaseFilePath(
|
|
|
|
|
Guild guild,
|
2023-07-16 15:55:36 -04:00
|
|
|
|
Channel channel,
|
2023-02-17 13:48:20 -05:00
|
|
|
|
string outputPath,
|
|
|
|
|
ExportFormat format,
|
|
|
|
|
Snowflake? after = null,
|
2023-08-22 14:17:19 -04:00
|
|
|
|
Snowflake? before = null
|
|
|
|
|
)
|
2023-02-17 13:48:20 -05:00
|
|
|
|
{
|
2023-02-17 14:30:10 -05:00
|
|
|
|
var actualOutputPath = FormatPath(outputPath, guild, channel, after, before);
|
2023-01-03 03:34:53 -05:00
|
|
|
|
|
|
|
|
|
// Output is a directory
|
2023-08-22 14:17:19 -04:00
|
|
|
|
if (
|
|
|
|
|
Directory.Exists(actualOutputPath)
|
|
|
|
|
|| string.IsNullOrWhiteSpace(Path.GetExtension(actualOutputPath))
|
|
|
|
|
)
|
2023-01-03 03:34:53 -05:00
|
|
|
|
{
|
|
|
|
|
var fileName = GetDefaultOutputFileName(guild, channel, format, after, before);
|
|
|
|
|
return Path.Combine(actualOutputPath, fileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Output is a file
|
|
|
|
|
return actualOutputPath;
|
|
|
|
|
}
|
2023-08-22 14:17:19 -04:00
|
|
|
|
}
|