コード例 #1
0
        /// <summary>
        /// Bot meta reload admin command.
        /// </summary>
        public void CMD_Reload(string[] cmds, SocketMessage message)
        {
            // NOTE: This implies a one-guild bot. A multi-guild bot probably shouldn't have this "BotCommander" role-based verification.
            // But under current scale, a true-admin confirmation isn't worth the bother.
            if (!Bot.IsBotCommander(message.Author as SocketGuildUser))
            {
                SendErrorMessageReply(message, "Authorization Failure", "Nope! That's not for you!");
                return;
            }
            SendGenericPositiveMessageReply(message, "Reloading", "Yes, boss. Reloading meta documentation now...");
            BuildNumberTracker.UpdateAll();
            MetaDocs docs = new MetaDocs();

            docs.DownloadAll();
            Program.CurrentMeta = docs;
            EmbedBuilder embed = new EmbedBuilder().WithTitle("Reload Complete").WithDescription("Documentation reloaded successfully.");

            if (docs.LoadErrors.Count > 0)
            {
                List <string> errors = docs.LoadErrors.Count > 5 ? docs.LoadErrors.GetRange(0, 5) : docs.LoadErrors;
                SendErrorMessageReply(message, "Error(s) While Reloading", string.Join("\n", errors));
                embed.AddField("Errors", docs.LoadErrors.Count, true);
            }
            embed.AddField("Commands", docs.Commands.Count, true);
            embed.AddField("Mechanisms", docs.Mechanisms.Count, true);
            embed.AddField("Tags", docs.Tags.Count, true);
            embed.AddField("Events", docs.Events.Count, true);
            embed.AddField("Actions", docs.Actions.Count, true);
            embed.AddField("Languages", docs.Languages.Count, true);
            SendReply(message, embed.Build());
        }
コード例 #2
0
        public static string HtmlizeTags(string[] tags, MetaDocs meta)
        {
            StringBuilder tagOutput = new StringBuilder();

            foreach (string tag in tags)
            {
                string[] parts      = tag.Split(' ', 2);
                string   properName = $"<code>{ScriptHighlighter.ColorArgument(Util.EscapeForHTML(parts[0]), false)}</code>";
                if (parts.Length == 2)
                {
                    tagOutput.Append(properName).Append(' ').Append(ParseAndEscape(parts[1]));
                }
                else
                {
                    MetaTag actualTag = meta.FindTag(parts[0]);
                    if (actualTag == null)
                    {
                        string nameLow = parts[0].ToLowerFast();
                        tagOutput.Append(Util.EscapeForHTML(parts[0])).Append((nameLow == "none" || nameLow == "todo") ? "" : " ERROR: TAG INVALID");
                    }
                    else
                    {
                        string desc = ParseAndEscape(actualTag.Description);
                        if (desc.Contains('\n'))
                        {
                            desc = desc.Before('\n') + $" <a href=\"/Docs/Tags/{actualTag.CleanedName}\">(...)</a>";
                        }
                        tagOutput.Append($"<a href=\"/Docs/Tags/{actualTag.CleanedName}\">").Append(properName).Append("</a> ").Append(desc);
                    }
                }
                tagOutput.Append("\n<br>");
            }
            return(tagOutput.ToString());
        }
コード例 #3
0
 /// <summary><see cref="MetaObject.AddTo(MetaDocs)"/></summary>
 public override void AddTo(MetaDocs docs)
 {
     docs.Tags.Add(CleanName, this);
     docs.TagBases.Add(CleanName.BeforeAndAfter('.', out string otherBits));
     foreach (string bit in otherBits.Split('.'))
     {
         docs.TagParts.Add(bit);
     }
 }
コード例 #4
0
 /// <summary>
 /// Post-check handler to require specific values be set (not-null).
 /// </summary>
 /// <param name="docs">The relevant docs object.</param>
 /// <param name="requiredValues">The values that are required.</param>
 public void Require(MetaDocs docs, params object[] requiredValues)
 {
     foreach (object obj in requiredValues)
     {
         if (obj == null)
         {
             docs.LoadErrors.Add($"{Type.Name} '{Name}' is missing a required meta key.");
         }
     }
 }
コード例 #5
0
 /// <summary><see cref="MetaObject.PostCheck(MetaDocs)"/></summary>
 public override void PostCheck(MetaDocs docs)
 {
     Require(docs, Actions[0], Triggers);
     PostCheckLinkableText(docs, Triggers);
     foreach (string context in Context)
     {
         PostCheckLinkableText(docs, context);
     }
     foreach (string determine in Determinations)
     {
         PostCheckLinkableText(docs, determine);
     }
 }
