director/Program.cs

167 lines
6.5 KiB
C#

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 Newtonsoft.Json;
using ShowHandlers;
namespace director
{
public class Program
{
//private static Telefranz tf;
public static Config conf;
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 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<Config>(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}")));
//tf = new Telefranz("scheduler", conf.kafka_bootstrap);
scratch = Scratch.LoadScratch();
for (var i = 0; i < concurrentWorkers; i++)
{
Task.Run(threadwork);
}
while (true)
{
Task.WaitAll(
checkCalendars(),
Task.Delay(calendarNaptime)
);
}
}
private static async Task checkCalendars()
{
try
{
lock (scratch)
{
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;
})
);
lock (scratch)
{
scratch.Save();
}
}
catch (Exception e)
{
Console.Error.WriteLine(e);
}
foreach (var s in scratch.agenda)
{
if ((s.Showtime - conf.preshowBufferTime) - DateTime.Now <= calendarNaptime)
{
var copy = JsonConvert.DeserializeObject<Schedulable.Schedulable>(JsonConvert.SerializeObject(s));
workQueue.Enqueue(copy);
_signal.Set();
}
}
Console.WriteLine("calendars checked");
}
private delegate void schedulableCreate(ref Schedulable.Schedulable creating);
private static async Task checkCalendar(string calendarUri, string calLabel, schedulableCreate createSchedulable)
{
//?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>();
lock (scratch)
{
scratch.Calendars[calLabel] = calString;
iCalHoopJumping.LoadCalendar(calLabel, calString);
foreach (var occurrence in iCalHoopJumping.getOccurrences(calLabel))
{
var newSchedulable = new Schedulable.Schedulable()
{
Occurrence = occurrence,
Showtime = occurrence.OccurrenceStart
};
createSchedulable(ref newSchedulable);
scratch.agenda.Add(newSchedulable);
}
}
}
private static void threadwork()
{
Schedulable.Schedulable todo = null;
while (true)
{
_signal.WaitOne(calendarNaptime);
if (!workQueue.TryDequeue(out todo)) { continue; }
Console.WriteLine($"threadwork consumes! showtime at {todo.Showtime}; wake me at {todo.Showtime - conf.preshowBufferTime}");
switch(todo.ScedulableType)
{
case Schedulable.ScedulableType.TwitchStream:
Console.WriteLine("it's a twitch stream");
break;
case Schedulable.ScedulableType.YTRelease:
Console.WriteLine("it's a yt release");
break;
}
//Task.WaitAll(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(todo.Occurrence);
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;
}
}
}
}
}