director/Program.cs

200 lines
8.2 KiB
C#
Raw Normal View History

2021-08-17 04:21:48 -04:00
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
2021-08-18 23:16:57 -04:00
using System.IO;
using System.Linq;
using System.Net;
2021-08-18 23:16:57 -04:00
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
using System.Threading;
2021-08-18 23:16:57 -04:00
using System.Threading.Tasks;
using DirectorConfiguration;
2021-08-18 23:16:57 -04:00
using franz;
using Newtonsoft.Json;
2021-08-17 04:21:48 -04:00
namespace director
{
public class Program
2021-08-17 04:21:48 -04:00
{
2021-10-26 07:36:25 -04:00
private static Telefranz tf;
public static Config directorConf;
2021-08-18 23:16:57 -04:00
private static TimeSpan calendarNaptime = TimeSpan.FromHours(1);
public static Scratch scratch;
2021-08-18 23:16:57 -04:00
private static HttpClient httpClient;
private static readonly ConcurrentQueue<schedulable.Scheduled> workQueue = new ConcurrentQueue<schedulable.Scheduled>();
private static readonly AutoResetEvent _signal = new AutoResetEvent(false);
2021-10-07 08:51:52 -04:00
private const int concurrentWorkers = 5;
2021-08-17 04:21:48 -04:00
static void Main(string[] args)
{
2021-08-18 23:16:57 -04:00
if (!File.Exists("appsettings.json"))
{
Console.Error.WriteLine("appsettings.json was not found!");
directorConf = new DirectorConfiguration.Config();
File.WriteAllText("appsettings.json", JsonConvert.SerializeObject(directorConf, Formatting.Indented));
2021-08-18 23:16:57 -04:00
return;
}
directorConf = JsonConvert.DeserializeObject<Config>(File.ReadAllText("appsettings.json"));
HumanCommunication.Configure(directorConf.call_for_humans_discord_webhook);
2021-08-18 23:16:57 -04:00
httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(
System.Text.Encoding.ASCII.GetBytes($"{directorConf.webdav_username}:{directorConf.webdav_password}")));
Telefranz.Configure("scheduler", directorConf.kafka_bootstrap);
2021-10-26 07:36:25 -04:00
tf = Telefranz.Instance;
2021-08-18 23:16:57 -04:00
scratch = Scratch.LoadScratch();
for (var i = 0; i < concurrentWorkers; i++)
{
Task.Run(threadwork);
}
2021-08-18 23:16:57 -04:00
while (true)
{
Task.WaitAll(
2021-08-21 00:23:14 -04:00
Task.Run(checkCalendars),
2021-08-18 23:16:57 -04:00
Task.Delay(calendarNaptime)
);
}
}
2021-08-21 00:23:14 -04:00
private static void checkCalendars()
2021-08-18 23:16:57 -04:00
{
try
{
2021-08-20 00:26:00 -04:00
lock (scratch)
{
scratch.agenda.Clear();
}
var calChecks = new List<Task>();
foreach (var calendar in directorConf.webdav_calendars)
{
calChecks.Add(checkCalendar(calendar));
}
Task.WaitAll(calChecks.ToArray());
2021-10-26 07:36:25 -04:00
scratch.agenda = scratch.agenda.OrderBy(s => s.Showtime).ToList();
2021-08-20 00:26:00 -04:00
lock (scratch)
{
scratch.Save();
}
2021-08-18 23:16:57 -04:00
}
catch (Exception e)
{
Console.Error.WriteLine(e);
}
2021-08-20 00:26:00 -04:00
foreach (var s in scratch.agenda)
{
//todo: find the perfect lead time.
if ((s.Showtime - TimeSpan.FromDays(1)) - DateTime.Now <= calendarNaptime)
2021-08-20 00:26:00 -04:00
{
var copy = JsonConvert.DeserializeObject<schedulable.Scheduled>(JsonConvert.SerializeObject(s));
workQueue.Enqueue(copy);
_signal.Set();
2021-08-20 00:26:00 -04:00
}
}
Console.WriteLine("calendars checked");
2021-10-26 07:45:15 -04:00
// #if (DEBUG)
// //if(true)
// {
// Console.WriteLine("debug test");
2021-10-07 08:51:52 -04:00
2021-10-26 07:45:15 -04:00
// var psuedo = new schedulable.Scheduled();
// psuedo.Showtime = DateTime.Now + TimeSpan.FromMinutes(30);
// // foreach(var a in scratch.agenda){
// // Console.WriteLine(a.Occurrence._event.Summary);
// // }
// var partiallyCopiable = scratch.agenda?.First(a => a.Occurrence._event.Summary == "Good Morning, Phyrexia (in the morning)!");
// psuedo.Occurrence = partiallyCopiable.Occurrence;
// psuedo.Occurrence.OccurrenceStart = psuedo.Showtime;
// psuedo.Occurrence.OccurrenceEnd = psuedo.Showtime;
// workQueue.Enqueue(psuedo);
// _signal.Set();
// }
// #endif
2021-08-18 23:16:57 -04:00
}
private static async Task checkCalendar(string calendarUri)
2021-08-18 23:16:57 -04:00
{
//?export is a hack to allow me to access the calendar
2021-08-20 00:26:00 -04:00
//it likes to throw an error saying "this is the webDAV interface, use webDAV" at my webDAV client, stopping me from using webDAV.
Console.WriteLine(calendarUri);
var calString = await httpClient.GetStringAsync(directorConf.webdav_uri + calendarUri + "?export");
2021-10-26 07:36:25 -04:00
lock (scratch)
{
var calName = iCalHoopJumping.LoadCalendar(calString);
scratch.Calendars[calName] = calString;
2021-10-26 07:36:25 -04:00
//todo: make sure I'm getting things in the present.
foreach (var occurrence in iCalHoopJumping.getOccurrences(calName))
{
var newSchedulable = new schedulable.Scheduled()
{
Occurrence = occurrence,
Showtime = occurrence.OccurrenceStart
2021-08-20 00:26:00 -04:00
};
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);
scratch.agenda.Add(newSchedulable);
}
}
2021-08-18 23:16:57 -04:00
}
}
private static void threadwork()
{
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}");
todo.Configuration = findConfig(todo.Occurrence.CalendarSourceName, todo.Occurrence._event.Summary);
if (todo.Configuration == null)
{
Console.WriteLine("configuration not found, skipping :(");
continue;
}
Console.WriteLine("configuration found");
2021-10-26 07:36:25 -04:00
var handler = new ShowHandler(todo, directorConf.workingDirectory + todo.Showtime.ToString("_yyyy-MM-dd"), () => {
//tf.ProduceMessage(new silver_messages.directorial.execute_command(){command = "directors_datasync", timeout = TimeSpan.Zero});
});
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;
}
2021-08-17 04:21:48 -04:00
}
}