#pragma warning disable CS8618 using System; using System.Linq; using System.Net.Http.Json; using Ical.Net; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml; using HtmlAgilityPack; using System.Diagnostics; using Newtonsoft.Json; namespace newsletter { class Program { static async Task Main(string[] args) { var conf = Configure(); if (conf == null) return; var reports = await CollectReports(CollectReporters(conf)); var fullHtml = AssembleHTML(reports.Select(r => r.ReportContent)); fullHtml.Save(conf.ExportPath); } static Configuration Configure(string configurationPath = "appsettings.json") { if (!File.Exists(configurationPath)) { Console.Error.WriteLine($"could not find configuration at {configurationPath}! copying sample to that spot."); File.Copy("sample-appsettings.json", configurationPath); //and you know what, if that explodes at the OS level, the OS should give you an error return null; } var fileContents = File.ReadAllText(configurationPath); if (string.IsNullOrWhiteSpace(fileContents)) { Console.Error.WriteLine($"configuration file at {configurationPath} was empty! overwriting with sample settings."); File.Copy("sample-appsettings.json", configurationPath, true); return null; } var conf = JsonConvert.DeserializeObject(fileContents); if (conf == null) { Console.Error.WriteLine($"configuration file at {configurationPath} was empty! overwriting with sample settings."); File.Copy("sample-appsettings.json", configurationPath, true); return null; } return conf; } static List> CollectReporters(Configuration conf) { var toReturn = new List>(); var reporterTypes = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(domainAssembly => domainAssembly.GetTypes()) .Where(type => type.IsSubclassOf(typeof(newsletter.Reporters.Reporter)) && !type.IsAbstract) .ToList(); var skipPortionInName = "newsletter.Reporters.".Length; foreach(var discoveredConfType in conf.Reporters.Select(r => r.ReporterClass)) { Console.WriteLine($"{discoveredConfType} configuration type discovered"); } foreach (var reporterType in reporterTypes) { Console.WriteLine($"{reporterType.ToString().Substring(skipPortionInName).ToLower()} reporter class discovered"); Func predicate = r => r.ReporterClass == reporterType.ToString().Substring(skipPortionInName).ToLower(); if (!conf.Reporters.Any(predicate)) { Console.WriteLine($"no configurations for it"); } else { var configurationsFor = conf.Reporters.Where(predicate); Console.WriteLine($"{configurationsFor.Count()} configurations for it"); foreach (var confFor in configurationsFor) { var instance = (newsletter.Reporters.Reporter) Activator.CreateInstance(reporterType); toReturn.Add(instance.Report(confFor)); } } } return toReturn; } static async Task> CollectReports(List> tasks) { var results = new List(); foreach (var task in tasks) { var rep = await task; results.Add(rep); } return results; } static HtmlDocument AssembleHTML(IEnumerable reportSections) { //TODO Console.WriteLine($"assembling {reportSections.Count()} sections"); throw new NotImplementedException(); } } }