// !! MAY HAVE BUGS private async Task ExportChatLogAsync(ChatLog chatLog, string filePath, ExportFormat format, string S3BucketName = null) { // Create output directory var dirPath = Path.GetDirectoryName(filePath); if (!dirPath.IsNullOrWhiteSpace()) { Directory.CreateDirectory(dirPath); } // Render chat log to output file using (var writer = File.CreateText(filePath)) { var renderer = new CsvChatLogRenderer(filePath, _settingsService.DateFormat); await renderer.RenderAsync(chatLog); } if (S3BucketName != null) { await UploadToS3(S3BucketName, filePath); } }
public async Task GetAndExportChannelMessagesAsync(AuthToken token, Guild guild, Channel channel, CsvChatLogRenderer renderer, DateTimeOffset?after = null, DateTimeOffset?before = null, IProgress <double> progress = null) { Message firstMsg = null, currentLastMsg = null; Mentionables mentionables = null; // Get the last message JToken response = await GetApiResponseAsync(token, "channels", $"{channel.Id}/messages", "limit=1", $"before={before?.ToSnowflake()}"); Message lastMessage = response.Select(ParseMessage).FirstOrDefault(); // If the last message doesn't exist or it's outside of range - return if (lastMessage == null || lastMessage.Timestamp < after) { progress?.Report(1); return; } // Get other messages string offsetId = after?.ToSnowflake() ?? "0"; while (true) { // Get message batch response = await GetApiResponseAsync(token, "channels", $"{channel.Id}/messages", "limit=1000", $"after={offsetId}"); // Parse Message[] messages = response .Select(ParseMessage) .Reverse() // reverse because messages appear newest first .ToArray(); // Break if there are no messages (can happen if messages are deleted during execution) if (!messages.Any()) { break; } // Trim messages to range (until last message) Message[] messagesInRange = messages .TakeWhile(m => m.Id != lastMessage.Id && m.Timestamp < lastMessage.Timestamp) .ToArray(); mentionables = await GetMentionablesAsync(token, guild.Id, messagesInRange); await renderer.RenderAsync(new ChatLog(guild, channel, after, before, messagesInRange, mentionables)); // Break if messages were trimmed (which means the last message was encountered) if (messagesInRange.Length != messages.Length) { break; } if (firstMsg == null) { firstMsg = messagesInRange.First(); } currentLastMsg = messagesInRange.Last(); // Report progress (based on the time range of parsed messages compared to total) progress?.Report((currentLastMsg.Timestamp - firstMsg.Timestamp).TotalSeconds / (lastMessage.Timestamp - firstMsg.Timestamp).TotalSeconds); // Move offset offsetId = currentLastMsg.Id; } var lastMessageList = new Message[] { lastMessage }; mentionables = await GetMentionablesAsync(token, guild.Id, lastMessageList); await renderer.RenderAsync(new ChatLog(guild, channel, after, before, lastMessageList, mentionables)); // Report progress progress?.Report(1); }