using BetterSecondBot.HttpService; using BetterSecondBotShared.API; using BetterSecondBotShared.IO; using BetterSecondBotShared.Json; using BetterSecondBotShared.logs; using BetterSecondBotShared.Static; using EmbedIO; using System; using System.Collections.Generic; using System.Reflection; using System.Text; namespace BetterSecondBot.WikiMake { class DebugModeCreateWiki { protected Dictionary> api_reports = new Dictionary>(); protected string html_header = ""; protected string html_footer = ""; protected string buildVersion = ""; protected SimpleIO io; protected Dictionary seen_command_names = new Dictionary(); public string CreateRoot() { StringBuilder sb = new StringBuilder(); sb.Append(html_header); sb.Append("

Build: "); sb.Append(buildVersion); sb.Append("


"); sb.Append(""); foreach (KeyValuePair> entry in api_reports) { sb.Append(""); sb.Append(""); sb.Append(""); } sb.Append("
InterfaceCommandsStatus
"); sb.Append(entry.Key); sb.Append(""); sb.Append(entry.Value.Key.ToString()); sb.Append(""); sb.Append(entry.Value.Value); sb.Append("
"); sb.Replace("[[AREA]]", "Home"); sb.Replace("[[SUBFOLDER]]", "files/"); sb.Replace("[[RETURNROOT]]", ""); sb = DebugModeCreateWiki.MenuActive(sb, "Home"); sb.Append(html_footer); return sb.ToString(); } protected static StringBuilder MenuActive(StringBuilder index, string area) { Dictionary active_swaps = new Dictionary { { "CoreActive", "" }, { "CLIActive", "" }, { "JSONActive", "" }, { "RLVapiActive", "" }, { "HTTPActive", "" } }; active_swaps["" + area + "Active"] = "Active"; foreach (KeyValuePair pair in active_swaps) { index = index.Replace("[[" + pair.Key + "]]", pair.Value); } return index; } protected void InterfaceCommands(string area, API_supported_interface shared_interface, bool track_commands = false) { string[] cmds = shared_interface.GetCommandsList(); string interface_name = shared_interface.GetType().Name; foreach (string c in cmds) { if (track_commands == true) { if (seen_command_names.ContainsKey(c) == false) { seen_command_names.Add(c, interface_name); } else { LogFormater.Debug("command " + c + " from " + interface_name + " overlaps an ready loaded command from " + seen_command_names[c] + ""); } } string workspace = shared_interface.GetCommandWorkspace(c); StringBuilder sb = new StringBuilder(); sb.Append(html_header); sb.Append("

Build: "); sb.Append(buildVersion); sb.Append("


"); sb.Append("

Interface: [[AREA]]"); if (workspace != "") { sb.Append(" / [[WORKSPACE]]"); } sb.Append("


[[COMMAND]]

"); int loop = 0; int minargs = shared_interface.GetCommandArgs(c); string[] arg_types = shared_interface.GetCommandArgTypes(c); string[] arg_hints = shared_interface.GetCommandArgHints(c); if (area == "Core") { StringBuilder ExampleCall = new StringBuilder(); ExampleCall.Append("Example: [[COMMAND]]"); ExampleCall.Append("|||"); string addon = ""; while (loop < minargs) { ExampleCall.Append(addon); addon = "~#~"; string hint_value = ""; if (arg_hints.Length > loop) { if (arg_hints[loop] != null) { string[] bits = arg_hints[loop].Split("
", StringSplitOptions.RemoveEmptyEntries); if (bits.Length >= 1) { hint_value = bits[0]; } } } if (hint_value != "") { ExampleCall.Append(hint_value); } else { ExampleCall.Append("?"); LogFormater.Debug("[WikiMake] " + area + " Command " + c + " missing some required hint values"); } loop++; } sb.Append(ExampleCall.ToString()); sb.Append("
"); } sb.Append("[[HELP]]"); if (arg_types.Length > 0) { sb.Append("

Args helper

"); loop = 0; sb.Append(""); while (loop < arg_types.Length) { string hint = ""; if (arg_hints.Length > loop) { hint = arg_hints[loop]; } string Required = "X"; if ((loop + 1) > minargs) { Required = ""; } sb.Append(""); loop++; } sb.Append("
NumTypeRequiredHint
" + (loop + 1).ToString() + "" + arg_types[loop] + "" + Required + "" + hint + "
"); } sb.Append(html_footer); sb.Replace("[[COMMAND]]", c); sb.Replace("[[HELP]]", shared_interface.GetCommandHelp(c)); sb.Replace("[[MINARGS]]", minargs.ToString()); sb.Replace("[[WORKSPACE]]", workspace); sb.Replace("[[AREA]]", area); sb.Replace("[[SUBFOLDER]]", ""); sb.Replace("[[RETURNROOT]]", "../"); sb = DebugModeCreateWiki.MenuActive(sb, area); string target_file = "" + area + "" + workspace + "" + c + ".html"; io.writefile(target_file, sb.ToString()); } } protected void InterfaceWorkspaces(string area, API_supported_interface shared_interface) { string[] cmds = shared_interface.GetCommandsList(); foreach (string workspace in shared_interface.GetAllWorkspaces()) { StringBuilder sb = new StringBuilder(); sb.Append(html_header); sb.Append("

Interface: [[AREA]]"); if (workspace != "") { sb.Append(" / [[WORKSPACE]]"); } sb.Append("


"); sb.Append("

Build: "); sb.Append(buildVersion); sb.Append("


"); sb.Append(""); foreach (string c in cmds) { if (shared_interface.GetCommandWorkspace(c) == workspace) { int args = shared_interface.GetCommandArgs(c); sb.Append(""); } } sb.Append("
CommandMin args
"); sb.Append(c); sb.Append(""); sb.Append(args.ToString()); sb.Append("
"); sb.Replace("[[SUBFOLDER]]", ""); sb.Replace("[[RETURNROOT]]", "../"); sb.Replace("[[WORKSPACE]]", workspace); sb.Replace("[[AREA]]", area); sb.Append(html_footer); sb = DebugModeCreateWiki.MenuActive(sb, area); string target_file = "" + area + "" + workspace + ".html"; io.writefile(target_file, sb.ToString()); } } protected void InterfaceIndex(string area, API_supported_interface shared_interface) { StringBuilder sb = new StringBuilder(); sb.Append(html_header); sb.Append("

Interface:"); sb.Append(area); sb.Append("


"); sb.Append("

Build: "); sb.Append(buildVersion); sb.Append("


"); string[] cmds = shared_interface.GetCommandsList(); sb.Append(""); foreach (string workspace in shared_interface.GetAllWorkspaces()) { int commands_count = 0; foreach (string c in cmds) { if (shared_interface.GetCommandWorkspace(c) == workspace) { commands_count++; } } string workspace_link = "" + workspace + ""; sb.Append(""); } sb.Append("
WorkspaceCommands
"); sb.Append(workspace_link); sb.Append(""); sb.Append(commands_count.ToString()); sb.Append("
"); sb.Replace("[[SUBFOLDER]]", ""); sb.Replace("[[RETURNROOT]]", "../"); sb.Replace("[[AREA]]", area); sb.Append(html_footer); sb = DebugModeCreateWiki.MenuActive(sb, area); io.writefile("" + area + ".html", sb.ToString()); } protected void InterfaceWiki(string area, API_supported_interface shared_interface, bool track_commands = false) { LogFormater.Info("[WIKI] Starting area " + area + ""); // create index InterfaceIndex(area, shared_interface); // create workspaces InterfaceWorkspaces(area, shared_interface); // create commands InterfaceCommands(area, shared_interface, track_commands); LogFormater.Info("[WIKI] Done with area"); } public DebugModeCreateWiki(string Version, SimpleIO shareio) { io = shareio; buildVersion = Version; html_header = helpers.ReadResourceFile(Assembly.GetExecutingAssembly(), "wiki_header.txt"); html_footer = helpers.ReadResourceFile(Assembly.GetExecutingAssembly(), "wiki_footer.txt"); io.ChangeRoot("wiki"); io.ChangeRoot("wiki/files"); // JSONcfg MakeJsonConfig defaultJson = new MakeJsonConfig(); api_reports.Add("JSON", new KeyValuePair(defaultJson.ApiCommandsCount, "Ready")); InterfaceWiki("JSON", defaultJson); // CMD BetterSecondBot.Commands.CoreCommandsInterface cmd = new BetterSecondBot.Commands.CoreCommandsInterface(null); api_reports.Add("Core", new KeyValuePair(cmd.ApiCommandsCount, "Good")); InterfaceWiki("Core", cmd, true); // HTTP HTTPWiki(); io.ChangeRoot("wiki"); io.writefile("index.html", CreateRoot()); } protected void HTTPWiki() { LogFormater.Info("[WIKI] Starting area HTTP endpoint"); HTTPendpoint HTTP = new HTTPendpoint(); HTTPmenu("HTTP", HTTP); // create workspaces HTTPWorkspaces("HTTP", HTTP); // create commands HTTPCommands("HTTP", HTTP); HTTP = null; LogFormater.Info("[WIKI] Done with area"); } protected string getURLargs(Dictionary> values) { List urlargs = new List(); foreach (KeyValuePair> entry in values) { if (entry.Value.Key == "URLARG") { urlargs.Add("{"+entry.Key+"}"); } } return String.Join('/', urlargs); } protected void HTTPCommands(string area, HTTPendpoint HTTP) { foreach (string workspace in HTTP.getEndPoints()) { foreach (string c in HTTP.getEndpointCommands(workspace)) { StringBuilder sb = new StringBuilder(); sb.Append(html_header); sb.Append("

Build: "); sb.Append(buildVersion); sb.Append("


"); sb.Append("

Interface: [[AREA]]"); if (workspace != "") { sb.Append(" / [[WORKSPACE]]"); } sb.Append("


[[COMMAND]]

"); sb.Append("[[URLENDPOINT]]/[[WORKSPACE]]/[[COMMAND]]/[[URLADDON]]
"); sb.Append("Method: [[APIMETHOD]]"); sb.Append("
"); sb.Append("[[HELP]]"); Dictionary> values = HTTP.getCommandArgs(workspace, c); int ValueCount = values.Count; if (ValueCount > 0) { sb.Append("

Args helper

"); sb.Append(""); foreach (KeyValuePair> entry in values) { string hint = entry.Value.Value; string type = entry.Value.Key; if (entry.Value.Key.Contains("Optional") == true) { type = type.Replace("Optional", "{Optional} "); } else if (entry.Value.Key == "URLARG") { type = "URL arg"; } sb.Append(""); } sb.Append("
NameTypeHint
" + entry.Key + "" + type + "" + hint + "
"); } string[] returnvalues = HTTP.getReturnsValues(workspace, c); if (returnvalues.Length > 0) { sb.Append("

Possible replys

"); sb.Append("
    "); foreach (string entry in returnvalues) { sb.Append("
  • "+entry+"
  • "); } sb.Append("
"); } sb = DebugModeCreateWiki.MenuActive(sb, area); sb.Append(html_footer); sb.Replace("[[COMMAND]]", c); sb.Replace("[[URLENDPOINT]]", "http://localhost:8080"); sb.Replace("[[APIMETHOD]]", HTTP.getCommandMethod(workspace, c)); sb.Replace("[[URLADDON]]", getURLargs(values)); sb.Replace("[[HELP]]", HTTP.getCommandAbout(workspace, c)); sb.Replace("[[MINARGS]]", ValueCount.ToString()); sb.Replace("[[WORKSPACE]]", workspace); sb.Replace("[[AREA]]", area); sb.Replace("[[SUBFOLDER]]", ""); sb.Replace("[[RETURNROOT]]", "../"); string target_file = "" + area + "" + workspace + "" + c + ".html"; io.writefile(target_file, sb.ToString()); } } } protected void HTTPmenu(string area, HTTPendpoint HTTP) { api_reports.Add(area, new KeyValuePair(HTTP.getFullCount(), "Basic")); // create index StringBuilder sb = new StringBuilder(); sb.Append(html_header); sb.Append("

Interface:"); sb.Append("HTTP"); sb.Append("


"); sb.Append("

Build: "); sb.Append(buildVersion); sb.Append("


"); sb.Append(""); foreach (string workspace in HTTP.getEndPoints()) { string workspace_link = "" + workspace + ""; sb.Append(""); } sb.Append("
WorkspaceCommands
"); sb.Append(workspace_link); sb.Append(""); sb.Append(HTTP.getEndpointCount(workspace).ToString()); sb.Append("
"); sb.Replace("[[SUBFOLDER]]", ""); sb.Replace("[[RETURNROOT]]", "../"); sb.Replace("[[AREA]]", area); sb.Append(html_footer); sb = DebugModeCreateWiki.MenuActive(sb, area); io.writefile("" + area + ".html", sb.ToString()); } protected void HTTPWorkspaces(string area, HTTPendpoint HTTP) { foreach (string workspace in HTTP.getEndPoints()) { StringBuilder sb = new StringBuilder(); sb.Append(html_header); sb.Append("

Interface: [[AREA]]"); if (workspace != "") { sb.Append(" / [[WORKSPACE]]"); } sb.Append("


"); sb.Append("

Build: "); sb.Append(buildVersion); sb.Append("


"); sb.Append(""); foreach (string c in HTTP.getEndpointCommands(workspace)) { int args = HTTP.getCommandArgCount(workspace, c); sb.Append(""); } sb.Append("
CommandMin args
"); sb.Append(c); sb.Append(""); sb.Append(args.ToString()); sb.Append("
"); sb.Replace("[[SUBFOLDER]]", ""); sb.Replace("[[RETURNROOT]]", "../"); sb.Replace("[[WORKSPACE]]", workspace); sb.Replace("[[AREA]]", area); sb.Append(html_footer); sb = DebugModeCreateWiki.MenuActive(sb, area); string target_file = "" + area + "" + workspace + ".html"; io.writefile(target_file, sb.ToString()); } } } public class HTTPendpoint { protected List endpoints = new List(); public void createEndpoint(string name, Type Api) { Endpoint Endpoint = new Endpoint(); Endpoint.name = name; foreach (MethodInfo M in Api.GetMethods()) { APIcall C = new APIcall(); CustomAttributeData httpverb = null; CustomAttributeData NeedsToken = null; CustomAttributeData About = null; List ArgHints = new List(); List ReturnValues = new List(); foreach (CustomAttributeData At in M.CustomAttributes) { if (At.AttributeType.Name == "RouteAttribute") { httpverb = At; } else if (At.AttributeType.Name == "NeedsToken") { NeedsToken = At; } else if (At.AttributeType.Name == "About") { About = At; } else if (At.AttributeType.Name == "ArgHints") { ArgHints.Add(At); } else if (At.AttributeType.Name == "ReturnHints") { ReturnValues.Add(At); } } if (httpverb != null) { C.name = M.Name.ToLowerInvariant(); C.type = "Post"; C.about = "Http interface command about missing"; if (About != null) { C.about = About.ConstructorArguments[0].Value.ToString(); } if ((int)httpverb.ConstructorArguments[0].Value == 2) { C.type = "Get"; } C.RequiresToken = true; if (NeedsToken != null) { C.RequiresToken = (bool)NeedsToken.ConstructorArguments[0].Value; } foreach (CustomAttributeData cad in ArgHints) { C.values.Add(cad.ConstructorArguments[0].Value.ToString(), new KeyValuePair(cad.ConstructorArguments[1].Value.ToString(), cad.ConstructorArguments[2].Value.ToString())); } foreach (CustomAttributeData cad in ReturnValues) { C.returns.Add(cad.ConstructorArguments[0].Value.ToString()); } C.Setup(); Endpoint.callable.Add(C); } } endpoints.Add(Endpoint); } public HTTPendpoint() { createEndpoint("core", typeof(HttpApiCore)); createEndpoint("inventory", typeof(HttpApiInventory)); createEndpoint("im", typeof(HttpApiIM)); createEndpoint("groups", typeof(HttpApiGroup)); createEndpoint("chat", typeof(HttpApiLocalchat)); createEndpoint("parcel", typeof(HttpApiParcel)); createEndpoint("estate", typeof(HttpAPIEstate)); } public string getCommandMethod(string endpoint, string command) { foreach (Endpoint End in endpoints) { if (End.name == endpoint) { foreach (APIcall api in End.callable) { if (api.name == command) { return api.type; } } } } return "?"; } public string getCommandAbout(string endpoint, string command) { foreach (Endpoint End in endpoints) { if (End.name == endpoint) { foreach (APIcall api in End.callable) { if (api.name == command) { return api.about; } } } } return "?"; } public string[] getReturnsValues(string endpoint, string command) { foreach (Endpoint End in endpoints) { if (End.name == endpoint) { foreach (APIcall api in End.callable) { if (api.name == command) { return api.returns.ToArray(); } } } } return new string[] { }; } public int getCommandArgCount(string endpoint, string command) { foreach (Endpoint End in endpoints) { if (End.name == endpoint) { foreach (APIcall api in End.callable) { if (api.name == command) { return api.values.Count; } } } } return 0; } public string[] getEndpointCommands(string endpointname) { List commands = new List(); foreach (Endpoint End in endpoints) { if (End.name == endpointname) { foreach (APIcall api in End.callable) { commands.Add(api.name); } } } return commands.ToArray(); } public string[] getEndPoints() { List names = new List(); foreach (Endpoint End in endpoints) { names.Add(End.name); } return names.ToArray(); } public int getEndpointCount(string endpointname) { foreach (Endpoint End in endpoints) { if (End.name == endpointname) { return End.callable.Count; } } return 0; } public int getFullCount() { int count = 0; foreach (Endpoint End in endpoints) { count += End.callable.Count; } return count; } public Dictionary> getCommandArgs(string endpoint, string command) { Dictionary> empty = new Dictionary>(); foreach (Endpoint End in endpoints) { if (End.name == endpoint) { foreach (APIcall api in End.callable) { if (api.name == command) { return api.values; } } } } return empty; } } public class Endpoint { public string name = "Notset"; public List callable = new List(); } public class APIcall { public string name { get; set; } public string type = "get"; public string about = "A API call that is missing its about value"; public Dictionary> values = new Dictionary>(); public List returns = new List(); public bool RequiresToken = true; public virtual void Setup() { if (RequiresToken == true) { returns.Add("Token not accepted"); values.Add( "token", new KeyValuePair( "URLARG", "the api access token") ); } } } }