rework progress

todo: don't have containers, just have each line be "text" if you want
This commit is contained in:
Adam R. Grey 2021-10-13 09:25:03 -04:00
parent 58b2560051
commit c4d994f76b
15 changed files with 237 additions and 338 deletions

View File

@ -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<string, string> phase_handlers { get; set; }
public IEnumerable<string> webdav_calendars { get; set; }
public string workingDirectory { get; set; }
public IEnumerable<ConfigFileLocator> scheduleConfigs { get; set; }
}
}

View File

@ -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; }
}
}

View File

@ -3,7 +3,7 @@ using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace Director
namespace director
{
public class HumanCommunication
{

View File

@ -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<Schedulable.Schedulable> workQueue = new ConcurrentQueue<Schedulable.Schedulable>();
private static readonly ConcurrentQueue<schedulable.Scheduled> workQueue = new ConcurrentQueue<schedulable.Scheduled>();
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<Config>(File.ReadAllText("appsettings.json"));
HumanCommunication.Configure(conf.call_for_humans_discord_webhook);
directorConf = JsonConvert.DeserializeObject<Config>(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<Task>();
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<Schedulable.Schedulable>(JsonConvert.SerializeObject(s));
var copy = JsonConvert.DeserializeObject<schedulable.Scheduled>(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<Schedulable.Schedulable>();
Console.WriteLine(calendarUri);
var calString = await httpClient.GetStringAsync(directorConf.webdav_uri + calendarUri + "?export");
var knownChecklist = new List<schedulable.Scheduled>();
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);
var asActualEvent = iCalHoopJumping.parseEvent(calName, occurrence.Event);
if(scratch.agenda.FirstOrDefault(s => iCalHoopJumping.parseEvent(calLabel, s.Occurrence.Event)?.Uid == asActualEvent.Uid) == null)
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<schedulable.Schedulable>(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;
}
}
}

View File

@ -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<Schedulable.Schedulable> agenda { get; set; } = new List<Schedulable.Schedulable>();
public List<schedulable.Scheduled> agenda { get; set; } = new List<schedulable.Scheduled>();
public Dictionary<string, string> Calendars { get; set; } = new Dictionary<string, string>();
//calendar ICSs

100
ShowHandler.cs Normal file
View File

@ -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<ProcessionLine> checklistFlattened()
{
if (todo.Configuration.checklist?.Count() > 0)
{
var toReturn = new List<ProcessionLine>();
foreach(var line in todo.Configuration.checklist)
{
toReturn.AddRange(recurseChecklist(line));
}
return toReturn;
}
return null;
}
private IEnumerable<ProcessionLine> recurseChecklist(ProcessionLine line)
{
var asContainer = line as container;
if (asContainer == null || asContainer.subitems?.Count() == 0)
{
return new List<ProcessionLine>() { line };
}
else
{
var toReturn = new List<ProcessionLine>();
toReturn.AddRange(recurseChecklist(line));
return toReturn;
}
}
internal void HandleChecklist()
{
Console.WriteLine($"should now be at the desired lead time. showtime: {todo.Showtime}");
}
}
}

View File

@ -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<string, Calendar> Calendars = new ConcurrentDictionary<string, Calendar>();
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<CalendarOccurrence> getOccurrences(string calLabel)
{
var usefulList = new List<CalendarOccurrence>();
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();

24
schedulable/Checklist.cs Normal file
View File

@ -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<string> args { get; set; }
}
public class container : ProcessionLine
{
public IEnumerable<ProcessionLine> subitems { get; set; }
}
public class awaitShowtime : ProcessionLine { }
public class awaitCutSignal : ProcessionLine { }
}

View File

@ -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; }
}
}

View File

@ -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<string> AgentsNeeded { get; set; }
public IEnumerable<ProcessionLine> checklist { get; set; }
// public Object conductorConfig{get;set;}
}
public enum ScedulableType { TwitchStream, YTRelease, Other };
}

12
schedulable/Scheduled.cs Normal file
View File

@ -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; }
}
}

View File

@ -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<Checklistable> Manual { get; set; }
public IEnumerable<CommandLine> Commands { get; set; }
}
public class PreshowTaskList : TaskList
{
public IEnumerable<string> AgentsNeeded { get; set; }
public IEnumerable<CommandLineCheck> Checks { get; set; }
}
public class Checklistable
{
//for humans
public string Label { get; set; }
public IEnumerable<Checklistable> 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 { }
}

View File

@ -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; }
}
}

View File

@ -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<string>() { 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<string>() { 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.");
}
}
}

View File

@ -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<string> agentsPresent {get;set;} = new List<string>();
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<silver_messages.global.report>(agentReports);
//Telefranz.Instance.removeHandler<silver_messages.directorial.check_complete>(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<silver_messages.global.report>(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<string>() { JsonConvert.SerializeObject(evt) };
Telefranz.Instance.addHandler<silver_messages.youtube.metadata_needed>(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"));
}
}
}