using System; using System.IO; using System.Threading.Tasks; using System.Xml; using System.ServiceModel.Syndication; using System.Linq; using System.Collections.Generic; using System.Net.Http; using Newtonsoft.Json; using Discord; namespace rssberg { class Program { private const string archivePath = "doneIDs.txt"; private const string configPath = "config.json"; static readonly HttpClient client = new HttpClient(); static List doneIDs; static void Main(string[] args) { if (!File.Exists(configPath)){ File.CreateText(configPath); var sampleCfg = new Config(); sampleCfg.FeedPairs.Add("rss", "webhook"); File.WriteAllText(configPath, JsonConvert.SerializeObject(sampleCfg)); } var cfg = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); Console.WriteLine("rss reader alive"); if (!File.Exists(archivePath)) { File.CreateText(archivePath); } doneIDs = File.ReadAllLines(archivePath).ToList(); var postMetaTasks = new List(); foreach (var kvp in cfg.FeedPairs.ToList()) { postMetaTasks.Add(rss2webhook(kvp.Key, kvp.Value)); } Console.WriteLine($"rss reader collected {postMetaTasks.Count} post metatasks"); Task.WaitAll(postMetaTasks.ToArray()); while(doneIDs.Count > 5000){ doneIDs.RemoveAt(0); } File.WriteAllLines(archivePath, doneIDs); Console.WriteLine("rss reader actually done"); } private static async Task rss2webhook(string key, string value) { var postTasks = new List>(); postTasks.Add(Task.Run(() => {return (ulong)1;})); //dummy task for debugging var responseStream = await client.GetStreamAsync(key); var wh = new Discord.Webhook.DiscordWebhookClient(value); using (XmlReader xr = XmlReader.Create(responseStream)) { var feed = SyndicationFeed.Load(xr); foreach (var item in feed.Items) { var date = item.PublishDate; if(item.LastUpdatedTime > item.PublishDate) { date = item.LastUpdatedTime; //imo the library should automatically set last updated to created, in this case //but I think that would break with tradition in a painful way, so meh } if(!doneIDs.Contains(item.Id) && DateTime.UtcNow - date < TimeSpan.FromDays(5)) { // var sb = new StringBuilder(); // using(XmlWriter xw = XmlWriter.Create(sb)){ // item.Content.WriteTo(xw, "html", null); // } Console.WriteLine($"to post! {item.Id} {item.Title?.Text}"); doneIDs.Add(item.Id); postTasks.Add(wh.SendMessageAsync(item.Title?.Text + ' ' + item.Links?.ToList().FirstOrDefault()?.Uri.ToString())); } } } Task.WaitAll(postTasks.ToArray()); } static async Task> rssArticles(string rssURL) { var toReturn = new List(); var responseStream = await client.GetStreamAsync(rssURL); using (XmlReader xr = XmlReader.Create(responseStream)) { var feed = SyndicationFeed.Load(xr); foreach (var item in feed.Items) { if(!doneIDs.Contains(item.Id)) { toReturn.Add(item); } } } return toReturn; } } }