diff --git a/CSharp/ExecuteCommand.csharp b/CSharp/ExecuteCommand.csharp new file mode 100644 index 0000000..ec5385f --- /dev/null +++ b/CSharp/ExecuteCommand.csharp @@ -0,0 +1,59 @@ +using System; +using System.IO; +using System.Text; +using System.Diagnostics; +using System.Collections.Generic; + +namespace AniNIX.Shared { + + public static class ExecuteCommand { + + /// + /// This method allows a CSharp app to execute a command on the OS. + /// + /// The command string to run as the string argument to "bash -c 'command'" + /// The effective replacement for the command's stdinThe stdout of the command + /// + public static String Run(String command, String input) { + //Sanitize inputs. + if (command.Contains("\'")) { + throw new Exception("Command strings cannot include \'."); + } + + //Create process. + Process proc = new Process(); + proc.StartInfo.CreateNoWindow = true; + proc.StartInfo.FileName = "/bin/bash"; + proc.StartInfo.Arguments = String.Format("-c \'{0}\'",command); + proc.StartInfo.UseShellExecute=false; + ReportMessage.Log(Verbosity.Verbose,String.Format("{0} {1}",proc.StartInfo.FileName,proc.StartInfo.Arguments)); + + //Redirect input + proc.StartInfo.RedirectStandardOutput=true; + proc.StartInfo.RedirectStandardInput=true; + + //Start process + proc.Start(); + + //Add input and read output. + proc.StandardInput.Write(input); + proc.StandardInput.Close(); + proc.WaitForExit(); + if (proc.ExitCode != 0) { + throw new Exception(String.Format("Failed to exit command with return code {0}",proc.ExitCode)); + } + String stdoutString = proc.StandardOutput.ReadToEnd(); + + //Close up and return + proc.Close(); + return stdoutString; + } + + //Add polymorphism to allow no stdin + public static String Run(String command) { + return Run(command,null); + } + + } +} diff --git a/CSharp/ReportMessage.csharp b/CSharp/ReportMessage.csharp new file mode 100644 index 0000000..a951af9 --- /dev/null +++ b/CSharp/ReportMessage.csharp @@ -0,0 +1,47 @@ +using System; + +namespace AniNIX.Shared { + + public enum Verbosity { + Always = -2, + Error, + Quiet = 0, + Verbose, + VeryVerbose, + Explicit, + } + + public static class ReportMessage { + + // Set this statically here, but allow others to override. + public static Verbosity verbosity = Verbosity.Quiet; + + /// + /// Log a new message for the user. + /// + public static void Log(Verbosity level,String message) { + + if (level == Verbosity.Error) { + Console.Error.WriteLine(message); + return; + } + + if (ReportMessage.verbosity == Verbosity.Quiet) { + return; + } + + if (level == Verbosity.Always + || (ReportMessage.verbosity == Verbosity.Verbose && level == Verbosity.Verbose) + || (ReportMessage.verbosity == Verbosity.VeryVerbose && (level == Verbosity.Verbose || level == Verbosity.VeryVerbose)) + || (ReportMessage.verbosity == Verbosity.Explicit && (level == Verbosity.Verbose || level == Verbosity.VeryVerbose || level == Verbosity.Explicit)) + ) { + Console.WriteLine(message); + } + + } + + public static void Log(String message) { + Log(Verbosity.VeryVerbose,message); + } + } +} diff --git a/CSharp/WebPageAPI.csharp b/CSharp/WebPageAPI.csharp new file mode 100644 index 0000000..b2fd906 --- /dev/null +++ b/CSharp/WebPageAPI.csharp @@ -0,0 +1,39 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using System.Text.RegularExpressions; + +namespace AniNIX.Shared { + + public static class WebPageAPI { + + // Thanks to MSDN for this regex. + // https://msdn.microsoft.com/en-us/library/ms998267.aspx + public static Regex URLRegEx = new Regex(@"(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?"); + + /// + /// Get a webpage source -- we use this instead of WebClient because Mono doesn't handle SSL well on Linux. + /// /usr/bin/curl -s SOMEURL + /// + /// the webpage whose title we should get + /// the webpage source + public static string GetPage(String pageURL) { + return ExecuteCommand.Run(String.Format("/usr/bin/curl -s {0}",pageURL)); + } + + /// + /// Get a webpage title + /// Should be equivalent to: + /// /bin/bash -c '/usr/bin/curl -s SOMEURL | perl -l -0777 -ne "print \$1 if /\s*(.*?)\s*<\/title/si"' + /// + /// the webpage whose title we should get + /// the webpage title + public static string GetPageTitle(String pageURL) { + string source = GetPage(pageURL); + return Regex.Match(source, @"\]*\>\s*(?[\s\S]*?)\</title\>", RegexOptions.IgnoreCase).Groups["Title"].Value; + } + + } +}