/// <summary> /// Converts the Discord.Net IMessage, downloads atatchments, and writes. /// </summary> /// <param name="message">The Discord.Net IMessage to be written.</param> /// <returns>The CsvMessage version of the Discord.Net IMessage.</returns> private CsvMessage ConvertMessageAndWrite(IMessage message) { DownloadResults attachments = DownloadAttachments(message); CsvMessage msg = new CsvMessage(message, attachments, _timeZone); _csv.WriteRecord(msg); _csv.NextRecord(); Console.WriteLine($"Wrote message #{_msgWritten}"); _msgWritten++; return(msg); }
/// <summary> /// Creates a CsvMessage from a Discord.Net IMessage. /// </summary> /// <param name="message">A Discord.Net IMessage.</param> /// <param name="attachments">Result of each Discord attachment download.</param> /// <param name="timeZone">The time zone to format the timestamps to.</param> public CsvMessage(IMessage message, DownloadResults attachments, TimeSpan timeZone) { Time = ConvertTimeAndFormat(message.Timestamp, timeZone); User = $"{message.Author.Username}#{message.Author.Discriminator}"; Message = message.Content; Embed = JsonSerializer.Serialize(message.Embeds, JSON_OPTIONS); Attachments = JsonSerializer.Serialize(attachments.Success, JSON_OPTIONS); FailedAttachments = JsonSerializer.Serialize(attachments.Failed, JSON_OPTIONS); LastEdited = ConvertTimeAndFormat(message.EditedTimestamp, timeZone); Pinned = message.IsPinned.ToString(); Tts = message.IsTTS.ToString(); Id = message.Id; }
/// <summary> /// Calls CsvMessage(IMessage message, DownloadResults attachments, TimeSpan timeZone), /// but converting the TimeZone string to a TimeSpan. /// </summary> /// <param name="message">A Discord.Net IMessage.</param> /// <param name="attachments">Result of each Discord attachment download.</param> /// <param name="timeZone">The time zone to format the timestamps to, as a string.</param> public CsvMessage(IMessage message, DownloadResults attachments, string timeZone) : this(message, attachments, TimeSpan.Parse(timeZone.Replace("+", ""))) // time zone should not have a + { // empty }
/// <summary> /// Downloads the attachment(s) that are part of the message. /// Note the downloads are not async. /// </summary> /// <param name="message">The message with attachments.</param> /// <returns>Results of all attachments in this message.</returns> private DownloadResults DownloadAttachments(IMessage message) { DownloadResults results = new DownloadResults(); if (message.Attachments.Count == 0) { return(results); } if (!_includeAttachments) { foreach (IAttachment attachment in message.Attachments) { results.Failed.Add(attachment.Filename); } return(results); } string path = Path.Join(_path, FILES_DIR, message.Id.ToString()); Directory.CreateDirectory(path); uint count = 0; foreach (IAttachment attachment in message.Attachments) { string filePath = Path.Join(path, attachment.Filename); string subdir = Path.Join(FILES_DIR, attachment.Filename); // for writing attachments/msgId/filename for easier reading in tsv // basic duplicate checking/renaming just in case... // but i think shouldn't be possible to have attachments with duplicate file names while (File.Exists(filePath)) { count++; filePath += $"_{count}"; subdir += $"_{count}"; } // attempt proxy url download first try { using (WebClient client = new WebClient()) { client.DownloadFile(attachment.ProxyUrl, filePath); results.Success.Add(attachment.Filename); } continue; } catch (Exception ex) { Console.WriteLine($"An error occurred while downloading {attachment.ProxyUrl}, trying another URL."); } // fallback to original url if cdn failed, which does seem to happen try { using (WebClient client = new WebClient()) { client.DownloadFile(attachment.Url, filePath); results.Success.Add(attachment.Filename); } } catch (Exception ex) { Console.WriteLine($"An error occurred while downloading {attachment.Url}. This attachment will be skipped."); results.Failed.Add(attachment.Filename); } } return(results); }