diff --git a/Config.cs b/Config.cs index dda220d..6241e41 100644 --- a/Config.cs +++ b/Config.cs @@ -13,8 +13,6 @@ 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 string show_template_yt_release { get; set; } public string show_template_twitch_streams { get; set; } public Dictionary phase_handlers { get; set; } } diff --git a/HumanCommunication.cs b/HumanCommunication.cs index b97db8c..66dba3e 100644 --- a/HumanCommunication.cs +++ b/HumanCommunication.cs @@ -6,7 +6,7 @@ namespace Director { public class HumanCommunication { - private static string call_for_humans_discord_webhook{get;set;} + private static string call_for_humans_discord_webhook { get; set; } private static HumanCommunication _instance = null; private static readonly object createLock = new object(); public static void Configure(string call_for_humans_discord_webhook) @@ -42,7 +42,7 @@ namespace Director Console.WriteLine($"[{DateTime.Now.ToLongTimeString()}] [{logLevel.ToString()}] {message}"); //if(logLevel >= LogLevel.Warning && false) - if(false) //TODO: re-enable + if (false) //TODO: re-enable { var httpWebRequest = (HttpWebRequest)WebRequest.Create(call_for_humans_discord_webhook); httpWebRequest.ContentType = "application/json"; @@ -54,7 +54,15 @@ namespace Director httpWebRequest.GetResponse(); } } - public enum LogLevel { Trace, Verbose, Info, Warning, Error, Showstopper } + public enum LogLevel + { + Trace, //development + Verbose, + Info, //archival purposes, status checking, curiosity satisfaciton + Warning, + Error, //it's going to go up, but look bad. The bar is (currently) low enough that this won't necessarily damage the brand, but for better creators it would. + Showstopper //it's not going to go up + } } public class NotInitializedException : Exception { diff --git a/Program.cs b/Program.cs index 7e8765e..60c90a0 100644 --- a/Program.cs +++ b/Program.cs @@ -86,7 +86,8 @@ namespace director foreach (var s in scratch.agenda) { - if ((s.Showtime - conf.preshowBufferTime) - DateTime.Now <= calendarNaptime) + //todo: find the perfect lead time. + if ((s.Showtime - TimeSpan.FromDays(1)) - DateTime.Now <= calendarNaptime) { var copy = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(s)); workQueue.Enqueue(copy); @@ -121,7 +122,8 @@ namespace director { scratch.Calendars[calLabel] = calString; iCalHoopJumping.LoadCalendar(calLabel, calString); - foreach (var occurrence in iCalHoopJumping.getOccurrences(calLabel)) + //todo: I'm pretty sure some library is returning me only things in the future. Verify, and also make sure it's returning things in the present. + foreach (var occurrence in iCalHoopJumping.getOccurrences(calLabel)) { var newSchedulable = new Schedulable.Schedulable() { @@ -142,17 +144,24 @@ namespace director if (!workQueue.TryDequeue(out todo)) { continue; } - var napLength = (todo.Showtime - conf.preshowBufferTime) - DateTime.Now; - Console.WriteLine($"threadwork consumes! showtime at {todo.Showtime}; napping until {todo.Showtime - conf.preshowBufferTime} ({napLength})"); + ShowHandler handler = null; switch (todo.ScedulableType) { case Schedulable.ScedulableType.TwitchStream: Console.WriteLine("it's a twitch stream"); + handler = new TwitchStreamHandler(); break; case Schedulable.ScedulableType.YTRelease: Console.WriteLine("it's a yt release"); + handler = new YoutubeHandler(); break; + default: + HumanCommunication.Instance.Say($"unknown schedulable type!\n{JsonConvert.SerializeObject(todo)}", HumanCommunication.LogLevel.Showstopper); + continue; } + var napLength = (todo.Showtime - handler.LeadTimeDesired) - DateTime.Now; + Console.WriteLine($"threadwork consumes! showtime at {todo.Showtime}; napping until {todo.Showtime - handler.LeadTimeDesired} ({napLength})"); + if (napLength.TotalMinutes > 0) { Task.WaitAll(Task.Delay(napLength)); @@ -161,17 +170,7 @@ namespace director try { - switch (todo.ScedulableType) - { - case Schedulable.ScedulableType.TwitchStream: - new TwitchStreamHandler().Handle(todo.Occurrence); - break; - case Schedulable.ScedulableType.YTRelease: - new YoutubeHandler().Handle(todo.Occurrence); - break; - default: - throw new NotImplementedException($"unknown schedulable type!\n{JsonConvert.SerializeObject(todo)}"); - } + handler.Handle(todo.Occurrence); } catch (Exception e) { diff --git a/appsettings.example.json b/appsettings.example.json index 4edacd4..2122615 100644 --- a/appsettings.example.json +++ b/appsettings.example.json @@ -7,7 +7,6 @@ "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", - "preshowBufferTime": "04:00:00", "show_template_yt_release": "./yt release/config.json", "show_template_twitch_streams": "./twitch stream configs/" } \ No newline at end of file diff --git a/iCalHoopJumping.cs b/iCalHoopJumping.cs index bd78ef3..33a9183 100644 --- a/iCalHoopJumping.cs +++ b/iCalHoopJumping.cs @@ -48,6 +48,7 @@ namespace director internal static string Event_ToString(CalendarEvent asEvent) { //return asEvent.ToString(); //lol no + if(asEvent == null){return null;} return ser.SerializeToString(asEvent); } public static IEnumerable getOccurrences(string calLabel) diff --git a/showHandlers/ShowHandler.cs b/showHandlers/ShowHandler.cs index 39b64c6..a108a70 100644 --- a/showHandlers/ShowHandler.cs +++ b/showHandlers/ShowHandler.cs @@ -6,5 +6,6 @@ namespace ShowHandlers public abstract class ShowHandler { public abstract void Handle(iCalHoopJumping.CalendarOccurrence evt); + public abstract TimeSpan LeadTimeDesired { get; } } } \ No newline at end of file diff --git a/showHandlers/TwitchStreamHandler.cs b/showHandlers/TwitchStreamHandler.cs index 7b8761c..d3f8d6c 100644 --- a/showHandlers/TwitchStreamHandler.cs +++ b/showHandlers/TwitchStreamHandler.cs @@ -5,11 +5,54 @@ namespace ShowHandlers { public class TwitchStreamHandler : ShowHandler { + public override TimeSpan LeadTimeDesired => TimeSpan.FromHours(4); + public override void Handle(iCalHoopJumping.CalendarOccurrence evt) { Console.WriteLine("I am a twitch stream handler, it falls to me to..."); Console.WriteLine(" H A N D L E "); Console.WriteLine($"current time is {DateTime.Now}"); } + protected void preShow_RunCommands(iCalHoopJumping.CalendarOccurrence evt) + { + // Console.WriteLine($"pre show: run commands: {string.Join(", ", PreShowCommands.Select(c => c.cmd))}"); + // foreach (var cmd in PreShowCommands.OrderByDescending(cmd => cmd.leadTime)) + // { + // if (DateTime.Now < evt.OccurrenceStart - cmd.leadTime) + // { + // var waitTime = evt.OccurrenceStart - cmd.leadTime - DateTime.Now; + // Console.WriteLine($"waiting {waitTime} before executing {cmd.cmd}"); + // Task.WaitAll(Task.Delay(waitTime)); + // } + // var argsList = new List() { JsonConvert.SerializeObject(evt) }.Append(cmd.args).ToList(); + + // Console.WriteLine($"telefranzing execution: {cmd.cmd} with args {string.Join(' ', argsList)}"); + // // Telefranz.Instance.ProduceMessage(new silver_messages.directorial.execute_command() + // // { + // // command = cmd.cmd, + // // args = argsList, + // // timeout = (int)cmd.timeout.TotalMilliseconds //TODO: update when franz gets updated + // // }); + // } + // Console.WriteLine("seems all pre-show commands have been issued, but to be fair I wasn't listening for output."); + } + protected void PostShow(iCalHoopJumping.CalendarOccurrence evt) + { + + // Console.WriteLine($"post show: run commands: {string.Join(", ", config.PostShow.Commands.Select(c => c.cmd))}"); + // foreach (var cmd in config.PostShow.Commands) + // { + // var argsList = new List() { JsonConvert.SerializeObject(evt) }.Append(cmd.args).ToList(); + + // Console.WriteLine($"telefranzing execution: {cmd.cmd} with args {string.Join(' ', argsList)}"); + // // Telefranz.Instance.ProduceMessage(new silver_messages.directorial.execute_command() + // // { + // // command = cmd.cmd, + // // args = argsList, + // // timeout = (int)cmd.timeout.TotalMilliseconds //TODO: update when franz gets updated + // // }); + // } + // Console.WriteLine("seems all post-show commands have been issued, but to be fair I wasn't listening for output."); + } } } \ No newline at end of file diff --git a/showHandlers/YoutubeHandler.cs b/showHandlers/YoutubeHandler.cs index 5214823..1fdd13d 100644 --- a/showHandlers/YoutubeHandler.cs +++ b/showHandlers/YoutubeHandler.cs @@ -14,17 +14,16 @@ namespace ShowHandlers { public class YoutubeHandler : ShowHandler { - private YoutubeRelease config; - private List agentsPresent = new List(); - private Dictionary checksProgress = new Dictionary(); private readonly AutoResetEvent checkSignal = new AutoResetEvent(false); + private static string[] AgentsNeeded { get; set; } = { "youtube" }; + private List agentsPresent {get;set;} = new List(); + public override TimeSpan LeadTimeDesired { get => TimeSpan.FromDays(1); } + private silver_messages.youtube.yt_metadata metadataSoFar = new silver_messages.youtube.yt_metadata(); public override void Handle(iCalHoopJumping.CalendarOccurrence evt) { Console.WriteLine($"begin youtube handler. current time {DateTime.Now.ToLongTimeString()}"); Console.WriteLine(JsonConvert.SerializeObject(evt)); - var ytConfig = File.ReadAllText(Program.conf.show_template_yt_release); - config = JsonConvert.DeserializeObject(ytConfig); Task.Run(() => PreShow(evt)); Console.WriteLine("kicked off the pre-show"); if (evt.OccurrenceStart > DateTime.Now) @@ -42,104 +41,57 @@ namespace ShowHandlers protected void PreShow(iCalHoopJumping.CalendarOccurrence evt) { Console.WriteLine($"it's the pre-show, showtime at: {evt.OccurrenceStart}"); - config.PreShow.AgentsNeeded = config.PreShow.AgentsNeeded.Select(s => s.ToLower()).ToList(); - var commandLeadNeeded = TimeSpan.FromMinutes(15); - foreach(var cl in config.PreShow.Commands) - { - if(cl.leadTime > commandLeadNeeded){ - commandLeadNeeded = cl.leadTime; - } - } - - preShow_GetAgents(evt, commandLeadNeeded + TimeSpan.FromMinutes(10)); - preShow_RunChecks(evt, commandLeadNeeded); - preShow_RunCommands(evt); + preShow_GetAgents(evt, TimeSpan.FromMinutes(10)); + preShow_RunChecks(evt, TimeSpan.FromMinutes(10)); Console.WriteLine("pre show seems to be set."); } protected void preShow_GetAgents(iCalHoopJumping.CalendarOccurrence evt, TimeSpan leadNeeded) { - Console.WriteLine($"preshow agents needed: {string.Join(", ", config.PreShow.AgentsNeeded)}"); + Console.WriteLine($"preshow agents needed: {string.Join(", ", AgentsNeeded)}"); agentsPresent.Clear(); //TODO: actual telefranz //Telefranz.Instance.addHandler(agentReports); //Telefranz.Instance.ProduceMessage(new silver_messages.global.sound_off()); - while (config.PreShow.AgentsNeeded.Where(ap => !agentsPresent.Contains(ap))?.Count() > 0) + while (AgentsNeeded.Where(ap => !agentsPresent.Contains(ap))?.Count() > 0) { checkSignal.WaitOne(TimeSpan.FromSeconds(15)); - if(DateTime.Now > evt.OccurrenceStart - leadNeeded) + if (DateTime.Now > evt.OccurrenceStart - leadNeeded) { - var miaAgents = string.Join(", ", config.PreShow.AgentsNeeded.Where(ap => !agentsPresent.Contains(ap))); + var miaAgents = string.Join(", ", AgentsNeeded.Where(ap => !agentsPresent.Contains(ap))); HumanCommunication.Instance.Say($"Youtube handler getting antsy and going forward. mia agents: {miaAgents}", - HumanCommunication.LogLevel.Error); + HumanCommunication.LogLevel.Warning); break; } } - Console.WriteLine("going forward"); } protected void preShow_RunChecks(iCalHoopJumping.CalendarOccurrence evt, TimeSpan leadNeeded) { - checksProgress.Clear(); var argsList = new List() { JsonConvert.SerializeObject(evt) }; - //Telefranz.Instance.addHandler() - foreach (var c in config.PreShow.Checks) + //Telefranz.Instance.addHandler(youtubeAgentReports); + Console.WriteLine($"pre show: run check. It's just going to be \"is the metadata set\"."); + Action issueChecks = () => { - checksProgress.Add(c.cmd, false); - } - Console.WriteLine($"pre show: run checks: {string.Join(", ", config.PreShow.Checks.Select(c => c.cmd))}"); - Action issueChecks = () => { - foreach (var checkCmd in checksProgress.Where(cp => cp.Value == false).Select(kvp => kvp.Key)) - { - var check = config.PreShow.Checks.First(clc => clc.cmd == checkCmd); - // Telefranz.Instance.ProduceMessage(new silver_messages.directorial.execute_check() - // { - // check = check.cmd, - // args = argsList.Append(check.args).ToList() - // }); - } + //Telefranz.Instance.ProduceMessage(new silver_messages.youtube.request_metadata_needed()); }; issueChecks(); - while (checksProgress.ContainsValue(false)) + while (metadataUnset(metadataSoFar)) { + //checkSignal.WaitOne(TimeSpan.FromHours(6)); checkSignal.WaitOne(TimeSpan.FromSeconds(15)); - if(DateTime.Now > evt.OccurrenceStart - leadNeeded) + if (DateTime.Now > evt.OccurrenceStart - leadNeeded) { - var stillFailing = string.Join(", ", checksProgress.Where(cp => cp.Value == false).Select(cp => cp.Key)); - HumanCommunication.Instance.Say($"Youtube handler getting antsy and going forward. checks still failing: {stillFailing}", + HumanCommunication.Instance.Say($"Youtube handler reports no metadata in time! too late now though. {JsonConvert.SerializeObject(metadataSoFar)}", HumanCommunication.LogLevel.Error); break; } issueChecks(); } - Console.WriteLine("going forward"); - } - protected void preShow_RunCommands(iCalHoopJumping.CalendarOccurrence evt) - { - Console.WriteLine($"pre show: run commands: {string.Join(", ", config.PreShow.Commands.Select(c => c.cmd))}"); - foreach(var cmd in config.PreShow.Commands.OrderByDescending(cmd => cmd.leadTime)) - { - if(DateTime.Now < evt.OccurrenceStart - cmd.leadTime) - { - var waitTime = evt.OccurrenceStart - cmd.leadTime - DateTime.Now; - Console.WriteLine($"waiting {waitTime} before executing {cmd.cmd}"); - Task.WaitAll(Task.Delay(waitTime)); - } - var argsList = new List() { JsonConvert.SerializeObject(evt) }.Append(cmd.args).ToList(); - - Console.WriteLine($"telefranzing execution: {cmd.cmd} with args {string.Join(' ', argsList)}"); - // Telefranz.Instance.ProduceMessage(new silver_messages.directorial.execute_command() - // { - // command = cmd.cmd, - // args = argsList, - // timeout = (int)cmd.timeout.TotalMilliseconds //TODO: update when franz gets updated - // }); - } - Console.WriteLine("seems all pre-show commands have been issued, but to be fair I wasn't listening for output."); } protected void agentReports(silver_messages.global.report r) { - if (config.PreShow.AgentsNeeded?.FirstOrDefault(an => an.ToLower() == r.name.ToLower()) != null) + if (AgentsNeeded?.FirstOrDefault(an => an.ToLower() == r.name.ToLower()) != null) { lock (agentsPresent) { @@ -148,35 +100,25 @@ namespace ShowHandlers } } } - protected void checkReports(silver_messages.directorial.check_complete check) + protected void youtubeAgentReports(silver_messages.youtube.metadata_needed neededmsg) { - var myCheck = config.PreShow.Checks.FirstOrDefault(psc => psc.cmd == check.check); - if (myCheck != null) - { - lock (checksProgress) - { - checksProgress[myCheck.cmd] = check.result == myCheck.target; - } - checkSignal.Set(); - } + metadataSoFar = neededmsg.needed.Where(kvp => kvp.Key == "key")?.Select(kvp => kvp.Value)?.FirstOrDefault(); + checkSignal.Set(); + } + protected bool metadataUnset(silver_messages.youtube.yt_metadata metadata) + { + return ( + string.IsNullOrWhiteSpace(metadata.playlist) + || metadata.recording == null + || metadata.release == null + || string.IsNullOrWhiteSpace(metadata.thumbnail) + || string.IsNullOrWhiteSpace(metadata.title) + ); } protected void PostShow(iCalHoopJumping.CalendarOccurrence evt) { - - Console.WriteLine($"post show: run commands: {string.Join(", ", config.PostShow.Commands.Select(c => c.cmd))}"); - foreach(var cmd in config.PostShow.Commands) - { - var argsList = new List() { JsonConvert.SerializeObject(evt) }.Append(cmd.args).ToList(); - - Console.WriteLine($"telefranzing execution: {cmd.cmd} with args {string.Join(' ', argsList)}"); - // Telefranz.Instance.ProduceMessage(new silver_messages.directorial.execute_command() - // { - // command = cmd.cmd, - // args = argsList, - // timeout = (int)cmd.timeout.TotalMilliseconds //TODO: update when franz gets updated - // }); - } - Console.WriteLine("seems all post-show commands have been issued, but to be fair I wasn't listening for output."); + Console.WriteLine("there really isn't a post-show atm, but in future would be cool to pester matrix/discord/twitter"); + //Telefranz.Instance.ProduceMessage(new silver_messages.directorial.execute_command("advertise")); } } } \ No newline at end of file