diff --git a/Config.cs b/Config.cs index d0276e8..6f631b2 100644 --- a/Config.cs +++ b/Config.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace director @@ -12,6 +13,7 @@ namespace director public string calendar_youtube { get; set; } public string calendar_twitch { get; set; } public string calendar_other { get; set; } + public TimeSpan preshowBufferTime { get; set; } public Dictionary phase_handlers { get; set; } } } \ No newline at end of file diff --git a/Log.cs b/Log.cs new file mode 100644 index 0000000..137d9d2 --- /dev/null +++ b/Log.cs @@ -0,0 +1,20 @@ +using System; +using System.IO; +using System.Net; + +public class Log +{ + public static string call_for_humans_discord_webhook{get;set;} + public static void Panic(string message) + { + Console.Error.WriteLine(message); + var httpWebRequest = (HttpWebRequest)WebRequest.Create(call_for_humans_discord_webhook); + httpWebRequest.ContentType = "application/json"; + httpWebRequest.Method = "POST"; + using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) + { + streamWriter.Write("{\"content\":\"" + message + "\"}"); + } + httpWebRequest.GetResponse(); + } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index d2e79e2..fa72be9 100644 --- a/Program.cs +++ b/Program.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Net.Http; using System.Net.Http.Headers; +using System.Threading; using System.Threading.Tasks; using franz; using Ical.Net; @@ -11,6 +14,7 @@ using Ical.Net.CalendarComponents; using Ical.Net.DataTypes; using Ical.Net.Serialization; using Newtonsoft.Json; +using ShowHandlers; namespace director { @@ -25,14 +29,21 @@ namespace director private static DateTime searchEnd = DateTime.Now.AddDays(7); //I don't understand why the entire .net ecosystem insists on ignoring ToString(). Is it really that much fun writing a serializer factory? ...java programmers. private static EventSerializer ser = new EventSerializer(); + private static readonly ConcurrentQueue workQueue = new ConcurrentQueue(); + private static readonly AutoResetEvent _signal = new AutoResetEvent(false); + private const int concurrentWorkers = 2; static void Main(string[] args) { if (!File.Exists("appsettings.json")) { Console.Error.WriteLine("appsettings.json was not found!"); + conf = new Config(); + File.WriteAllText("appsettings.json", JsonConvert.SerializeObject(conf, Formatting.Indented)); return; } conf = JsonConvert.DeserializeObject(File.ReadAllText("appsettings.json")); + Log.call_for_humans_discord_webhook = conf.call_for_humans_discord_webhook; + httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String( System.Text.Encoding.ASCII.GetBytes($"{conf.webdav_username}:{conf.webdav_password}"))); @@ -40,16 +51,19 @@ namespace director scratch = Scratch.LoadScratch(); + for (var i = 0; i < concurrentWorkers; i++) + { + Task.Run(threadwork); + } while (true) { Task.WaitAll( - //await and do next calendar task, - calendarCheck(), + checkCalendars(), Task.Delay(calendarNaptime) ); } } - private static async Task calendarCheck() + private static async Task checkCalendars() { try { @@ -80,10 +94,11 @@ namespace director foreach (var s in scratch.agenda) { - if (s.Showtime - DateTime.Now <= calendarNaptime) + if ((s.Showtime - conf.preshowBufferTime) - DateTime.Now <= calendarNaptime) { - Console.WriteLine("I'm an item on the agenda and showtime is near!"); - Console.WriteLine(s.Event); + var copy = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(s)); + workQueue.Enqueue(copy); + _signal.Set(); } } } @@ -115,5 +130,39 @@ namespace director } } } + private static void threadwork() + { + Schedulable.Schedulable todo = null; + while (true) + { + _signal.WaitOne(calendarNaptime); + + if (!workQueue.TryDequeue(out todo)) { continue; } + + Console.WriteLine("threadwork consumes!"); + Task.Delay(todo.Showtime - conf.preshowBufferTime - DateTime.Now); + Console.WriteLine("time to prep!"); + + switch (todo.ScedulableType) + { + case Schedulable.ScedulableType.TwitchStream: + try + { + // var handler = new TwitchStreamHandler(); + // handler.Handle(); + } + catch(Exception e) + { + Log.Panic($"error in twitch stream handler! Panicking!\n{JsonConvert.SerializeObject(e)}"); + } + break; + // case Schedulable.ScedulableType.YTRelease: + // break; + default: + Log.Panic($"unknown schedulable type! abandoning!"); + break; + } + } + } } } diff --git a/appsettings.example.json b/appsettings.example.json index 2fc0cf9..736a1ac 100644 --- a/appsettings.example.json +++ b/appsettings.example.json @@ -6,5 +6,6 @@ "webdav_password": "sw0rdf1sh", "calendar_youtube": "calendars/1wingedangle/youtube-channel_shared_by_adam", "calendar_twitch": "calendars/1wingedangle/twitch-channel_shared_by_adam", - "calendar_other": "calendars/1wingedangle/other_shared_by_adam" + "calendar_other": "calendars/1wingedangle/other_shared_by_adam", + "preshowBufferTime": "04:00:00" } \ No newline at end of file diff --git a/showHandlers/TwitchStreamHandler.cs b/showHandlers/TwitchStreamHandler.cs new file mode 100644 index 0000000..0f1a711 --- /dev/null +++ b/showHandlers/TwitchStreamHandler.cs @@ -0,0 +1,18 @@ +using Ical.Net.CalendarComponents; + +namespace ShowHandlers +{ + public class TwitchStreamHandler + { + public TwitchStreamHandler(CalendarEvent evt) + { + Event = evt; + } + + public CalendarEvent Event { get; } + + public void Handle() + { + } + } +} \ No newline at end of file