diff --git a/Config.cs b/Config.cs index f7f4fdf..d0276e8 100644 --- a/Config.cs +++ b/Config.cs @@ -1,13 +1,17 @@ +using System.Collections.Generic; + namespace director { public class Config { public string kafka_bootstrap { get; set; } public string call_for_humans_discord_webhook { get; set; } - public string webdav_uri { get; set; } - public string webdav_username { get; set; } - public string webdav_password { get; set; } - public string calendar_youtube { get; set; } - public string calendar_twitch { get; set; } + public string webdav_uri { get; set; } + public string webdav_username { get; set; } + public string webdav_password { get; set; } + public string calendar_youtube { get; set; } + public string calendar_twitch { get; set; } + public string calendar_other { get; set; } + public Dictionary phase_handlers { get; set; } } } \ No newline at end of file diff --git a/Program.cs b/Program.cs index 9ec2c35..f0a4ced 100644 --- a/Program.cs +++ b/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; @@ -6,6 +7,8 @@ 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 @@ -18,7 +21,7 @@ namespace director 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(7); + private static DateTime searchEnd = DateTime.Now.AddDays(14); static void Main(string[] args) { if (!File.Exists("appsettings.json")) @@ -31,12 +34,9 @@ namespace director 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); - //todo: subscribe to event appears message - you don't need to respond to an event disappearing message - - //todo: talk to dave. What's coming up in the next short timeframe? - + scratch = Scratch.LoadScratch(); - + while (true) { Task.WaitAll( @@ -55,6 +55,7 @@ namespace director checkYoutube(), checkTwitch() ); + //await checkTwitch(); } catch (Exception e) { @@ -62,45 +63,118 @@ namespace director 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) { - //verify against existing copy, react to changes - //put in 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() { - var calString = await httpClient.GetStringAsync(conf.webdav_uri + conf.calendar_twitch + "?export"); - lock(scratch) - { - scratch.Calendars["twitch"] = calString; - } - var calT = Calendar.Load(calString); - Console.WriteLine($"calendar name: {calT.Name}"); - foreach(var evt in calT.Events){ - var upcoming = evt.GetOccurrences(searchStart, searchEnd)?.FirstOrDefault(); - if(upcoming != null){ - Console.WriteLine($"[twitch] event {evt.Summary} has an occurence: {upcoming.Period.StartTime}"); - } - - } + await checkCalendar(conf.calendar_twitch, "twitch", + (e) => { return new Schedulable.Schedulable() { Event = e }; }, + (o, e) => { }, + (o) => { } + ); } private static async Task checkYoutube() { - var calString = await httpClient.GetStringAsync(conf.webdav_uri + conf.calendar_youtube + "?export"); - lock(scratch) - { - scratch.Calendars["youtube"] = calString; - } - var calYT = Calendar.Load(calString); - Console.WriteLine($"calendar name: {calYT.Name}"); - foreach(var evt in calYT.Events){ - var upcoming = evt.GetOccurrences(searchStart, searchEnd)?.FirstOrDefault(); - if(upcoming != null){ - Console.WriteLine($"[youtube] event {evt.Summary} has an occurence: {upcoming.Period.StartTime}"); - } - - } + await checkCalendar(conf.calendar_youtube, "youtube", + (e) => { return new Schedulable.Schedulable() { Event = e }; }, + (o, e) => { }, + (o) => { } + ); } } } diff --git a/appsettings.example.json b/appsettings.example.json index 17c62ef..2fc0cf9 100644 --- a/appsettings.example.json +++ b/appsettings.example.json @@ -5,5 +5,6 @@ "webdav_username": "xX_sephiroth_Xx@aol.com", "webdav_password": "sw0rdf1sh", "calendar_youtube": "calendars/1wingedangle/youtube-channel_shared_by_adam", - "calendar_twitch": "calendars/1wingedangle/twitch-channel_shared_by_adam" + "calendar_twitch": "calendars/1wingedangle/twitch-channel_shared_by_adam", + "calendar_other": "calendars/1wingedangle/other_shared_by_adam" } \ No newline at end of file diff --git a/schedulable/Schedulable.cs b/schedulable/Schedulable.cs index d8e3360..f25a868 100644 --- a/schedulable/Schedulable.cs +++ b/schedulable/Schedulable.cs @@ -1,8 +1,12 @@ using System; +using Ical.Net.CalendarComponents; +using Ical.Net.DataTypes; + namespace Schedulable -{ - public abstract class Schedulable +{ + public class Schedulable { - public DateTime Time { get; set; } + public CalendarEvent Event { get; set; } + public Occurrence Occurrence { get; set; } } } \ No newline at end of file diff --git a/schedulable/show/YoutubeRelease.cs b/schedulable/show/YoutubeRelease.cs index f74337b..260ea3f 100644 --- a/schedulable/show/YoutubeRelease.cs +++ b/schedulable/show/YoutubeRelease.cs @@ -2,6 +2,6 @@ namespace Schedulable.Show { public class YoutubeRelease : Show { - + //do I even need anything? } } \ No newline at end of file