using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using franz; using Ical.Net; using Ical.Net.CalendarComponents; using Ical.Net.DataTypes; using Newtonsoft.Json; namespace director { class Program { //private static Telefranz tf; public static Config conf; private static TimeSpan calendarNaptime = TimeSpan.FromHours(1); private static Scratch scratch; private static HttpClient httpClient; private static DateTime searchStart = DateTime.Now; //is it slower to just call datetime.now every time? /shrug private static DateTime searchEnd = DateTime.Now.AddDays(14); static void Main(string[] args) { if (!File.Exists("appsettings.json")) { Console.Error.WriteLine("appsettings.json was not found!"); return; } conf = JsonConvert.DeserializeObject(File.ReadAllText("appsettings.json")); httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String( System.Text.Encoding.ASCII.GetBytes($"{conf.webdav_username}:{conf.webdav_password}"))); //tf = new Telefranz("scheduler", conf.kafka_bootstrap); scratch = Scratch.LoadScratch(); while (true) { Task.WaitAll( //await and do next calendar task, calendarCheck(), Task.Delay(calendarNaptime) ); } } private static async Task calendarCheck() { //pull calendar ics's try { Task.WaitAll( checkYoutube(), checkTwitch() ); //await checkTwitch(); } catch (Exception e) { Console.Error.WriteLine("sure would be nice if it threw an error"); Console.Error.WriteLine(e); } Console.WriteLine("k."); } private delegate Schedulable.Schedulable schedulableCreate(CalendarEvent evt); private delegate void schedulableUpdate(Schedulable.Schedulable old, CalendarEvent evt); private delegate void schedulableRemove(Schedulable.Schedulable removed); private static async Task checkCalendar(string calendarUri, string calLabel, schedulableCreate createSchedulable, schedulableUpdate updateSchedulable, schedulableRemove removeSchedulable) { //?export is a hack to allow me to access the calendar //it likes to throw an error saying "this is the webDAV interface, use webDAV" at my webDAV client. var calString = await httpClient.GetStringAsync(conf.webdav_uri + calendarUri + "?export"); var calT = Calendar.Load(calString); var knownChecklist = new List(); lock (scratch) { scratch.Calendars[calLabel] = calString; foreach (var s in scratch.agenda) { if (s.Event.Calendar == calT) { knownChecklist.Add(s); } } foreach (var evt in calT.Events) { if(evt.Start.Value >= searchStart && evt.End.Value <= searchEnd) { Console.WriteLine($"[{calLabel}] hi im an event in the search space, {evt.Summary} on {evt.Start}"); } } foreach(var calOccurrence in calT.GetOccurrences(searchStart, searchEnd)) { var asEvent = calOccurrence.Source as Ical.Net.CalendarComponents.CalendarEvent; Console.WriteLine($"[{calLabel}] hi im an occurence in the search space, {asEvent.Summary} on {calOccurrence.Period.StartTime}"); Console.WriteLine($"{asEvent.Uid}"); } // foreach (var evt in calT.Events) // { // var foundInRange = evt.GetOccurrences(searchStart, searchEnd); // if (foundInRange?.Count > 0) // { // Console.WriteLine($"[{calLabel}] event {evt.Summary} has {foundInRange.Count} occurences"); // foreach (var upcoming in foundInRange) // { // if (upcoming != null) // { // Console.WriteLine($"[{calLabel}] event {evt.Summary} has an occurence: {upcoming.Period.StartTime.Date.ToShortDateString()}; uid: {evt.Uid}"); // Console.WriteLine($"Description: {evt.Description}"); // Console.WriteLine($"Calendar: {evt.Calendar}"); // Console.WriteLine($"Children: {evt.Children.Count}"); // Console.WriteLine($"Class: {evt.Class}"); // Console.WriteLine($"stamp: {evt.DtStamp} created: {evt.Created} start: {evt.DtStart} end: {evt.DtEnd}"); // // Console.WriteLine($"Name: {evt.Name}"); // // Console.WriteLine($"Parent: {evt.Parent}"); // // Console.WriteLine($"Properties: {evt.Properties.Count}"); // // if (evt.Properties.Count > 0) // // { // // foreach (var thing in evt.Properties) // // { // // Console.WriteLine($"{thing.Name}: {thing.Value}"); // // } // // } // Console.WriteLine($"RecurrenceRules: {evt.RecurrenceRules.Count}"); // // var existing = scratch.agenda.FirstOrDefault(s => s.Event.Uid == upcoming); // // if(existing == null) // // { // // scratch.agenda.Add(createSchedulable(upcoming)); // // } // // else // // { // // knownChecklist.Remove(existing); // // if(existing.Event != upcoming) // // { // // Console.WriteLine("existing event != new event, but has same uid"); // // updateSchedulable(existing, upcoming); // // existing.Event = upcoming; // // } // // } // } // } // } // } if (knownChecklist.Count > 0) { foreach (var removed in knownChecklist) { scratch.agenda.Remove(removed); removeSchedulable(removed); } } } } private static async Task checkTwitch() { await checkCalendar(conf.calendar_twitch, "twitch", (e) => { return new Schedulable.Schedulable() { Event = e }; }, (o, e) => { }, (o) => { } ); } private static async Task checkYoutube() { await checkCalendar(conf.calendar_youtube, "youtube", (e) => { return new Schedulable.Schedulable() { Event = e }; }, (o, e) => { }, (o) => { } ); } } }