evennia/docs/2.x/_modules/evennia/commands/default/help.html
Evennia docbuilder action e535f5782a Updated HTML docs.
2023-10-19 20:22:27 +00:00

1148 lines
No EOL
134 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.commands.default.help &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../../../../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../../../../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../../../../" src="../../../../_static/documentation_options.js"></script>
<script src="../../../../_static/jquery.js"></script>
<script src="../../../../_static/underscore.js"></script>
<script src="../../../../_static/doctools.js"></script>
<script src="../../../../_static/language_data.js"></script>
<link rel="shortcut icon" href="../../../../_static/favicon.ico"/>
<link rel="index" title="Index" href="../../../../genindex.html" />
<link rel="search" title="Search" href="../../../../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../../evennia.html" accesskey="U">evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.commands.default.help</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../../../../index.html">
<img class="logo" src="../../../../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Doc Versions</h3>
<ul>
<li><a href="help.html">2.x (main branch)</a></li>
<ul>
<li><a href="../1.3.0/index.html">1.3.0 (v1.3.0 branch)</a></li>
<li><a href="../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.commands.default.help</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">The help command. The basic idea is that help texts for commands are best</span>
<span class="sd">written by those that write the commands - the developers. So command-help is</span>
<span class="sd">all auto-loaded and searched from the current command set. The normal,</span>
<span class="sd">database-tied help system is used for collaborative creation of other help</span>
<span class="sd">topics such as RP help or game-world aides. Help entries can also be created</span>
<span class="sd">outside the game in modules given by ``settings.FILE_HELP_ENTRY_MODULES``.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
<span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">chain</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">evennia.help.filehelp</span> <span class="kn">import</span> <span class="n">FILE_HELP_ENTRIES</span>
<span class="kn">from</span> <span class="nn">evennia.help.models</span> <span class="kn">import</span> <span class="n">HelpEntry</span>
<span class="kn">from</span> <span class="nn">evennia.help.utils</span> <span class="kn">import</span> <span class="n">help_search_with_index</span><span class="p">,</span> <span class="n">parse_entry_for_subcategories</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">create</span><span class="p">,</span> <span class="n">evmore</span>
<span class="kn">from</span> <span class="nn">evennia.utils.ansi</span> <span class="kn">import</span> <span class="n">ANSIString</span>
<span class="kn">from</span> <span class="nn">evennia.utils.eveditor</span> <span class="kn">import</span> <span class="n">EvEditor</span>
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">class_from_module</span><span class="p">,</span> <span class="n">dedent</span><span class="p">,</span> <span class="n">format_grid</span><span class="p">,</span> <span class="n">inherits_from</span><span class="p">,</span> <span class="n">pad</span>
<span class="n">CMD_IGNORE_PREFIXES</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CMD_IGNORE_PREFIXES</span>
<span class="n">COMMAND_DEFAULT_CLASS</span> <span class="o">=</span> <span class="n">class_from_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">)</span>
<span class="n">HELP_MORE_ENABLED</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">HELP_MORE_ENABLED</span>
<span class="n">DEFAULT_HELP_CATEGORY</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_HELP_CATEGORY</span>
<span class="n">HELP_CLICKABLE_TOPICS</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">HELP_CLICKABLE_TOPICS</span>
<span class="c1"># limit symbol import for API</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;CmdHelp&quot;</span><span class="p">,</span> <span class="s2">&quot;CmdSetHelp&quot;</span><span class="p">)</span>
<span class="nd">@dataclass</span>
<span class="k">class</span> <span class="nc">HelpCategory</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Mock &#39;help entry&#39; to search categories with the same code.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span><span class="p">:</span> <span class="nb">str</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">search_index_entry</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{</span>
<span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">,</span>
<span class="s2">&quot;aliases&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;category&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">,</span>
<span class="s2">&quot;no_prefix&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;tags&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;text&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">id</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<div class="viewcode-block" id="CmdHelp"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp">[docs]</a><span class="k">class</span> <span class="nc">CmdHelp</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get help.</span>
<span class="sd"> Usage:</span>
<span class="sd"> help</span>
<span class="sd"> help &lt;topic, command or category&gt;</span>
<span class="sd"> help &lt;topic&gt;/&lt;subtopic&gt;</span>
<span class="sd"> help &lt;topic&gt;/&lt;subtopic&gt;/&lt;subsubtopic&gt; ...</span>
<span class="sd"> Use the &#39;help&#39; command alone to see an index of all help topics, organized</span>
<span class="sd"> by category. Some big topics may offer additional sub-topics.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;help&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;?&quot;</span><span class="p">]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span>
<span class="n">arg_regex</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">&quot;\s|$&quot;</span>
<span class="c1"># this is a special cmdhandler flag that makes the cmdhandler also pack</span>
<span class="c1"># the current cmdset with the call to self.func().</span>
<span class="n">return_cmdset</span> <span class="o">=</span> <span class="kc">True</span>
<span class="c1"># Help messages are wrapped in an EvMore call (unless using the webclient</span>
<span class="c1"># with separate help popups) If you want to avoid this, simply add</span>
<span class="c1"># &#39;HELP_MORE_ENABLED = False&#39; in your settings/conf/settings.py</span>
<span class="n">help_more</span> <span class="o">=</span> <span class="n">HELP_MORE_ENABLED</span>
<span class="c1"># colors for the help index</span>
<span class="n">index_type_separator_clr</span> <span class="o">=</span> <span class="s2">&quot;|w&quot;</span>
<span class="n">index_category_clr</span> <span class="o">=</span> <span class="s2">&quot;|W&quot;</span>
<span class="n">index_topic_clr</span> <span class="o">=</span> <span class="s2">&quot;|G&quot;</span>
<span class="c1"># suggestion cutoff, between 0 and 1 (1 =&gt; perfect match)</span>
<span class="n">suggestion_cutoff</span> <span class="o">=</span> <span class="mf">0.6</span>
<span class="c1"># number of suggestions (set to 0 to remove suggestions from help)</span>
<span class="n">suggestion_maxnum</span> <span class="o">=</span> <span class="mi">5</span>
<span class="c1"># separator between subtopics:</span>
<span class="n">subtopic_separator_char</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">&quot;/&quot;</span>
<span class="c1"># should topics disply their help entry when clicked</span>
<span class="n">clickable_topics</span> <span class="o">=</span> <span class="n">HELP_CLICKABLE_TOPICS</span>
<div class="viewcode-block" id="CmdHelp.msg_help"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.msg_help">[docs]</a> <span class="k">def</span> <span class="nf">msg_help</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> messages text to the caller, adding an extra oob argument to indicate</span>
<span class="sd"> that this is a help command result and could be rendered in a separate</span>
<span class="sd"> help window.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">help_more</span><span class="p">:</span>
<span class="n">usemore</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">protocol_key</span> <span class="ow">in</span> <span class="p">(</span>
<span class="s2">&quot;websocket&quot;</span><span class="p">,</span>
<span class="s2">&quot;ajax/comet&quot;</span><span class="p">,</span>
<span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">options</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">account</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_saved_webclient_options</span>
<span class="k">if</span> <span class="n">options</span> <span class="ow">and</span> <span class="n">options</span><span class="p">[</span><span class="s2">&quot;helppopup&quot;</span><span class="p">]:</span>
<span class="n">usemore</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">if</span> <span class="n">usemore</span><span class="p">:</span>
<span class="c1"># adding the &#39;text_kwargs&#39; keyword means it will be sent with the text outputfunc</span>
<span class="c1"># for every page.</span>
<span class="n">evmore</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">,</span> <span class="n">text_kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;help&quot;</span><span class="p">},</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">text</span><span class="o">=</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="p">{</span><span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;help&quot;</span><span class="p">}))</span></div>
<div class="viewcode-block" id="CmdHelp.format_help_entry"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.format_help_entry">[docs]</a> <span class="k">def</span> <span class="nf">format_help_entry</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">topic</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">help_text</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">aliases</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">suggested</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">subtopics</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">click_topics</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;This visually formats the help entry.</span>
<span class="sd"> This method can be overridden to customize the way a help</span>
<span class="sd"> entry is displayed.</span>
<span class="sd"> Args:</span>
<span class="sd"> title (str, optional): The title of the help entry.</span>
<span class="sd"> help_text (str, optional): Text of the help entry.</span>
<span class="sd"> aliases (list, optional): List of help-aliases (displayed in header).</span>
<span class="sd"> suggested (list, optional): Strings suggested reading (based on title).</span>
<span class="sd"> subtopics (list, optional): A list of strings - the subcategories available</span>
<span class="sd"> for this entry.</span>
<span class="sd"> click_topics (bool, optional): Should help topics be clickable. Default is True.</span>
<span class="sd"> Returns:</span>
<span class="sd"> help_message (str): Help entry formated for console.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">separator</span> <span class="o">=</span> <span class="s2">&quot;|C&quot;</span> <span class="o">+</span> <span class="s2">&quot;-&quot;</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_width</span><span class="p">()</span> <span class="o">+</span> <span class="s2">&quot;|n&quot;</span>
<span class="n">start</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">separator</span><span class="si">}</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="n">title</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;|CHelp for |w</span><span class="si">{</span><span class="n">topic</span><span class="si">}</span><span class="s2">|n&quot;</span> <span class="k">if</span> <span class="n">topic</span> <span class="k">else</span> <span class="s2">&quot;|rNo help found|n&quot;</span>
<span class="k">if</span> <span class="n">aliases</span><span class="p">:</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="s2">&quot; |C(aliases: </span><span class="si">{}</span><span class="s2">|C)|n&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="s2">&quot;|C,|n &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;|w</span><span class="si">{</span><span class="n">ali</span><span class="si">}</span><span class="s2">|n&quot;</span> <span class="k">for</span> <span class="n">ali</span> <span class="ow">in</span> <span class="n">aliases</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">help_text</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="n">dedent</span><span class="p">(</span><span class="n">help_text</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">))</span> <span class="k">if</span> <span class="n">help_text</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="n">subtopics</span><span class="p">:</span>
<span class="k">if</span> <span class="n">click_topics</span><span class="p">:</span>
<span class="n">subtopics</span> <span class="o">=</span> <span class="p">[</span>
<span class="sa">f</span><span class="s2">&quot;|lchelp </span><span class="si">{</span><span class="n">topic</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">subtop</span><span class="si">}</span><span class="s2">|lt|w</span><span class="si">{</span><span class="n">topic</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">subtop</span><span class="si">}</span><span class="s2">|n|le&quot;</span> <span class="k">for</span> <span class="n">subtop</span> <span class="ow">in</span> <span class="n">subtopics</span>
<span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">subtopics</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">&quot;|w</span><span class="si">{</span><span class="n">topic</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">subtop</span><span class="si">}</span><span class="s2">|n&quot;</span> <span class="k">for</span> <span class="n">subtop</span> <span class="ow">in</span> <span class="n">subtopics</span><span class="p">]</span>
<span class="n">subtopics</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|CSubtopics:|n</span><span class="se">\n</span><span class="s2"> </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="s2">&quot;</span><span class="se">\n</span><span class="s2"> &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="n">format_grid</span><span class="p">(</span>
<span class="n">subtopics</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">client_width</span><span class="p">(),</span> <span class="n">line_prefix</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">index_topic_clr</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">subtopics</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="n">suggested</span><span class="p">:</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">suggested</span><span class="p">)</span>
<span class="k">if</span> <span class="n">click_topics</span><span class="p">:</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">&quot;|lchelp </span><span class="si">{</span><span class="n">sug</span><span class="si">}</span><span class="s2">|lt|w</span><span class="si">{</span><span class="n">sug</span><span class="si">}</span><span class="s2">|n|le&quot;</span> <span class="k">for</span> <span class="n">sug</span> <span class="ow">in</span> <span class="n">suggested</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">&quot;|w</span><span class="si">{</span><span class="n">sug</span><span class="si">}</span><span class="s2">|n&quot;</span> <span class="k">for</span> <span class="n">sug</span> <span class="ow">in</span> <span class="n">suggested</span><span class="p">]</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|COther topic suggestions:|n</span><span class="se">\n</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="s2">&quot;</span><span class="se">\n</span><span class="s2"> &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="n">format_grid</span><span class="p">(</span>
<span class="n">suggested</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">client_width</span><span class="p">(),</span> <span class="n">line_prefix</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">index_topic_clr</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">start</span>
<span class="n">partorder</span> <span class="o">=</span> <span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">title</span> <span class="o">+</span> <span class="n">aliases</span><span class="p">,</span> <span class="n">help_text</span><span class="p">,</span> <span class="n">subtopics</span><span class="p">,</span> <span class="n">suggested</span><span class="p">,</span> <span class="n">end</span><span class="p">)</span>
<span class="k">return</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span> <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">partorder</span> <span class="k">if</span> <span class="n">part</span><span class="p">)</span></div>
<div class="viewcode-block" id="CmdHelp.format_help_index"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.format_help_index">[docs]</a> <span class="k">def</span> <span class="nf">format_help_index</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="n">cmd_help_dict</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">db_help_dict</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">title_lone_category</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">click_topics</span><span class="o">=</span><span class="kc">True</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Output a category-ordered g for displaying the main help, grouped by</span>
<span class="sd"> category.</span>
<span class="sd"> Args:</span>
<span class="sd"> cmd_help_dict (dict): A dict `{&quot;category&quot;: [topic, topic, ...]}` for</span>
<span class="sd"> command-based help.</span>
<span class="sd"> db_help_dict (dict): A dict `{&quot;category&quot;: [topic, topic], ...]}` for</span>
<span class="sd"> database-based help.</span>
<span class="sd"> title_lone_category (bool, optional): If a lone category should</span>
<span class="sd"> be titled with the category name or not. While pointless in a</span>
<span class="sd"> general index, the title should probably show when explicitly</span>
<span class="sd"> listing the category itself.</span>
<span class="sd"> click_topics (bool, optional): If help-topics are clickable or not</span>
<span class="sd"> (for webclient or telnet clients with MXP support).</span>
<span class="sd"> Returns:</span>
<span class="sd"> str: The help index organized into a grid.</span>
<span class="sd"> Notes:</span>
<span class="sd"> The input are the pre-loaded help files for commands and database-helpfiles</span>
<span class="sd"> respectively. You can override this method to return a custom display of the list of</span>
<span class="sd"> commands and topics.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">_group_by_category</span><span class="p">(</span><span class="n">help_dict</span><span class="p">):</span>
<span class="n">grid</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">verbatim_elements</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">help_dict</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">title_lone_category</span><span class="p">:</span>
<span class="c1"># don&#39;t list categories if there is only one</span>
<span class="k">for</span> <span class="n">category</span> <span class="ow">in</span> <span class="n">help_dict</span><span class="p">:</span>
<span class="c1"># gather and sort the entries from the help dictionary</span>
<span class="n">entries</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">help_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">category</span><span class="p">,</span> <span class="p">[])))</span>
<span class="c1"># make the help topics clickable</span>
<span class="k">if</span> <span class="n">click_topics</span><span class="p">:</span>
<span class="n">entries</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">&quot;|lchelp </span><span class="si">{</span><span class="n">entry</span><span class="si">}</span><span class="s2">|lt</span><span class="si">{</span><span class="n">entry</span><span class="si">}</span><span class="s2">|le&quot;</span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">entries</span><span class="p">]</span>
<span class="c1"># add the entries to the grid</span>
<span class="n">grid</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">entries</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># list the categories</span>
<span class="k">for</span> <span class="n">category</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">help_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">()))):</span>
<span class="n">category_str</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;-- </span><span class="si">{</span><span class="n">category</span><span class="o">.</span><span class="n">title</span><span class="p">()</span><span class="si">}</span><span class="s2"> &quot;</span>
<span class="n">grid</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="n">ANSIString</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">index_category_clr</span>
<span class="o">+</span> <span class="n">category_str</span>
<span class="o">+</span> <span class="s2">&quot;-&quot;</span> <span class="o">*</span> <span class="p">(</span><span class="n">width</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">category_str</span><span class="p">))</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">index_topic_clr</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="n">verbatim_elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">grid</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1"># gather and sort the entries from the help dictionary</span>
<span class="n">entries</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">help_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">category</span><span class="p">,</span> <span class="p">[])))</span>
<span class="c1"># make the help topics clickable</span>
<span class="k">if</span> <span class="n">click_topics</span><span class="p">:</span>
<span class="n">entries</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">&quot;|lchelp </span><span class="si">{</span><span class="n">entry</span><span class="si">}</span><span class="s2">|lt</span><span class="si">{</span><span class="n">entry</span><span class="si">}</span><span class="s2">|le&quot;</span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">entries</span><span class="p">]</span>
<span class="c1"># add the entries to the grid</span>
<span class="n">grid</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">entries</span><span class="p">)</span>
<span class="k">return</span> <span class="n">grid</span><span class="p">,</span> <span class="n">verbatim_elements</span>
<span class="n">help_index</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">width</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_width</span><span class="p">()</span>
<span class="n">grid</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">verbatim_elements</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">cmd_grid</span><span class="p">,</span> <span class="n">db_grid</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">cmd_help_dict</span><span class="o">.</span><span class="n">values</span><span class="p">()):</span>
<span class="c1"># get the command-help entries by-category</span>
<span class="n">sep1</span> <span class="o">=</span> <span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">index_type_separator_clr</span>
<span class="o">+</span> <span class="n">pad</span><span class="p">(</span><span class="s2">&quot;Commands&quot;</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span> <span class="n">fillchar</span><span class="o">=</span><span class="s2">&quot;-&quot;</span><span class="p">)</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">index_topic_clr</span>
<span class="p">)</span>
<span class="n">grid</span><span class="p">,</span> <span class="n">verbatim_elements</span> <span class="o">=</span> <span class="n">_group_by_category</span><span class="p">(</span><span class="n">cmd_help_dict</span><span class="p">)</span>
<span class="n">gridrows</span> <span class="o">=</span> <span class="n">format_grid</span><span class="p">(</span>
<span class="n">grid</span><span class="p">,</span>
<span class="n">width</span><span class="p">,</span>
<span class="n">sep</span><span class="o">=</span><span class="s2">&quot; &quot;</span><span class="p">,</span>
<span class="n">verbatim_elements</span><span class="o">=</span><span class="n">verbatim_elements</span><span class="p">,</span>
<span class="n">line_prefix</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">index_topic_clr</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">cmd_grid</span> <span class="o">=</span> <span class="n">ANSIString</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">gridrows</span><span class="p">)</span> <span class="k">if</span> <span class="n">gridrows</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">db_help_dict</span><span class="o">.</span><span class="n">values</span><span class="p">()):</span>
<span class="c1"># get db-based help entries by-category</span>
<span class="n">sep2</span> <span class="o">=</span> <span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">index_type_separator_clr</span>
<span class="o">+</span> <span class="n">pad</span><span class="p">(</span><span class="s2">&quot;Game &amp; World&quot;</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span> <span class="n">fillchar</span><span class="o">=</span><span class="s2">&quot;-&quot;</span><span class="p">)</span>
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">index_topic_clr</span>
<span class="p">)</span>
<span class="n">grid</span><span class="p">,</span> <span class="n">verbatim_elements</span> <span class="o">=</span> <span class="n">_group_by_category</span><span class="p">(</span><span class="n">db_help_dict</span><span class="p">)</span>
<span class="n">gridrows</span> <span class="o">=</span> <span class="n">format_grid</span><span class="p">(</span>
<span class="n">grid</span><span class="p">,</span>
<span class="n">width</span><span class="p">,</span>
<span class="n">sep</span><span class="o">=</span><span class="s2">&quot; &quot;</span><span class="p">,</span>
<span class="n">verbatim_elements</span><span class="o">=</span><span class="n">verbatim_elements</span><span class="p">,</span>
<span class="n">line_prefix</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">index_topic_clr</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">db_grid</span> <span class="o">=</span> <span class="n">ANSIString</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">gridrows</span><span class="p">)</span> <span class="k">if</span> <span class="n">gridrows</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="c1"># only show the main separators if there are actually both cmd and db-based help</span>
<span class="k">if</span> <span class="n">cmd_grid</span> <span class="ow">and</span> <span class="n">db_grid</span><span class="p">:</span>
<span class="n">help_index</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">sep1</span><span class="si">}</span><span class="se">\n</span><span class="si">{</span><span class="n">cmd_grid</span><span class="si">}</span><span class="se">\n</span><span class="si">{</span><span class="n">sep2</span><span class="si">}</span><span class="se">\n</span><span class="si">{</span><span class="n">db_grid</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">help_index</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">cmd_grid</span><span class="si">}{</span><span class="n">db_grid</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">return</span> <span class="n">help_index</span></div>
<div class="viewcode-block" id="CmdHelp.can_read_topic"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.can_read_topic">[docs]</a> <span class="k">def</span> <span class="nf">can_read_topic</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cmd_or_topic</span><span class="p">,</span> <span class="n">caller</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper method. If this return True, the given help topic</span>
<span class="sd"> be viewable in the help listing. Note that even if this returns False,</span>
<span class="sd"> the entry will still be visible in the help index unless `should_list_topic`</span>
<span class="sd"> is also returning False.</span>
<span class="sd"> Args:</span>
<span class="sd"> cmd_or_topic (Command, HelpEntry or FileHelpEntry): The topic/command to test.</span>
<span class="sd"> caller: the caller checking for access.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: If command can be viewed or not.</span>
<span class="sd"> Notes:</span>
<span class="sd"> This uses the &#39;read&#39; lock. If no &#39;read&#39; lock is defined, the topic is assumed readable</span>
<span class="sd"> by all.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">cmd_or_topic</span><span class="p">,</span> <span class="s2">&quot;evennia.commands.command.Command&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="n">cmd_or_topic</span><span class="o">.</span><span class="n">auto_help</span> <span class="ow">and</span> <span class="n">cmd_or_topic</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;read&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">cmd_or_topic</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;read&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>
<div class="viewcode-block" id="CmdHelp.can_list_topic"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.can_list_topic">[docs]</a> <span class="k">def</span> <span class="nf">can_list_topic</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cmd_or_topic</span><span class="p">,</span> <span class="n">caller</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Should the specified command appear in the help table?</span>
<span class="sd"> This method only checks whether a specified command should appear in the table of</span>
<span class="sd"> topics/commands. The command can be used by the caller (see the &#39;should_show_help&#39; method)</span>
<span class="sd"> and the command will still be available, for instance, if a character type &#39;help name of the</span>
<span class="sd"> command&#39;. However, if you return False, the specified command will not appear in the table.</span>
<span class="sd"> This is sometimes useful to &quot;hide&quot; commands in the table, but still access them through the</span>
<span class="sd"> help system.</span>
<span class="sd"> Args:</span>
<span class="sd"> cmd_or_topic (Command, HelpEntry or FileHelpEntry): The topic/command to test.</span>
<span class="sd"> caller: the caller checking for access.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: If command should be listed or not.</span>
<span class="sd"> Notes:</span>
<span class="sd"> The `.auto_help` propery is checked for commands. For all help entries,</span>
<span class="sd"> the &#39;view&#39; lock will be checked, and if no such lock is defined, the &#39;read&#39;</span>
<span class="sd"> lock will be used. If neither lock is defined, the help entry is assumed to be</span>
<span class="sd"> accessible to all.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">cmd_or_topic</span><span class="p">,</span> <span class="s2">&quot;auto_help&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">cmd_or_topic</span><span class="o">.</span><span class="n">auto_help</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="n">has_view</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;view:&quot;</span> <span class="ow">in</span> <span class="n">cmd_or_topic</span><span class="o">.</span><span class="n">locks</span>
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">cmd_or_topic</span><span class="p">,</span> <span class="s2">&quot;evennia.commands.command.Command&quot;</span><span class="p">)</span>
<span class="k">else</span> <span class="n">cmd_or_topic</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;view&quot;</span><span class="p">)</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">has_view</span><span class="p">:</span>
<span class="k">return</span> <span class="n">cmd_or_topic</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;view&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># no explicit &#39;view&#39; lock - use the &#39;read&#39; lock</span>
<span class="k">return</span> <span class="n">cmd_or_topic</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;read&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>
<div class="viewcode-block" id="CmdHelp.collect_topics"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.collect_topics">[docs]</a> <span class="k">def</span> <span class="nf">collect_topics</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">caller</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s2">&quot;list&quot;</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Collect help topics from all sources (cmd/db/file).</span>
<span class="sd"> Args:</span>
<span class="sd"> caller (Object or Account): The user of the Command.</span>
<span class="sd"> mode (str): One of &#39;list&#39; or &#39;query&#39;, where the first means we are collecting to view</span>
<span class="sd"> the help index and the second because of wanting to search for a specific help</span>
<span class="sd"> entry/cmd to read. This determines which access should be checked.</span>
<span class="sd"> Returns:</span>
<span class="sd"> tuple: A tuple of three dicts containing the different types of help entries</span>
<span class="sd"> in the order cmd-help, db-help, file-help:</span>
<span class="sd"> `({key: cmd,...}, {key: dbentry,...}, {key: fileentry,...}`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># start with cmd-help</span>
<span class="n">cmdset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmdset</span>
<span class="c1"># removing doublets in cmdset, caused by cmdhandler</span>
<span class="c1"># having to allow doublet commands to manage exits etc.</span>
<span class="n">cmdset</span><span class="o">.</span><span class="n">make_unique</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="c1"># retrieve all available commands and database / file-help topics.</span>
<span class="c1"># also check the &#39;cmd:&#39; lock here</span>
<span class="n">cmd_help_topics</span> <span class="o">=</span> <span class="p">[</span><span class="n">cmd</span> <span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">cmdset</span> <span class="k">if</span> <span class="n">cmd</span> <span class="ow">and</span> <span class="n">cmd</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;cmd&quot;</span><span class="p">)]</span>
<span class="c1"># get all file-based help entries, checking perms</span>
<span class="n">file_help_topics</span> <span class="o">=</span> <span class="p">{</span><span class="n">topic</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">():</span> <span class="n">topic</span> <span class="k">for</span> <span class="n">topic</span> <span class="ow">in</span> <span class="n">FILE_HELP_ENTRIES</span><span class="o">.</span><span class="n">all</span><span class="p">()}</span>
<span class="c1"># get db-based help entries, checking perms</span>
<span class="n">db_help_topics</span> <span class="o">=</span> <span class="p">{</span><span class="n">topic</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">():</span> <span class="n">topic</span> <span class="k">for</span> <span class="n">topic</span> <span class="ow">in</span> <span class="n">HelpEntry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()}</span>
<span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s2">&quot;list&quot;</span><span class="p">:</span>
<span class="c1"># check the view lock for all help entries/commands and determine key</span>
<span class="n">cmd_help_topics</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">cmd</span><span class="o">.</span><span class="n">auto_help_display_key</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="s2">&quot;auto_help_display_key&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">cmd</span><span class="o">.</span><span class="n">key</span><span class="p">:</span> <span class="n">cmd</span>
<span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">cmd_help_topics</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">can_list_topic</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">caller</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">db_help_topics</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">key</span><span class="p">:</span> <span class="n">entry</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">db_help_topics</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">can_list_topic</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">caller</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">file_help_topics</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">key</span><span class="p">:</span> <span class="n">entry</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">file_help_topics</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">can_list_topic</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">caller</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># query - check the read lock on entries</span>
<span class="n">cmd_help_topics</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">cmd</span><span class="o">.</span><span class="n">auto_help_display_key</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="s2">&quot;auto_help_display_key&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">cmd</span><span class="o">.</span><span class="n">key</span><span class="p">:</span> <span class="n">cmd</span>
<span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">cmd_help_topics</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">can_read_topic</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">caller</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">db_help_topics</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">key</span><span class="p">:</span> <span class="n">entry</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">db_help_topics</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">can_read_topic</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">caller</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">file_help_topics</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">key</span><span class="p">:</span> <span class="n">entry</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">file_help_topics</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">can_read_topic</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">caller</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">cmd_help_topics</span><span class="p">,</span> <span class="n">db_help_topics</span><span class="p">,</span> <span class="n">file_help_topics</span></div>
<div class="viewcode-block" id="CmdHelp.do_search"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.do_search">[docs]</a> <span class="k">def</span> <span class="nf">do_search</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">entries</span><span class="p">,</span> <span class="n">search_fields</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Perform a help-query search, default using Lunr search engine.</span>
<span class="sd"> Args:</span>
<span class="sd"> query (str): The help entry to search for.</span>
<span class="sd"> entries (list): All possibilities. A mix of commands, HelpEntries and FileHelpEntries.</span>
<span class="sd"> search_fields (list): A list of dicts defining how Lunr will find the</span>
<span class="sd"> search data on the elements. If not given, will use a default.</span>
<span class="sd"> Returns:</span>
<span class="sd"> tuple: A tuple (match, suggestions).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">search_fields</span><span class="p">:</span>
<span class="c1"># lunr search fields/boosts</span>
<span class="n">search_fields</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span><span class="s2">&quot;field_name&quot;</span><span class="p">:</span> <span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="s2">&quot;boost&quot;</span><span class="p">:</span> <span class="mi">10</span><span class="p">},</span>
<span class="p">{</span><span class="s2">&quot;field_name&quot;</span><span class="p">:</span> <span class="s2">&quot;aliases&quot;</span><span class="p">,</span> <span class="s2">&quot;boost&quot;</span><span class="p">:</span> <span class="mi">9</span><span class="p">},</span>
<span class="p">{</span><span class="s2">&quot;field_name&quot;</span><span class="p">:</span> <span class="s2">&quot;no_prefix&quot;</span><span class="p">,</span> <span class="s2">&quot;boost&quot;</span><span class="p">:</span> <span class="mi">8</span><span class="p">},</span>
<span class="p">{</span><span class="s2">&quot;field_name&quot;</span><span class="p">:</span> <span class="s2">&quot;category&quot;</span><span class="p">,</span> <span class="s2">&quot;boost&quot;</span><span class="p">:</span> <span class="mi">7</span><span class="p">},</span>
<span class="p">{</span><span class="s2">&quot;field_name&quot;</span><span class="p">:</span> <span class="s2">&quot;tags&quot;</span><span class="p">,</span> <span class="s2">&quot;boost&quot;</span><span class="p">:</span> <span class="mi">1</span><span class="p">},</span> <span class="c1"># tags are not used by default</span>
<span class="p">]</span>
<span class="n">match</span><span class="p">,</span> <span class="n">suggestions</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span>
<span class="k">for</span> <span class="n">match_query</span> <span class="ow">in</span> <span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">*&quot;</span><span class="p">):</span>
<span class="c1"># We first do an exact word-match followed by a start-by query. The</span>
<span class="c1"># return of this will either be a HelpCategory, a Command or a</span>
<span class="c1"># HelpEntry/FileHelpEntry.</span>
<span class="n">matches</span><span class="p">,</span> <span class="n">suggestions</span> <span class="o">=</span> <span class="n">help_search_with_index</span><span class="p">(</span>
<span class="n">match_query</span><span class="p">,</span> <span class="n">entries</span><span class="p">,</span> <span class="n">suggestion_maxnum</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">suggestion_maxnum</span><span class="p">,</span> <span class="n">fields</span><span class="o">=</span><span class="n">search_fields</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">matches</span><span class="p">:</span>
<span class="n">match</span> <span class="o">=</span> <span class="n">matches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">break</span>
<span class="k">return</span> <span class="n">match</span><span class="p">,</span> <span class="n">suggestions</span></div>
<div class="viewcode-block" id="CmdHelp.parse"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.parse">[docs]</a> <span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> input is a string containing the command or topic to match.</span>
<span class="sd"> The allowed syntax is</span>
<span class="sd"> ::</span>
<span class="sd"> help &lt;topic&gt;[/&lt;subtopic&gt;[/&lt;subtopic&gt;[/...]]]</span>
<span class="sd"> The database/command query is always for `&lt;topic&gt;`, and any subtopics</span>
<span class="sd"> is then parsed from there. If a `&lt;topic&gt;` has spaces in it, it is</span>
<span class="sd"> always matched before assuming the space begins a subtopic.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># parse the query</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">subtopics</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">part</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">subtopic_separator_char</span><span class="p">)</span>
<span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">topic</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subtopics</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">topic</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">subtopics</span> <span class="o">=</span> <span class="p">[]</span></div>
<div class="viewcode-block" id="CmdHelp.strip_cmd_prefix"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.strip_cmd_prefix">[docs]</a> <span class="k">def</span> <span class="nf">strip_cmd_prefix</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">all_keys</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Conditional strip of a command prefix, such as @ in @desc. By default</span>
<span class="sd"> this will be hidden unless there is a duplicate without the prefix</span>
<span class="sd"> in the full command set (such as @open and open).</span>
<span class="sd"> Args:</span>
<span class="sd"> key (str): Command key to analyze.</span>
<span class="sd"> all_cmds (list): All command-keys (and potentially aliases).</span>
<span class="sd"> Returns:</span>
<span class="sd"> str: Potentially modified key to use in help display.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">key</span> <span class="ow">and</span> <span class="n">key</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="n">CMD_IGNORE_PREFIXES</span> <span class="ow">and</span> <span class="n">key</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">all_keys</span><span class="p">:</span>
<span class="c1"># filter out e.g. `@` prefixes from display if there is duplicate</span>
<span class="c1"># with the prefix in the set (such as @open/open)</span>
<span class="k">return</span> <span class="n">key</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="k">return</span> <span class="n">key</span></div>
<div class="viewcode-block" id="CmdHelp.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Run the dynamic help entry creator.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">caller</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="n">query</span><span class="p">,</span> <span class="n">subtopics</span><span class="p">,</span> <span class="n">cmdset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">topic</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">subtopics</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmdset</span>
<span class="n">clickable_topics</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">clickable_topics</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">query</span><span class="p">:</span>
<span class="c1"># list all available help entries, grouped by category. We want to</span>
<span class="c1"># build dictionaries {category: [topic, topic, ...], ...}</span>
<span class="n">cmd_help_topics</span><span class="p">,</span> <span class="n">db_help_topics</span><span class="p">,</span> <span class="n">file_help_topics</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">collect_topics</span><span class="p">(</span>
<span class="n">caller</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s2">&quot;list&quot;</span>
<span class="p">)</span>
<span class="c1"># db-topics override file-based ones</span>
<span class="n">file_db_help_topics</span> <span class="o">=</span> <span class="p">{</span><span class="o">**</span><span class="n">file_help_topics</span><span class="p">,</span> <span class="o">**</span><span class="n">db_help_topics</span><span class="p">}</span>
<span class="c1"># group by category (cmds are listed separately)</span>
<span class="n">cmd_help_by_category</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
<span class="n">file_db_help_by_category</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
<span class="c1"># get a collection of all keys + aliases to be able to strip prefixes like @</span>
<span class="n">key_and_aliases</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">chain</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">cmd</span><span class="o">.</span><span class="n">_keyaliases</span> <span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">cmd_help_topics</span><span class="o">.</span><span class="n">values</span><span class="p">())))</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">cmd_help_topics</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">key</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">strip_cmd_prefix</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">key_and_aliases</span><span class="p">)</span>
<span class="n">cmd_help_by_category</span><span class="p">[</span><span class="n">cmd</span><span class="o">.</span><span class="n">help_category</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">file_db_help_topics</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">file_db_help_by_category</span><span class="p">[</span><span class="n">entry</span><span class="o">.</span><span class="n">help_category</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="c1"># generate the index and display</span>
<span class="n">output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_help_index</span><span class="p">(</span>
<span class="n">cmd_help_by_category</span><span class="p">,</span> <span class="n">file_db_help_by_category</span><span class="p">,</span> <span class="n">click_topics</span><span class="o">=</span><span class="n">clickable_topics</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg_help</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># search for a specific entry. We need to check for &#39;read&#39; access here before</span>
<span class="c1"># building the set of possibilities.</span>
<span class="n">cmd_help_topics</span><span class="p">,</span> <span class="n">db_help_topics</span><span class="p">,</span> <span class="n">file_help_topics</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">collect_topics</span><span class="p">(</span>
<span class="n">caller</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s2">&quot;query&quot;</span>
<span class="p">)</span>
<span class="c1"># get a collection of all keys + aliases to be able to strip prefixes like @</span>
<span class="n">key_and_aliases</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">chain</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">cmd</span><span class="o">.</span><span class="n">_keyaliases</span> <span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">cmd_help_topics</span><span class="o">.</span><span class="n">values</span><span class="p">())))</span>
<span class="c1"># db-help topics takes priority over file-help</span>
<span class="n">file_db_help_topics</span> <span class="o">=</span> <span class="p">{</span><span class="o">**</span><span class="n">file_help_topics</span><span class="p">,</span> <span class="o">**</span><span class="n">db_help_topics</span><span class="p">}</span>
<span class="c1"># commands take priority over the other types</span>
<span class="n">all_topics</span> <span class="o">=</span> <span class="p">{</span><span class="o">**</span><span class="n">file_db_help_topics</span><span class="p">,</span> <span class="o">**</span><span class="n">cmd_help_topics</span><span class="p">}</span>
<span class="c1"># get all categories</span>
<span class="n">all_categories</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span>
<span class="nb">set</span><span class="p">(</span><span class="n">HelpCategory</span><span class="p">(</span><span class="n">topic</span><span class="o">.</span><span class="n">help_category</span><span class="p">)</span> <span class="k">for</span> <span class="n">topic</span> <span class="ow">in</span> <span class="n">all_topics</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
<span class="p">)</span>
<span class="c1"># all available help options - will be searched in order. We also check # the</span>
<span class="c1"># read-permission here.</span>
<span class="n">entries</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">all_topics</span><span class="o">.</span><span class="n">values</span><span class="p">())</span> <span class="o">+</span> <span class="n">all_categories</span>
<span class="c1"># lunr search fields/boosts</span>
<span class="n">match</span><span class="p">,</span> <span class="n">suggestions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">do_search</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">entries</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
<span class="c1"># no topic matches found. Only give suggestions.</span>
<span class="n">help_text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;There is no help topic matching &#39;</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">&#39;.&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">suggestions</span><span class="p">:</span>
<span class="c1"># we don&#39;t even have a good suggestion. Run a second search,</span>
<span class="c1"># doing a full-text search in the actual texts of the help</span>
<span class="c1"># entries</span>
<span class="n">search_fields</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span><span class="s2">&quot;field_name&quot;</span><span class="p">:</span> <span class="s2">&quot;text&quot;</span><span class="p">,</span> <span class="s2">&quot;boost&quot;</span><span class="p">:</span> <span class="mi">1</span><span class="p">},</span>
<span class="p">]</span>
<span class="k">for</span> <span class="n">match_query</span> <span class="ow">in</span> <span class="p">[</span><span class="n">query</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">*&quot;</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;*</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">]:</span>
<span class="n">_</span><span class="p">,</span> <span class="n">suggestions</span> <span class="o">=</span> <span class="n">help_search_with_index</span><span class="p">(</span>
<span class="n">match_query</span><span class="p">,</span>
<span class="n">entries</span><span class="p">,</span>
<span class="n">suggestion_maxnum</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">suggestion_maxnum</span><span class="p">,</span>
<span class="n">fields</span><span class="o">=</span><span class="n">search_fields</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">suggestions</span><span class="p">:</span>
<span class="n">help_text</span> <span class="o">+=</span> <span class="p">(</span>
<span class="s2">&quot;</span><span class="se">\n</span><span class="s2">... But matches were found within the help &quot;</span>
<span class="s2">&quot;texts of the suggestions below.&quot;</span>
<span class="p">)</span>
<span class="n">suggestions</span> <span class="o">=</span> <span class="p">[</span>
<span class="bp">self</span><span class="o">.</span><span class="n">strip_cmd_prefix</span><span class="p">(</span><span class="n">sugg</span><span class="p">,</span> <span class="n">key_and_aliases</span><span class="p">)</span> <span class="k">for</span> <span class="n">sugg</span> <span class="ow">in</span> <span class="n">suggestions</span>
<span class="p">]</span>
<span class="k">break</span>
<span class="n">output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_help_entry</span><span class="p">(</span>
<span class="n">topic</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="c1"># this will give a no-match style title</span>
<span class="n">help_text</span><span class="o">=</span><span class="n">help_text</span><span class="p">,</span>
<span class="n">suggested</span><span class="o">=</span><span class="n">suggestions</span><span class="p">,</span>
<span class="n">click_topics</span><span class="o">=</span><span class="n">clickable_topics</span><span class="p">,</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg_help</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">match</span><span class="p">,</span> <span class="n">HelpCategory</span><span class="p">):</span>
<span class="c1"># no subtopics for categories - these are just lists of topics</span>
<span class="n">category</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">key</span>
<span class="n">category_lower</span> <span class="o">=</span> <span class="n">category</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="n">cmds_in_category</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">key</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">cmd_help_topics</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">category_lower</span> <span class="o">==</span> <span class="n">cmd</span><span class="o">.</span><span class="n">help_category</span>
<span class="p">]</span>
<span class="n">topics_in_category</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">key</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">topic</span> <span class="ow">in</span> <span class="n">file_db_help_topics</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="k">if</span> <span class="n">category_lower</span> <span class="o">==</span> <span class="n">topic</span><span class="o">.</span><span class="n">help_category</span>
<span class="p">]</span>
<span class="n">output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_help_index</span><span class="p">(</span>
<span class="p">{</span><span class="n">category</span><span class="p">:</span> <span class="n">cmds_in_category</span><span class="p">},</span>
<span class="p">{</span><span class="n">category</span><span class="p">:</span> <span class="n">topics_in_category</span><span class="p">},</span>
<span class="n">title_lone_category</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">click_topics</span><span class="o">=</span><span class="n">clickable_topics</span><span class="p">,</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg_help</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">match</span><span class="p">,</span> <span class="s2">&quot;evennia.commands.command.Command&quot;</span><span class="p">):</span>
<span class="c1"># a command match</span>
<span class="n">topic</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">key</span>
<span class="n">help_text</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">get_help</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="n">cmdset</span><span class="p">)</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">aliases</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="n">suggestions</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># a database (or file-help) match</span>
<span class="n">topic</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">key</span>
<span class="n">help_text</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">entrytext</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">aliases</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">match</span><span class="o">.</span><span class="n">aliases</span><span class="p">,</span> <span class="nb">list</span><span class="p">)</span> <span class="k">else</span> <span class="n">match</span><span class="o">.</span><span class="n">aliases</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="n">suggestions</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="c1"># parse for subtopics. The subtopic_map is a dict with the current topic/subtopic</span>
<span class="c1"># text is stored under a `None` key and all other keys are subtopic titles pointing</span>
<span class="c1"># to nested dicts.</span>
<span class="n">subtopic_map</span> <span class="o">=</span> <span class="n">parse_entry_for_subcategories</span><span class="p">(</span><span class="n">help_text</span><span class="p">)</span>
<span class="n">help_text</span> <span class="o">=</span> <span class="n">subtopic_map</span><span class="p">[</span><span class="kc">None</span><span class="p">]</span>
<span class="n">subtopic_index</span> <span class="o">=</span> <span class="p">[</span><span class="n">subtopic</span> <span class="k">for</span> <span class="n">subtopic</span> <span class="ow">in</span> <span class="n">subtopic_map</span> <span class="k">if</span> <span class="n">subtopic</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">]</span>
<span class="k">if</span> <span class="n">subtopics</span><span class="p">:</span>
<span class="c1"># if we asked for subtopics, parse the found topic_text to see if any match.</span>
<span class="c1"># the subtopics is a list describing the path through the subtopic_map.</span>
<span class="k">for</span> <span class="n">subtopic_query</span> <span class="ow">in</span> <span class="n">subtopics</span><span class="p">:</span>
<span class="k">if</span> <span class="n">subtopic_query</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">subtopic_map</span><span class="p">:</span>
<span class="c1"># exact match failed. Try startswith-match</span>
<span class="n">fuzzy_match</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">subtopic_map</span><span class="p">:</span>
<span class="k">if</span> <span class="n">key</span> <span class="ow">and</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">subtopic_query</span><span class="p">):</span>
<span class="n">subtopic_query</span> <span class="o">=</span> <span class="n">key</span>
<span class="n">fuzzy_match</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">break</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">fuzzy_match</span><span class="p">:</span>
<span class="c1"># startswith failed - try an &#39;in&#39; match</span>
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">subtopic_map</span><span class="p">:</span>
<span class="k">if</span> <span class="n">key</span> <span class="ow">and</span> <span class="n">subtopic_query</span> <span class="ow">in</span> <span class="n">key</span><span class="p">:</span>
<span class="n">subtopic_query</span> <span class="o">=</span> <span class="n">key</span>
<span class="n">fuzzy_match</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">break</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">fuzzy_match</span><span class="p">:</span>
<span class="c1"># no match found - give up</span>
<span class="n">checked_topic</span> <span class="o">=</span> <span class="n">topic</span> <span class="o">+</span> <span class="sa">f</span><span class="s2">&quot;/</span><span class="si">{</span><span class="n">subtopic_query</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="n">output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_help_entry</span><span class="p">(</span>
<span class="n">topic</span><span class="o">=</span><span class="n">topic</span><span class="p">,</span>
<span class="n">help_text</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;No help entry found for &#39;</span><span class="si">{</span><span class="n">checked_topic</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">,</span>
<span class="n">subtopics</span><span class="o">=</span><span class="n">subtopic_index</span><span class="p">,</span>
<span class="n">click_topics</span><span class="o">=</span><span class="n">clickable_topics</span><span class="p">,</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg_help</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># if we get here we have an exact or fuzzy match</span>
<span class="n">subtopic_map</span> <span class="o">=</span> <span class="n">subtopic_map</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">subtopic_query</span><span class="p">)</span>
<span class="n">subtopic_index</span> <span class="o">=</span> <span class="p">[</span><span class="n">subtopic</span> <span class="k">for</span> <span class="n">subtopic</span> <span class="ow">in</span> <span class="n">subtopic_map</span> <span class="k">if</span> <span class="n">subtopic</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">]</span>
<span class="c1"># keep stepping down into the tree, append path to show position</span>
<span class="n">topic</span> <span class="o">=</span> <span class="n">topic</span> <span class="o">+</span> <span class="sa">f</span><span class="s2">&quot;/</span><span class="si">{</span><span class="n">subtopic_query</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="c1"># we reached the bottom of the topic tree</span>
<span class="n">help_text</span> <span class="o">=</span> <span class="n">subtopic_map</span><span class="p">[</span><span class="kc">None</span><span class="p">]</span>
<span class="n">topic</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">strip_cmd_prefix</span><span class="p">(</span><span class="n">topic</span><span class="p">,</span> <span class="n">key_and_aliases</span><span class="p">)</span>
<span class="k">if</span> <span class="n">subtopics</span><span class="p">:</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">strip_cmd_prefix</span><span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">key_and_aliases</span><span class="p">)</span> <span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">aliases</span><span class="p">]</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">strip_cmd_prefix</span><span class="p">(</span><span class="n">sugg</span><span class="p">,</span> <span class="n">key_and_aliases</span><span class="p">)</span> <span class="k">for</span> <span class="n">sugg</span> <span class="ow">in</span> <span class="n">suggested</span><span class="p">]</span>
<span class="n">output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_help_entry</span><span class="p">(</span>
<span class="n">topic</span><span class="o">=</span><span class="n">topic</span><span class="p">,</span>
<span class="n">help_text</span><span class="o">=</span><span class="n">help_text</span><span class="p">,</span>
<span class="n">aliases</span><span class="o">=</span><span class="n">aliases</span><span class="p">,</span>
<span class="n">subtopics</span><span class="o">=</span><span class="n">subtopic_index</span><span class="p">,</span>
<span class="n">suggested</span><span class="o">=</span><span class="n">suggested</span><span class="p">,</span>
<span class="n">click_topics</span><span class="o">=</span><span class="n">clickable_topics</span><span class="p">,</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg_help</span><span class="p">(</span><span class="n">output</span><span class="p">)</span></div></div>
<span class="k">def</span> <span class="nf">_loadhelp</span><span class="p">(</span><span class="n">caller</span><span class="p">):</span>
<span class="n">entry</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_editing_help</span>
<span class="k">if</span> <span class="n">entry</span><span class="p">:</span>
<span class="k">return</span> <span class="n">entry</span><span class="o">.</span><span class="n">entrytext</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="k">def</span> <span class="nf">_savehelp</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="n">buffer</span><span class="p">):</span>
<span class="n">entry</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_editing_help</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Saved help entry.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">entry</span><span class="p">:</span>
<span class="n">entry</span><span class="o">.</span><span class="n">entrytext</span> <span class="o">=</span> <span class="n">buffer</span>
<span class="k">def</span> <span class="nf">_quithelp</span><span class="p">(</span><span class="n">caller</span><span class="p">):</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Closing the editor.&quot;</span><span class="p">)</span>
<span class="k">del</span> <span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_editing_help</span>
<div class="viewcode-block" id="CmdSetHelp"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdSetHelp">[docs]</a><span class="k">class</span> <span class="nc">CmdSetHelp</span><span class="p">(</span><span class="n">CmdHelp</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Edit the help database.</span>
<span class="sd"> Usage:</span>
<span class="sd"> sethelp[/switches] &lt;topic&gt;[[;alias;alias][,category[,locks]] [= &lt;text&gt;]</span>
<span class="sd"> Switches:</span>
<span class="sd"> edit - open a line editor to edit the topic&#39;s help text.</span>
<span class="sd"> replace - overwrite existing help topic.</span>
<span class="sd"> append - add text to the end of existing topic with a newline between.</span>
<span class="sd"> extend - as append, but don&#39;t add a newline.</span>
<span class="sd"> delete - remove help topic.</span>
<span class="sd"> Examples:</span>
<span class="sd"> sethelp lore = In the beginning was ...</span>
<span class="sd"> sethelp/append pickpocketing,Thievery = This steals ...</span>
<span class="sd"> sethelp/replace pickpocketing, ,attr(is_thief) = This steals ...</span>
<span class="sd"> sethelp/edit thievery</span>
<span class="sd"> If not assigning a category, the `settings.DEFAULT_HELP_CATEGORY` category</span>
<span class="sd"> will be used. If no lockstring is specified, everyone will be able to read</span>
<span class="sd"> the help entry. Sub-topics are embedded in the help text.</span>
<span class="sd"> Note that this cannot modify command-help entries - these are modified</span>
<span class="sd"> in-code, outside the game.</span>
<span class="sd"> # SUBTOPICS</span>
<span class="sd"> ## Adding subtopics</span>
<span class="sd"> Subtopics helps to break up a long help entry into sub-sections. Users can</span>
<span class="sd"> access subtopics with |whelp topic/subtopic/...|n Subtopics are created and</span>
<span class="sd"> stored together with the main topic.</span>
<span class="sd"> To start adding subtopics, add the text &#39;# SUBTOPICS&#39; on a new line at the</span>
<span class="sd"> end of your help text. After this you can now add any number of subtopics,</span>
<span class="sd"> each starting with &#39;## &lt;subtopic-name&gt;&#39; on a line, followed by the</span>
<span class="sd"> help-text of that subtopic.</span>
<span class="sd"> Use &#39;### &lt;subsub-name&gt;&#39; to add a sub-subtopic and so on. Max depth is 5. A</span>
<span class="sd"> subtopic&#39;s title is case-insensitive and can consist of multiple words -</span>
<span class="sd"> the user will be able to enter a partial match to access it.</span>
<span class="sd"> For example:</span>
<span class="sd"> | Main help text for &lt;topic&gt;</span>
<span class="sd"> |</span>
<span class="sd"> | # SUBTOPICS</span>
<span class="sd"> |</span>
<span class="sd"> | ## about</span>
<span class="sd"> |</span>
<span class="sd"> | Text for the &#39;&lt;topic&gt;/about&#39; subtopic&#39;</span>
<span class="sd"> |</span>
<span class="sd"> | ### more about-info</span>
<span class="sd"> |</span>
<span class="sd"> | Text for the &#39;&lt;topic&gt;/about/more about-info sub-subtopic</span>
<span class="sd"> |</span>
<span class="sd"> | ## extra</span>
<span class="sd"> |</span>
<span class="sd"> | Text for the &#39;&lt;topic&gt;/extra&#39; subtopic</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;sethelp&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;edit&quot;</span><span class="p">,</span> <span class="s2">&quot;replace&quot;</span><span class="p">,</span> <span class="s2">&quot;append&quot;</span><span class="p">,</span> <span class="s2">&quot;extend&quot;</span><span class="p">,</span> <span class="s2">&quot;delete&quot;</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:perm(Helper)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Building&quot;</span>
<span class="n">arg_regex</span> <span class="o">=</span> <span class="kc">None</span>
<div class="viewcode-block" id="CmdSetHelp.parse"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdSetHelp.parse">[docs]</a> <span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;We want to use the default parser rather than the CmdHelp.parse&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">COMMAND_DEFAULT_CLASS</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
<div class="viewcode-block" id="CmdSetHelp.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdSetHelp.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Implement the function&quot;&quot;&quot;</span>
<span class="n">switches</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span>
<span class="n">lhslist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhslist</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span>
<span class="s2">&quot;Usage: sethelp[/switches] &lt;topic&gt;[;alias;alias][,category[,locks,..] = &lt;text&gt;&quot;</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="n">nlist</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">lhslist</span><span class="p">)</span>
<span class="n">topicstr</span> <span class="o">=</span> <span class="n">lhslist</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">nlist</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">topicstr</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You have to define a topic!&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">topicstrlist</span> <span class="o">=</span> <span class="n">topicstr</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;;&quot;</span><span class="p">)</span>
<span class="n">topicstr</span><span class="p">,</span> <span class="n">aliases</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">topicstrlist</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
<span class="n">topicstrlist</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">topicstr</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="p">[],</span>
<span class="p">)</span>
<span class="n">aliastxt</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;(aliases: </span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">aliases</span><span class="p">))</span> <span class="k">if</span> <span class="n">aliases</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="n">old_entry</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># check if we have an old entry with the same name</span>
<span class="n">cmd_help_topics</span><span class="p">,</span> <span class="n">db_help_topics</span><span class="p">,</span> <span class="n">file_help_topics</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">collect_topics</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s2">&quot;query&quot;</span>
<span class="p">)</span>
<span class="c1"># db-help topics takes priority over file-help</span>
<span class="n">file_db_help_topics</span> <span class="o">=</span> <span class="p">{</span><span class="o">**</span><span class="n">file_help_topics</span><span class="p">,</span> <span class="o">**</span><span class="n">db_help_topics</span><span class="p">}</span>
<span class="c1"># commands take priority over the other types</span>
<span class="n">all_topics</span> <span class="o">=</span> <span class="p">{</span><span class="o">**</span><span class="n">file_db_help_topics</span><span class="p">,</span> <span class="o">**</span><span class="n">cmd_help_topics</span><span class="p">}</span>
<span class="c1"># get all categories</span>
<span class="n">all_categories</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span>
<span class="nb">set</span><span class="p">(</span><span class="n">HelpCategory</span><span class="p">(</span><span class="n">topic</span><span class="o">.</span><span class="n">help_category</span><span class="p">)</span> <span class="k">for</span> <span class="n">topic</span> <span class="ow">in</span> <span class="n">all_topics</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
<span class="p">)</span>
<span class="c1"># all available help options - will be searched in order. We also check # the</span>
<span class="c1"># read-permission here.</span>
<span class="n">entries</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">all_topics</span><span class="o">.</span><span class="n">values</span><span class="p">())</span> <span class="o">+</span> <span class="n">all_categories</span>
<span class="c1"># default setup</span>
<span class="n">category</span> <span class="o">=</span> <span class="n">lhslist</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="n">nlist</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="n">DEFAULT_HELP_CATEGORY</span>
<span class="n">lockstring</span> <span class="o">=</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lhslist</span><span class="p">[</span><span class="mi">2</span><span class="p">:])</span> <span class="k">if</span> <span class="n">nlist</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="k">else</span> <span class="s2">&quot;read:all()&quot;</span>
<span class="c1"># search for existing entries of this or other types</span>
<span class="n">old_entry</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">for</span> <span class="n">querystr</span> <span class="ow">in</span> <span class="n">topicstrlist</span><span class="p">:</span>
<span class="n">match</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">do_search</span><span class="p">(</span><span class="n">querystr</span><span class="p">,</span> <span class="n">entries</span><span class="p">)</span>
<span class="k">if</span> <span class="n">match</span><span class="p">:</span>
<span class="n">warning</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">match</span><span class="p">,</span> <span class="n">HelpCategory</span><span class="p">):</span>
<span class="n">warning</span> <span class="o">=</span> <span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;&#39;</span><span class="si">{</span><span class="n">querystr</span><span class="si">}</span><span class="s2">&#39; matches (or partially matches) the name of &quot;</span>
<span class="sa">f</span><span class="s2">&quot;help-category &#39;</span><span class="si">{</span><span class="n">match</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39;. If you continue, your help entry will &quot;</span>
<span class="s2">&quot;take precedence and the category (or part of its name) *may* not &quot;</span>
<span class="s2">&quot;be usable for grouping help entries anymore.&quot;</span>
<span class="p">)</span>
<span class="k">elif</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">match</span><span class="p">,</span> <span class="s2">&quot;evennia.commands.command.Command&quot;</span><span class="p">):</span>
<span class="n">warning</span> <span class="o">=</span> <span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;&#39;</span><span class="si">{</span><span class="n">querystr</span><span class="si">}</span><span class="s2">&#39; matches (or partially matches) the key/alias of &quot;</span>
<span class="sa">f</span><span class="s2">&quot;Command &#39;</span><span class="si">{</span><span class="n">match</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39;. Command-help take precedence over other &quot;</span>
<span class="s2">&quot;help entries so your help *may* be impossible to reach for those &quot;</span>
<span class="s2">&quot;with access to that command.&quot;</span>
<span class="p">)</span>
<span class="k">elif</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">match</span><span class="p">,</span> <span class="s2">&quot;evennia.help.filehelp.FileHelpEntry&quot;</span><span class="p">):</span>
<span class="n">warning</span> <span class="o">=</span> <span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;&#39;</span><span class="si">{</span><span class="n">querystr</span><span class="si">}</span><span class="s2">&#39; matches (or partially matches) the name/alias of the &quot;</span>
<span class="sa">f</span><span class="s2">&quot;file-based help topic &#39;</span><span class="si">{</span><span class="n">match</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39;. File-help entries cannot be &quot;</span>
<span class="s2">&quot;modified from in-game (they are files on-disk). If you continue, &quot;</span>
<span class="s2">&quot;your help entry may shadow the file-based one&#39;s name partly or &quot;</span>
<span class="s2">&quot;completely.&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">warning</span><span class="p">:</span>
<span class="c1"># show a warning for a clashing help-entry type. Even if user accepts this</span>
<span class="c1"># we don&#39;t break here since we may need to show warnings for other inputs.</span>
<span class="c1"># We don&#39;t count this as an old-entry hit because we can&#39;t edit these</span>
<span class="c1"># types of entries.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;|rWarning:</span><span class="se">\n</span><span class="s2">|r</span><span class="si">{</span><span class="n">warning</span><span class="si">}</span><span class="s2">|n&quot;</span><span class="p">)</span>
<span class="n">repl</span> <span class="o">=</span> <span class="k">yield</span> <span class="p">(</span><span class="s2">&quot;|wDo you still want to continue? Y/[N]?|n&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">repl</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;y&quot;</span><span class="p">,</span> <span class="s2">&quot;yes&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Aborted.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># a db-based help entry - this is OK</span>
<span class="n">old_entry</span> <span class="o">=</span> <span class="n">match</span>
<span class="n">category</span> <span class="o">=</span> <span class="n">lhslist</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="n">nlist</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="n">old_entry</span><span class="o">.</span><span class="n">help_category</span>
<span class="n">lockstring</span> <span class="o">=</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lhslist</span><span class="p">[</span><span class="mi">2</span><span class="p">:])</span> <span class="k">if</span> <span class="n">nlist</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="k">else</span> <span class="n">old_entry</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
<span class="k">break</span>
<span class="n">category</span> <span class="o">=</span> <span class="n">category</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="k">if</span> <span class="s2">&quot;edit&quot;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># open the line editor to edit the helptext. No = is needed.</span>
<span class="k">if</span> <span class="n">old_entry</span><span class="p">:</span>
<span class="n">topicstr</span> <span class="o">=</span> <span class="n">old_entry</span><span class="o">.</span><span class="n">key</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="c1"># we assume append here.</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">entrytext</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span>
<span class="n">helpentry</span> <span class="o">=</span> <span class="n">old_entry</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">helpentry</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_help_entry</span><span class="p">(</span>
<span class="n">topicstr</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">,</span>
<span class="n">category</span><span class="o">=</span><span class="n">category</span><span class="p">,</span>
<span class="n">locks</span><span class="o">=</span><span class="n">lockstring</span><span class="p">,</span>
<span class="n">aliases</span><span class="o">=</span><span class="n">aliases</span><span class="p">,</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_editing_help</span> <span class="o">=</span> <span class="n">helpentry</span>
<span class="n">EvEditor</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span>
<span class="n">loadfunc</span><span class="o">=</span><span class="n">_loadhelp</span><span class="p">,</span>
<span class="n">savefunc</span><span class="o">=</span><span class="n">_savehelp</span><span class="p">,</span>
<span class="n">quitfunc</span><span class="o">=</span><span class="n">_quithelp</span><span class="p">,</span>
<span class="n">key</span><span class="o">=</span><span class="s2">&quot;topic </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">topicstr</span><span class="p">),</span>
<span class="n">persistent</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;append&quot;</span> <span class="ow">in</span> <span class="n">switches</span> <span class="ow">or</span> <span class="s2">&quot;merge&quot;</span> <span class="ow">in</span> <span class="n">switches</span> <span class="ow">or</span> <span class="s2">&quot;extend&quot;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># merge/append operations</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">old_entry</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Could not find topic &#39;</span><span class="si">{</span><span class="n">topicstr</span><span class="si">}</span><span class="s2">&#39;. You must give an exact name.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You must supply text to append/merge.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;merge&quot;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">entrytext</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">entrytext</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">aliases</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">aliases</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Entry updated:</span><span class="se">\n</span><span class="si">{</span><span class="n">old_entry</span><span class="o">.</span><span class="n">entrytext</span><span class="si">}{</span><span class="n">aliastxt</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;delete&quot;</span> <span class="ow">in</span> <span class="n">switches</span> <span class="ow">or</span> <span class="s2">&quot;del&quot;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># delete the help entry</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">old_entry</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Could not find topic &#39;</span><span class="si">{</span><span class="n">topicstr</span><span class="si">}</span><span class="s2">&#39;</span><span class="si">{</span><span class="n">aliastxt</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Deleted help entry &#39;</span><span class="si">{</span><span class="n">topicstr</span><span class="si">}</span><span class="s2">&#39;</span><span class="si">{</span><span class="n">aliastxt</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># at this point it means we want to add a new help entry.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You must supply a help text to add.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">old_entry</span><span class="p">:</span>
<span class="k">if</span> <span class="s2">&quot;replace&quot;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># overwrite old entry</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">topicstr</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">entrytext</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">help_category</span> <span class="o">=</span> <span class="n">category</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">lockstring</span><span class="p">)</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">aliases</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">aliases</span><span class="p">)</span>
<span class="n">old_entry</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Overwrote the old topic &#39;</span><span class="si">{</span><span class="n">topicstr</span><span class="si">}</span><span class="s2">&#39;</span><span class="si">{</span><span class="n">aliastxt</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Topic &#39;</span><span class="si">{</span><span class="n">topicstr</span><span class="si">}</span><span class="s2">&#39;</span><span class="si">{</span><span class="n">aliastxt</span><span class="si">}</span><span class="s2"> already exists. Use /edit to open in editor, or &quot;</span>
<span class="s2">&quot;/replace, /append and /merge to modify it directly.&quot;</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># no old entry. Create a new one.</span>
<span class="n">new_entry</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_help_entry</span><span class="p">(</span>
<span class="n">topicstr</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="n">category</span><span class="p">,</span> <span class="n">locks</span><span class="o">=</span><span class="n">lockstring</span><span class="p">,</span> <span class="n">aliases</span><span class="o">=</span><span class="n">aliases</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">new_entry</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Topic &#39;</span><span class="si">{</span><span class="n">topicstr</span><span class="si">}</span><span class="s2">&#39;</span><span class="si">{</span><span class="n">aliastxt</span><span class="si">}</span><span class="s2"> was successfully created.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;edit&quot;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># open the line editor to edit the helptext</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">_editing_help</span> <span class="o">=</span> <span class="n">new_entry</span>
<span class="n">EvEditor</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span>
<span class="n">loadfunc</span><span class="o">=</span><span class="n">_loadhelp</span><span class="p">,</span>
<span class="n">savefunc</span><span class="o">=</span><span class="n">_savehelp</span><span class="p">,</span>
<span class="n">quitfunc</span><span class="o">=</span><span class="n">_quithelp</span><span class="p">,</span>
<span class="n">key</span><span class="o">=</span><span class="s2">&quot;topic </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">new_entry</span><span class="o">.</span><span class="n">key</span><span class="p">),</span>
<span class="n">persistent</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error when creating topic &#39;</span><span class="si">{</span><span class="n">topicstr</span><span class="si">}</span><span class="s2">&#39;</span><span class="si">{</span><span class="n">aliastxt</span><span class="si">}</span><span class="s2">! Contact an admin.&quot;</span><span class="p">)</span></div></div>
</pre></div>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../../evennia.html" >evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.commands.default.help</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>