From 5b77672ac7adfd7d1d76ca125c3042806bcb58af Mon Sep 17 00:00:00 2001 From: "Adam R. Grey" Date: Fri, 23 Jul 2021 01:51:40 -0400 Subject: [PATCH] ostensibly, working ready for updates from franz, and needs to be tested. But other than that this is where the fun starts --- Program.cs | 134 ++++++++++++++++++++++++++++++++----- directors-assistant.csproj | 4 +- 2 files changed, 120 insertions(+), 18 deletions(-) diff --git a/Program.cs b/Program.cs index 50ec975..b99494d 100644 --- a/Program.cs +++ b/Program.cs @@ -1,11 +1,14 @@ using franz; using Newtonsoft.Json; +using silver_messages.directorial; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Net; using System.Net.Http; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -16,30 +19,129 @@ namespace directors_assistant public static Config conf; public static Telefranz telefranz; static async Task Main(string[] args) - { + { conf = JsonConvert.DeserializeObject(File.ReadAllText("appsettings.json")); - telefranz = new Telefranz(conf.name, conf.bootstrap_servers, conf.kafka_location, - new List(){"proof_of_concept"}); - telefranz.addHandler((silver_messages.directorial.execute_command ec) => { - Console.WriteLine("for FUCK'S sake"); + telefranz = new Telefranz(conf.name, conf.bootstrap_servers, new List() { "proof_of_concept" }); + telefranz.addHandler((silver_messages.directorial.execute_command ec) => + { Console.WriteLine(JsonConvert.SerializeObject(ec)); - if(ec.command == "proof_of_concept") + var matchedCommands = conf.commands.Where(c => c.name == ec.command)?.ToList(); + //I swear I have a vague memory of foreach in linq'd query throwing an exception when results empty. + if (matchedCommands != null && matchedCommands.Count > 0) { - Console.WriteLine("it's a POC"); - var content = new StringContent("{\"username\": \"" + conf.name +"\", \"content\": \"hi\"}"); - var client = new HttpClient(); - client.DefaultRequestHeaders.Add("Content-Type", "application/json"); - client.PostAsync("super secret url", - content); - Console.WriteLine("I'm P-O-C, I'm dyn-o-mite"); + foreach (var cmd in matchedCommands) + { + Console.WriteLine($"executing {cmd.name}, given args {ec.args}" + cmd.name); + + var cmdAndArgs = cmd.shell.Split(' '); + var justArgs = cmdAndArgs.Skip(1).ToList(); + justArgs.AddRange(ec.args); + var commandPath = cmdAndArgs[0]; + var commandArguments = String.Join(' ', justArgs); + if (ec.timeout > 0) + { + executeTimed(cmd.name, commandPath, commandArguments, ec.timeout); + } + else + { + Task.Run(() => + { + executeUntimed(cmd.name, commandPath, commandArguments); + }); + } + } } - Console.WriteLine("it's not a proof of concept call"); }); Console.WriteLine("off we go"); - telefranz.StartListening(); + await Task.Delay(1000); + Console.WriteLine("im a strong independent director's assistant who don't need no director"); + telefranz.ProduceMessage(new silver_messages.global.sound_off()); - await Task.Delay(20000); + await Task.Delay(120000); Console.WriteLine("alright fuck it"); } + + private static void executeTimed(string commandName, string commandPath, string commandArguments, int timeout) + { + var process = readableProcess(commandPath, commandArguments); + var outputs = new List(); + var errors = new List(); + process.OutputDataReceived += new DataReceivedEventHandler((s, e) => { outputs.Add(e.Data); }); + process.ErrorDataReceived += new DataReceivedEventHandler((s, e) => { errors.Add(e.Data); }); + + var stopwatch = new Stopwatch(); + stopwatch.Start(); + process.Start(); + process.BeginErrorReadLine(); + process.BeginOutputReadLine(); + Task.WaitAny( + Task.Run(() => + { + process.WaitForExit(); + }), + Task.Delay(new TimeSpan(0, 0, timeout)) + ); + if (process.HasExited) + { + stopwatch.Stop(); + telefranz.ProduceMessage(new silver_messages.directorial.command_completed() + { + command = commandName, + runtime = (uint)stopwatch.ElapsedMilliseconds, + exit_code = process.ExitCode, + stdout = string.Join('\n', outputs), + stderr = string.Join('\n', errors) + }); + } + else + { + process.Kill(); + telefranz.ProduceMessage(new silver_messages.directorial.command_expired() + { + command = commandName, + runtime = (uint)timeout + }); + } + } + + private static void executeUntimed(string commandName, string commandPath, string commandArguments) + { + var process = readableProcess(commandPath, commandArguments); + process.OutputDataReceived += new DataReceivedEventHandler((s, e) => { + telefranz.ProduceMessage(new silver_messages.directorial.command_output() { + stdout = e.Data + }); + }); + process.ErrorDataReceived += new DataReceivedEventHandler((s, e) => { + telefranz.ProduceMessage(new silver_messages.directorial.command_error() { + stderr = e.Data + }); + }); + + var stopwatch = new Stopwatch(); + stopwatch.Start(); + process.Start(); + process.BeginErrorReadLine(); + process.BeginOutputReadLine(); + process.WaitForExit(); + telefranz.ProduceMessage(new silver_messages.directorial.command_completed() + { + command = commandName, + runtime = (uint)stopwatch.ElapsedMilliseconds, + exit_code = process.ExitCode + }); + } + + private static Process readableProcess(string commandPath, string commandArguments) + { + var pi = new ProcessStartInfo(commandPath, commandArguments); + pi.UseShellExecute = false; + pi.CreateNoWindow = true; + pi.RedirectStandardError = true; + pi.RedirectStandardOutput = true; + var process = new Process(); + process.StartInfo = pi; + return process; + } } } diff --git a/directors-assistant.csproj b/directors-assistant.csproj index 5d1662c..b8adb97 100644 --- a/directors-assistant.csproj +++ b/directors-assistant.csproj @@ -4,7 +4,7 @@ Exe net5.0 directors_assistant - $(RestoreSources);../pkgs while i procastinate on a feed;https://api.nuget.org/v3/index.json + $(RestoreSources);../packages/nuget/;https://api.nuget.org/v3/index.json @@ -13,7 +13,7 @@ - +