diff --git a/Config.cs b/DirectorConfiguration/Config.cs similarity index 53% rename from Config.cs rename to DirectorConfiguration/Config.cs index 6241e41..9078212 100644 --- a/Config.cs +++ b/DirectorConfiguration/Config.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace director +namespace DirectorConfiguration { public class Config { @@ -10,10 +10,8 @@ namespace director 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 string show_template_twitch_streams { get; set; } - public Dictionary phase_handlers { get; set; } + public IEnumerable webdav_calendars { get; set; } + public string workingDirectory { get; set; } + public IEnumerable scheduleConfigs { get; set; } } } \ No newline at end of file diff --git a/DirectorConfiguration/ConfigFileLocator.cs b/DirectorConfiguration/ConfigFileLocator.cs new file mode 100644 index 0000000..9e65856 --- /dev/null +++ b/DirectorConfiguration/ConfigFileLocator.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace DirectorConfiguration +{ + public class ConfigFileLocator + { + public string Calendar { get; set; } + public Regex EventName { get; set; } + public string SchedulableConfiguration { get; set; } + } +} \ No newline at end of file diff --git a/HumanCommunication.cs b/HumanCommunication.cs index e11a751..7919f4d 100644 --- a/HumanCommunication.cs +++ b/HumanCommunication.cs @@ -3,7 +3,7 @@ using System.IO; using System.Net; using System.Threading.Tasks; -namespace Director +namespace director { public class HumanCommunication { diff --git a/Program.cs b/Program.cs index 964b2f9..c3bc553 100644 --- a/Program.cs +++ b/Program.cs @@ -6,23 +6,23 @@ using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using Director; +using DirectorConfiguration; using franz; using Newtonsoft.Json; -using ShowHandlers; namespace director { public class Program { //private static Telefranz tf; - public static Config conf; + public static Config directorConf; private static TimeSpan calendarNaptime = TimeSpan.FromHours(1); public static Scratch scratch; private static HttpClient httpClient; - private static readonly ConcurrentQueue workQueue = new ConcurrentQueue(); + private static readonly ConcurrentQueue workQueue = new ConcurrentQueue(); private static readonly AutoResetEvent _signal = new AutoResetEvent(false); private const int concurrentWorkers = 5; static void Main(string[] args) @@ -30,18 +30,18 @@ namespace director 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)); + directorConf = new DirectorConfiguration.Config(); + File.WriteAllText("appsettings.json", JsonConvert.SerializeObject(directorConf, Formatting.Indented)); return; } - conf = JsonConvert.DeserializeObject(File.ReadAllText("appsettings.json")); - HumanCommunication.Configure(conf.call_for_humans_discord_webhook); + directorConf = JsonConvert.DeserializeObject(File.ReadAllText("appsettings.json")); + HumanCommunication.Configure(directorConf.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}"))); + System.Text.Encoding.ASCII.GetBytes($"{directorConf.webdav_username}:{directorConf.webdav_password}"))); - Telefranz.Configure("scheduler", conf.kafka_bootstrap); + Telefranz.Configure("scheduler", directorConf.kafka_bootstrap); scratch = Scratch.LoadScratch(); @@ -65,16 +65,14 @@ namespace director { scratch.agenda.Clear(); } - Task.WaitAll( - checkCalendar(conf.calendar_youtube, "youtube", (ref Schedulable.Schedulable n) => - { - n.ScedulableType = Schedulable.ScedulableType.YTRelease; - }), - checkCalendar(conf.calendar_twitch, "twitch", (ref Schedulable.Schedulable n) => - { - n.ScedulableType = Schedulable.ScedulableType.TwitchStream; - }) - ); + + var calChecks = new List(); + foreach (var calendar in directorConf.webdav_calendars) + { + calChecks.Add(checkCalendar(calendar)); + } + Task.WaitAll(calChecks.ToArray()); + lock (scratch) { scratch.Save(); @@ -90,7 +88,7 @@ namespace director //todo: find the perfect lead time. if ((s.Showtime - TimeSpan.FromDays(1)) - DateTime.Now <= calendarNaptime) { - var copy = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(s)); + var copy = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(s)); workQueue.Enqueue(copy); _signal.Set(); } @@ -101,43 +99,42 @@ namespace director { Console.WriteLine("debug test"); - var psuedo = new Schedulable.Schedulable(); + var psuedo = new schedulable.Scheduled(); psuedo.Showtime = DateTime.Now + TimeSpan.FromSeconds(30); - var partiallyCopiable = scratch.agenda?.FirstOrDefault(s => s.ScedulableType == Schedulable.ScedulableType.TwitchStream); + var partiallyCopiable = scratch.agenda?.FirstOrDefault(); psuedo.Occurrence = partiallyCopiable.Occurrence; psuedo.Occurrence.OccurrenceStart = psuedo.Showtime; psuedo.Occurrence.OccurrenceEnd = psuedo.Showtime; - psuedo.ScedulableType = Schedulable.ScedulableType.YTRelease; workQueue.Enqueue(psuedo); _signal.Set(); } #endif } - private delegate void schedulableCreate(ref Schedulable.Schedulable creating); - private static async Task checkCalendar(string calendarUri, string calLabel, schedulableCreate createSchedulable) + private static async Task checkCalendar(string calendarUri) { //?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, stopping me from using webDAV. - var calString = await httpClient.GetStringAsync(conf.webdav_uri + calendarUri + "?export"); - var knownChecklist = new List(); + Console.WriteLine(calendarUri); + var calString = await httpClient.GetStringAsync(directorConf.webdav_uri + calendarUri + "?export"); + var knownChecklist = new List(); lock (scratch) { - scratch.Calendars[calLabel] = calString; - iCalHoopJumping.LoadCalendar(calLabel, calString); + var calName = iCalHoopJumping.LoadCalendar(calString); + scratch.Calendars[calName] = calString; //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)) + foreach (var occurrence in iCalHoopJumping.getOccurrences(calName)) { - var newSchedulable = new Schedulable.Schedulable() + var newSchedulable = new schedulable.Scheduled() { Occurrence = occurrence, Showtime = occurrence.OccurrenceStart }; - var asActualEvent = iCalHoopJumping.parseEvent(calLabel, occurrence.Event); - - if(scratch.agenda.FirstOrDefault(s => iCalHoopJumping.parseEvent(calLabel, s.Occurrence.Event)?.Uid == asActualEvent.Uid) == null) + var asActualEvent = iCalHoopJumping.parseEvent(calName, occurrence.Event); + + if (scratch.agenda.FirstOrDefault(s => iCalHoopJumping.parseEvent(calName, s.Occurrence.Event)?.Uid == asActualEvent.Uid) == null) { - createSchedulable(ref newSchedulable); + //createSchedulable(ref newSchedulable); scratch.agenda.Add(newSchedulable); } } @@ -145,47 +142,51 @@ namespace director } private static void threadwork() { - Schedulable.Schedulable todo = null; + schedulable.Scheduled todo = null; while (true) { _signal.WaitOne(calendarNaptime); if (!workQueue.TryDequeue(out todo)) { continue; } + Console.WriteLine($"threadwork consumes! showtime at {todo.Showtime}, {todo.Occurrence._event.Summary} on {todo.Occurrence.CalendarSourceName}"); - ShowHandler handler = null; - switch (todo.ScedulableType) + todo.Configuration = findConfig(todo.Occurrence.CalendarSourceName, todo.Occurrence._event.Summary); + if (todo.Configuration == null) { - 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; + Console.WriteLine("configuration not found, skipping :("); + continue; } - var napLength = (todo.Showtime - handler.LeadTimeDesired) - DateTime.Now; - Console.WriteLine($"threadwork consumes! showtime at {todo.Showtime}; napping until {todo.Showtime - handler.LeadTimeDesired} ({napLength})"); + Console.WriteLine("configuration found"); - if (napLength.TotalMinutes > 0) - { - Task.WaitAll(Task.Delay(napLength)); - } - Console.WriteLine("places, everyone!"); - - try - { - handler.Handle(todo.Occurrence); - } - catch (Exception e) - { - HumanCommunication.Instance.Say($"error in show handler! Panicking!\n{JsonConvert.SerializeObject(e)}", HumanCommunication.LogLevel.Showstopper); - } - break; + var handler = new ShowHandler(todo, directorConf.workingDirectory + "/" + todo.Showtime.ToShortDateString()); + handler.StartHandling(); } } + + private static schedulable.Schedulable findConfig(string CalendarSourceName, string eventName) + { + foreach (var locator in directorConf.scheduleConfigs) + { + if (locator.Calendar == CalendarSourceName) + { + if (locator.EventName.IsMatch(eventName)) + { + var configurationName = locator.EventName.Replace(eventName, locator.SchedulableConfiguration); + Console.WriteLine($"found match good enough, I guess. going to load {configurationName} for {eventName}"); + try + { + return JsonConvert.DeserializeObject(File.ReadAllText(configurationName)); + } + catch (Exception e) + { + Console.Error.WriteLine($"error btw. not sure who's not throwing one. {e.Message}"); + return null; + } + } + } + } + //HumanCommunication.Instance.forwardToDiscord($"couldn't find suitable configuration for {eventName} within {CalendarSourceName}", HumanCommunication.LogLevel.Info); + return null; + } } } diff --git a/Scratch.cs b/Scratch.cs index c553c2e..85d5bfb 100644 --- a/Scratch.cs +++ b/Scratch.cs @@ -2,14 +2,14 @@ using System; using System.Collections.Generic; using System.IO; using Newtonsoft.Json; -using Schedulable; +using schedulable; namespace director { public class Scratch { private const string path = "scratch.json"; - public List agenda { get; set; } = new List(); + public List agenda { get; set; } = new List(); public Dictionary Calendars { get; set; } = new Dictionary(); //calendar ICSs diff --git a/ShowHandler.cs b/ShowHandler.cs new file mode 100644 index 0000000..e959d4c --- /dev/null +++ b/ShowHandler.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections; +using System.Linq; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using schedulable; +using System.Collections.Generic; + +namespace director +{ + public class ShowHandler + { + private Scheduled todo; + private string outputPath; + public ShowHandler(Scheduled todo, string outputPath) + { + this.todo = todo; + this.outputPath = outputPath; + } + + internal void StartHandling() + { + Console.WriteLine("start handling"); + CreateChecklist(); + var napLength = (todo.Showtime - todo.Configuration.LeadTimeDesired) - DateTime.Now; + + Console.WriteLine($"napping until {todo.Showtime - todo.Configuration.LeadTimeDesired} ({napLength})"); + + if (napLength.TotalMinutes > 0) + { + Task.WaitAll(Task.Delay(napLength)); + } + Console.WriteLine("nap done, begin the checklist. which to us effectively means SHOWTIME"); + //or do I want to split the checklists in the config file? consider later. + try + { + HandleChecklist(); + } + catch (Exception e) + { + HumanCommunication.Instance.Say($"error in show handler! Panicking!\n{JsonConvert.SerializeObject(e)}", HumanCommunication.LogLevel.Showstopper); + } + } + + private void CreateChecklist() + { + Console.WriteLine($"begin the pre-pre show by creating a checklist."); + Directory.CreateDirectory(outputPath); + var text = new StringBuilder(); + text.AppendLine($"# {todo.Occurrence._event.Description}"); + + #region share with humans + var allItems = checklistFlattened(); + if(allItems?.FirstOrDefault(pl => pl.type == "manual") != null) + { + Console.WriteLine($"nothing manual, not sharing with humans."); + } + else + { + //TODO: share + } + #endregion + } + private IEnumerable checklistFlattened() + { + if (todo.Configuration.checklist?.Count() > 0) + { + var toReturn = new List(); + foreach(var line in todo.Configuration.checklist) + { + toReturn.AddRange(recurseChecklist(line)); + } + return toReturn; + } + return null; + } + private IEnumerable recurseChecklist(ProcessionLine line) + { + var asContainer = line as container; + if (asContainer == null || asContainer.subitems?.Count() == 0) + { + return new List() { line }; + } + else + { + var toReturn = new List(); + toReturn.AddRange(recurseChecklist(line)); + return toReturn; + } + } + + + internal void HandleChecklist() + { + Console.WriteLine($"should now be at the desired lead time. showtime: {todo.Showtime}"); + } + } +} \ No newline at end of file diff --git a/iCalHoopJumping.cs b/iCalHoopJumping.cs index b4bf442..f179493 100644 --- a/iCalHoopJumping.cs +++ b/iCalHoopJumping.cs @@ -13,9 +13,12 @@ namespace director 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); public static readonly ConcurrentDictionary Calendars = new ConcurrentDictionary(); - public static void LoadCalendar(string key, string calendarString) + public static string LoadCalendar(string calendarString) { - Calendars[key] = Calendar.Load(calendarString); + var cal = Calendar.Load(calendarString); + var key = cal.Properties["X-WR-CALNAME"].Value.ToString(); + Calendars[key] = cal; + return key; } //I don't understand why the entire .net ecosystem insists on ignoring ToString(). Is it really that much fun writing ThingSerializerFactory? ...java programmers. @@ -48,13 +51,13 @@ namespace director internal static string Event_ToString(CalendarEvent asEvent) { //return asEvent.ToString(); //lol no - if(asEvent == null){return null;} + if (asEvent == null) { return null; } return ser.SerializeToString(asEvent); } public static IEnumerable getOccurrences(string calLabel) { var usefulList = new List(); - foreach(var icalOcc in Calendars[calLabel].GetOccurrences(searchStart, searchEnd)) + foreach (var icalOcc in Calendars[calLabel].GetOccurrences(searchStart, searchEnd)) { var asEvent = icalOcc.Source as Ical.Net.CalendarComponents.CalendarEvent; var newCO = new CalendarOccurrence(); diff --git a/schedulable/Checklist.cs b/schedulable/Checklist.cs new file mode 100644 index 0000000..9f7ed3a --- /dev/null +++ b/schedulable/Checklist.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +namespace schedulable +{ + public class ProcessionLine + { + public string description { get; set; } + public string type { get; set; } = "generic"; //TODO: experiment with $type, apparnetly newtonsoft json can use that to choose deserialization? + public ProcessionLine() { type = GetType().ToString(); } + } + public class manual : ProcessionLine { } + public class command : ProcessionLine + { + public string cmd { get; set; } + public IEnumerable args { get; set; } + } + public class container : ProcessionLine + { + public IEnumerable subitems { get; set; } + } + public class awaitShowtime : ProcessionLine { } + public class awaitCutSignal : ProcessionLine { } +} \ No newline at end of file diff --git a/schedulable/MessageRelay.cs b/schedulable/MessageRelay.cs deleted file mode 100644 index 2003a75..0000000 --- a/schedulable/MessageRelay.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Schedulable -{ - //You said to echo back a message - public class MessageRelay : Schedulable - { - public silver_messages.message MessageToRelay { get; set; } - } -} \ No newline at end of file diff --git a/schedulable/Schedulable.cs b/schedulable/Schedulable.cs index bf87b3a..b2cbba8 100644 --- a/schedulable/Schedulable.cs +++ b/schedulable/Schedulable.cs @@ -1,13 +1,14 @@ using System; +using System.Collections.Generic; using director; -namespace Schedulable +namespace schedulable { public class Schedulable { - public iCalHoopJumping.CalendarOccurrence Occurrence { get; set; } - public DateTime Showtime { get; set; } - public ScedulableType ScedulableType { get; set; } = ScedulableType.Other; + public TimeSpan LeadTimeDesired { get; set; } + public IEnumerable AgentsNeeded { get; set; } + public IEnumerable checklist { get; set; } + // public Object conductorConfig{get;set;} } - public enum ScedulableType { TwitchStream, YTRelease, Other }; } \ No newline at end of file diff --git a/schedulable/Scheduled.cs b/schedulable/Scheduled.cs new file mode 100644 index 0000000..71a06b3 --- /dev/null +++ b/schedulable/Scheduled.cs @@ -0,0 +1,12 @@ +using System; +using director; + +namespace schedulable +{ + public class Scheduled + { + public iCalHoopJumping.CalendarOccurrence Occurrence { get; set; } + public DateTime Showtime { get; set; } + public Schedulable Configuration { get; set; } + } +} \ No newline at end of file diff --git a/schedulable/Show.cs b/schedulable/Show.cs deleted file mode 100644 index 8214fa5..0000000 --- a/schedulable/Show.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Schedulable.Show -{ - public class Show - { - public PreshowTaskList PreShow { get; set; } - public TaskList PostShow { get; set; } - - #region components - public class TaskList - { - public IEnumerable Manual { get; set; } - public IEnumerable Commands { get; set; } - } - public class PreshowTaskList : TaskList - { - public IEnumerable AgentsNeeded { get; set; } - public IEnumerable Checks { get; set; } - } - public class Checklistable - { - //for humans - public string Label { get; set; } - public IEnumerable Items { get; set; } //if no items, just throw up a checkbox - } - public class CommandLine - { - public string cmd { get; set; } - public string args { get; set; } - public TimeSpan timeout { get; set; } - public TimeSpan leadTime { get; set; } - } - public class CommandLineCheck - { - public string cmd { get; set; } - public string args { get; set; } - public string target { get; set; } - } - #endregion - } - public class TwitchStream : Show - { - public string TwitchTitle { get; set; } - public string TwitchCategory { get; set; } - } - public class YoutubeRelease : Show { } -} \ No newline at end of file diff --git a/showHandlers/ShowHandler.cs b/showHandlers/ShowHandler.cs deleted file mode 100644 index a108a70..0000000 --- a/showHandlers/ShowHandler.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using director; - -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 deleted file mode 100644 index d3f8d6c..0000000 --- a/showHandlers/TwitchStreamHandler.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using director; - -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 deleted file mode 100644 index 58a15a8..0000000 --- a/showHandlers/YoutubeHandler.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using director; -using Director; -using franz; -using Newtonsoft.Json; -using Schedulable.Show; - -namespace ShowHandlers -{ - public class YoutubeHandler : ShowHandler - { - 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)); - Task.Run(() => PreShow(evt)); - Console.WriteLine("kicked off the pre-show"); - if (evt.OccurrenceStart > DateTime.Now) - { - Task.WaitAll(Task.Delay(evt.OccurrenceStart - DateTime.Now)); - } - //youtube releases in particular jump right to post-show - PostShow(evt); - } - ~YoutubeHandler() - { - //Telefranz.Instance.removeHandler(agentReports); - //Telefranz.Instance.removeHandler(checkReports); - } - protected void PreShow(iCalHoopJumping.CalendarOccurrence evt) - { - Console.WriteLine($"it's the pre-show, showtime at: {evt.OccurrenceStart}"); - - 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(", ", AgentsNeeded)}"); - agentsPresent.Clear(); - - Telefranz.Instance.addHandler(agentReports); - Telefranz.Instance.ProduceMessage(new silver_messages.global.sound_off()); - while (AgentsNeeded.Where(ap => !agentsPresent.Contains(ap))?.Count() > 0) - { - checkSignal.WaitOne(TimeSpan.FromSeconds(15)); - //Telefranz.Instance.ProduceMessage(new silver_messages.global.sound_off()); - if (DateTime.Now > evt.OccurrenceStart - leadNeeded) - { - 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.Warning); - break; - } - } - } - protected void preShow_RunChecks(iCalHoopJumping.CalendarOccurrence evt, TimeSpan leadNeeded) - { - var argsList = new List() { JsonConvert.SerializeObject(evt) }; - Telefranz.Instance.addHandler(youtubeAgentReports); - Console.WriteLine($"pre show: run check. It's just going to be \"is the metadata set\"."); - Action issueChecks = () => - { - //Telefranz.Instance.ProduceMessage(new silver_messages.youtube.request_metadata_needed()); - }; - issueChecks(); - while (metadataUnset(metadataSoFar)) - { - //checkSignal.WaitOne(TimeSpan.FromHours(6)); //so bother me every 6 hours before yt release time if metadata isn't ready - checkSignal.WaitOne(TimeSpan.FromSeconds(15)); - if (DateTime.Now > evt.OccurrenceStart - leadNeeded) - { - HumanCommunication.Instance.Say($"Youtube handler reports no metadata in time! too late now though. {JsonConvert.SerializeObject(metadataSoFar)}", - HumanCommunication.LogLevel.Error); - break; - } - issueChecks(); - } - } - protected void agentReports(silver_messages.global.report r) - { - Console.WriteLine($"agent responding to sound off: {r.name}"); - if (AgentsNeeded?.FirstOrDefault(an => an.ToLower() == r.name.ToLower()) != null) - { - lock (agentsPresent) - { - agentsPresent.Add(r.name.ToLower()); - checkSignal.Set(); - } - } - } - protected void youtubeAgentReports(silver_messages.youtube.metadata_needed neededmsg) - { - 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("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