コード例 #6
0
 public override void PostCheck(MetaDocs docs)
 {
     Require(docs, MechObject, MechName, Input, Description);
     PostCheckTags(docs, Tags);
     PostCheckLinkableText(docs, Description);
     if (Tags.IsEmpty())
     {
         if (docs.Tags.ContainsKey(CleanName))
         {
             docs.LoadErrors.Add($"Mechanism '{Name}' has no Tags link, but has the same name as an existing tag. A link should be added.");
         }
     }
 }
コード例 #7
0
 /// <summary>
 /// Post-check handler for tags, used in <see cref="MetaCommand"/> and <see cref="MetaMechanism"/>.
 /// </summary>
 /// <param name="docs">The relevant docs object.</param>
 /// <param name="tags">The relevant tags list.</param>
 public void PostCheckTags(MetaDocs docs, string[] tags)
 {
     foreach (string tag in tags)
     {
         if (tag.EndsWith(">"))
         {
             MetaTag realTag = docs.FindTag(tag);
             if (realTag == null)
             {
                 docs.LoadErrors.Add($"{Type.Name} '{Name}' references tag '{tag}', which doesn't exist.");
             }
         }
         PostCheckLinkableText(docs, tag);
     }
 }
コード例 #8
0
        /// <summary>Bot meta reload admin command.</summary>
        public void CMD_Reload(CommandData command)
        {
            // NOTE: This implies a one-guild bot. A multi-guild bot probably shouldn't have this "BotCommander" role-based verification.
            // But under current scale, a true-admin confirmation isn't worth the bother.
            if (!DenizenMetaBot.IsBotCommander(command.Message.Author as SocketGuildUser))
            {
                SendErrorMessageReply(command.Message, "Authorization Failure", "Nope! That's not for you!");
                return;
            }
            SendGenericPositiveMessageReply(command.Message, "Reloading", "Yes, boss. Reloading meta documentation now...");
            BuildNumberTracker.UpdateAll();
            MetaDocs docs = MetaDocsLoader.DownloadAll();

            MetaDocs.CurrentMeta = docs;
            EmbedBuilder embed = new EmbedBuilder().WithTitle("Reload Complete").WithDescription("Documentation reloaded successfully.");

            if (docs.LoadErrors.Count > 0)
            {
                List <string> errors = docs.LoadErrors.Count > 5 ? docs.LoadErrors.GetRange(0, 5) : docs.LoadErrors;
                SendErrorMessageReply(command.Message, "Error(s) While Reloading", string.Join("\n", errors));
                embed.AddField("Errors", docs.LoadErrors.Count, true);
            }
            embed.AddField("Commands", docs.Commands.Count, true);
            embed.AddField("Mechanisms", docs.Mechanisms.Count, true);
            embed.AddField("Tags", docs.Tags.Count, true);
            embed.AddField("Object Types", docs.ObjectTypes.Count, true);
            embed.AddField("Events", docs.Events.Count, true);
            embed.AddField("Actions", docs.Actions.Count, true);
            embed.AddField("Languages", docs.Languages.Count, true);
            embed.AddField("Guide Pages", docs.GuidePages.Count, true);
            SendReply(command.Message, embed.Build());
            foreach (string url in DenizenMetaBot.ReloadWebooks)
            {
                try
                {
                    Program.ReusableWebClient.PostAsync(url, new ByteArrayContent(Array.Empty <byte>())).Wait();
                }
                catch (Exception ex)
                {
                    Console.Error.Write($"Failed to ping webhook URL '{url}': {ex}");
                }
            }
        }
コード例 #9
0
 /// <summary><see cref="MetaObject.PostCheck(MetaDocs)"/></summary>
 public override void PostCheck(MetaDocs docs)
 {
     Require(docs, TagFull, Returns, Description);
     if (!string.IsNullOrWhiteSpace(Mechanism))
     {
         if (!docs.Mechanisms.ContainsKey(Mechanism.ToLowerFast()))
         {
             docs.LoadErrors.Add($"Tag '{Name}' references mechanism '{Mechanism}', which doesn't exist.");
         }
         PostCheckLinkableText(docs, Mechanism);
     }
     else
     {
         if (docs.Mechanisms.ContainsKey(CleanedName))
         {
             docs.LoadErrors.Add($"Tag '{Name}' has no mechanism link, but has the same name as an existing mechanism. A link should be added.");
         }
     }
     PostCheckLinkableText(docs, Description);
 }
コード例 #10
0
        /// <summary>
        /// Post-check handler for linkable text, to find bad links.
        /// </summary>
        /// <param name="docs">The relevant docs object.</param>
        /// <param name="linkedtext">The relevant linkable list.</param>
        public void PostCheckLinkableText(MetaDocs docs, string linkedtext)
        {
            if (string.IsNullOrWhiteSpace(linkedtext))
            {
                return;
            }
            int nextLinkIndex = linkedtext.IndexOf("<@link");

            if (nextLinkIndex < 0)
            {
                return;
            }
            while (nextLinkIndex >= 0)
            {
                int endIndex = FindClosingTagMark(linkedtext, nextLinkIndex + 1);
                if (endIndex < 0)
                {
                    return;
                }
                int    startOfMetaCommand = nextLinkIndex + "<@link ".Length;
                string metaCommand        = linkedtext[startOfMetaCommand..endIndex];
コード例 #11
0
 /// <summary><see cref="MetaObject.AddTo(MetaDocs)"/></summary>
 public override void AddTo(MetaDocs docs)
 {
     docs.Actions.Add(CleanName, this);
 }
コード例 #12
0
 /// <summary><see cref="MetaObject.PostCheck(MetaDocs)"/></summary>
 public override void PostCheck(MetaDocs docs)
 {
     Require(docs, Short, Description, Syntax, CommandName);
     PostCheckTags(docs, Tags);
     PostCheckLinkableText(docs, Description);
 }
コード例 #13
0
 /// <summary><see cref="MetaObject.AddTo(MetaDocs)"/></summary>
 public override void AddTo(MetaDocs docs)
 {
     docs.Commands.Add(CleanName, this);
 }
コード例 #14
0
 public override void PostCheck(MetaDocs docs)
 {
     Require(docs, LangName, Description);
     PostCheckLinkableText(docs, Description);
 }
コード例 #15
0
 /// <summary><see cref="MetaObject.AddTo(MetaDocs)"/></summary>
 public override void AddTo(MetaDocs docs)
 {
     docs.GuidePages.Add(CleanName, this);
 }
コード例 #16
0
 /// <summary>
 /// Checks the object for validity, after all loading is done.
 /// </summary>
 /// <param name="docs">The relevant docs object.</param>
 public virtual void PostCheck(MetaDocs docs)
 {
 }
コード例 #17
0
 /// <summary>
 /// Adds the object to the meta docs set.
 /// </summary>
 /// <param name="docs">The docs set.</param>
 public abstract void AddTo(MetaDocs docs);
コード例 #18
0
        public static void ReloadMeta()
        {
            lock (ReloadTimeLock)
            {
                DateTimeOffset now = DateTimeOffset.UtcNow;
                if (now.Subtract(LastReload).TotalSeconds < 15)
                {
                    Console.WriteLine("Ignoring too-fast reload...");
                    return;
                }
                LastReload = now;
            }
            lock (ReloadLock)
            {
                Console.WriteLine("Reloading meta...");
                MetaDocs docs = MetaDocsLoader.DownloadAll();
                Console.WriteLine("Meta loaded, HTMLizing...");
                List <WebsiteMetaCommand>    _commands    = new List <WebsiteMetaCommand>();
                List <WebsiteMetaTag>        _tags        = new List <WebsiteMetaTag>();
                List <WebsiteMetaObjectType> _objectTypes = new List <WebsiteMetaObjectType>();
                List <WebsiteMetaEvent>      _events      = new List <WebsiteMetaEvent>();
                List <WebsiteMetaAction>     _actions     = new List <WebsiteMetaAction>();
                List <WebsiteMetaLanguage>   _languages   = new List <WebsiteMetaLanguage>();
                List <WebsiteMetaMechanism>  _mechanisms  = new List <WebsiteMetaMechanism>();
                List <WebsiteMetaObject>     _allObjects  = new List <WebsiteMetaObject>();
                void procSet <T, T2>(ref List <T> webObjs, ICollection <T2> origObjs) where T : WebsiteMetaObject <T2>, new() where T2 : MetaObject
                {
                    foreach (T2 obj in origObjs)
                    {
                        T webObj = new T()
                        {
                            Object = obj
                        };
                        webObjs.Add(webObj);
                    }
                    webObjs = webObjs.OrderBy(o => string.IsNullOrWhiteSpace(o.Object.Plugin) ? 0 : 1).ThenBy(o => o.Object.Warnings.Count).ThenBy(o => o.Object.Group).ThenBy(o => o.Object.CleanName).ToList();
                    _allObjects.AddRange(webObjs);
                }

                procSet(ref _commands, docs.Commands.Values);
                procSet(ref _tags, docs.Tags.Values);
                procSet(ref _objectTypes, docs.ObjectTypes.Values);
                procSet(ref _events, docs.Events.Values);
                procSet(ref _actions, docs.Actions.Values);
                procSet(ref _languages, docs.Languages.Values);
                procSet(ref _mechanisms, docs.Mechanisms.Values);
                foreach (WebsiteMetaObject obj in _allObjects)
                {
                    obj.Docs = docs;
                    obj.LoadHTML();
                    obj.AllSearchableText = obj.ObjectGeneric.GetAllSearchableText().ToLowerFast();
                }
                Commands             = _commands;
                Tags                 = _tags;
                ObjectTypes          = _objectTypes;
                Events               = _events;
                Actions              = _actions;
                Languages            = _languages;
                Mechanisms           = _mechanisms;
                AllObjects           = _allObjects;
                MetaDocs.CurrentMeta = docs;
                Console.WriteLine("Meta loaded and ready!");
            }
        }
コード例 #19
0
        /// <summary>
        /// Post-check handler for linkable text, to find bad links.
        /// </summary>
        /// <param name="docs">The relevant docs object.</param>
        /// <param name="linkedtext">The relevant linkable list.</param>
        public void PostCheckLinkableText(MetaDocs docs, string linkedtext)
        {
            if (string.IsNullOrWhiteSpace(linkedtext))
            {
                return;
            }
            int nextLinkIndex = linkedtext.IndexOf("<@link");

            if (nextLinkIndex < 0)
            {
                return;
            }
            while (nextLinkIndex >= 0)
            {
                int endIndex = FindClosingTagMark(linkedtext, nextLinkIndex + 1);
                if (endIndex < 0)
                {
                    return;
                }
                int    startOfMetaCommand = nextLinkIndex + "<@link ".Length;
                string metaCommand        = linkedtext.Substring(startOfMetaCommand, endIndex - startOfMetaCommand);
                if (!metaCommand.StartsWith("url"))
                {
                    int firstSpace = metaCommand.IndexOf(' ');
                    if (firstSpace < 0)
                    {
                        docs.LoadErrors.Add($"{Type.Name} '{Name}' contains text link '{metaCommand}', which is formatted incorrectly.");
                        return;
                    }
                    string type       = metaCommand.Substring(0, firstSpace).ToLowerFast();
                    string searchText = metaCommand.Substring(firstSpace + 1).ToLowerFast();
                    bool   exists;
                    if (type.Equals("command"))
                    {
                        exists = docs.Commands.ContainsKey(searchText);
                    }
                    else if (type.Equals("tag"))
                    {
                        exists = docs.FindTag(searchText) != null;
                    }
                    else if (type.Equals("mechanism"))
                    {
                        exists = docs.Mechanisms.ContainsKey(searchText);
                    }
                    else if (type.Equals("event"))
                    {
                        if (searchText.StartsWith("on "))
                        {
                            searchText = searchText.Substring("on ".Length);
                        }
                        exists = docs.Events.Values.Any(e => e.CleanEvents.Any(s => s.Contains(searchText)));
                        if (!exists)
                        {
                            exists = docs.Events.Values.Any(e => e.RegexMatcher.IsMatch(searchText));
                        }
                    }
                    else if (type.Equals("action"))
                    {
                        if (searchText.StartsWith("on "))
                        {
                            searchText = searchText.Substring("on ".Length);
                        }
                        exists = docs.Actions.Values.Any(a => a.CleanActions.Any(s => s.Contains(searchText)));
                    }
                    else if (type.Equals("language"))
                    {
                        exists = docs.Languages.Keys.Any(s => s.Contains(searchText));
                    }
                    else
                    {
                        docs.LoadErrors.Add($"{Type.Name} '{Name}' contains text link '{metaCommand}', which refers to an unknown meta type.");
                        return;
                    }
                    if (!exists)
                    {
                        docs.LoadErrors.Add($"{Type.Name} '{Name}' contains text link '{metaCommand}', which does not exist.");
                        return;
                    }
                }
                nextLinkIndex = linkedtext.IndexOf("<@link", endIndex + 1);
            }
        }
コード例 #20
0
 public override void AddTo(MetaDocs docs)
 {
     docs.Mechanisms.Add(CleanName, this);
 }