Updated HTML docs

This commit is contained in:
Griatch 2021-05-15 00:35:21 +02:00
parent 485838ffe2
commit effa0f90f0
128 changed files with 8699 additions and 4764 deletions

View file

@ -136,7 +136,6 @@
<span class="n">TASK_HANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">TICKER_HANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">MONITOR_HANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">CHANNEL_HANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># Containers</span>
<span class="n">GLOBAL_SCRIPTS</span> <span class="o">=</span> <span class="kc">None</span>
@ -190,7 +189,7 @@
<span class="k">global</span> <span class="n">signals</span>
<span class="k">global</span> <span class="n">settings</span><span class="p">,</span> <span class="n">lockfuncs</span><span class="p">,</span> <span class="n">logger</span><span class="p">,</span> <span class="n">utils</span><span class="p">,</span> <span class="n">gametime</span><span class="p">,</span> <span class="n">ansi</span><span class="p">,</span> <span class="n">spawn</span><span class="p">,</span> <span class="n">managers</span>
<span class="k">global</span> <span class="n">contrib</span><span class="p">,</span> <span class="n">TICKER_HANDLER</span><span class="p">,</span> <span class="n">MONITOR_HANDLER</span><span class="p">,</span> <span class="n">SESSION_HANDLER</span>
<span class="k">global</span> <span class="n">CHANNEL_HANDLER</span><span class="p">,</span> <span class="n">TASK_HANDLER</span>
<span class="k">global</span> <span class="n">TASK_HANDLER</span>
<span class="k">global</span> <span class="n">GLOBAL_SCRIPTS</span><span class="p">,</span> <span class="n">OPTION_CLASSES</span>
<span class="k">global</span> <span class="n">EvMenu</span><span class="p">,</span> <span class="n">EvTable</span><span class="p">,</span> <span class="n">EvForm</span><span class="p">,</span> <span class="n">EvMore</span><span class="p">,</span> <span class="n">EvEditor</span>
<span class="k">global</span> <span class="n">ANSIString</span>
@ -253,7 +252,6 @@
<span class="kn">from</span> <span class="nn">.scripts.tickerhandler</span> <span class="kn">import</span> <span class="n">TICKER_HANDLER</span>
<span class="kn">from</span> <span class="nn">.scripts.taskhandler</span> <span class="kn">import</span> <span class="n">TASK_HANDLER</span>
<span class="kn">from</span> <span class="nn">.server.sessionhandler</span> <span class="kn">import</span> <span class="n">SESSION_HANDLER</span>
<span class="kn">from</span> <span class="nn">.comms.channelhandler</span> <span class="kn">import</span> <span class="n">CHANNEL_HANDLER</span>
<span class="kn">from</span> <span class="nn">.scripts.monitorhandler</span> <span class="kn">import</span> <span class="n">MONITOR_HANDLER</span>
<span class="c1"># containers</span>
@ -382,7 +380,6 @@
<span class="sd"> CMD_NOINPUT - no input was given on command line</span>
<span class="sd"> CMD_NOMATCH - no valid command key was found</span>
<span class="sd"> CMD_MULTIMATCH - multiple command matches were found</span>
<span class="sd"> CMD_CHANNEL - the command name is a channel name</span>
<span class="sd"> CMD_LOGINSTART - this command will be called as the very</span>
<span class="sd"> first command when an account connects to</span>
<span class="sd"> the server.</span>
@ -397,7 +394,6 @@
<span class="n">CMD_NOINPUT</span> <span class="o">=</span> <span class="n">cmdhandler</span><span class="o">.</span><span class="n">CMD_NOINPUT</span>
<span class="n">CMD_NOMATCH</span> <span class="o">=</span> <span class="n">cmdhandler</span><span class="o">.</span><span class="n">CMD_NOMATCH</span>
<span class="n">CMD_MULTIMATCH</span> <span class="o">=</span> <span class="n">cmdhandler</span><span class="o">.</span><span class="n">CMD_MULTIMATCH</span>
<span class="n">CMD_CHANNEL</span> <span class="o">=</span> <span class="n">cmdhandler</span><span class="o">.</span><span class="n">CMD_CHANNEL</span>
<span class="n">CMD_LOGINSTART</span> <span class="o">=</span> <span class="n">cmdhandler</span><span class="o">.</span><span class="n">CMD_LOGINSTART</span>
<span class="k">del</span> <span class="n">cmdhandler</span>

View file

@ -90,6 +90,7 @@
<span class="n">_MAX_NR_CHARACTERS</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">MAX_NR_CHARACTERS</span>
<span class="n">_CMDSET_ACCOUNT</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CMDSET_ACCOUNT</span>
<span class="n">_MUDINFO_CHANNEL</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_CONNECT_CHANNEL</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_CMDHANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># Create throttles for too many account-creations and login attempts</span>
@ -275,6 +276,21 @@
<span class="k">return</span> <span class="n">objs</span>
<div class="viewcode-block" id="DefaultAccount.get_display_name"><a class="viewcode-back" href="../../../api/evennia.accounts.accounts.html#evennia.accounts.accounts.DefaultAccount.get_display_name">[docs]</a> <span class="k">def</span> <span class="nf">get_display_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">looker</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is used by channels and other OOC communications methods to give a</span>
<span class="sd"> custom display of this account&#39;s input.</span>
<span class="sd"> Args:</span>
<span class="sd"> looker (Account): The one that will see this name.</span>
<span class="sd"> **kwargs: Unused by default, can be used to pass game-specific data.</span>
<span class="sd"> Returns:</span>
<span class="sd"> str: The name, possibly modified.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;|c</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">|n&quot;</span></div>
<span class="c1"># session-related methods</span>
<div class="viewcode-block" id="DefaultAccount.disconnect_session_from_account"><a class="viewcode-back" href="../../../api/evennia.accounts.accounts.html#evennia.accounts.accounts.DefaultAccount.disconnect_session_from_account">[docs]</a> <span class="k">def</span> <span class="nf">disconnect_session_from_account</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">reason</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
@ -987,6 +1003,89 @@
<span class="bp">self</span><span class="p">,</span> <span class="n">raw_string</span><span class="p">,</span> <span class="n">callertype</span><span class="o">=</span><span class="s2">&quot;account&quot;</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">)</span></div>
<span class="c1"># channel receive hooks</span>
<div class="viewcode-block" id="DefaultAccount.at_pre_channel_msg"><a class="viewcode-back" href="../../../api/evennia.accounts.accounts.html#evennia.accounts.accounts.DefaultAccount.at_pre_channel_msg">[docs]</a> <span class="k">def</span> <span class="nf">at_pre_channel_msg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called by the Channel just before passing a message into `channel_msg`.</span>
<span class="sd"> This allows for tweak messages per-user and also to abort the</span>
<span class="sd"> receive on the receiver-level.</span>
<span class="sd"> Args:</span>
<span class="sd"> message (str): The message sent to the channel.</span>
<span class="sd"> channel (Channel): The sending channel.</span>
<span class="sd"> senders (list, optional): Accounts or Objects acting as senders.</span>
<span class="sd"> For most normal messages, there is only a single sender. If</span>
<span class="sd"> there are no senders, this may be a broadcasting message.</span>
<span class="sd"> **kwargs: These are additional keywords passed into `channel_msg`.</span>
<span class="sd"> If `no_prefix=True` or `emit=True` are passed, the channel</span>
<span class="sd"> prefix will not be added (`[channelname]: ` by default)</span>
<span class="sd"> Returns:</span>
<span class="sd"> str or None: Allows for customizing the message for this recipient.</span>
<span class="sd"> If returning `None` (or `False`) message-receiving is aborted.</span>
<span class="sd"> The returning string will be passed into `self.channel_msg`.</span>
<span class="sd"> Notes:</span>
<span class="sd"> This support posing/emotes by starting channel-send with : or ;.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">senders</span><span class="p">:</span>
<span class="n">sender_string</span> <span class="o">=</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sender</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="k">for</span> <span class="n">sender</span> <span class="ow">in</span> <span class="n">senders</span><span class="p">)</span>
<span class="n">message_lstrip</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">lstrip</span><span class="p">()</span>
<span class="k">if</span> <span class="n">message_lstrip</span><span class="o">.</span><span class="n">startswith</span><span class="p">((</span><span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="s1">&#39;;&#39;</span><span class="p">)):</span>
<span class="c1"># this is a pose, should show as e.g. &quot;User1 smiles to channel&quot;</span>
<span class="n">spacing</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span> <span class="k">if</span> <span class="n">message_lstrip</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span><span class="o">.</span><span class="n">startswith</span><span class="p">((</span><span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\&#39;</span><span class="s1">&#39;</span><span class="p">,</span> <span class="s1">&#39;,&#39;</span><span class="p">))</span> <span class="k">else</span> <span class="s2">&quot; &quot;</span>
<span class="n">message</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">sender_string</span><span class="si">}{</span><span class="n">spacing</span><span class="si">}{</span><span class="n">message_lstrip</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># normal message</span>
<span class="n">message</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">sender_string</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">message</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;no_prefix&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;emit&quot;</span><span class="p">):</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">channel_prefix</span><span class="p">()</span> <span class="o">+</span> <span class="n">message</span>
<span class="k">return</span> <span class="n">message</span></div>
<div class="viewcode-block" id="DefaultAccount.channel_msg"><a class="viewcode-back" href="../../../api/evennia.accounts.accounts.html#evennia.accounts.accounts.DefaultAccount.channel_msg">[docs]</a> <span class="k">def</span> <span class="nf">channel_msg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This performs the actions of receiving a message to an un-muted</span>
<span class="sd"> channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> message (str): The message sent to the channel.</span>
<span class="sd"> channel (Channel): The sending channel.</span>
<span class="sd"> senders (list, optional): Accounts or Objects acting as senders.</span>
<span class="sd"> For most normal messages, there is only a single sender. If</span>
<span class="sd"> there are no senders, this may be a broadcasting message or</span>
<span class="sd"> similar.</span>
<span class="sd"> **kwargs: These are additional keywords originally passed into</span>
<span class="sd"> `Channel.msg`.</span>
<span class="sd"> Notes:</span>
<span class="sd"> Before this, `Channel.at_pre_channel_msg` will fire, which offers a way</span>
<span class="sd"> to customize the message for the receiver on the channel-level.</span>
<span class="sd"> &quot;&quot;&quot;</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">message</span><span class="p">,</span> <span class="p">{</span><span class="s2">&quot;from_channel&quot;</span><span class="p">:</span> <span class="n">channel</span><span class="o">.</span><span class="n">id</span><span class="p">}),</span>
<span class="n">from_obj</span><span class="o">=</span><span class="n">senders</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;from_channel&quot;</span><span class="p">:</span> <span class="n">channel</span><span class="o">.</span><span class="n">id</span><span class="p">})</span></div>
<div class="viewcode-block" id="DefaultAccount.at_post_channel_msg"><a class="viewcode-back" href="../../../api/evennia.accounts.accounts.html#evennia.accounts.accounts.DefaultAccount.at_post_channel_msg">[docs]</a> <span class="k">def</span> <span class="nf">at_post_channel_msg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called by `self.channel_msg` after message was received.</span>
<span class="sd"> Args:</span>
<span class="sd"> message (str): The message sent to the channel.</span>
<span class="sd"> channel (Channel): The sending channel.</span>
<span class="sd"> senders (list, optional): Accounts or Objects acting as senders.</span>
<span class="sd"> For most normal messages, there is only a single sender. If</span>
<span class="sd"> there are no senders, this may be a broadcasting message.</span>
<span class="sd"> **kwargs: These are additional keywords passed into `channel_msg`.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<span class="c1"># search method</span>
<div class="viewcode-block" id="DefaultAccount.search"><a class="viewcode-back" href="../../../api/evennia.accounts.accounts.html#evennia.accounts.accounts.DefaultAccount.search">[docs]</a> <span class="k">def</span> <span class="nf">search</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">searchdata</span><span class="p">,</span>
@ -1294,30 +1393,42 @@
<span class="k">def</span> <span class="nf">_send_to_connect_channel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper method for loading and sending to the comm channel</span>
<span class="sd"> dedicated to connection messages.</span>
<span class="sd"> Helper method for loading and sending to the comm channel dedicated to</span>
<span class="sd"> connection messages. This will also be sent to the mudinfo channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> message (str): A message to send to the connect channel.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_MUDINFO_CHANNEL</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_MUDINFO_CHANNEL</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">_MUDINFO_CHANNEL</span> <span class="o">=</span> <span class="n">ChannelDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_MUDINFO</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">])[</span>
<span class="mi">0</span>
<span class="p">]</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="k">global</span> <span class="n">_MUDINFO_CHANNEL</span><span class="p">,</span> <span class="n">_CONNECT_CHANNEL</span>
<span class="k">if</span> <span class="n">_MUDINFO_CHANNEL</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_MUDINFO</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">_MUDINFO_CHANNEL</span> <span class="o">=</span> <span class="n">ChannelDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
<span class="n">db_key</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_MUDINFO</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">])</span>
<span class="k">except</span> <span class="n">ChannelDB</span><span class="o">.</span><span class="n">DoesNotExist</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">_MUDINFO</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">_CONNECT_CHANNEL</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_CONNECTINFO</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">_CONNECT_CHANNEL</span> <span class="o">=</span> <span class="n">ChannelDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
<span class="n">db_key</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_CONNECTINFO</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">])</span>
<span class="k">except</span> <span class="n">ChannelDB</span><span class="o">.</span><span class="n">DoesNotExist</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">_CONNECT_CHANNEL</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">settings</span><span class="o">.</span><span class="n">USE_TZ</span><span class="p">:</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">timezone</span><span class="o">.</span><span class="n">localtime</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">timezone</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="n">now</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%02i</span><span class="s2">-</span><span class="si">%02i</span><span class="s2">-</span><span class="si">%02i</span><span class="s2">(</span><span class="si">%02i</span><span class="s2">:</span><span class="si">%02i</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">now</span><span class="o">.</span><span class="n">year</span><span class="p">,</span> <span class="n">now</span><span class="o">.</span><span class="n">month</span><span class="p">,</span> <span class="n">now</span><span class="o">.</span><span class="n">day</span><span class="p">,</span> <span class="n">now</span><span class="o">.</span><span class="n">hour</span><span class="p">,</span> <span class="n">now</span><span class="o">.</span><span class="n">minute</span><span class="p">)</span>
<span class="k">if</span> <span class="n">_MUDINFO_CHANNEL</span><span class="p">:</span>
<span class="n">_MUDINFO_CHANNEL</span><span class="o">.</span><span class="n">tempmsg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="n">_MUDINFO_CHANNEL</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">now</span><span class="si">}</span><span class="s2">]: </span><span class="si">{</span><span class="n">message</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="n">logger</span><span class="o">.</span><span class="n">log_info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="n">now</span><span class="si">}</span><span class="s2">]: </span><span class="si">{</span><span class="n">message</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">_MUDINFO_CHANNEL</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="n">now</span><span class="si">}</span><span class="s2">]: </span><span class="si">{</span><span class="n">message</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">_CONNECT_CHANNEL</span><span class="p">:</span>
<span class="n">_CONNECT_CHANNEL</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="n">now</span><span class="si">}</span><span class="s2">]: </span><span class="si">{</span><span class="n">message</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<div class="viewcode-block" id="DefaultAccount.at_post_login"><a class="viewcode-back" href="../../../api/evennia.accounts.accounts.html#evennia.accounts.accounts.DefaultAccount.at_post_login">[docs]</a> <span class="k">def</span> <span class="nf">at_post_login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>

View file

@ -48,10 +48,6 @@
<span class="sd">1. The calling object (caller) is analyzed based on its callertype.</span>
<span class="sd">2. Cmdsets are gathered from different sources:</span>
<span class="sd"> - channels: all available channel names are auto-created into a cmdset, to allow</span>
<span class="sd"> for giving the channel name and have the following immediately</span>
<span class="sd"> sent to the channel. The sending is performed by the CMD_CHANNEL</span>
<span class="sd"> system command.</span>
<span class="sd"> - object cmdsets: all objects at caller&#39;s location are scanned for non-empty</span>
<span class="sd"> cmdsets. This includes cmdsets on exits.</span>
<span class="sd"> - caller: the caller is searched for its own currently active cmdset.</span>
@ -65,14 +61,12 @@
<span class="sd"> cmdset, or fallback to error message. Exit.</span>
<span class="sd">7. If no match was found -&gt; check for CMD_NOMATCH in current cmdset or</span>
<span class="sd"> fallback to error message. Exit.</span>
<span class="sd">8. A single match was found. If this is a channel-command (i.e. the</span>
<span class="sd"> ommand name is that of a channel), --&gt; check for CMD_CHANNEL in</span>
<span class="sd"> current cmdset or use channelhandler default. Exit.</span>
<span class="sd">9. At this point we have found a normal command. We assign useful variables to it that</span>
<span class="sd">8. At this point we have found a normal command. We assign useful variables to it that</span>
<span class="sd"> will be available to the command coder at run-time.</span>
<span class="sd">12. We have a unique cmdobject, primed for use. Call all hooks:</span>
<span class="sd">9. We have a unique cmdobject, primed for use. Call all hooks:</span>
<span class="sd"> `at_pre_cmd()`, `cmdobj.parse()`, `cmdobj.func()` and finally `at_post_cmd()`.</span>
<span class="sd">13. Return deferred that will fire with the return from `cmdobj.func()` (unused by default).</span>
<span class="sd">10. Return deferred that will fire with the return from `cmdobj.func()` (unused by default).</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>
@ -86,7 +80,6 @@
<span class="kn">from</span> <span class="nn">twisted.internet.defer</span> <span class="kn">import</span> <span class="n">inlineCallbacks</span><span class="p">,</span> <span class="n">returnValue</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.commands.command</span> <span class="kn">import</span> <span class="n">InterruptCommand</span>
<span class="kn">from</span> <span class="nn">evennia.comms.channelhandler</span> <span class="kn">import</span> <span class="n">CHANNELHANDLER</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">logger</span><span class="p">,</span> <span class="n">utils</span>
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">string_suggestions</span>
@ -117,12 +110,11 @@
<span class="n">CMD_NOMATCH</span> <span class="o">=</span> <span class="s2">&quot;__nomatch_command&quot;</span>
<span class="c1"># command to call if multiple command matches were found</span>
<span class="n">CMD_MULTIMATCH</span> <span class="o">=</span> <span class="s2">&quot;__multimatch_command&quot;</span>
<span class="c1"># command to call if found command is the name of a channel</span>
<span class="n">CMD_CHANNEL</span> <span class="o">=</span> <span class="s2">&quot;__send_to_channel_command&quot;</span>
<span class="c1"># command to call as the very first one when the user connects.</span>
<span class="c1"># (is expected to display the login screen)</span>
<span class="n">CMD_LOGINSTART</span> <span class="o">=</span> <span class="s2">&quot;__unloggedin_look_command&quot;</span>
<span class="c1"># Function for handling multiple command matches.</span>
<span class="n">_SEARCH_AT_RESULT</span> <span class="o">=</span> <span class="n">utils</span><span class="o">.</span><span class="n">variable_from_module</span><span class="p">(</span><span class="o">*</span><span class="n">settings</span><span class="o">.</span><span class="n">SEARCH_AT_RESULT</span><span class="o">.</span><span class="n">rsplit</span><span class="p">(</span><span class="s2">&quot;.&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
@ -345,19 +337,6 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="nd">@inlineCallbacks</span>
<span class="k">def</span> <span class="nf">_get_channel_cmdset</span><span class="p">(</span><span class="n">account_or_obj</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper-method; Get channel-cmdsets</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Create cmdset for all account&#39;s available channels</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">channel_cmdset</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">CHANNELHANDLER</span><span class="o">.</span><span class="n">get_cmdset</span><span class="p">(</span><span class="n">account_or_obj</span><span class="p">)</span>
<span class="n">returnValue</span><span class="p">([</span><span class="n">channel_cmdset</span><span class="p">])</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">_msg_err</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="n">_ERROR_CMDSETS</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">ErrorReported</span><span class="p">(</span><span class="n">raw_string</span><span class="p">)</span>
<span class="nd">@inlineCallbacks</span>
<span class="k">def</span> <span class="nf">_get_local_obj_cmdsets</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -447,13 +426,13 @@
<span class="n">cmdset</span> <span class="k">for</span> <span class="n">cmdset</span> <span class="ow">in</span> <span class="n">local_obj_cmdsets</span> <span class="k">if</span> <span class="n">cmdset</span><span class="o">.</span><span class="n">key</span> <span class="o">!=</span> <span class="s2">&quot;ExitCmdSet&quot;</span>
<span class="p">]</span>
<span class="n">cmdsets</span> <span class="o">+=</span> <span class="n">local_obj_cmdsets</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">current</span><span class="o">.</span><span class="n">no_channels</span><span class="p">:</span>
<span class="c1"># also objs may have channels</span>
<span class="n">channel_cmdsets</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">_get_channel_cmdset</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
<span class="n">cmdsets</span> <span class="o">+=</span> <span class="n">channel_cmdsets</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">current</span><span class="o">.</span><span class="n">no_channels</span><span class="p">:</span>
<span class="n">channel_cmdsets</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">_get_channel_cmdset</span><span class="p">(</span><span class="n">account</span><span class="p">)</span>
<span class="n">cmdsets</span> <span class="o">+=</span> <span class="n">channel_cmdsets</span>
<span class="c1"># if not current.no_channels:</span>
<span class="c1"># # also objs may have channels</span>
<span class="c1"># channel_cmdsets = yield _get_channel_cmdset(obj)</span>
<span class="c1"># cmdsets += channel_cmdsets</span>
<span class="c1"># if not current.no_channels:</span>
<span class="c1"># channel_cmdsets = yield _get_channel_cmdset(account)</span>
<span class="c1"># cmdsets += channel_cmdsets</span>
<span class="k">elif</span> <span class="n">callertype</span> <span class="o">==</span> <span class="s2">&quot;account&quot;</span><span class="p">:</span>
<span class="c1"># we are calling the command from the account level</span>
@ -471,11 +450,11 @@
<span class="n">cmdset</span> <span class="k">for</span> <span class="n">cmdset</span> <span class="ow">in</span> <span class="n">local_obj_cmdsets</span> <span class="k">if</span> <span class="n">cmdset</span><span class="o">.</span><span class="n">key</span> <span class="o">!=</span> <span class="s2">&quot;ExitCmdSet&quot;</span>
<span class="p">]</span>
<span class="n">cmdsets</span> <span class="o">+=</span> <span class="n">local_obj_cmdsets</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">current</span><span class="o">.</span><span class="n">no_channels</span><span class="p">:</span>
<span class="c1"># also objs may have channels</span>
<span class="n">cmdsets</span> <span class="o">+=</span> <span class="k">yield</span> <span class="n">_get_channel_cmdset</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">current</span><span class="o">.</span><span class="n">no_channels</span><span class="p">:</span>
<span class="n">cmdsets</span> <span class="o">+=</span> <span class="k">yield</span> <span class="n">_get_channel_cmdset</span><span class="p">(</span><span class="n">account</span><span class="p">)</span>
<span class="c1"># if not current.no_channels:</span>
<span class="c1"># # also objs may have channels</span>
<span class="c1"># cmdsets += yield _get_channel_cmdset(obj)</span>
<span class="c1"># if not current.no_channels:</span>
<span class="c1"># cmdsets += yield _get_channel_cmdset(account)</span>
<span class="k">elif</span> <span class="n">callertype</span> <span class="o">==</span> <span class="s2">&quot;object&quot;</span><span class="p">:</span>
<span class="c1"># we are calling the command from the object level</span>
@ -489,9 +468,9 @@
<span class="n">cmdset</span> <span class="k">for</span> <span class="n">cmdset</span> <span class="ow">in</span> <span class="n">local_obj_cmdsets</span> <span class="k">if</span> <span class="n">cmdset</span><span class="o">.</span><span class="n">key</span> <span class="o">!=</span> <span class="s2">&quot;ExitCmdSet&quot;</span>
<span class="p">]</span>
<span class="n">cmdsets</span> <span class="o">+=</span> <span class="k">yield</span> <span class="n">local_obj_cmdsets</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">current</span><span class="o">.</span><span class="n">no_channels</span><span class="p">:</span>
<span class="c1"># also objs may have channels</span>
<span class="n">cmdsets</span> <span class="o">+=</span> <span class="k">yield</span> <span class="n">_get_channel_cmdset</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
<span class="c1"># if not current.no_channels:</span>
<span class="c1"># # also objs may have channels</span>
<span class="c1"># cmdsets += yield _get_channel_cmdset(obj)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;get_and_merge_cmdsets: callertype </span><span class="si">%s</span><span class="s2"> is not valid.&quot;</span> <span class="o">%</span> <span class="n">callertype</span><span class="p">)</span>
@ -814,18 +793,6 @@
<span class="n">sysarg</span> <span class="o">+=</span> <span class="n">_</span><span class="p">(</span><span class="s1">&#39; Type &quot;help&quot; for help.&#39;</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">ExecSystemCommand</span><span class="p">(</span><span class="n">syscmd</span><span class="p">,</span> <span class="n">sysarg</span><span class="p">)</span>
<span class="c1"># Check if this is a Channel-cmd match.</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;is_channel&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">cmd</span><span class="o">.</span><span class="n">is_channel</span><span class="p">:</span>
<span class="c1"># even if a user-defined syscmd is not defined, the</span>
<span class="c1"># found cmd is already a system command in its own right.</span>
<span class="n">syscmd</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">cmdset</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">CMD_CHANNEL</span><span class="p">)</span>
<span class="k">if</span> <span class="n">syscmd</span><span class="p">:</span>
<span class="c1"># replace system command with custom version</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">syscmd</span>
<span class="n">cmd</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">session</span>
<span class="n">sysarg</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">cmdname</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">ExecSystemCommand</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">sysarg</span><span class="p">)</span>
<span class="c1"># A normal command.</span>
<span class="n">ret</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">_run_command</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">cmdname</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">raw_cmdname</span><span class="p">,</span> <span class="n">cmdset</span><span class="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">account</span><span class="p">)</span>
<span class="n">returnValue</span><span class="p">(</span><span class="n">ret</span><span class="p">)</span>

View file

@ -161,9 +161,11 @@
<span class="c1"># parsing errors.</span>
<div class="viewcode-block" id="Command"><a class="viewcode-back" href="../../../api/evennia.commands.command.html#evennia.commands.cmdhandler.Command">[docs]</a><span class="k">class</span> <span class="nc">Command</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">metaclass</span><span class="o">=</span><span class="n">CommandMeta</span><span class="p">):</span>
<div class="viewcode-block" id="Command"><a class="viewcode-back" href="../../../api/evennia.commands.command.html#evennia.commands.cmdhandler.Command">[docs]</a><span class="k">class</span> <span class="nc">Command</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">CommandMeta</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Base command</span>
<span class="sd"> ## Base command</span>
<span class="sd"> (you may see this if a child command had no help text defined)</span>
<span class="sd"> Usage:</span>
<span class="sd"> command [args]</span>

View file

@ -101,15 +101,15 @@
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">admin</span><span class="o">.</span><span class="n">CmdNewPassword</span><span class="p">())</span>
<span class="c1"># Comm commands</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdChannel</span><span class="p">())</span>
<span class="c1"># self.add(comms.CmdChannels())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdAddCom</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdDelCom</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdAllCom</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdChannels</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdCdestroy</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdChannelCreate</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdClock</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdCBoot</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdCemit</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdCWho</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdCdesc</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">comms</span><span class="o">.</span><span class="n">CmdPage</span><span class="p">())</span>

File diff suppressed because it is too large Load diff

View file

@ -41,114 +41,75 @@
<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</span>
<span class="sd">are best written by those that write the commands - the admins. So</span>
<span class="sd">command-help is all auto-loaded and searched from the current command</span>
<span class="sd">set. The normal, database-tied help system is used for collaborative</span>
<span class="sd">creation of other help topics such as RP help or game-world aides.</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">import</span> <span class="nn">re</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">django.conf</span> <span class="kn">import</span> <span class="n">settings</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">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">fill</span><span class="p">,</span> <span class="n">dedent</span>
<span class="kn">from</span> <span class="nn">evennia.commands.command</span> <span class="kn">import</span> <span class="n">Command</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.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.help.filehelp</span> <span class="kn">import</span> <span class="n">FILE_HELP_ENTRIES</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="p">(</span>
<span class="n">string_suggestions</span><span class="p">,</span>
<span class="n">class_from_module</span><span class="p">,</span>
<span class="n">inherits_from</span><span class="p">,</span>
<span class="n">format_grid</span><span class="p">,</span>
<span class="n">format_grid</span><span class="p">,</span> <span class="n">pad</span>
<span class="p">)</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="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</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">HELP_MORE</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">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="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="n">_DEFAULT_WIDTH</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CLIENT_DEFAULT_WIDTH</span>
<span class="n">_SEP</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="n">_DEFAULT_WIDTH</span> <span class="o">+</span> <span class="s2">&quot;|n&quot;</span>
<span class="n">_LUNR</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_LUNR_EXCEPTION</span> <span class="o">=</span> <span class="kc">None</span>
<span class="nd">@dataclass</span>
<span class="k">class</span> <span class="nc">HelpCategory</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</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="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">key</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="nb">str</span><span class="p">(</span><span class="bp">self</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;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">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;Category: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="nb">str</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">lower</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">id</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">help_search_with_index</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">candidate_entries</span><span class="p">,</span> <span class="n">suggestion_maxnum</span><span class="o">=</span><span class="mi">5</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Lunr-powered fast index search and suggestion wrapper</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_LUNR</span><span class="p">,</span> <span class="n">_LUNR_EXCEPTION</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_LUNR</span><span class="p">:</span>
<span class="c1"># we have to delay-load lunr because it messes with logging if it&#39;s imported</span>
<span class="c1"># before twisted&#39;s logging has been set up</span>
<span class="kn">from</span> <span class="nn">lunr</span> <span class="kn">import</span> <span class="n">lunr</span> <span class="k">as</span> <span class="n">_LUNR</span>
<span class="kn">from</span> <span class="nn">lunr.exceptions</span> <span class="kn">import</span> <span class="n">QueryParseError</span> <span class="k">as</span> <span class="n">_LUNR_EXCEPTION</span>
<span class="n">indx</span> <span class="o">=</span> <span class="p">[</span><span class="n">cnd</span><span class="o">.</span><span class="n">search_index_entry</span> <span class="k">for</span> <span class="n">cnd</span> <span class="ow">in</span> <span class="n">candidate_entries</span><span class="p">]</span>
<span class="n">mapping</span> <span class="o">=</span> <span class="p">{</span><span class="n">indx</span><span class="p">[</span><span class="n">ix</span><span class="p">][</span><span class="s2">&quot;key&quot;</span><span class="p">]:</span> <span class="n">cand</span> <span class="k">for</span> <span class="n">ix</span><span class="p">,</span> <span class="n">cand</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">candidate_entries</span><span class="p">)}</span>
<span class="n">search_index</span> <span class="o">=</span> <span class="n">_LUNR</span><span class="p">(</span>
<span class="n">ref</span><span class="o">=</span><span class="s2">&quot;key&quot;</span><span class="p">,</span>
<span class="n">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;category&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;tags&quot;</span><span class="p">,</span> <span class="s2">&quot;boost&quot;</span><span class="p">:</span> <span class="mi">5</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="n">documents</span><span class="o">=</span><span class="n">indx</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">matches</span> <span class="o">=</span> <span class="n">search_index</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">query</span><span class="p">)[:</span><span class="n">suggestion_maxnum</span><span class="p">]</span>
<span class="k">except</span> <span class="n">_LUNR_EXCEPTION</span><span class="p">:</span>
<span class="c1"># this is a user-input problem</span>
<span class="n">matches</span> <span class="o">=</span> <span class="p">[]</span>
<span class="c1"># matches (objs), suggestions (strs)</span>
<span class="k">return</span> <span class="p">(</span>
<span class="p">[</span><span class="n">mapping</span><span class="p">[</span><span class="n">match</span><span class="p">[</span><span class="s2">&quot;ref&quot;</span><span class="p">]]</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">matches</span><span class="p">],</span>
<span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">match</span><span class="p">[</span><span class="s2">&quot;ref&quot;</span><span class="p">])</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">matches</span><span class="p">],</span> <span class="c1"># + f&quot; (score {match[&#39;score&#39;]})&quot;) # good debug</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="sd">&quot;&quot;&quot;</span>
<span class="sd"> View help or a list of topics</span>
<span class="sd"> Get help.</span>
<span class="sd"> Usage:</span>
<span class="sd"> help &lt;topic or command&gt;</span>
<span class="sd"> help list</span>
<span class="sd"> help all</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.eSome big topics may offer additional sub-topics.</span>
<span class="sd"> This will search for help on commands and other</span>
<span class="sd"> topics related to the game.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;help&quot;</span>
@ -162,8 +123,13 @@
<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 = False&#39; in your settings/conf/settings.py</span>
<span class="n">help_more</span> <span class="o">=</span> <span class="n">HELP_MORE</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>
@ -171,6 +137,9 @@
<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>
<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="sd">&quot;&quot;&quot;</span>
<span class="sd"> messages text to the caller, adding an extra oob argument to indicate</span>
@ -194,65 +163,142 @@
<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="nd">@staticmethod</span>
<span class="k">def</span> <span class="nf">format_help_entry</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">help_text</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>
<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="sd">&quot;&quot;&quot;</span>
<span class="sd"> This visually formats the help entry.</span>
<span class="sd"> This method can be overriden to customize the way a help</span>
<span class="sd"> entry is displayed.</span>
<span class="sd"> Args:</span>
<span class="sd"> title (str): the title of the help entry.</span>
<span class="sd"> help_text (str): the text of the help entry.</span>
<span class="sd"> aliases (list of str or None): the list of aliases.</span>
<span class="sd"> suggested (list of str or None): suggested reading.</span>
<span class="sd"> title (str): The title of the help entry.</span>
<span class="sd"> help_text (str): Text of the help entry.</span>
<span class="sd"> aliases (list): List of help-aliases (displayed in header).</span>
<span class="sd"> suggested (list): Strings suggested reading (based on title).</span>
<span class="sd"> subtopics (list): A list of strings - the subcategories available</span>
<span class="sd"> for this entry.</span>
<span class="sd"> Returns the formatted string, ready to be sent.</span>
<span class="sd"> &quot;&quot;&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">_SEP</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">title</span><span class="si">}</span><span class="s2">|n&quot;</span> <span class="k">if</span> <span class="n">title</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">(</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">if</span> <span class="n">aliases</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">help_text</span> <span class="o">=</span> <span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;</span><span class="se">\n</span><span class="si">{</span><span class="n">dedent</span><span class="p">(</span><span class="n">help_text</span><span class="o">.</span><span class="n">rstrip</span><span class="p">())</span><span class="si">}</span><span class="s2">&quot;</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="p">)</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">|CSuggested:|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="n">fill</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">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="k">if</span> <span class="n">suggested</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">end</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="se">\n</span><span class="si">{</span><span class="n">_SEP</span><span class="si">}</span><span class="s2">&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="k">return</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">start</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">aliases</span><span class="p">,</span> <span class="n">help_text</span><span class="p">,</span> <span class="n">suggested</span><span class="p">,</span> <span class="n">end</span><span class="p">))</span></div>
<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>
<div class="viewcode-block" id="CmdHelp.format_help_list"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.format_help_list">[docs]</a> <span class="k">def</span> <span class="nf">format_help_list</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">hdict_cmds</span><span class="p">,</span> <span class="n">hdict_db</span><span class="p">):</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="p">(</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="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
<span class="n">help_text</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n\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="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">))</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</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="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="p">(</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="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">subtopics</span> <span class="o">=</span> <span class="s1">&#39;&#39;</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="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="p">(</span>
<span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|CSuggestions:|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="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">suggested</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
<span class="n">end</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="se">\n</span><span class="si">{</span><span class="n">separator</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">start</span><span class="p">,</span> <span class="n">title</span><span class="p">,</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></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="sd">&quot;&quot;&quot;</span>
<span class="sd"> Output a category-ordered list. The input are the</span>
<span class="sd"> 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"> Returns:</span>
<span class="sd"> str: The help index organized into a grid.</span>
<span class="sd"> The input are the</span>
<span class="sd"> pre-loaded help files for commands and database-helpfiles</span>
<span class="sd"> respectively. You can override this method to return a</span>
<span class="sd"> custom display of the list of commands and topics.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">category_clr</span> <span class="o">=</span> <span class="s2">&quot;|w&quot;</span>
<span class="n">topic_clr</span> <span class="o">=</span> <span class="s2">&quot;|G&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="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="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="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="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="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">hdict_cmds</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> <span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="n">hdict_db</span><span class="o">.</span><span class="n">keys</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="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="n">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="n">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="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="s1">&#39;-&#39;</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">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="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">hdict_cmds</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="o">+</span> <span class="n">hdict_db</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="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">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="s1">&#39;-&#39;</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">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="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">gridrows</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">return</span> <span class="n">gridrows</span></div>
<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.check_show_help"><a class="viewcode-back" href="../../../../api/evennia.commands.default.help.html#evennia.commands.default.help.CmdHelp.check_show_help">[docs]</a> <span class="k">def</span> <span class="nf">check_show_help</span><span class="p">(</span><span class="bp">self</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="sd">&quot;&quot;&quot;</span>
@ -298,109 +344,233 @@
<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="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="bp">self</span><span class="o">.</span><span class="n">original_args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</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></div>
<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="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.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="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">query</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">args</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmdset</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">suggestion_cutoff</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">suggestion_cutoff</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="k">if</span> <span class="ow">not</span> <span class="n">query</span><span class="p">:</span>
<span class="n">query</span> <span class="o">=</span> <span class="s2">&quot;all&quot;</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="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 topics</span>
<span class="c1"># retrieve all available commands and database / file-help topics</span>
<span class="n">all_cmds</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="bp">self</span><span class="o">.</span><span class="n">check_show_help</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="n">all_topics</span> <span class="o">=</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">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="p">]</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="p">[</span><span class="n">HelpCategory</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="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">all_cmds</span><span class="p">]</span>
<span class="o">+</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="p">]</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">query</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;list&quot;</span><span class="p">,</span> <span class="s2">&quot;all&quot;</span><span class="p">):</span>
<span class="c1"># we want to list all available help entries, grouped by category</span>
<span class="n">hdict_cmd</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">hdict_topic</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"># create the dictionaries {category:[topic, topic ...]} required by format_help_list</span>
<span class="c1"># we group the file-help topics with the db ones, giving the db ones priority</span>
<span class="n">file_help_topics</span> <span class="o">=</span> <span class="n">FILE_HELP_ENTRIES</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">return_dict</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">db_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">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="p">}</span>
<span class="n">all_db_topics</span> <span class="o">=</span> <span class="nb">list</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_topics</span><span class="p">}</span><span class="o">.</span><span class="n">values</span><span class="p">())</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="p">[</span><span class="n">HelpCategory</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="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">all_cmds</span><span class="p">]</span>
<span class="o">+</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_db_topics</span><span class="p">]</span>
<span class="p">))</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_dict</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">db_help_dict</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"># Filter commands that should be reached by the help</span>
<span class="c1"># system, but not be displayed in the table, or be displayed differently.</span>
<span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">all_cmds</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">should_list_cmd</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="n">key</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">hdict_cmd</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="p">[</span><span class="n">hdict_topic</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="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">topic</span><span class="o">.</span><span class="n">key</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="p">]</span>
<span class="c1"># report back</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg_help</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">format_help_list</span><span class="p">(</span><span class="n">hdict_cmd</span><span class="p">,</span> <span class="n">hdict_topic</span><span class="p">))</span>
<span class="n">cmd_help_dict</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">db_topic</span> <span class="ow">in</span> <span class="n">all_db_topics</span><span class="p">:</span>
<span class="n">db_help_dict</span><span class="p">[</span><span class="n">db_topic</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">db_topic</span><span class="o">.</span><span class="n">key</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="n">cmd_help_dict</span><span class="p">,</span> <span class="n">db_help_dict</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"># Try to access a particular help entry or category</span>
<span class="n">entries</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">all_cmds</span> <span class="k">if</span> <span class="n">cmd</span><span class="p">]</span> <span class="o">+</span> <span class="nb">list</span><span class="p">(</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="o">+</span> <span class="n">all_categories</span>
<span class="c1"># We have a query - try to find a specific topic/category using the</span>
<span class="c1"># Lunr search engine</span>
<span class="k">for</span> <span class="n">match_query</span> <span class="ow">in</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">~1&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="c1"># We first do an exact word-match followed by a start-by query</span>
<span class="c1"># all available options</span>
<span class="n">entries</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">all_cmds</span> <span class="k">if</span> <span class="n">cmd</span><span class="p">]</span> <span class="o">+</span> <span class="n">all_db_topics</span> <span class="o">+</span> <span class="n">all_categories</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;category&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;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="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">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">formatted</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_help_list</span><span class="p">(</span>
<span class="p">{</span>
<span class="n">match</span><span class="o">.</span><span class="n">key</span><span class="p">:</span> <span class="p">[</span>
<span class="n">cmd</span><span class="o">.</span><span class="n">key</span>
<span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">all_cmds</span>
<span class="k">if</span> <span class="n">match</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">cmd</span><span class="o">.</span><span class="n">help_category</span>
<span class="p">]</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="n">match</span><span class="o">.</span><span class="n">key</span><span class="p">:</span> <span class="p">[</span>
<span class="n">topic</span><span class="o">.</span><span class="n">key</span>
<span class="k">for</span> <span class="n">topic</span> <span class="ow">in</span> <span class="n">all_topics</span>
<span class="k">if</span> <span class="n">match</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">topic</span><span class="o">.</span><span class="n">help_category</span>
<span class="p">]</span>
<span class="p">},</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">formatted</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">match</span><span class="o">.</span><span class="n">key</span><span class="p">,</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="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="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">formatted</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">match</span><span class="o">.</span><span class="n">key</span><span class="p">,</span>
<span class="n">match</span><span class="o">.</span><span class="n">entrytext</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="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="k">break</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="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="bp">self</span><span class="o">.</span><span class="n">msg_help</span><span class="p">(</span><span class="n">formatted</span><span class="p">)</span>
<span class="k">return</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="s2">&quot;</span><span class="se">\n</span><span class="s2">... But matches where found within the help texts of the suggestions below.&quot;</span>
<span class="k">break</span>
<span class="c1"># no exact matches found. Just give suggestions.</span>
<span class="bp">self</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">format_help_entry</span><span class="p">(</span>
<span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;No help entry found for &#39;</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">,</span> <span class="kc">None</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">options</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="p">)</span></div></div>
<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="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">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">match</span><span class="o">.</span><span class="n">key</span><span class="p">:</span> <span class="p">[</span>
<span class="n">cmd</span><span class="o">.</span><span class="n">key</span>
<span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">all_cmds</span>
<span class="k">if</span> <span class="n">match</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">cmd</span><span class="o">.</span><span class="n">help_category</span>
<span class="p">]</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="n">match</span><span class="o">.</span><span class="n">key</span><span class="p">:</span> <span class="p">[</span>
<span class="n">topic</span><span class="o">.</span><span class="n">key</span>
<span class="k">for</span> <span class="n">topic</span> <span class="ow">in</span> <span class="n">all_db_topics</span>
<span class="k">if</span> <span class="n">match</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">topic</span><span class="o">.</span><span class="n">help_category</span>
<span class="p">]</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="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="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">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="k">if</span> <span class="ow">not</span> <span class="n">subtopics</span> <span class="k">else</span> <span class="kc">None</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="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>
@ -438,15 +608,51 @@
<span class="sd"> delete - remove help topic.</span>
<span class="sd"> Examples:</span>
<span class="sd"> sethelp throw = This throws something at ...</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"> This command manipulates the help database. A help entry can be created,</span>
<span class="sd"> appended/merged to and deleted. If you don&#39;t assign a category, the</span>
<span class="sd"> &quot;General&quot; category will be used. If no lockstring is specified, default</span>
<span class="sd"> is to let everyone read the help file.</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>
@ -491,7 +697,7 @@
<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">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">old_entry</span> <span class="o">=</span> <span class="kc">None</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="s2">&quot;General&quot;</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;view:all()&quot;</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>
@ -534,6 +740,7 @@
<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="s2">&quot;Entry updated:</span><span class="se">\n</span><span class="si">%s%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">old_entry</span><span class="o">.</span><span class="n">entrytext</span><span class="p">,</span> <span class="n">aliastxt</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>

View file

@ -69,7 +69,6 @@
<span class="kn">from</span> <span class="nn">evennia.commands.cmdhandler</span> <span class="kn">import</span> <span class="n">CMD_NOINPUT</span>
<span class="kn">from</span> <span class="nn">evennia.commands.cmdhandler</span> <span class="kn">import</span> <span class="n">CMD_NOMATCH</span>
<span class="kn">from</span> <span class="nn">evennia.commands.cmdhandler</span> <span class="kn">import</span> <span class="n">CMD_MULTIMATCH</span>
<span class="kn">from</span> <span class="nn">evennia.commands.cmdhandler</span> <span class="kn">import</span> <span class="n">CMD_CHANNEL</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">utils</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
@ -146,53 +145,6 @@
<span class="n">matches</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">matches</span>
<span class="c1"># at_search_result will itself msg the multimatch options to the caller.</span>
<span class="n">at_search_result</span><span class="p">([</span><span class="n">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">matches</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">query</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="mi">0</span><span class="p">])</span></div></div>
<span class="c1"># Command called when the command given at the command line</span>
<span class="c1"># was identified as a channel name, like there existing a</span>
<span class="c1"># channel named &#39;ooc&#39; and the user wrote</span>
<span class="c1"># &gt; ooc Hello!</span>
<div class="viewcode-block" id="SystemSendToChannel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.syscommands.html#evennia.commands.default.syscommands.SystemSendToChannel">[docs]</a><span class="k">class</span> <span class="nc">SystemSendToChannel</span><span class="p">(</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is a special command that the cmdhandler calls</span>
<span class="sd"> when it detects that the command given matches</span>
<span class="sd"> an existing Channel object key (or alias).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">CMD_CHANNEL</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span>
<div class="viewcode-block" id="SystemSendToChannel.parse"><a class="viewcode-back" href="../../../../api/evennia.commands.default.syscommands.html#evennia.commands.default.syscommands.SystemSendToChannel.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="n">channelname</span><span class="p">,</span> <span class="n">msg</span> <span class="o">=</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="s2">&quot;:&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">channelname</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span> <span class="n">msg</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span></div>
<div class="viewcode-block" id="SystemSendToChannel.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.syscommands.html#evennia.commands.default.syscommands.SystemSendToChannel.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="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create a new message and send it to channel, using</span>
<span class="sd"> the already formatted input.</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">channelkey</span><span class="p">,</span> <span class="n">msg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">msg</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;Say what?&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">ChannelDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_channel</span><span class="p">(</span><span class="n">channelkey</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel</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;Channel &#39;</span><span class="si">%s</span><span class="s2">&#39; not found.&quot;</span> <span class="o">%</span> <span class="n">channelkey</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel</span><span class="o">.</span><span class="n">has_connection</span><span class="p">(</span><span class="n">caller</span><span class="p">):</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;You are not connected to channel &#39;</span><span class="si">%s</span><span class="s2">&#39;.&quot;</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span> <span class="o">%</span> <span class="n">channelkey</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel</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;send&quot;</span><span class="p">):</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;You are not permitted to send to channel &#39;</span><span class="si">%s</span><span class="s2">&#39;.&quot;</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span> <span class="o">%</span> <span class="n">channelkey</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s2">&quot;[</span><span class="si">%s</span><span class="s2">] </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">caller</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span>
<span class="n">msgobj</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_message</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">channels</span><span class="o">=</span><span class="p">[</span><span class="n">channel</span><span class="p">])</span>
<span class="n">channel</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">msgobj</span><span class="p">)</span></div></div>
</pre></div>
<div class="clearer"></div>

View file

@ -58,6 +58,7 @@
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">from</span> <span class="nn">anything</span> <span class="kn">import</span> <span class="n">Anything</span>
<span class="kn">from</span> <span class="nn">parameterized</span> <span class="kn">import</span> <span class="n">parameterized</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">unittest.mock</span> <span class="kn">import</span> <span class="n">patch</span><span class="p">,</span> <span class="n">Mock</span><span class="p">,</span> <span class="n">MagicMock</span>
@ -65,7 +66,7 @@
<span class="kn">from</span> <span class="nn">evennia.commands.default.cmdset_character</span> <span class="kn">import</span> <span class="n">CharacterCmdSet</span>
<span class="kn">from</span> <span class="nn">evennia.utils.test_resources</span> <span class="kn">import</span> <span class="n">EvenniaTest</span>
<span class="kn">from</span> <span class="nn">evennia.commands.default</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">help</span><span class="p">,</span>
<span class="n">help</span> <span class="k">as</span> <span class="n">help_module</span><span class="p">,</span>
<span class="n">general</span><span class="p">,</span>
<span class="n">system</span><span class="p">,</span>
<span class="n">admin</span><span class="p">,</span>
@ -76,7 +77,6 @@
<span class="n">unloggedin</span><span class="p">,</span>
<span class="n">syscommands</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">evennia.commands.cmdparser</span> <span class="kn">import</span> <span class="n">build_matches</span>
<span class="kn">from</span> <span class="nn">evennia.commands.default.muxcommand</span> <span class="kn">import</span> <span class="n">MuxCommand</span>
<span class="kn">from</span> <span class="nn">evennia.commands.command</span> <span class="kn">import</span> <span class="n">Command</span><span class="p">,</span> <span class="n">InterruptCommand</span>
<span class="kn">from</span> <span class="nn">evennia.commands</span> <span class="kn">import</span> <span class="n">cmdparser</span>
@ -244,7 +244,7 @@
<span class="k">else</span><span class="p">:</span>
<span class="c1"># a single expected string and thus a single receiver (defaults to caller)</span>
<span class="n">receiver</span> <span class="o">=</span> <span class="n">receiver</span> <span class="k">if</span> <span class="n">receiver</span> <span class="k">else</span> <span class="n">caller</span>
<span class="n">receiver_mapping</span><span class="p">[</span><span class="n">receiver</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">if</span> <span class="n">msg</span> <span class="k">else</span> <span class="kc">None</span>
<span class="n">receiver_mapping</span><span class="p">[</span><span class="n">receiver</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">if</span> <span class="n">msg</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="kc">None</span>
<span class="n">unmocked_msg_methods</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="n">receiver_mapping</span><span class="p">:</span>
@ -289,6 +289,12 @@
<span class="k">except</span> <span class="n">InterruptCommand</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">for</span> <span class="n">inp</span> <span class="ow">in</span> <span class="n">inputs</span><span class="p">:</span>
<span class="c1"># if there are any inputs left, we may have a non-generator</span>
<span class="c1"># input to handle (get_input/ask_yes_no that uses a separate</span>
<span class="c1"># cmdset rather than a yield</span>
<span class="n">caller</span><span class="o">.</span><span class="n">execute_cmd</span><span class="p">(</span><span class="n">inp</span><span class="p">)</span>
<span class="c1"># At this point the mocked .msg methods on each receiver will have</span>
<span class="c1"># stored all calls made to them (that&#39;s a basic function of the Mock</span>
<span class="c1"># class). We will not extract them and compare to what we expected to</span>
@ -443,6 +449,9 @@
<div class="viewcode-block" id="TestHelp"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestHelp">[docs]</a><span class="k">class</span> <span class="nc">TestHelp</span><span class="p">(</span><span class="n">CommandTest</span><span class="p">):</span>
<span class="n">maxDiff</span> <span class="o">=</span> <span class="kc">None</span>
<div class="viewcode-block" id="TestHelp.setUp"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestHelp.setUp">[docs]</a> <span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">setUp</span><span class="p">()</span>
<span class="c1"># we need to set up a logger here since lunr takes over the logger otherwise</span>
@ -457,15 +466,135 @@
<span class="n">logging</span><span class="o">.</span><span class="n">disable</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">ERROR</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestHelp.test_help"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestHelp.test_help">[docs]</a> <span class="k">def</span> <span class="nf">test_help</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">help</span><span class="o">.</span><span class="n">CmdHelp</span><span class="p">(),</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="s2">&quot;Admin&quot;</span><span class="p">,</span> <span class="n">cmdset</span><span class="o">=</span><span class="n">CharacterCmdSet</span><span class="p">())</span></div>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">help_module</span><span class="o">.</span><span class="n">CmdHelp</span><span class="p">(),</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="s2">&quot;Commands&quot;</span><span class="p">,</span> <span class="n">cmdset</span><span class="o">=</span><span class="n">CharacterCmdSet</span><span class="p">())</span></div>
<div class="viewcode-block" id="TestHelp.test_set_help"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestHelp.test_set_help">[docs]</a> <span class="k">def</span> <span class="nf">test_set_help</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="n">help</span><span class="o">.</span><span class="n">CmdSetHelp</span><span class="p">(),</span>
<span class="n">help_module</span><span class="o">.</span><span class="n">CmdSetHelp</span><span class="p">(),</span>
<span class="s2">&quot;testhelp, General = This is a test&quot;</span><span class="p">,</span>
<span class="s2">&quot;Topic &#39;testhelp&#39; was successfully created.&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">help</span><span class="o">.</span><span class="n">CmdHelp</span><span class="p">(),</span> <span class="s2">&quot;testhelp&quot;</span><span class="p">,</span> <span class="s2">&quot;Help for testhelp&quot;</span><span class="p">,</span> <span class="n">cmdset</span><span class="o">=</span><span class="n">CharacterCmdSet</span><span class="p">())</span></div></div>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">help_module</span><span class="o">.</span><span class="n">CmdHelp</span><span class="p">(),</span> <span class="s2">&quot;testhelp&quot;</span><span class="p">,</span> <span class="s2">&quot;Help for testhelp&quot;</span><span class="p">,</span> <span class="n">cmdset</span><span class="o">=</span><span class="n">CharacterCmdSet</span><span class="p">())</span></div>
<span class="nd">@parameterized</span><span class="o">.</span><span class="n">expand</span><span class="p">([</span>
<span class="p">(</span><span class="s2">&quot;test&quot;</span><span class="p">,</span> <span class="c1"># main help entry</span>
<span class="s2">&quot;Help for test</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Main help text</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Subtopics:</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot; test/creating extra stuff&quot;</span>
<span class="s2">&quot; test/something else&quot;</span>
<span class="s2">&quot; test/more&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/creating extra stuff&quot;</span><span class="p">,</span> <span class="c1"># subtopic, full match</span>
<span class="s2">&quot;Help for test/creating extra stuff</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Help on creating extra stuff.</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Subtopics:</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot; test/creating extra stuff/subsubtopic</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/creating&quot;</span><span class="p">,</span> <span class="c1"># startswith-match</span>
<span class="s2">&quot;Help for test/creating extra stuff</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Help on creating extra stuff.</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Subtopics:</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot; test/creating extra stuff/subsubtopic</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/extra&quot;</span><span class="p">,</span> <span class="c1"># partial match</span>
<span class="s2">&quot;Help for test/creating extra stuff</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Help on creating extra stuff.</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Subtopics:</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot; test/creating extra stuff/subsubtopic</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/extra/subsubtopic&quot;</span><span class="p">,</span> <span class="c1"># partial subsub-match</span>
<span class="s2">&quot;Help for test/creating extra stuff/subsubtopic</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;A subsubtopic text&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/creating extra/subsub&quot;</span><span class="p">,</span> <span class="c1"># partial subsub-match</span>
<span class="s2">&quot;Help for test/creating extra stuff/subsubtopic</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;A subsubtopic text&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/Something else&quot;</span><span class="p">,</span> <span class="c1"># case</span>
<span class="s2">&quot;Help for test/something else</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Something else&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/More&quot;</span><span class="p">,</span> <span class="c1"># case</span>
<span class="s2">&quot;Help for test/more</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Another text</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Subtopics:</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot; test/more/second-more&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/More/Second-more&quot;</span><span class="p">,</span>
<span class="s2">&quot;Help for test/more/second-more</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;The Second More text.</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Subtopics:</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot; test/more/second-more/more again&quot;</span>
<span class="s2">&quot; test/more/second-more/third more&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/More/-more&quot;</span><span class="p">,</span> <span class="c1"># partial match</span>
<span class="s2">&quot;Help for test/more/second-more</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;The Second More text.</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Subtopics:</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot; test/more/second-more/more again&quot;</span>
<span class="s2">&quot; test/more/second-more/third more&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/more/second/more again&quot;</span><span class="p">,</span>
<span class="s2">&quot;Help for test/more/second-more/more again</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Even more text.</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;test/more/second/third&quot;</span><span class="p">,</span>
<span class="s2">&quot;Help for test/more/second-more/third more</span><span class="se">\n\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Third more text</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="p">),</span>
<span class="p">])</span>
<span class="k">def</span> <span class="nf">test_subtopic_fetch</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">helparg</span><span class="p">,</span> <span class="n">expected</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check retrieval of subtopics.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">class</span> <span class="nc">TestCmd</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Main help text</span>
<span class="sd"> # SUBTOPICS</span>
<span class="sd"> ## creating extra stuff</span>
<span class="sd"> Help on creating extra stuff.</span>
<span class="sd"> ### subsubtopic</span>
<span class="sd"> A subsubtopic text</span>
<span class="sd"> ## Something else</span>
<span class="sd"> Something else</span>
<span class="sd"> ## More</span>
<span class="sd"> Another text</span>
<span class="sd"> ### Second-More</span>
<span class="sd"> The Second More text.</span>
<span class="sd"> #### More again</span>
<span class="sd"> Even more text.</span>
<span class="sd"> #### Third more</span>
<span class="sd"> Third more text</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;test&quot;</span>
<span class="k">class</span> <span class="nc">TestCmdSet</span><span class="p">(</span><span class="n">CmdSet</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">at_cmdset_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">TestCmd</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">help_module</span><span class="o">.</span><span class="n">CmdHelp</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">help_module</span><span class="o">.</span><span class="n">CmdHelp</span><span class="p">(),</span>
<span class="n">helparg</span><span class="p">,</span>
<span class="n">expected</span><span class="p">,</span>
<span class="n">cmdset</span><span class="o">=</span><span class="n">TestCmdSet</span><span class="p">())</span></div>
<div class="viewcode-block" id="TestSystem"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestSystem">[docs]</a><span class="k">class</span> <span class="nc">TestSystem</span><span class="p">(</span><span class="n">CommandTest</span><span class="p">):</span>
@ -1603,21 +1732,13 @@
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="n">comms</span><span class="o">.</span><span class="n">CmdAddCom</span><span class="p">(),</span>
<span class="s2">&quot;tc = testchan&quot;</span><span class="p">,</span>
<span class="s2">&quot;You are already connected to channel testchan. You can now&quot;</span><span class="p">,</span>
<span class="s2">&quot;You are already connected to channel testchan.| You can now&quot;</span><span class="p">,</span>
<span class="n">receiver</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">account</span><span class="p">,</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="n">comms</span><span class="o">.</span><span class="n">CmdDelCom</span><span class="p">(),</span>
<span class="s2">&quot;tc&quot;</span><span class="p">,</span>
<span class="s2">&quot;Your alias &#39;tc&#39; for channel testchan was cleared.&quot;</span><span class="p">,</span>
<span class="n">receiver</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">account</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="TestComms.test_channels"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestComms.test_channels">[docs]</a> <span class="k">def</span> <span class="nf">test_channels</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="n">comms</span><span class="o">.</span><span class="n">CmdChannels</span><span class="p">(),</span>
<span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;Available channels (use comlist,addcom and delcom to manage&quot;</span><span class="p">,</span>
<span class="s2">&quot;Any alias &#39;tc&#39; for channel testchan was cleared.&quot;</span><span class="p">,</span>
<span class="n">receiver</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">account</span><span class="p">,</span>
<span class="p">)</span></div>
@ -1625,7 +1746,7 @@
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="n">comms</span><span class="o">.</span><span class="n">CmdAllCom</span><span class="p">(),</span>
<span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;Available channels (use comlist,addcom and delcom to manage&quot;</span><span class="p">,</span>
<span class="s2">&quot;Available channels:&quot;</span><span class="p">,</span>
<span class="n">receiver</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">account</span><span class="p">,</span>
<span class="p">)</span></div>
@ -1645,14 +1766,6 @@
<span class="n">receiver</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">account</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="TestComms.test_cemit"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestComms.test_cemit">[docs]</a> <span class="k">def</span> <span class="nf">test_cemit</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="n">comms</span><span class="o">.</span><span class="n">CmdCemit</span><span class="p">(),</span>
<span class="s2">&quot;testchan = Test Message&quot;</span><span class="p">,</span>
<span class="s2">&quot;[testchan] Test Message|Sent to channel testchan: Test Message&quot;</span><span class="p">,</span>
<span class="n">receiver</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">account</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="TestComms.test_cwho"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestComms.test_cwho">[docs]</a> <span class="k">def</span> <span class="nf">test_cwho</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="n">comms</span><span class="o">.</span><span class="n">CmdCWho</span><span class="p">(),</span>
@ -1689,6 +1802,227 @@
<span class="p">)</span></div></div>
<span class="kn">from</span> <span class="nn">evennia.utils.create</span> <span class="kn">import</span> <span class="n">create_channel</span> <span class="c1"># noqa</span>
<div class="viewcode-block" id="TestCommsChannel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel">[docs]</a><span class="k">class</span> <span class="nc">TestCommsChannel</span><span class="p">(</span><span class="n">CommandTest</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Test the central `channel` command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="TestCommsChannel.setUp"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.setUp">[docs]</a> <span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">CommandTest</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">setUp</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="n">create_channel</span><span class="p">(</span>
<span class="n">key</span><span class="o">=</span><span class="s2">&quot;testchannel&quot;</span><span class="p">,</span>
<span class="n">desc</span><span class="o">=</span><span class="s2">&quot;A test channel&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span> <span class="o">=</span> <span class="n">comms</span><span class="o">.</span><span class="n">CmdChannel</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="o">.</span><span class="n">account_caller</span> <span class="o">=</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="TestCommsChannel.tearDown"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.tearDown">[docs]</a> <span class="k">def</span> <span class="nf">tearDown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">pk</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span></div>
<span class="c1"># test channel command</span>
<div class="viewcode-block" id="TestCommsChannel.test_channel__noarg"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__noarg">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__noarg</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;Channel subscriptions&quot;</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__msg"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__msg">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__msg</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;testchannel = Test message&quot;</span><span class="p">,</span>
<span class="s2">&quot;&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="s2">&quot;Test message&quot;</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__list"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__list">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__list</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/list&quot;</span><span class="p">,</span>
<span class="s2">&quot;Channel subscriptions&quot;</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__all"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__all">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__all</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/all&quot;</span><span class="p">,</span>
<span class="s2">&quot;Available channels&quot;</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__history"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__history">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__history</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s2">&quot;evennia.commands.default.comms.tail_log_file&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">mock_tail</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/history testchannel&quot;</span><span class="p">,</span>
<span class="s2">&quot;&quot;</span>
<span class="p">)</span>
<span class="n">mock_tail</span><span class="o">.</span><span class="n">assert_called</span><span class="p">()</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__sub"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__sub">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__sub</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/sub testchannel&quot;</span><span class="p">,</span>
<span class="s2">&quot;You are now subscribed&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">all</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">nickreplace</span><span class="p">(</span><span class="s2">&quot;testchannel Hello&quot;</span><span class="p">),</span> <span class="s2">&quot;channel testchannel = Hello&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__unsub"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__unsub">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__unsub</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/unsub testchannel&quot;</span><span class="p">,</span>
<span class="s2">&quot;You un-subscribed&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">all</span><span class="p">())</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__alias__unalias"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__alias__unalias">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__alias__unalias</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Add and then remove a channel alias&quot;&quot;&quot;</span>
<span class="c1"># add alias</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/alias testchannel = foo&quot;</span><span class="p">,</span>
<span class="s2">&quot;Added/updated your alias &#39;foo&#39; for channel testchannel.&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">nickreplace</span><span class="p">(</span><span class="s1">&#39;foo Hello&#39;</span><span class="p">),</span> <span class="s2">&quot;channel testchannel = Hello&quot;</span><span class="p">)</span>
<span class="c1"># use alias</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;foo = test message&quot;</span><span class="p">,</span>
<span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="s2">&quot;test message&quot;</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="p">)</span>
<span class="c1"># remove alias</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/unalias foo&quot;</span><span class="p">,</span>
<span class="s2">&quot;Removed your channel alias &#39;foo&#39;&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;foo $1&#39;</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">&quot;channel&quot;</span><span class="p">),</span> <span class="kc">None</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__mute"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__mute">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__mute</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/mute testchannel&quot;</span><span class="p">,</span>
<span class="s2">&quot;Muted channel testchannel&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">mutelist</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__unmute"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__unmute">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__unmute</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">mute</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/unmute testchannel = Char1&quot;</span><span class="p">,</span>
<span class="s2">&quot;Un-muted channel testchannel&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">mutelist</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__create"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__create">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__create</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/create testchannel2&quot;</span><span class="p">,</span>
<span class="s2">&quot;Created (and joined) new channel&quot;</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__destroy"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__destroy">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__destroy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/destroy testchannel = delete reason&quot;</span><span class="p">,</span>
<span class="s2">&quot;Are you sure you want to delete channel &quot;</span><span class="p">,</span>
<span class="n">inputs</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;Yes&#39;</span><span class="p">]</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span>
<span class="s2">&quot;delete reason&quot;</span><span class="p">,</span> <span class="n">bypass_mute</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__desc"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__desc">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__desc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/desc testchannel = Another description&quot;</span><span class="p">,</span>
<span class="s2">&quot;Updated channel description.&quot;</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__lock"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__lock">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__lock</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/lock testchannel = foo:false()&quot;</span><span class="p">,</span>
<span class="s2">&quot;Added/updated lock on channel&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">channel</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="s1">&#39;foo&#39;</span><span class="p">),</span> <span class="s1">&#39;foo:false()&#39;</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__unlock"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__unlock">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__unlock</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</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="s2">&quot;foo:true()&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/unlock testchannel = foo&quot;</span><span class="p">,</span>
<span class="s2">&quot;Removed lock from channel&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">channel</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="s1">&#39;foo&#39;</span><span class="p">),</span> <span class="s1">&#39;&#39;</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__boot"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__boot">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__boot</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char2</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char2</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">all</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">char2</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/boot testchannel = Char2 : Booting from channel!&quot;</span><span class="p">,</span>
<span class="s2">&quot;Are you sure &quot;</span><span class="p">,</span>
<span class="n">inputs</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Yes&quot;</span><span class="p">]</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span>
<span class="s2">&quot;Char2 was booted from channel by Char. Reason: Booting from channel!&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">char2</span><span class="o">.</span><span class="n">msg</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span>
<span class="s2">&quot;You were booted from channel testchannel by Char. Reason: Booting from channel!&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__ban__unban"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__ban__unban">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__ban__unban</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Test first ban and then unban&quot;&quot;&quot;</span>
<span class="c1"># ban</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char2</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char2</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">all</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">char2</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/ban testchannel = Char2 : Banning from channel!&quot;</span><span class="p">,</span>
<span class="s2">&quot;Are you sure &quot;</span><span class="p">,</span>
<span class="n">inputs</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Yes&quot;</span><span class="p">]</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">msg</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span>
<span class="s2">&quot;Char2 was booted from channel by Char. Reason: Banning from channel!&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">char2</span><span class="o">.</span><span class="n">msg</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span>
<span class="s2">&quot;You were booted from channel testchannel by Char. Reason: Banning from channel!&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char2</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">banlist</span><span class="p">)</span>
<span class="c1"># unban</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/unban testchannel = Char2&quot;</span><span class="p">,</span>
<span class="s2">&quot;Un-banned Char2 from channel testchannel&quot;</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char2</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="o">.</span><span class="n">banlist</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCommsChannel.test_channel__who"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestCommsChannel.test_channel__who">[docs]</a> <span class="k">def</span> <span class="nf">test_channel__who</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cmdchannel</span><span class="p">(),</span>
<span class="s2">&quot;/who testchannel&quot;</span><span class="p">,</span>
<span class="s2">&quot;Subscribed to testchannel:</span><span class="se">\n</span><span class="s2">Char&quot;</span>
<span class="p">)</span></div></div>
<div class="viewcode-block" id="TestBatchProcess"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestBatchProcess">[docs]</a><span class="k">class</span> <span class="nc">TestBatchProcess</span><span class="p">(</span><span class="n">CommandTest</span><span class="p">):</span>
<div class="viewcode-block" id="TestBatchProcess.test_batch_commands"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestBatchProcess.test_batch_commands">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">&quot;evennia.contrib.tutorial_examples.red_button.repeat&quot;</span><span class="p">)</span>
@ -1760,16 +2094,7 @@
<span class="n">multimatch</span> <span class="o">=</span> <span class="n">syscommands</span><span class="o">.</span><span class="n">SystemMultimatch</span><span class="p">()</span>
<span class="n">multimatch</span><span class="o">.</span><span class="n">matches</span> <span class="o">=</span> <span class="n">matches</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">multimatch</span><span class="p">,</span> <span class="s2">&quot;look&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestSystemCommands.test_channelcommand"><a class="viewcode-back" href="../../../../api/evennia.commands.default.tests.html#evennia.commands.default.tests.TestSystemCommands.test_channelcommand">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">&quot;evennia.commands.default.syscommands.ChannelDB&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_channelcommand</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mock_channeldb</span><span class="p">):</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span>
<span class="n">channel</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span>
<span class="n">mock_channeldb</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_channel</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">(</span><span class="n">return_value</span><span class="o">=</span><span class="n">channel</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">syscommands</span><span class="o">.</span><span class="n">SystemSendToChannel</span><span class="p">(),</span> <span class="s2">&quot;public:Hello&quot;</span><span class="p">)</span>
<span class="n">channel</span><span class="o">.</span><span class="n">msg</span><span class="o">.</span><span class="n">assert_called</span><span class="p">()</span></div></div>
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">multimatch</span><span class="p">,</span> <span class="s2">&quot;look&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span></div></div>
</pre></div>
<div class="clearer"></div>

View file

@ -1,428 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.comms.channelhandler &#8212; Evennia 1.0-dev 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 1.0-dev</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.comms.channelhandler</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.comms.channelhandler</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">The channel handler, accessed from this module as CHANNEL_HANDLER is a</span>
<span class="sd">singleton that handles the stored set of channels and how they are</span>
<span class="sd">represented against the cmdhandler.</span>
<span class="sd">If there is a channel named &#39;newbie&#39;, we want to be able to just write</span>
<span class="sd"> newbie Hello!</span>
<span class="sd">For this to work, &#39;newbie&#39;, the name of the channel, must be</span>
<span class="sd">identified by the cmdhandler as a command name. The channelhandler</span>
<span class="sd">stores all channels as custom &#39;commands&#39; that the cmdhandler can</span>
<span class="sd">import and look through.</span>
<span class="sd">&gt; Warning - channel names take precedence over command names, so make</span>
<span class="sd">sure to not pick clashing channel names.</span>
<span class="sd">Unless deleting a channel you normally don&#39;t need to bother about the</span>
<span class="sd">channelhandler at all - the create_channel method handles the update.</span>
<span class="sd">To delete a channel cleanly, delete the channel object, then call</span>
<span class="sd">update() on the channelhandler. Or use Channel.objects.delete() which</span>
<span class="sd">does this for you.</span>
<span class="sd">&quot;&quot;&quot;</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.commands</span> <span class="kn">import</span> <span class="n">cmdset</span>
<span class="kn">from</span> <span class="nn">evennia.utils.logger</span> <span class="kn">import</span> <span class="n">tail_log_file</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="kn">from</span> <span class="nn">django.utils.translation</span> <span class="kn">import</span> <span class="n">gettext</span> <span class="k">as</span> <span class="n">_</span>
<span class="c1"># we must late-import these since any overloads are likely to</span>
<span class="c1"># themselves be using these classes leading to a circular import.</span>
<span class="n">_CHANNEL_HANDLER_CLASS</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_CHANNEL_COMMAND_CLASS</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_CHANNELDB</span> <span class="o">=</span> <span class="kc">None</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>
<div class="viewcode-block" id="ChannelCommand"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelCommand">[docs]</a><span class="k">class</span> <span class="nc">ChannelCommand</span><span class="p">(</span><span class="n">_COMMAND_DEFAULT_CLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> {channelkey} channel</span>
<span class="sd"> {channeldesc}</span>
<span class="sd"> Usage:</span>
<span class="sd"> {lower_channelkey} &lt;message&gt;</span>
<span class="sd"> {lower_channelkey}/history [start]</span>
<span class="sd"> {lower_channelkey} off - mutes the channel</span>
<span class="sd"> {lower_channelkey} on - unmutes the channel</span>
<span class="sd"> Switch:</span>
<span class="sd"> history: View 20 previous messages, either from the end or</span>
<span class="sd"> from &lt;start&gt; number of messages from the end.</span>
<span class="sd"> Example:</span>
<span class="sd"> {lower_channelkey} Hello World!</span>
<span class="sd"> {lower_channelkey}/history</span>
<span class="sd"> {lower_channelkey}/history 30</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># ^note that channeldesc and lower_channelkey will be filled</span>
<span class="c1"># automatically by ChannelHandler</span>
<span class="c1"># this flag is what identifies this cmd as a channel cmd</span>
<span class="c1"># and branches off to the system send-to-channel command</span>
<span class="c1"># (which is customizable by admin)</span>
<span class="n">is_channel</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;general&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Channel Names&quot;</span>
<span class="n">obj</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">arg_regex</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">&quot;\s.*?|/history.*?&quot;</span>
<div class="viewcode-block" id="ChannelCommand.parse"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelCommand.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="sd">&quot;&quot;&quot;</span>
<span class="sd"> Simple parser</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># cmdhandler sends channame:msg here.</span>
<span class="n">channelname</span><span class="p">,</span> <span class="n">msg</span> <span class="o">=</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="s2">&quot;:&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">history_start</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">msg</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;/history&quot;</span><span class="p">):</span>
<span class="n">arg</span> <span class="o">=</span> <span class="n">msg</span><span class="p">[</span><span class="mi">8</span><span class="p">:]</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">history_start</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">if</span> <span class="n">arg</span> <span class="k">else</span> <span class="mi">0</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="c1"># if no valid number was given, ignore it</span>
<span class="k">pass</span>
<span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">channelname</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span> <span class="n">msg</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span></div>
<div class="viewcode-block" id="ChannelCommand.func"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelCommand.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="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create a new message and send it to channel, using</span>
<span class="sd"> the already formatted input.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_CHANNELDB</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_CHANNELDB</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">evennia.comms.models</span> <span class="kn">import</span> <span class="n">ChannelDB</span> <span class="k">as</span> <span class="n">_CHANNELDB</span>
<span class="n">channelkey</span><span class="p">,</span> <span class="n">msg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</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="k">if</span> <span class="ow">not</span> <span class="n">msg</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="n">_</span><span class="p">(</span><span class="s2">&quot;Say what?&quot;</span><span class="p">))</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">_CHANNELDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_channel</span><span class="p">(</span><span class="n">channelkey</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel</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="n">_</span><span class="p">(</span><span class="s2">&quot;Channel &#39;</span><span class="si">%s</span><span class="s2">&#39; not found.&quot;</span><span class="p">)</span> <span class="o">%</span> <span class="n">channelkey</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel</span><span class="o">.</span><span class="n">has_connection</span><span class="p">(</span><span class="n">caller</span><span class="p">):</span>
<span class="n">string</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;You are not connected to channel &#39;</span><span class="si">%s</span><span class="s2">&#39;.&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="n">string</span> <span class="o">%</span> <span class="n">channelkey</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel</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;send&quot;</span><span class="p">):</span>
<span class="n">string</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;You are not permitted to send to channel &#39;</span><span class="si">%s</span><span class="s2">&#39;.&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="n">string</span> <span class="o">%</span> <span class="n">channelkey</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">msg</span> <span class="o">==</span> <span class="s2">&quot;on&quot;</span><span class="p">:</span>
<span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;account&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">caller</span><span class="o">.</span><span class="n">account</span>
<span class="n">unmuted</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">unmute</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="k">if</span> <span class="n">unmuted</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="n">_</span><span class="p">(</span><span class="s2">&quot;You start listening to </span><span class="si">%s</span><span class="s2">.&quot;</span><span class="p">)</span> <span class="o">%</span> <span class="n">channel</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">_</span><span class="p">(</span><span class="s2">&quot;You were already listening to </span><span class="si">%s</span><span class="s2">.&quot;</span><span class="p">)</span> <span class="o">%</span> <span class="n">channel</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">msg</span> <span class="o">==</span> <span class="s2">&quot;off&quot;</span><span class="p">:</span>
<span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;account&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">caller</span><span class="o">.</span><span class="n">account</span>
<span class="n">muted</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">mute</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="k">if</span> <span class="n">muted</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="n">_</span><span class="p">(</span><span class="s2">&quot;You stop listening to </span><span class="si">%s</span><span class="s2">.&quot;</span><span class="p">)</span> <span class="o">%</span> <span class="n">channel</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">_</span><span class="p">(</span><span class="s2">&quot;You were already not listening to </span><span class="si">%s</span><span class="s2">.&quot;</span><span class="p">)</span> <span class="o">%</span> <span class="n">channel</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">history_start</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="c1"># Try to view history</span>
<span class="n">log_file</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;log_file&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;channel_</span><span class="si">%s</span><span class="s2">.log&quot;</span> <span class="o">%</span> <span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">send_msg</span><span class="p">(</span><span class="n">lines</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="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">line</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="mi">1</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="s2">&quot;[-]&quot;</span> <span class="ow">in</span> <span class="n">line</span> <span class="k">else</span> <span class="n">line</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">tail_log_file</span><span class="p">(</span><span class="n">log_file</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">history_start</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">send_msg</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;account&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">caller</span><span class="o">.</span><span class="n">account</span>
<span class="k">if</span> <span class="n">caller</span> <span class="ow">in</span> <span class="n">channel</span><span class="o">.</span><span class="n">mutelist</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="n">_</span><span class="p">(</span><span class="s2">&quot;You currently have </span><span class="si">%s</span><span class="s2"> muted.&quot;</span><span class="p">)</span> <span class="o">%</span> <span class="n">channel</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">channel</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="n">online</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>
<div class="viewcode-block" id="ChannelCommand.get_extra_info"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelCommand.get_extra_info">[docs]</a> <span class="k">def</span> <span class="nf">get_extra_info</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="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Let users know that this command is for communicating on a channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> caller (TypedObject): A Character or Account who has entered an ambiguous command.</span>
<span class="sd"> Returns:</span>
<span class="sd"> A string with identifying information to disambiguate the object, conventionally with a preceding space.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot; (channel)&quot;</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="ChannelHandler"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelHandler">[docs]</a><span class="k">class</span> <span class="nc">ChannelHandler</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> The ChannelHandler manages all active in-game channels and</span>
<span class="sd"> dynamically creates channel commands for users so that they can</span>
<span class="sd"> just give the channel&#39;s key or alias to write to it. Whenever a</span>
<span class="sd"> new channel is created in the database, the update() method on</span>
<span class="sd"> this handler must be called to sync it with the database (this is</span>
<span class="sd"> done automatically if creating the channel with</span>
<span class="sd"> evennia.create_channel())</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="ChannelHandler.__init__"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelHandler.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Initializes the channel handler&#39;s internal state.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_channel_cmds</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_cmdsets</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_channels</span> <span class="o">=</span> <span class="p">{}</span></div>
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Returns the string representation of the handler</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span> <span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cached_channel_cmds</span><span class="p">)</span>
<div class="viewcode-block" id="ChannelHandler.clear"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelHandler.clear">[docs]</a> <span class="k">def</span> <span class="nf">clear</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Reset the cache storage.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_channel_cmds</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_cmdsets</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_channels</span> <span class="o">=</span> <span class="p">{}</span></div>
<div class="viewcode-block" id="ChannelHandler.add"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelHandler.add">[docs]</a> <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">channel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Add an individual channel to the handler. This is called</span>
<span class="sd"> whenever a new channel is created.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to add.</span>
<span class="sd"> Notes:</span>
<span class="sd"> To remove a channel, simply delete the channel object and</span>
<span class="sd"> run self.update on the handler. This should usually be</span>
<span class="sd"> handled automatically by one of the deletion methos of</span>
<span class="sd"> the Channel itself.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_CHANNEL_COMMAND_CLASS</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_CHANNEL_COMMAND_CLASS</span><span class="p">:</span>
<span class="n">_CHANNEL_COMMAND_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">CHANNEL_COMMAND_CLASS</span><span class="p">)</span>
<span class="c1"># map the channel to a searchable command</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">_CHANNEL_COMMAND_CLASS</span><span class="p">(</span>
<span class="n">key</span><span class="o">=</span><span class="n">channel</span><span class="o">.</span><span class="n">key</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="n">aliases</span><span class="o">=</span><span class="n">channel</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">locks</span><span class="o">=</span><span class="s2">&quot;cmd:all();</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">channel</span><span class="o">.</span><span class="n">locks</span><span class="p">,</span>
<span class="n">help_category</span><span class="o">=</span><span class="s2">&quot;Channel names&quot;</span><span class="p">,</span>
<span class="n">obj</span><span class="o">=</span><span class="n">channel</span><span class="p">,</span>
<span class="n">is_channel</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="p">)</span>
<span class="c1"># format the help entry</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">key</span>
<span class="n">cmd</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> <span class="n">cmd</span><span class="o">.</span><span class="vm">__doc__</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">channelkey</span><span class="o">=</span><span class="n">key</span><span class="p">,</span>
<span class="n">lower_channelkey</span><span class="o">=</span><span class="n">key</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="n">channeldesc</span><span class="o">=</span><span class="n">channel</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_channel_cmds</span><span class="p">[</span><span class="n">channel</span><span class="p">]</span> <span class="o">=</span> <span class="n">cmd</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_channels</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">channel</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_cmdsets</span> <span class="o">=</span> <span class="p">{}</span></div>
<span class="n">add_channel</span> <span class="o">=</span> <span class="n">add</span> <span class="c1"># legacy alias</span>
<div class="viewcode-block" id="ChannelHandler.remove"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelHandler.remove">[docs]</a> <span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">channel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Remove channel from channelhandler. This will also delete it.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): Channel to remove/delete.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">channel</span><span class="o">.</span><span class="n">pk</span><span class="p">:</span>
<span class="n">channel</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">update</span><span class="p">()</span></div>
<div class="viewcode-block" id="ChannelHandler.update"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelHandler.update">[docs]</a> <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Updates the handler completely, including removing old removed</span>
<span class="sd"> Channel objects. This must be called after deleting a Channel.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_CHANNELDB</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_CHANNELDB</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">evennia.comms.models</span> <span class="kn">import</span> <span class="n">ChannelDB</span> <span class="k">as</span> <span class="n">_CHANNELDB</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_channel_cmds</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_cmdsets</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_channels</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">channel</span> <span class="ow">in</span> <span class="n">_CHANNELDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_all_channels</span><span class="p">():</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span></div>
<div class="viewcode-block" id="ChannelHandler.get"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelHandler.get">[docs]</a> <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">channelname</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get a channel from the handler, or all channels</span>
<span class="sd"> Args:</span>
<span class="sd"> channelame (str, optional): Channel key, case insensitive.</span>
<span class="sd"> Returns</span>
<span class="sd"> channels (list): The matching channels in a list, or all</span>
<span class="sd"> channels in the handler.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">channelname</span><span class="p">:</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cached_channels</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">channelname</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="n">channel</span><span class="p">]</span> <span class="k">if</span> <span class="n">channel</span> <span class="k">else</span> <span class="p">[]</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_cached_channels</span><span class="o">.</span><span class="n">values</span><span class="p">())</span></div>
<div class="viewcode-block" id="ChannelHandler.get_cmdset"><a class="viewcode-back" href="../../../api/evennia.comms.channelhandler.html#evennia.comms.channelhandler.ChannelHandler.get_cmdset">[docs]</a> <span class="k">def</span> <span class="nf">get_cmdset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">source_object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Retrieve cmdset for channels this source_object has</span>
<span class="sd"> access to send to.</span>
<span class="sd"> Args:</span>
<span class="sd"> source_object (Object): An object subscribing to one</span>
<span class="sd"> or more channels.</span>
<span class="sd"> Returns:</span>
<span class="sd"> cmdsets (list): The Channel-Cmdsets `source_object` has</span>
<span class="sd"> access to.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">source_object</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cached_cmdsets</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cached_cmdsets</span><span class="p">[</span><span class="n">source_object</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># create a new cmdset holding all viable channels</span>
<span class="n">chan_cmdset</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">chan_cmds</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">channelcmd</span>
<span class="k">for</span> <span class="n">channel</span><span class="p">,</span> <span class="n">channelcmd</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cached_channel_cmds</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="k">if</span> <span class="n">channel</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">has</span><span class="p">(</span><span class="n">source_object</span><span class="p">)</span>
<span class="ow">and</span> <span class="n">channelcmd</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">source_object</span><span class="p">,</span> <span class="s2">&quot;send&quot;</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">if</span> <span class="n">chan_cmds</span><span class="p">:</span>
<span class="n">chan_cmdset</span> <span class="o">=</span> <span class="n">cmdset</span><span class="o">.</span><span class="n">CmdSet</span><span class="p">()</span>
<span class="n">chan_cmdset</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;ChannelCmdSet&quot;</span>
<span class="n">chan_cmdset</span><span class="o">.</span><span class="n">priority</span> <span class="o">=</span> <span class="mi">101</span>
<span class="n">chan_cmdset</span><span class="o">.</span><span class="n">duplicates</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">for</span> <span class="n">cmd</span> <span class="ow">in</span> <span class="n">chan_cmds</span><span class="p">:</span>
<span class="n">chan_cmdset</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cached_cmdsets</span><span class="p">[</span><span class="n">source_object</span><span class="p">]</span> <span class="o">=</span> <span class="n">chan_cmdset</span>
<span class="k">return</span> <span class="n">chan_cmdset</span></div></div>
<span class="c1"># set up the singleton</span>
<span class="n">CHANNEL_HANDLER</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">CHANNEL_HANDLER_CLASS</span><span class="p">)()</span>
<span class="n">CHANNELHANDLER</span> <span class="o">=</span> <span class="n">CHANNEL_HANDLER</span> <span class="c1"># legacy</span>
</pre></div>
<div class="clearer"></div>
</div>
</div>
</div>
<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">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
<a href="https://discord.gg/NecFePw">Discord</a> -
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
</li>
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="channelhandler.html">1.0-dev (develop 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="clearer"></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 1.0-dev</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.comms.channelhandler</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2020, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -54,18 +54,44 @@
<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">logger</span>
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">make_iter</span>
<span class="n">_CHANNEL_HANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<div class="viewcode-block" id="DefaultChannel"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel">[docs]</a><span class="k">class</span> <span class="nc">DefaultChannel</span><span class="p">(</span><span class="n">ChannelDB</span><span class="p">,</span> <span class="n">metaclass</span><span class="o">=</span><span class="n">TypeclassBase</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is the base class for all Channel Comms. Inherit from this to</span>
<span class="sd"> create different types of communication channels.</span>
<span class="sd"> Class-level variables:</span>
<span class="sd"> - `send_to_online_only` (bool, default True) - if set, will only try to</span>
<span class="sd"> send to subscribers that are actually active. This is a useful optimization.</span>
<span class="sd"> - `log_file` (str, default `&quot;channel_{channelname}.log&quot;`). This is the</span>
<span class="sd"> log file to which the channel history will be saved. The `{channelname}` tag</span>
<span class="sd"> will be replaced by the key of the Channel. If an Attribute &#39;log_file&#39;</span>
<span class="sd"> is set, this will be used instead. If this is None and no Attribute is found,</span>
<span class="sd"> no history will be saved.</span>
<span class="sd"> - `channel_prefix_string` (str, default `&quot;[{channelname} ]&quot;`) - this is used</span>
<span class="sd"> as a simple template to get the channel prefix with `.channel_prefix()`.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">objects</span> <span class="o">=</span> <span class="n">ChannelManager</span><span class="p">()</span>
<span class="c1"># channel configuration</span>
<span class="c1"># only send to characters/accounts who has an active session (this is a</span>
<span class="c1"># good optimization since people can still recover history separately).</span>
<span class="n">send_to_online_only</span> <span class="o">=</span> <span class="kc">True</span>
<span class="c1"># store log in log file. `channel_key tag will be replace with key of channel.</span>
<span class="c1"># Will use log_file Attribute first, if given</span>
<span class="n">log_file</span> <span class="o">=</span> <span class="s2">&quot;channel_</span><span class="si">{channelname}</span><span class="s2">.log&quot;</span>
<span class="c1"># which prefix to use when showing were a message is coming from. Set to</span>
<span class="c1"># None to disable and set this later.</span>
<span class="n">channel_prefix_string</span> <span class="o">=</span> <span class="s2">&quot;[</span><span class="si">{channelname}</span><span class="s2">] &quot;</span>
<span class="c1"># default nick-alias replacements (default using the &#39;channel&#39; command)</span>
<span class="n">channel_msg_nick_pattern</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">&quot;</span><span class="si">{alias}</span><span class="s2">\s*?|</span><span class="si">{alias}</span><span class="s2">\s+?(?P&lt;arg1&gt;.+?)&quot;</span>
<span class="n">channel_msg_nick_replacement</span> <span class="o">=</span> <span class="s2">&quot;channel </span><span class="si">{channelname}</span><span class="s2"> = $1&quot;</span>
<div class="viewcode-block" id="DefaultChannel.at_first_save"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.at_first_save">[docs]</a> <span class="k">def</span> <span class="nf">at_first_save</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called by the typeclass system the very first time the channel</span>
@ -75,7 +101,6 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">basetype_setup</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_channel_creation</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;log_file&quot;</span><span class="p">,</span> <span class="s2">&quot;channel_</span><span class="si">%s</span><span class="s2">.log&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;_createdict&quot;</span><span class="p">):</span>
<span class="c1"># this is only set if the channel was created</span>
<span class="c1"># with the utils.create.create_channel function.</span>
@ -97,14 +122,11 @@
<span class="bp">self</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">batch_add</span><span class="p">(</span><span class="o">*</span><span class="n">cdict</span><span class="p">[</span><span class="s2">&quot;tags&quot;</span><span class="p">])</span></div>
<div class="viewcode-block" id="DefaultChannel.basetype_setup"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.basetype_setup">[docs]</a> <span class="k">def</span> <span class="nf">basetype_setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># delayed import of the channelhandler</span>
<span class="k">global</span> <span class="n">_CHANNEL_HANDLER</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_CHANNEL_HANDLER</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">evennia.comms.channelhandler</span> <span class="kn">import</span> <span class="n">CHANNEL_HANDLER</span> <span class="k">as</span> <span class="n">_CHANNEL_HANDLER</span>
<span class="c1"># register ourselves with the channelhandler.</span>
<span class="n">_CHANNEL_HANDLER</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="bp">self</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="s2">&quot;send:all();listen:all();control:perm(Admin)&quot;</span><span class="p">)</span>
<span class="bp">self</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="s2">&quot;send:all();listen:all();control:perm(Admin)&quot;</span><span class="p">)</span></div>
<span class="c1"># make sure we don&#39;t have access to a same-named old channel&#39;s history.</span>
<span class="n">log_file</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_log_filename</span><span class="p">()</span>
<span class="n">logger</span><span class="o">.</span><span class="n">rotate_log_file</span><span class="p">(</span><span class="n">log_file</span><span class="p">,</span> <span class="n">num_lines_to_append</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.at_channel_creation"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.at_channel_creation">[docs]</a> <span class="k">def</span> <span class="nf">at_channel_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -115,6 +137,33 @@
<span class="c1"># helper methods, for easy overloading</span>
<span class="n">_log_file</span> <span class="o">=</span> <span class="kc">None</span>
<div class="viewcode-block" id="DefaultChannel.get_log_filename"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.get_log_filename">[docs]</a> <span class="k">def</span> <span class="nf">get_log_filename</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> File name to use for channel log.</span>
<span class="sd"> Returns:</span>
<span class="sd"> str: The filename to use (this is always assumed to be inside</span>
<span class="sd"> settings.LOG_DIR)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_file</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_log_file</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
<span class="s2">&quot;log_file&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">log_file</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">channelname</span><span class="o">=</span><span class="bp">self</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="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_file</span></div>
<div class="viewcode-block" id="DefaultChannel.set_log_filename"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.set_log_filename">[docs]</a> <span class="k">def</span> <span class="nf">set_log_filename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Set a custom log filename.</span>
<span class="sd"> Args:</span>
<span class="sd"> filename (str): The filename to set. This is a path starting from</span>
<span class="sd"> inside the settings.LOG_DIR location.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;log_file&quot;</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.has_connection"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.has_connection">[docs]</a> <span class="k">def</span> <span class="nf">has_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subscriber</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Checks so this account is actually listening</span>
@ -143,6 +192,10 @@
<span class="k">def</span> <span class="nf">mutelist</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">mute_list</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">banlist</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ban_list</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">wholist</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">subs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
@ -171,6 +224,10 @@
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if muting was successful, False if we were already</span>
<span class="sd"> muted.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">mutelist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mutelist</span>
<span class="k">if</span> <span class="n">subscriber</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">mutelist</span><span class="p">:</span>
@ -181,19 +238,67 @@
<div class="viewcode-block" id="DefaultChannel.unmute"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.unmute">[docs]</a> <span class="k">def</span> <span class="nf">unmute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subscriber</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Removes an entity to the list of muted subscribers. A muted subscriber will no longer see channel messages,</span>
<span class="sd"> but may use channel commands.</span>
<span class="sd"> Removes an entity from the list of muted subscribers. A muted subscriber</span>
<span class="sd"> will no longer see channel messages, but may use channel commands.</span>
<span class="sd"> Args:</span>
<span class="sd"> subscriber (Object or Account): The subscriber to unmute.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if unmuting was successful, False if we were already</span>
<span class="sd"> unmuted.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">mutelist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mutelist</span>
<span class="k">if</span> <span class="n">subscriber</span> <span class="ow">in</span> <span class="n">mutelist</span><span class="p">:</span>
<span class="n">mutelist</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">subscriber</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">mute_list</span> <span class="o">=</span> <span class="n">mutelist</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="DefaultChannel.ban"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.ban">[docs]</a> <span class="k">def</span> <span class="nf">ban</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Ban a given user from connecting to the channel. This will not stop</span>
<span class="sd"> users already connected, so the user must be booted for this to take</span>
<span class="sd"> effect.</span>
<span class="sd"> Args:</span>
<span class="sd"> target (Object or Account): The entity to unmute. This need not</span>
<span class="sd"> be a subscriber.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if banning was successful, False if target was already</span>
<span class="sd"> banned.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">banlist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">banlist</span>
<span class="k">if</span> <span class="n">target</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">banlist</span><span class="p">:</span>
<span class="n">banlist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ban_list</span> <span class="o">=</span> <span class="n">banlist</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="DefaultChannel.unban"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.unban">[docs]</a> <span class="k">def</span> <span class="nf">unban</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Un-Ban a given user. This will not reconnect them - they will still</span>
<span class="sd"> have to reconnect and set up aliases anew.</span>
<span class="sd"> Args:</span>
<span class="sd"> target (Object or Account): The entity to unmute. This need not</span>
<span class="sd"> be a subscriber.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if unbanning was successful, False if target was not</span>
<span class="sd"> previously banned.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">banlist</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">banlist</span><span class="p">)</span>
<span class="k">if</span> <span class="n">target</span> <span class="ow">in</span> <span class="n">banlist</span><span class="p">:</span>
<span class="n">banlist</span> <span class="o">=</span> <span class="p">[</span><span class="n">banned</span> <span class="k">for</span> <span class="n">banned</span> <span class="ow">in</span> <span class="n">banlist</span> <span class="k">if</span> <span class="n">banned</span> <span class="o">!=</span> <span class="n">target</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ban_list</span> <span class="o">=</span> <span class="n">banlist</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span></div>
@ -213,7 +318,7 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># check access</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">subscriber</span><span class="p">,</span> <span class="s2">&quot;listen&quot;</span><span class="p">):</span>
<span class="k">if</span> <span class="n">subscriber</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">banlist</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">subscriber</span><span class="p">,</span> <span class="s2">&quot;listen&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="c1"># pre-join hook</span>
<span class="n">connect</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pre_join_channel</span><span class="p">(</span><span class="n">subscriber</span><span class="p">)</span>
@ -286,7 +391,7 @@
<span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.create"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.create">[docs]</a> <span class="nd">@classmethod</span>
<span class="k">def</span> <span class="nf">create</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">account</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">create</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">creator</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Creates a basic Channel with default parameters, unless otherwise</span>
<span class="sd"> specified or extended.</span>
@ -295,7 +400,8 @@
<span class="sd"> Args:</span>
<span class="sd"> key (str): This must be unique.</span>
<span class="sd"> account (Account): Account to attribute this object to.</span>
<span class="sd"> creator (Account or Object): Entity to associate with this channel</span>
<span class="sd"> (used for tracking)</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> aliases (list of str): List of alternative (likely shorter) keynames.</span>
@ -323,8 +429,8 @@
<span class="c1"># Record creator id and creation IP</span>
<span class="k">if</span> <span class="n">ip</span><span class="p">:</span>
<span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">creator_ip</span> <span class="o">=</span> <span class="n">ip</span>
<span class="k">if</span> <span class="n">account</span><span class="p">:</span>
<span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">creator_id</span> <span class="o">=</span> <span class="n">account</span><span class="o">.</span><span class="n">id</span>
<span class="k">if</span> <span class="n">creator</span><span class="p">:</span>
<span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">creator_id</span> <span class="o">=</span> <span class="n">creator</span><span class="o">.</span><span class="n">id</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;An error occurred while creating this &#39;</span><span class="si">%s</span><span class="s2">&#39; object.&quot;</span> <span class="o">%</span> <span class="n">key</span><span class="p">)</span>
@ -334,284 +440,189 @@
<div class="viewcode-block" id="DefaultChannel.delete"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.delete">[docs]</a> <span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Deletes channel while also cleaning up channelhandler.</span>
<span class="sd"> Deletes channel.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">aliases</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="kn">from</span> <span class="nn">evennia.comms.channelhandler</span> <span class="kn">import</span> <span class="n">CHANNELHANDLER</span>
<span class="k">for</span> <span class="n">subscriber</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">all</span><span class="p">():</span>
<span class="bp">self</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">subscriber</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span></div>
<span class="n">CHANNELHANDLER</span><span class="o">.</span><span class="n">update</span><span class="p">()</span></div>
<div class="viewcode-block" id="DefaultChannel.message_transform"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.message_transform">[docs]</a> <span class="k">def</span> <span class="nf">message_transform</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="n">msgobj</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">sender_strings</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">external</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Generates the formatted string sent to listeners on a channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> msgobj (Msg): Message object to send.</span>
<span class="sd"> emit (bool, optional): In emit mode the message is not associated</span>
<span class="sd"> with a specific sender name.</span>
<span class="sd"> prefix (bool, optional): Prefix `msg` with a text given by `self.channel_prefix`.</span>
<span class="sd"> sender_strings (list, optional): Used by bots etc, one string per external sender.</span>
<span class="sd"> external (bool, optional): If this is an external sender or not.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">sender_strings</span> <span class="ow">or</span> <span class="n">external</span><span class="p">:</span>
<span class="n">body</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_external</span><span class="p">(</span><span class="n">msgobj</span><span class="p">,</span> <span class="n">sender_strings</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="n">emit</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">body</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_message</span><span class="p">(</span><span class="n">msgobj</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="n">emit</span><span class="p">)</span>
<span class="k">if</span> <span class="n">prefix</span><span class="p">:</span>
<span class="n">body</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">channel_prefix</span><span class="p">(</span><span class="n">msgobj</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="n">emit</span><span class="p">),</span> <span class="n">body</span><span class="p">)</span>
<span class="n">msgobj</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">body</span>
<span class="k">return</span> <span class="n">msgobj</span></div>
<div class="viewcode-block" id="DefaultChannel.distribute_message"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.distribute_message">[docs]</a> <span class="k">def</span> <span class="nf">distribute_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msgobj</span><span class="p">,</span> <span class="n">online</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Method for grabbing all listeners that a message should be</span>
<span class="sd"> sent to on this channel, and sending them a message.</span>
<span class="sd"> Args:</span>
<span class="sd"> msgobj (Msg or TempMsg): Message to distribute.</span>
<span class="sd"> online (bool): Only send to receivers who are actually online</span>
<span class="sd"> (not currently used):</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Notes:</span>
<span class="sd"> This is also where logging happens, if enabled.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># get all accounts or objects connected to this channel and send to them</span>
<span class="k">if</span> <span class="n">online</span><span class="p">:</span>
<span class="n">subs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">online</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">subs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="k">for</span> <span class="n">entity</span> <span class="ow">in</span> <span class="n">subs</span><span class="p">:</span>
<span class="c1"># if the entity is muted, we don&#39;t send them a message</span>
<span class="k">if</span> <span class="n">entity</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mutelist</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># note our addition of the from_channel keyword here. This could be checked</span>
<span class="c1"># by a custom account.msg() to treat channel-receives differently.</span>
<span class="n">entity</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span>
<span class="n">msgobj</span><span class="o">.</span><span class="n">message</span><span class="p">,</span> <span class="n">from_obj</span><span class="o">=</span><span class="n">msgobj</span><span class="o">.</span><span class="n">senders</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;from_channel&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">}</span>
<span class="p">)</span>
<span class="k">except</span> <span class="ne">AttributeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="se">\n</span><span class="s2">Cannot send msg to &#39;</span><span class="si">%s</span><span class="s2">&#39;.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">entity</span><span class="p">))</span>
<span class="k">if</span> <span class="n">msgobj</span><span class="o">.</span><span class="n">keep_log</span><span class="p">:</span>
<span class="c1"># log to file</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_file</span><span class="p">(</span>
<span class="n">msgobj</span><span class="o">.</span><span class="n">message</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;log_file&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="s2">&quot;channel_</span><span class="si">%s</span><span class="s2">.log&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.msg"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.msg">[docs]</a> <span class="k">def</span> <span class="nf">msg</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">msgobj</span><span class="p">,</span>
<span class="n">header</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">senders</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">sender_strings</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">keep_log</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">online</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">emit</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">external</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Send the given message to all accounts connected to channel. Note that</span>
<span class="sd"> no permission-checking is done here; it is assumed to have been</span>
<span class="sd"> done before calling this method. The optional keywords are not used if</span>
<span class="sd"> persistent is False.</span>
<span class="sd"> Args:</span>
<span class="sd"> msgobj (Msg, TempMsg or str): If a Msg/TempMsg, the remaining</span>
<span class="sd"> keywords will be ignored (since the Msg/TempMsg object already</span>
<span class="sd"> has all the data). If a string, this will either be sent as-is</span>
<span class="sd"> (if persistent=False) or it will be used together with `header`</span>
<span class="sd"> and `senders` keywords to create a Msg instance on the fly.</span>
<span class="sd"> header (str, optional): A header for building the message.</span>
<span class="sd"> senders (Object, Account or list, optional): Optional if persistent=False, used</span>
<span class="sd"> to build senders for the message.</span>
<span class="sd"> sender_strings (list, optional): Name strings of senders. Used for external</span>
<span class="sd"> connections where the sender is not an account or object.</span>
<span class="sd"> When this is defined, external will be assumed. The list will be </span>
<span class="sd"> filtered so each sender-string only occurs once.</span>
<span class="sd"> keep_log (bool or None, optional): This allows to temporarily change the logging status of</span>
<span class="sd"> this channel message. If `None`, the Channel&#39;s `keep_log` Attribute will</span>
<span class="sd"> be used. If `True` or `False`, that logging status will be used for this</span>
<span class="sd"> message only (note that for unlogged channels, a `True` value here will</span>
<span class="sd"> create a new log file only for this message).</span>
<span class="sd"> online (bool, optional) - If this is set true, only messages people who are</span>
<span class="sd"> online. Otherwise, messages all accounts connected. This can</span>
<span class="sd"> make things faster, but may not trigger listeners on accounts</span>
<span class="sd"> that are offline.</span>
<span class="sd"> emit (bool, optional) - Signals to the message formatter that this message is</span>
<span class="sd"> not to be directly associated with a name.</span>
<span class="sd"> external (bool, optional): Treat this message as being</span>
<span class="sd"> agnostic of its sender.</span>
<span class="sd"> Returns:</span>
<span class="sd"> success (bool): Returns `True` if message sending was</span>
<span class="sd"> successful, `False` otherwise.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">senders</span> <span class="o">=</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">senders</span><span class="p">)</span> <span class="k">if</span> <span class="n">senders</span> <span class="k">else</span> <span class="p">[]</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">msgobj</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="c1"># given msgobj is a string - convert to msgobject (always TempMsg)</span>
<span class="n">msgobj</span> <span class="o">=</span> <span class="n">TempMsg</span><span class="p">(</span><span class="n">senders</span><span class="o">=</span><span class="n">senders</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="n">header</span><span class="p">,</span> <span class="n">message</span><span class="o">=</span><span class="n">msgobj</span><span class="p">,</span> <span class="n">channels</span><span class="o">=</span><span class="p">[</span><span class="bp">self</span><span class="p">])</span>
<span class="c1"># we store the logging setting for use in distribute_message()</span>
<span class="n">msgobj</span><span class="o">.</span><span class="n">keep_log</span> <span class="o">=</span> <span class="n">keep_log</span> <span class="k">if</span> <span class="n">keep_log</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">keep_log</span>
<span class="c1"># start the sending</span>
<span class="n">msgobj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pre_send_message</span><span class="p">(</span><span class="n">msgobj</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">msgobj</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">sender_strings</span><span class="p">:</span>
<span class="n">sender_strings</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">make_iter</span><span class="p">(</span><span class="n">sender_strings</span><span class="p">)))</span>
<span class="n">msgobj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">message_transform</span><span class="p">(</span>
<span class="n">msgobj</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="n">emit</span><span class="p">,</span> <span class="n">sender_strings</span><span class="o">=</span><span class="n">sender_strings</span><span class="p">,</span> <span class="n">external</span><span class="o">=</span><span class="n">external</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">distribute_message</span><span class="p">(</span><span class="n">msgobj</span><span class="p">,</span> <span class="n">online</span><span class="o">=</span><span class="n">online</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">post_send_message</span><span class="p">(</span><span class="n">msgobj</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="DefaultChannel.tempmsg"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.tempmsg">[docs]</a> <span class="k">def</span> <span class="nf">tempmsg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A wrapper for sending non-persistent messages.</span>
<span class="sd"> Args:</span>
<span class="sd"> message (str): Message to send.</span>
<span class="sd"> header (str, optional): Header of message to send.</span>
<span class="sd"> senders (Object or list, optional): Senders of message to send.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="n">senders</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="n">header</span><span class="p">,</span> <span class="n">keep_log</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span></div>
<span class="c1"># hooks</span>
<div class="viewcode-block" id="DefaultChannel.channel_prefix"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.channel_prefix">[docs]</a> <span class="k">def</span> <span class="nf">channel_prefix</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<div class="viewcode-block" id="DefaultChannel.channel_prefix"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.channel_prefix">[docs]</a> <span class="k">def</span> <span class="nf">channel_prefix</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Hook method. How the channel should prefix itself for users.</span>
<span class="sd"> Args:</span>
<span class="sd"> msg (str, optional): Prefix text</span>
<span class="sd"> emit (bool, optional): Switches to emit mode, which usually</span>
<span class="sd"> means to not prefix the channel&#39;s info.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Returns:</span>
<span class="sd"> prefix (str): The created channel prefix.</span>
<span class="sd"> str: The channel prefix.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span> <span class="k">if</span> <span class="n">emit</span> <span class="k">else</span> <span class="s2">&quot;[</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">key</span></div>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel_prefix_string</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">channelname</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.format_senders"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.format_senders">[docs]</a> <span class="k">def</span> <span class="nf">format_senders</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<div class="viewcode-block" id="DefaultChannel.add_user_channel_alias"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.add_user_channel_alias">[docs]</a> <span class="k">def</span> <span class="nf">add_user_channel_alias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">alias</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Hook method. Function used to format a list of sender names.</span>
<span class="sd"> Add a personal user-alias for this channel to a given subscriber.</span>
<span class="sd"> Args:</span>
<span class="sd"> senders (list): Sender object names.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> user (Object or Account): The one to alias this channel.</span>
<span class="sd"> alias (str): The desired alias.</span>
<span class="sd"> Returns:</span>
<span class="sd"> formatted_list (str): The list of names formatted appropriately.</span>
<span class="sd"> Note:</span>
<span class="sd"> This is tightly coupled to the default `channel` command. If you</span>
<span class="sd"> change that, you need to change this as well.</span>
<span class="sd"> We add two nicks - one is a plain `alias -&gt; channel.key` that</span>
<span class="sd"> users need to be able to reference this channel easily. The other</span>
<span class="sd"> is a templated nick to easily be able to send messages to the</span>
<span class="sd"> channel without needing to give the full `channel` command. The</span>
<span class="sd"> structure of this nick is given by `self.channel_msg_nick_pattern`</span>
<span class="sd"> and `self.channel_msg_nick_replacement`. By default it maps</span>
<span class="sd"> `alias &lt;msg&gt; -&gt; channel &lt;channelname&gt; = &lt;msg&gt;`, so that you can</span>
<span class="sd"> for example just write `pub Hello` to send a message.</span>
<span class="sd"> The alias created is `alias $1 -&gt; channel channel = $1`, to allow</span>
<span class="sd"> for sending to channel using the main channel command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">chan_key</span> <span class="o">=</span> <span class="bp">self</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="c1"># the message-pattern allows us to type the channel on its own without</span>
<span class="c1"># needing to use the `channel` command explicitly.</span>
<span class="n">msg_nick_pattern</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel_msg_nick_pattern</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">alias</span><span class="o">=</span><span class="n">alias</span><span class="p">)</span>
<span class="n">msg_nick_replacement</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel_msg_nick_replacement</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">channelname</span><span class="o">=</span><span class="n">chan_key</span><span class="p">)</span>
<span class="n">user</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">msg_nick_pattern</span><span class="p">,</span> <span class="n">msg_nick_replacement</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">&quot;inputline&quot;</span><span class="p">,</span>
<span class="n">pattern_is_regex</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">chan_key</span> <span class="o">!=</span> <span class="n">alias</span><span class="p">:</span>
<span class="c1"># this allows for using the alias for general channel lookups</span>
<span class="n">user</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">chan_key</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">&quot;channel&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.remove_user_channel_alias"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.remove_user_channel_alias">[docs]</a> <span class="nd">@classmethod</span>
<span class="k">def</span> <span class="nf">remove_user_channel_alias</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">alias</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Remove a personal channel alias from a user.</span>
<span class="sd"> Args:</span>
<span class="sd"> user (Object or Account): The user to remove an alias from.</span>
<span class="sd"> alias (str): The alias to remove.</span>
<span class="sd"> **kwargs: Unused by default. Can be used to pass extra variables</span>
<span class="sd"> into a custom implementation.</span>
<span class="sd"> Notes:</span>
<span class="sd"> This function exists separately so that external sources</span>
<span class="sd"> can use it to format source names in the same manner as</span>
<span class="sd"> normal object/account names.</span>
<span class="sd"> The channel-alias actually consists of two aliases - one</span>
<span class="sd"> channel-based one for searching channels with the alias and one</span>
<span class="sd"> inputline one for doing the &#39;channelalias msg&#39; - call.</span>
<span class="sd"> This is a classmethod because it doesn&#39;t actually operate on the</span>
<span class="sd"> channel instance.</span>
<span class="sd"> It sits on the channel because the nick structure for this is</span>
<span class="sd"> pretty complex and needs to be located in a central place (rather</span>
<span class="sd"> on, say, the channel command).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">senders</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">senders</span><span class="p">)</span></div>
<span class="n">user</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">&quot;channel&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">msg_nick_pattern</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">channel_msg_nick_pattern</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">alias</span><span class="o">=</span><span class="n">alias</span><span class="p">)</span>
<span class="n">user</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">msg_nick_pattern</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">&quot;inputline&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.pose_transform"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.pose_transform">[docs]</a> <span class="k">def</span> <span class="nf">pose_transform</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msgobj</span><span class="p">,</span> <span class="n">sender_string</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<div class="viewcode-block" id="DefaultChannel.at_pre_msg"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.at_pre_msg">[docs]</a> <span class="k">def</span> <span class="nf">at_pre_msg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Hook method. Detects if the sender is posing, and modifies the</span>
<span class="sd"> message accordingly.</span>
<span class="sd"> Called before the starting of sending the message to a receiver. This</span>
<span class="sd"> is called before any hooks on the receiver itself. If this returns</span>
<span class="sd"> None/False, the sending will be aborted.</span>
<span class="sd"> Args:</span>
<span class="sd"> msgobj (Msg or TempMsg): The message to analyze for a pose.</span>
<span class="sd"> sender_string (str): The name of the sender/poser.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> message (str): The message to send.</span>
<span class="sd"> **kwargs (any): Keywords passed on from `.msg`. This includes</span>
<span class="sd"> `senders`.</span>
<span class="sd"> Returns:</span>
<span class="sd"> string (str): A message that combines the `sender_string`</span>
<span class="sd"> component with `msg` in different ways depending on if a</span>
<span class="sd"> pose was performed or not (this must be analyzed by the</span>
<span class="sd"> hook).</span>
<span class="sd"> str, False or None: Any custom changes made to the message. If</span>
<span class="sd"> falsy, no message will be sent.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">pose</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">msgobj</span><span class="o">.</span><span class="n">message</span>
<span class="n">message_start</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">lstrip</span><span class="p">()</span>
<span class="k">if</span> <span class="n">message_start</span><span class="o">.</span><span class="n">startswith</span><span class="p">((</span><span class="s2">&quot;:&quot;</span><span class="p">,</span> <span class="s2">&quot;;&quot;</span><span class="p">)):</span>
<span class="n">pose</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">message</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">startswith</span><span class="p">((</span><span class="s2">&quot;:&quot;</span><span class="p">,</span> <span class="s2">&quot;&#39;&quot;</span><span class="p">,</span> <span class="s2">&quot;,&quot;</span><span class="p">)):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">message</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">):</span>
<span class="n">message</span> <span class="o">=</span> <span class="s2">&quot; &quot;</span> <span class="o">+</span> <span class="n">message</span>
<span class="k">if</span> <span class="n">pose</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;</span><span class="si">%s%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">sender_string</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span>
<span class="k">return</span> <span class="n">message</span></div>
<div class="viewcode-block" id="DefaultChannel.msg"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.msg">[docs]</a> <span class="k">def</span> <span class="nf">msg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">bypass_mute</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Send message to channel, causing it to be distributed to all non-muted</span>
<span class="sd"> subscribed users of that channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> message (str): The message to send.</span>
<span class="sd"> senders (Object, Account or list, optional): If not given, there is</span>
<span class="sd"> no way to associate one or more senders with the message (like</span>
<span class="sd"> a broadcast message or similar).</span>
<span class="sd"> bypass_mute (bool, optional): If set, always send, regardless of</span>
<span class="sd"> individual mute-state of subscriber. This can be used for</span>
<span class="sd"> global announcements or warnings/alerts.</span>
<span class="sd"> **kwargs (any): This will be passed on to all hooks. Use `no_prefix`</span>
<span class="sd"> to exclude the channel prefix.</span>
<span class="sd"> Notes:</span>
<span class="sd"> The call hook calling sequence is:</span>
<span class="sd"> - `msg = channel.at_pre_msg(message, **kwargs)` (aborts for all if return None)</span>
<span class="sd"> - `msg = receiver.at_pre_channel_msg(msg, channel, **kwargs)` (aborts for receiver if return None)</span>
<span class="sd"> - `receiver.at_channel_msg(msg, channel, **kwargs)`</span>
<span class="sd"> - `receiver.at_post_channel_msg(msg, channel, **kwargs)``</span>
<span class="sd"> Called after all receivers are processed:</span>
<span class="sd"> - `channel.at_post_all_msg(message, **kwargs)`</span>
<span class="sd"> (where the senders/bypass_mute are embedded into **kwargs for</span>
<span class="sd"> later access in hooks)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">senders</span> <span class="o">=</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">senders</span><span class="p">)</span> <span class="k">if</span> <span class="n">senders</span> <span class="k">else</span> <span class="p">[]</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">send_to_online_only</span><span class="p">:</span>
<span class="n">receivers</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">online</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">sender_string</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span></div>
<span class="n">receivers</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subscriptions</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">bypass_mute</span><span class="p">:</span>
<span class="n">receivers</span> <span class="o">=</span> <span class="p">[</span><span class="n">receiver</span> <span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="n">receivers</span> <span class="k">if</span> <span class="n">receiver</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mutelist</span><span class="p">]</span>
<div class="viewcode-block" id="DefaultChannel.format_external"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.format_external">[docs]</a> <span class="k">def</span> <span class="nf">format_external</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msgobj</span><span class="p">,</span> <span class="n">senders</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="n">send_kwargs</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;senders&#39;</span><span class="p">:</span> <span class="n">senders</span><span class="p">,</span> <span class="s1">&#39;bypass_mute&#39;</span><span class="p">:</span> <span class="n">bypass_mute</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">}</span>
<span class="c1"># pre-send hook</span>
<span class="n">message</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">at_pre_msg</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">send_kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">message</span> <span class="ow">in</span> <span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
<span class="k">return</span>
<span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="n">receivers</span><span class="p">:</span>
<span class="c1"># send to each individual subscriber</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">recv_message</span> <span class="o">=</span> <span class="n">receiver</span><span class="o">.</span><span class="n">at_pre_channel_msg</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">send_kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">recv_message</span> <span class="ow">in</span> <span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
<span class="k">return</span>
<span class="n">receiver</span><span class="o">.</span><span class="n">channel_msg</span><span class="p">(</span><span class="n">recv_message</span><span class="p">,</span> <span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">send_kwargs</span><span class="p">)</span>
<span class="n">receiver</span><span class="o">.</span><span class="n">at_post_channel_msg</span><span class="p">(</span><span class="n">recv_message</span><span class="p">,</span> <span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">send_kwargs</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error sending channel message to </span><span class="si">{</span><span class="n">receiver</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="c1"># post-send hook</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_post_msg</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">send_kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.at_post_msg"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.at_post_msg">[docs]</a> <span class="k">def</span> <span class="nf">at_post_msg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Hook method. Used for formatting external messages. This is</span>
<span class="sd"> needed as a separate operation because the senders of external</span>
<span class="sd"> messages may not be in-game objects/accounts, and so cannot</span>
<span class="sd"> have things like custom user preferences.</span>
<span class="sd"> This is called after sending to *all* valid recipients. It is normally</span>
<span class="sd"> used for logging/channel history.</span>
<span class="sd"> Args:</span>
<span class="sd"> msgobj (Msg or TempMsg): The message to send.</span>
<span class="sd"> senders (list): Strings, one per sender.</span>
<span class="sd"> emit (bool, optional): A sender-agnostic message or not.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Returns:</span>
<span class="sd"> transformed (str): A formatted string.</span>
<span class="sd"> message (str): The message sent.</span>
<span class="sd"> **kwargs (any): Keywords passed on from `msg`, including `senders`.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">emit</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">senders</span><span class="p">:</span>
<span class="k">return</span> <span class="n">msgobj</span><span class="o">.</span><span class="n">message</span>
<span class="n">senders</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">senders</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pose_transform</span><span class="p">(</span><span class="n">msgobj</span><span class="p">,</span> <span class="n">senders</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.format_message"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.format_message">[docs]</a> <span class="k">def</span> <span class="nf">format_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msgobj</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Hook method. Formats a message body for display.</span>
<span class="sd"> Args:</span>
<span class="sd"> msgobj (Msg or TempMsg): The message object to send.</span>
<span class="sd"> emit (bool, optional): The message is agnostic of senders.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Returns:</span>
<span class="sd"> transformed (str): The formatted message.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># We don&#39;t want to count things like external sources as senders for</span>
<span class="c1"># the purpose of constructing the message string.</span>
<span class="n">senders</span> <span class="o">=</span> <span class="p">[</span><span class="n">sender</span> <span class="k">for</span> <span class="n">sender</span> <span class="ow">in</span> <span class="n">msgobj</span><span class="o">.</span><span class="n">senders</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="s2">&quot;key&quot;</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">senders</span><span class="p">:</span>
<span class="n">emit</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="n">emit</span><span class="p">:</span>
<span class="k">return</span> <span class="n">msgobj</span><span class="o">.</span><span class="n">message</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">senders</span> <span class="o">=</span> <span class="p">[</span><span class="n">sender</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">sender</span> <span class="ow">in</span> <span class="n">msgobj</span><span class="o">.</span><span class="n">senders</span><span class="p">]</span>
<span class="n">senders</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">senders</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">pose_transform</span><span class="p">(</span><span class="n">msgobj</span><span class="p">,</span> <span class="n">senders</span><span class="p">)</span></div>
<span class="c1"># save channel history to log file</span>
<span class="n">log_file</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_log_filename</span><span class="p">()</span>
<span class="k">if</span> <span class="n">log_file</span><span class="p">:</span>
<span class="n">senders</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">sender</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">sender</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;senders&quot;</span><span class="p">,</span> <span class="p">[]))</span>
<span class="n">senders</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">senders</span><span class="si">}</span><span class="s2">: &quot;</span> <span class="k">if</span> <span class="n">senders</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="n">message</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">senders</span><span class="si">}{</span><span class="n">message</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_file</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">log_file</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.pre_join_channel"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.pre_join_channel">[docs]</a> <span class="k">def</span> <span class="nf">pre_join_channel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">joiner</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -638,8 +649,13 @@
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Notes:</span>
<span class="sd"> By default this adds the needed channel nicks to the joiner.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<span class="n">key_and_aliases</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</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="p">[</span><span class="n">alias</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="bp">self</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="k">for</span> <span class="n">key_or_alias</span> <span class="ow">in</span> <span class="n">key_and_aliases</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_user_channel_alias</span><span class="p">(</span><span class="n">joiner</span><span class="p">,</span> <span class="n">key_or_alias</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.pre_leave_channel"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.pre_leave_channel">[docs]</a> <span class="k">def</span> <span class="nf">pre_leave_channel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">leaver</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -667,36 +683,12 @@
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="DefaultChannel.pre_send_message"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.pre_send_message">[docs]</a> <span class="k">def</span> <span class="nf">pre_send_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Hook method. Runs before a message is sent to the channel and</span>
<span class="sd"> should return the message object, after any transformations.</span>
<span class="sd"> If the message is to be discarded, return a false value.</span>
<span class="sd"> Args:</span>
<span class="sd"> msg (Msg or TempMsg): Message to send.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> Returns:</span>
<span class="sd"> result (Msg, TempMsg or bool): If False, abort send.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">msg</span></div>
<div class="viewcode-block" id="DefaultChannel.post_send_message"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.post_send_message">[docs]</a> <span class="k">def</span> <span class="nf">post_send_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Hook method. Run after a message is sent to the channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> msg (Msg or TempMsg): Message sent.</span>
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
<span class="sd"> overriding the call (unused by default).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<span class="n">chan_key</span> <span class="o">=</span> <span class="bp">self</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="n">key_or_aliases</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</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="p">[</span><span class="n">alias</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="bp">self</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">nicktuples</span> <span class="o">=</span> <span class="n">leaver</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">category</span><span class="o">=</span><span class="s2">&quot;channel&quot;</span><span class="p">,</span> <span class="n">return_tuple</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">return_list</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">key_or_aliases</span> <span class="o">+=</span> <span class="p">[</span><span class="n">tup</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">for</span> <span class="n">tup</span> <span class="ow">in</span> <span class="n">nicktuples</span> <span class="k">if</span> <span class="n">tup</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="n">chan_key</span><span class="p">]</span>
<span class="k">for</span> <span class="n">key_or_alias</span> <span class="ow">in</span> <span class="n">key_or_aliases</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove_user_channel_alias</span><span class="p">(</span><span class="n">leaver</span><span class="p">,</span> <span class="n">key_or_alias</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.at_init"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.at_init">[docs]</a> <span class="k">def</span> <span class="nf">at_init</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -861,7 +853,37 @@
<span class="k">return</span> <span class="s2">&quot;#&quot;</span></div>
<span class="c1"># Used by Django Sites/Admin</span>
<span class="n">get_absolute_url</span> <span class="o">=</span> <span class="n">web_get_detail_url</span></div>
<span class="n">get_absolute_url</span> <span class="o">=</span> <span class="n">web_get_detail_url</span>
<span class="c1"># TODO Evennia 1.0+ removed hooks. Remove in 1.1.</span>
<div class="viewcode-block" id="DefaultChannel.message_transform"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.message_transform">[docs]</a> <span class="k">def</span> <span class="nf">message_transform</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Channel.message_transform is no longer used in 1.0+. &quot;</span>
<span class="s2">&quot;Use Account/Object.at_pre_channel_msg instead.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.distribute_message"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.distribute_message">[docs]</a> <span class="k">def</span> <span class="nf">distribute_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msgobj</span><span class="p">,</span> <span class="n">online</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Channel.distribute_message is no longer used in 1.0+.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.format_senders"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.format_senders">[docs]</a> <span class="k">def</span> <span class="nf">format_senders</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Channel.format_senders is no longer used in 1.0+. &quot;</span>
<span class="s2">&quot;Use Account/Object.at_pre_channel_msg instead.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.pose_transform"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.pose_transform">[docs]</a> <span class="k">def</span> <span class="nf">pose_transform</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msgobj</span><span class="p">,</span> <span class="n">sender_string</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Channel.pose_transform is no longer used in 1.0+. &quot;</span>
<span class="s2">&quot;Use Account/Object.at_pre_channel_msg instead.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.format_external"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.format_external">[docs]</a> <span class="k">def</span> <span class="nf">format_external</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msgobj</span><span class="p">,</span> <span class="n">senders</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Channel.format_external is no longer used in 1.0+. &quot;</span>
<span class="s2">&quot;Use Account/Object.at_pre_channel_msg instead.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.format_message"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.format_message">[docs]</a> <span class="k">def</span> <span class="nf">format_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msgobj</span><span class="p">,</span> <span class="n">emit</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Channel.format_message is no longer used in 1.0+. &quot;</span>
<span class="s2">&quot;Use Account/Object.at_pre_channel_msg instead.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.pre_send_message"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.pre_send_message">[docs]</a> <span class="k">def</span> <span class="nf">pre_send_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Channel.pre_send_message was renamed to Channel.at_pre_msg.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="DefaultChannel.post_send_message"><a class="viewcode-back" href="../../../api/evennia.comms.comms.html#evennia.comms.comms.DefaultChannel.post_send_message">[docs]</a> <span class="k">def</span> <span class="nf">post_send_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Channel.post_send_message was renamed to Channel.at_post_msg.&quot;</span><span class="p">)</span></div></div>
</pre></div>
<div class="clearer"></div>

View file

@ -56,6 +56,7 @@
<span class="n">_AccountDB</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_ObjectDB</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_ChannelDB</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_ScriptDB</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_SESSIONS</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># error class</span>
@ -96,6 +97,8 @@
<span class="k">return</span> <span class="n">inp</span><span class="p">,</span> <span class="s2">&quot;object&quot;</span>
<span class="k">elif</span> <span class="n">clsname</span> <span class="o">==</span> <span class="s2">&quot;ChannelDB&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">inp</span><span class="p">,</span> <span class="s2">&quot;channel&quot;</span>
<span class="k">elif</span> <span class="n">clsname</span> <span class="o">==</span> <span class="s2">&quot;ScriptDB&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">inp</span><span class="p">,</span> <span class="s2">&quot;script&quot;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inp</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="k">return</span> <span class="n">inp</span><span class="p">,</span> <span class="s2">&quot;string&quot;</span>
<span class="k">elif</span> <span class="n">dbref</span><span class="p">(</span><span class="n">inp</span><span class="p">):</span>
@ -145,6 +148,14 @@
<span class="k">return</span> <span class="n">_ChannelDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_err</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">objtype</span><span class="p">,</span> <span class="n">inp</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">typ</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">inp</span><span class="p">)))</span>
<span class="k">raise</span> <span class="n">CommError</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">objtype</span> <span class="o">==</span> <span class="s2">&quot;script&quot;</span><span class="p">:</span>
<span class="k">if</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;string&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">_ScriptDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">db_key__iexact</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span>
<span class="k">if</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;dbref&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">_ScriptDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_err</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">objtype</span><span class="p">,</span> <span class="n">inp</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">typ</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">inp</span><span class="p">)))</span>
<span class="k">raise</span> <span class="n">CommError</span><span class="p">()</span>
<span class="c1"># an unknown</span>
<span class="k">return</span> <span class="kc">None</span></div>
@ -200,48 +211,30 @@
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span></div>
<div class="viewcode-block" id="MsgManager.get_messages_by_sender"><a class="viewcode-back" href="../../../api/evennia.comms.managers.html#evennia.comms.comms.MsgManager.get_messages_by_sender">[docs]</a> <span class="k">def</span> <span class="nf">get_messages_by_sender</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">exclude_channel_messages</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<div class="viewcode-block" id="MsgManager.get_messages_by_sender"><a class="viewcode-back" href="../../../api/evennia.comms.managers.html#evennia.comms.comms.MsgManager.get_messages_by_sender">[docs]</a> <span class="k">def</span> <span class="nf">get_messages_by_sender</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get all messages sent by one entity - this could be either a</span>
<span class="sd"> account or an object</span>
<span class="sd"> Args:</span>
<span class="sd"> sender (Account or Object): The sender of the message.</span>
<span class="sd"> exclude_channel_messages (bool, optional): Only return messages</span>
<span class="sd"> not aimed at a channel (that is, private tells for example)</span>
<span class="sd"> Returns:</span>
<span class="sd"> messages (list): List of matching messages</span>
<span class="sd"> QuerySet: Matching messages.</span>
<span class="sd"> Raises:</span>
<span class="sd"> CommError: For incorrect sender types.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">obj</span><span class="p">,</span> <span class="n">typ</span> <span class="o">=</span> <span class="n">identify_object</span><span class="p">(</span><span class="n">sender</span><span class="p">)</span>
<span class="k">if</span> <span class="n">exclude_channel_messages</span><span class="p">:</span>
<span class="c1"># explicitly exclude channel recipients</span>
<span class="k">if</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;account&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_sender_accounts</span><span class="o">=</span><span class="n">obj</span><span class="p">,</span> <span class="n">db_receivers_channels__isnull</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span>
<span class="n">db_hide_from_accounts</span><span class="o">=</span><span class="n">obj</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">elif</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;object&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_sender_objects</span><span class="o">=</span><span class="n">obj</span><span class="p">,</span> <span class="n">db_receivers_channels__isnull</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span>
<span class="n">db_hide_from_objects</span><span class="o">=</span><span class="n">obj</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CommError</span>
<span class="k">if</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;account&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_sender_accounts</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_accounts</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;object&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_sender_objects</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_objects</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;script&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_sender_scripts</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># get everything, channel or not</span>
<span class="k">if</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;account&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_sender_accounts</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_accounts</span><span class="o">=</span><span class="n">obj</span><span class="p">))</span>
<span class="k">elif</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;object&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_sender_objects</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_objects</span><span class="o">=</span><span class="n">obj</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CommError</span></div>
<span class="k">raise</span> <span class="n">CommError</span></div>
<div class="viewcode-block" id="MsgManager.get_messages_by_receiver"><a class="viewcode-back" href="../../../api/evennia.comms.managers.html#evennia.comms.comms.MsgManager.get_messages_by_receiver">[docs]</a> <span class="k">def</span> <span class="nf">get_messages_by_receiver</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">recipient</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -251,7 +244,7 @@
<span class="sd"> recipient (Object, Account or Channel): The recipient of the messages to search for.</span>
<span class="sd"> Returns:</span>
<span class="sd"> messages (list): Matching messages.</span>
<span class="sd"> Queryset: Matching messages.</span>
<span class="sd"> Raises:</span>
<span class="sd"> CommError: If the `recipient` is not of a valid type.</span>
@ -259,26 +252,14 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">obj</span><span class="p">,</span> <span class="n">typ</span> <span class="o">=</span> <span class="n">identify_object</span><span class="p">(</span><span class="n">recipient</span><span class="p">)</span>
<span class="k">if</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;account&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_receivers_accounts</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_accounts</span><span class="o">=</span><span class="n">obj</span><span class="p">))</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_receivers_accounts</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_accounts</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;object&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_receivers_objects</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_objects</span><span class="o">=</span><span class="n">obj</span><span class="p">))</span>
<span class="k">elif</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;channel&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_receivers_channels</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_channels</span><span class="o">=</span><span class="n">obj</span><span class="p">))</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_receivers_objects</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_objects</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">typ</span> <span class="o">==</span> <span class="s1">&#39;script&#39;</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_receivers_scripts</span><span class="o">=</span><span class="n">obj</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">CommError</span></div>
<div class="viewcode-block" id="MsgManager.get_messages_by_channel"><a class="viewcode-back" href="../../../api/evennia.comms.managers.html#evennia.comms.comms.MsgManager.get_messages_by_channel">[docs]</a> <span class="k">def</span> <span class="nf">get_messages_by_channel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">channel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get all persistent messages sent to one channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to find messages for.</span>
<span class="sd"> Returns:</span>
<span class="sd"> messages (list): Persistent Msg objects saved for this channel.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_receivers_channels</span><span class="o">=</span><span class="n">channel</span><span class="p">)</span><span class="o">.</span><span class="n">exclude</span><span class="p">(</span><span class="n">db_hide_from_channels</span><span class="o">=</span><span class="n">channel</span><span class="p">)</span></div>
<div class="viewcode-block" id="MsgManager.search_message"><a class="viewcode-back" href="../../../api/evennia.comms.managers.html#evennia.comms.comms.MsgManager.search_message">[docs]</a> <span class="k">def</span> <span class="nf">search_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">receiver</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">freetext</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">dbref</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -286,7 +267,7 @@
<span class="sd"> one of the arguments must be given to do a search.</span>
<span class="sd"> Args:</span>
<span class="sd"> sender (Object or Account, optional): Get messages sent by a particular account or object</span>
<span class="sd"> sender (Object, Account or Script, optional): Get messages sent by a particular sender.</span>
<span class="sd"> receiver (Object, Account or Channel, optional): Get messages</span>
<span class="sd"> received by a certain account,object or channel</span>
<span class="sd"> freetext (str): Search for a text string in a message. NOTE:</span>
@ -297,40 +278,45 @@
<span class="sd"> always gives only one match.</span>
<span class="sd"> Returns:</span>
<span class="sd"> messages (list or Msg): A list of message matches or a single match if `dbref` was given.</span>
<span class="sd"> Queryset: Message matches.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># unique msg id</span>
<span class="k">if</span> <span class="n">dbref</span><span class="p">:</span>
<span class="n">msg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">dbref</span><span class="p">)</span>
<span class="k">if</span> <span class="n">msg</span><span class="p">:</span>
<span class="k">return</span> <span class="n">msg</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">dbref</span><span class="p">)</span>
<span class="c1"># We use Q objects to gradually build up the query - this way we only</span>
<span class="c1"># need to do one database lookup at the end rather than gradually</span>
<span class="c1"># refining with multiple filter:s. Django Note: Q objects can be</span>
<span class="c1"># combined with &amp; and | (=AND,OR). ~ negates the queryset</span>
<span class="c1"># filter by sender</span>
<span class="c1"># filter by sender (we need __pk to avoid an error with empty Q() objects)</span>
<span class="n">sender</span><span class="p">,</span> <span class="n">styp</span> <span class="o">=</span> <span class="n">identify_object</span><span class="p">(</span><span class="n">sender</span><span class="p">)</span>
<span class="k">if</span> <span class="n">sender</span><span class="p">:</span>
<span class="n">spk</span> <span class="o">=</span> <span class="n">sender</span><span class="o">.</span><span class="n">pk</span>
<span class="k">if</span> <span class="n">styp</span> <span class="o">==</span> <span class="s2">&quot;account&quot;</span><span class="p">:</span>
<span class="n">sender_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_sender_accounts</span><span class="o">=</span><span class="n">sender</span><span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">Q</span><span class="p">(</span><span class="n">db_hide_from_accounts</span><span class="o">=</span><span class="n">sender</span><span class="p">)</span>
<span class="n">sender_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_sender_accounts__pk</span><span class="o">=</span><span class="n">spk</span><span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">Q</span><span class="p">(</span><span class="n">db_hide_from_accounts__pk</span><span class="o">=</span><span class="n">spk</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">styp</span> <span class="o">==</span> <span class="s2">&quot;object&quot;</span><span class="p">:</span>
<span class="n">sender_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_sender_objects</span><span class="o">=</span><span class="n">sender</span><span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">Q</span><span class="p">(</span><span class="n">db_hide_from_objects</span><span class="o">=</span><span class="n">sender</span><span class="p">)</span>
<span class="n">sender_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_sender_objects__pk</span><span class="o">=</span><span class="n">spk</span><span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">Q</span><span class="p">(</span><span class="n">db_hide_from_objects__pk</span><span class="o">=</span><span class="n">spk</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">styp</span> <span class="o">==</span> <span class="s1">&#39;script&#39;</span><span class="p">:</span>
<span class="n">sender_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_sender_scripts__pk</span><span class="o">=</span><span class="n">spk</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">sender_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">()</span>
<span class="c1"># filter by receiver</span>
<span class="n">receiver</span><span class="p">,</span> <span class="n">rtyp</span> <span class="o">=</span> <span class="n">identify_object</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span>
<span class="k">if</span> <span class="n">receiver</span><span class="p">:</span>
<span class="n">rpk</span> <span class="o">=</span> <span class="n">receiver</span><span class="o">.</span><span class="n">pk</span>
<span class="k">if</span> <span class="n">rtyp</span> <span class="o">==</span> <span class="s2">&quot;account&quot;</span><span class="p">:</span>
<span class="n">receiver_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_receivers_accounts</span><span class="o">=</span><span class="n">receiver</span><span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">Q</span><span class="p">(</span>
<span class="n">db_hide_from_accounts</span><span class="o">=</span><span class="n">receiver</span>
<span class="p">)</span>
<span class="n">receiver_restrict</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">Q</span><span class="p">(</span><span class="n">db_receivers_accounts__pk</span><span class="o">=</span><span class="n">rpk</span><span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">Q</span><span class="p">(</span><span class="n">db_hide_from_accounts__pk</span><span class="o">=</span><span class="n">rpk</span><span class="p">))</span>
<span class="k">elif</span> <span class="n">rtyp</span> <span class="o">==</span> <span class="s2">&quot;object&quot;</span><span class="p">:</span>
<span class="n">receiver_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_receivers_objects</span><span class="o">=</span><span class="n">receiver</span><span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">Q</span><span class="p">(</span><span class="n">db_hide_from_objects</span><span class="o">=</span><span class="n">receiver</span><span class="p">)</span>
<span class="n">receiver_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_receivers_objects__pk</span><span class="o">=</span><span class="n">rpk</span><span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">Q</span><span class="p">(</span><span class="n">db_hide_from_objects__pk</span><span class="o">=</span><span class="n">rpk</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">rtyp</span> <span class="o">==</span> <span class="s1">&#39;script&#39;</span><span class="p">:</span>
<span class="n">receiver_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_receivers_scripts__pk</span><span class="o">=</span><span class="n">rpk</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">rtyp</span> <span class="o">==</span> <span class="s2">&quot;channel&quot;</span><span class="p">:</span>
<span class="n">receiver_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="n">db_receivers_channels</span><span class="o">=</span><span class="n">receiver</span><span class="p">)</span> <span class="o">&amp;</span> <span class="o">~</span><span class="n">Q</span><span class="p">(</span>
<span class="n">db_hide_from_channels</span><span class="o">=</span><span class="n">receiver</span>
<span class="p">)</span>
<span class="k">raise</span> <span class="ne">DeprecationWarning</span><span class="p">(</span>
<span class="s2">&quot;Msg.objects.search don&#39;t accept channel recipients since &quot;</span>
<span class="s2">&quot;Channels no longer accepts Msg objects.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">receiver_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">()</span>
<span class="c1"># filter by full text</span>
@ -339,7 +325,7 @@
<span class="k">else</span><span class="p">:</span>
<span class="n">fulltext_restrict</span> <span class="o">=</span> <span class="n">Q</span><span class="p">()</span>
<span class="c1"># execute the query</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">sender_restrict</span> <span class="o">&amp;</span> <span class="n">receiver_restrict</span> <span class="o">&amp;</span> <span class="n">fulltext_restrict</span><span class="p">))</span></div>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">sender_restrict</span> <span class="o">&amp;</span> <span class="n">receiver_restrict</span> <span class="o">&amp;</span> <span class="n">fulltext_restrict</span><span class="p">)</span></div>
<span class="c1"># back-compatibility alias</span>
<span class="n">message_search</span> <span class="o">=</span> <span class="n">search_message</span></div>

View file

@ -76,8 +76,6 @@
<span class="n">_SA</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__setattr__</span>
<span class="n">_DA</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__delattr__</span>
<span class="n">_CHANNELHANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># ------------------------------------------------------------</span>
<span class="c1">#</span>
@ -201,6 +199,7 @@
<span class="n">db_hide_from_objects</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ManyToManyField</span><span class="p">(</span>
<span class="s2">&quot;objects.ObjectDB&quot;</span><span class="p">,</span> <span class="n">related_name</span><span class="o">=</span><span class="s2">&quot;hide_from_objects_set&quot;</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="kc">True</span>
<span class="p">)</span>
<span class="c1"># NOTE: deprecated in 1.0. Not used for channels anymore</span>
<span class="n">db_hide_from_channels</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ManyToManyField</span><span class="p">(</span>
<span class="s2">&quot;ChannelDB&quot;</span><span class="p">,</span> <span class="n">related_name</span><span class="o">=</span><span class="s2">&quot;hide_from_channels_set&quot;</span><span class="p">,</span> <span class="n">blank</span><span class="o">=</span><span class="kc">True</span>
<span class="p">)</span>
@ -307,9 +306,8 @@
<span class="k">elif</span> <span class="n">clsname</span> <span class="o">==</span> <span class="s2">&quot;ScriptDB&quot;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_sender_accounts</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">sender</span><span class="p">)</span></div>
<span class="c1"># receivers property</span>
<span class="c1"># @property</span>
<span class="k">def</span> <span class="nf">__receivers_get</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">receivers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Getter. Allows for value = self.receivers.</span>
<span class="sd"> Returns four lists of receivers: accounts, objects, scripts and channels.</span>
@ -321,8 +319,8 @@
<span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">db_receivers_channels</span><span class="o">.</span><span class="n">all</span><span class="p">())</span>
<span class="p">)</span>
<span class="c1"># @receivers.setter</span>
<span class="k">def</span> <span class="nf">__receivers_set</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">receivers</span><span class="p">):</span>
<span class="nd">@receivers</span><span class="o">.</span><span class="n">setter</span>
<span class="k">def</span> <span class="nf">receivers</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">receivers</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Setter. Allows for self.receivers = value.</span>
<span class="sd"> This appends a new receiver to the message.</span>
@ -342,8 +340,8 @@
<span class="k">elif</span> <span class="n">clsname</span> <span class="o">==</span> <span class="s2">&quot;ChannelDB&quot;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_receivers_channels</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span>
<span class="c1"># @receivers.deleter</span>
<span class="k">def</span> <span class="nf">__receivers_del</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="nd">@receivers</span><span class="o">.</span><span class="n">deleter</span>
<span class="k">def</span> <span class="nf">receivers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="s2">&quot;Deleter. Clears all receivers&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_receivers_accounts</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_receivers_objects</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
@ -351,7 +349,6 @@
<span class="bp">self</span><span class="o">.</span><span class="n">db_receivers_channels</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="n">receivers</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">__receivers_get</span><span class="p">,</span> <span class="n">__receivers_set</span><span class="p">,</span> <span class="n">__receivers_del</span><span class="p">)</span>
<div class="viewcode-block" id="Msg.remove_receiver"><a class="viewcode-back" href="../../../api/evennia.comms.models.html#evennia.comms.admin.Msg.remove_receiver">[docs]</a> <span class="k">def</span> <span class="nf">remove_receiver</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">receivers</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -645,9 +642,6 @@
<span class="sd"> no hooks will be called.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_CHANNELHANDLER</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_CHANNELHANDLER</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">evennia.comms.channelhandler</span> <span class="kn">import</span> <span class="n">CHANNEL_HANDLER</span> <span class="k">as</span> <span class="n">_CHANNELHANDLER</span>
<span class="k">for</span> <span class="n">subscriber</span> <span class="ow">in</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">entity</span><span class="p">):</span>
<span class="k">if</span> <span class="n">subscriber</span><span class="p">:</span>
<span class="n">clsname</span> <span class="o">=</span> <span class="n">subscriber</span><span class="o">.</span><span class="n">__dbclass__</span><span class="o">.</span><span class="vm">__name__</span>
@ -656,7 +650,6 @@
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">db_object_subscriptions</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">subscriber</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">clsname</span> <span class="o">==</span> <span class="s2">&quot;AccountDB&quot;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">db_account_subscriptions</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">subscriber</span><span class="p">)</span>
<span class="n">_CHANNELHANDLER</span><span class="o">.</span><span class="n">_cached_cmdsets</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">subscriber</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_recache</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">entity</span><span class="p">):</span>
@ -668,9 +661,6 @@
<span class="sd"> entities to un-subscribe from the channel.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_CHANNELHANDLER</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_CHANNELHANDLER</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">evennia.comms.channelhandler</span> <span class="kn">import</span> <span class="n">CHANNEL_HANDLER</span> <span class="k">as</span> <span class="n">_CHANNELHANDLER</span>
<span class="k">for</span> <span class="n">subscriber</span> <span class="ow">in</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">entity</span><span class="p">):</span>
<span class="k">if</span> <span class="n">subscriber</span><span class="p">:</span>
<span class="n">clsname</span> <span class="o">=</span> <span class="n">subscriber</span><span class="o">.</span><span class="n">__dbclass__</span><span class="o">.</span><span class="vm">__name__</span>
@ -679,7 +669,6 @@
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">db_account_subscriptions</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">entity</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">clsname</span> <span class="o">==</span> <span class="s2">&quot;ObjectDB&quot;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">db_object_subscriptions</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">entity</span><span class="p">)</span>
<span class="n">_CHANNELHANDLER</span><span class="o">.</span><span class="n">_cached_cmdsets</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">subscriber</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_recache</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">all</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>

View file

@ -1000,7 +1000,6 @@
<span class="sd"> things in the current location, like a furnace, windmill or anvil.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;craft&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;General&quot;</span>

View file

@ -141,7 +141,7 @@
<span class="s2">&quot;You work and work but you are not happy with the result. You need to start over.&quot;</span>
<span class="p">)</span>
<span class="k">def</span> <span class="nf">do_craft</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">craft</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Making a sword blade takes skill. Here we emulate this by introducing a</span>
<span class="sd"> random chance of failure (in a real game this could be a skill check</span>
@ -168,7 +168,7 @@
<span class="k">if</span> <span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">()</span> <span class="o">&lt;</span> <span class="mf">0.8</span><span class="p">:</span>
<span class="c1"># 80% chance of success. This will spawn the sword and show</span>
<span class="c1"># success-message.</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">do_craft</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="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">craft</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># fail and show failed message</span>
<span class="k">return</span> <span class="kc">None</span>

View file

@ -255,7 +255,7 @@
<span class="bp">self</span><span class="o">.</span><span class="n">assertIsNotNone</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">tool1</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertIsNotNone</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">tool2</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestCraftingRecipe.test_seed__succcess"><a class="viewcode-back" href="../../../../api/evennia.contrib.crafting.tests.html#evennia.contrib.crafting.tests.TestCraftingRecipe.test_seed__succcess">[docs]</a> <span class="k">def</span> <span class="nf">test_seed__succcess</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="TestCraftingRecipe.test_seed__success"><a class="viewcode-back" href="../../../../api/evennia.contrib.crafting.tests.html#evennia.contrib.crafting.tests.TestCraftingRecipe.test_seed__success">[docs]</a> <span class="k">def</span> <span class="nf">test_seed__success</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Test seed helper classmethod&quot;&quot;&quot;</span>
<span class="c1"># needed for other dbs to pass seed</span>

View file

@ -112,11 +112,11 @@
<span class="n">traversing_object</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You start moving </span><span class="si">%s</span><span class="s2"> at a </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</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="n">move_speed</span><span class="p">))</span>
<span class="c1"># create a delayed movement</span>
<span class="n">deferred</span> <span class="o">=</span> <span class="n">utils</span><span class="o">.</span><span class="n">delay</span><span class="p">(</span><span class="n">move_delay</span><span class="p">,</span> <span class="n">move_callback</span><span class="p">)</span>
<span class="n">t</span> <span class="o">=</span> <span class="n">utils</span><span class="o">.</span><span class="n">delay</span><span class="p">(</span><span class="n">move_delay</span><span class="p">,</span> <span class="n">move_callback</span><span class="p">)</span>
<span class="c1"># we store the deferred on the character, this will allow us</span>
<span class="c1"># to abort the movement. We must use an ndb here since</span>
<span class="c1"># deferreds cannot be pickled.</span>
<span class="n">traversing_object</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">currently_moving</span> <span class="o">=</span> <span class="n">deferred</span></div></div>
<span class="n">traversing_object</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">currently_moving</span> <span class="o">=</span> <span class="n">t</span></div></div>
<span class="c1">#</span>

View file

@ -0,0 +1,285 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.help.filehelp &#8212; Evennia 1.0-dev 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 1.0-dev</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.help.filehelp</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.help.filehelp</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">The filehelp-system allows for defining help files outside of the game. These</span>
<span class="sd">will be treated as non-command help entries and displayed in the same way as</span>
<span class="sd">help entries created using the `sethelp` default command. After changing an</span>
<span class="sd">entry on-disk you need to reload the server to have the change show in-game.</span>
<span class="sd">An filehelp file is a regular python modules with dicts representing each help</span>
<span class="sd">entry. If a list `HELP_ENTRY_DICTS` is found in the module, this should be a list of</span>
<span class="sd">dicts. Otherwise *all* top-level dicts in the module will be assumed to be a</span>
<span class="sd">help-entry dict.</span>
<span class="sd">Each help-entry dict is on the form</span>
<span class="sd">::</span>
<span class="sd"> {&#39;key&#39;: &lt;str&gt;,</span>
<span class="sd"> &#39;category&#39;: &lt;str&gt;, # optional, otherwise settings.DEFAULT_HELP_CATEGORY</span>
<span class="sd"> &#39;aliases&#39;: &lt;list&gt;, # optional</span>
<span class="sd"> &#39;text&#39;: &lt;str&gt;}``</span>
<span class="sd">where the ``category`` is optional and the ``text`` should be formatted on the</span>
<span class="sd">same form as other help entry-texts and contain ``# subtopics`` as normal.</span>
<span class="sd">New help-entry modules are added to the system by providing the python-path to</span>
<span class="sd">the module to `settings.FILE_HELP_ENTRY_MODULES`. Note that if same-key entries are</span>
<span class="sd">added, entries in latter modules will override that of earlier ones. Use</span>
<span class="sd">``settings.DEFAULT_HELP_CATEGORY`` to customize what category is used if</span>
<span class="sd">not set explicitly.</span>
<span class="sd">An example of the contents of a module:</span>
<span class="sd">::</span>
<span class="sd"> help_entry1 = {</span>
<span class="sd"> &quot;key&quot;: &quot;The Gods&quot;, # case-insensitive, can be searched by &#39;gods&#39; as well</span>
<span class="sd"> &quot;aliases&quot;: [&#39;pantheon&#39;, &#39;religion&#39;]</span>
<span class="sd"> &quot;category&quot;: &quot;Lore&quot;,</span>
<span class="sd"> &quot;text&quot;: &#39;&#39;&#39;</span>
<span class="sd"> The gods formed the world ...</span>
<span class="sd"> # Subtopics</span>
<span class="sd"> ## Pantheon</span>
<span class="sd"> ...</span>
<span class="sd"> ### God of love</span>
<span class="sd"> ...</span>
<span class="sd"> ### God of war</span>
<span class="sd"> ...</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="sd"> }</span>
<span class="sd"> HELP_ENTRY_DICTS = [</span>
<span class="sd"> help_entry1,</span>
<span class="sd"> ...</span>
<span class="sd"> ]</span>
<span class="sd">----</span>
<span class="sd">&quot;&quot;&quot;</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">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">variable_from_module</span><span class="p">,</span> <span class="n">make_iter</span><span class="p">,</span> <span class="n">all_from_module</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">logger</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>
<div class="viewcode-block" id="FileHelpEntry"><a class="viewcode-back" href="../../../api/evennia.help.filehelp.html#evennia.help.filehelp.FileHelpEntry">[docs]</a><span class="nd">@dataclass</span>
<span class="k">class</span> <span class="nc">FileHelpEntry</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Represents a help entry read from file. This mimics the api of the</span>
<span class="sd"> database-bound HelpEntry so that they can be used interchangeably in the</span>
<span class="sd"> help command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span><span class="p">:</span> <span class="nb">str</span>
<span class="n">aliases</span><span class="p">:</span> <span class="nb">list</span>
<span class="n">help_category</span><span class="p">:</span> <span class="nb">str</span>
<span class="n">entrytext</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="sd">&quot;&quot;&quot;</span>
<span class="sd"> Property for easily retaining a search index entry for this object.</span>
<span class="sd"> &quot;&quot;&quot;</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="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">aliases</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">help_category</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="bp">self</span><span class="o">.</span><span class="n">entrytext</span><span class="p">,</span>
<span class="p">}</span></div>
<div class="viewcode-block" id="FileHelpStorageHandler"><a class="viewcode-back" href="../../../api/evennia.help.filehelp.html#evennia.help.filehelp.FileHelpStorageHandler">[docs]</a><span class="k">class</span> <span class="nc">FileHelpStorageHandler</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This reads and stores help entries for quick access. By default</span>
<span class="sd"> it reads modules from `settings.FILE_HELP_ENTRY_MODULES`.</span>
<span class="sd"> Note that this is not meant to any searching/lookup - that is all handled</span>
<span class="sd"> by the help command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="FileHelpStorageHandler.__init__"><a class="viewcode-back" href="../../../api/evennia.help.filehelp.html#evennia.help.filehelp.FileHelpStorageHandler.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">help_file_modules</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">FILE_HELP_ENTRY_MODULES</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Initialize the storage.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">help_file_modules</span> <span class="o">=</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">part</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">help_file_modules</span><span class="p">)]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">help_entries</span> <span class="o">=</span> <span class="p">[]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">help_entries_dict</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">load</span><span class="p">()</span></div>
<div class="viewcode-block" id="FileHelpStorageHandler.load"><a class="viewcode-back" href="../../../api/evennia.help.filehelp.html#evennia.help.filehelp.FileHelpStorageHandler.load">[docs]</a> <span class="k">def</span> <span class="nf">load</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Load/reload file-based help-entries from file.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">loaded_help_dicts</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">module_or_path</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">help_file_modules</span><span class="p">:</span>
<span class="n">help_dict_list</span> <span class="o">=</span> <span class="n">variable_from_module</span><span class="p">(</span>
<span class="n">module_or_path</span><span class="p">,</span> <span class="n">variable</span><span class="o">=</span><span class="s2">&quot;HELP_ENTRY_DICTS&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">help_dict_list</span><span class="p">:</span>
<span class="n">help_dict_list</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">dct</span> <span class="k">for</span> <span class="n">dct</span> <span class="ow">in</span> <span class="n">all_from_module</span><span class="p">(</span><span class="n">module_or_path</span><span class="p">)</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dct</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)]</span>
<span class="k">if</span> <span class="n">help_dict_list</span><span class="p">:</span>
<span class="n">loaded_help_dicts</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">help_dict_list</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_err</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Could not find file-help module </span><span class="si">{</span><span class="n">module_or_path</span><span class="si">}</span><span class="s2"> (skipping).&quot;</span><span class="p">)</span>
<span class="c1"># validate and parse dicts into FileEntryHelp objects and make sure they are unique-by-key</span>
<span class="c1"># by letting latter added ones override earlier ones.</span>
<span class="n">unique_help_entries</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">dct</span> <span class="ow">in</span> <span class="n">loaded_help_dicts</span><span class="p">:</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">dct</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;key&#39;</span><span class="p">)</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">category</span> <span class="o">=</span> <span class="n">dct</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;category&#39;</span><span class="p">,</span> <span class="n">_DEFAULT_HELP_CATEGORY</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">dct</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;aliases&#39;</span><span class="p">,</span> <span class="p">[]))</span>
<span class="n">entrytext</span> <span class="o">=</span> <span class="n">dct</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;text&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">key</span> <span class="ow">and</span> <span class="n">entrytext</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot load file-help-entry (missing key or text): </span><span class="si">{</span><span class="n">dct</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">continue</span>
<span class="n">unique_help_entries</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">FileHelpEntry</span><span class="p">(</span>
<span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">,</span> <span class="n">help_category</span><span class="o">=</span><span class="n">category</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">entrytext</span><span class="o">=</span><span class="n">entrytext</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">help_entries_dict</span> <span class="o">=</span> <span class="n">unique_help_entries</span>
<span class="bp">self</span><span class="o">.</span><span class="n">help_entries</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">unique_help_entries</span><span class="o">.</span><span class="n">values</span><span class="p">())</span></div>
<div class="viewcode-block" id="FileHelpStorageHandler.all"><a class="viewcode-back" href="../../../api/evennia.help.filehelp.html#evennia.help.filehelp.FileHelpStorageHandler.all">[docs]</a> <span class="k">def</span> <span class="nf">all</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">return_dict</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get all help entries.</span>
<span class="sd"> Args:</span>
<span class="sd"> return_dict (bool): Return a dict ``{key: FileHelpEntry,...}``. Otherwise,</span>
<span class="sd"> return a list of ``FileHelpEntry`.</span>
<span class="sd"> Returns:</span>
<span class="sd"> dict or list: Depending on the setting of ``return_dict``.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">help_entries_dict</span> <span class="k">if</span> <span class="n">return_dict</span> <span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">help_entries</span></div></div>
<span class="c1"># singleton to hold the loaded help entries</span>
<span class="n">FILE_HELP_ENTRIES</span> <span class="o">=</span> <span class="n">FileHelpStorageHandler</span><span class="p">()</span>
</pre></div>
<div class="clearer"></div>
</div>
</div>
</div>
<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">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
<a href="https://discord.gg/NecFePw">Discord</a> -
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
</li>
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="filehelp.html">1.0-dev (develop 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="clearer"></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 1.0-dev</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.help.filehelp</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2020, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -151,11 +151,8 @@
<span class="c1">#</span>
<span class="c1">#</span>
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span>
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s2">&quot;</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">key</span>
<span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;&lt;HelpEntry </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&gt;&quot;</span>
<div class="viewcode-block" id="HelpEntry.access"><a class="viewcode-back" href="../../../api/evennia.help.models.html#evennia.help.admin.HelpEntry.access">[docs]</a> <span class="k">def</span> <span class="nf">access</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">accessing_obj</span><span class="p">,</span> <span class="n">access_type</span><span class="o">=</span><span class="s2">&quot;read&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>

View file

@ -0,0 +1,337 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.help.utils &#8212; Evennia 1.0-dev 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 1.0-dev</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.help.utils</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.help.utils</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Resources for indexing help entries and for splitting help entries into</span>
<span class="sd">sub-categories.</span>
<span class="sd">This is used primarily by the default `help` command.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="c1"># these are words that Lunr normally ignores but which we want to find</span>
<span class="c1"># since we use them (e.g. as command names).</span>
<span class="c1"># Lunr&#39;s default word list is found here:</span>
<span class="c1"># https://github.com/yeraydiazdiaz/lunr.py/blob/master/lunr/stop_word_filter.py</span>
<span class="n">_LUNR_STOP_WORD_FILTER_EXCEPTIONS</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;about&quot;</span><span class="p">,</span> <span class="s2">&quot;might&quot;</span><span class="p">)</span>
<span class="n">_LUNR</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_LUNR_EXCEPTION</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_LUNR_GET_BUILDER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_LUNR_BUILDER_PIPELINE</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_RE_HELP_SUBTOPICS_START</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
<span class="sa">r</span><span class="s2">&quot;^\s*?#\s*?subtopics\s*?$&quot;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">I</span> <span class="o">+</span> <span class="n">re</span><span class="o">.</span><span class="n">M</span><span class="p">)</span>
<span class="n">_RE_HELP_SUBTOPIC_SPLIT</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;^\s*?(\#{2,6}\s*?\w+?[a-z0-9 \-\?!,\.]*?)$&quot;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">M</span> <span class="o">+</span> <span class="n">re</span><span class="o">.</span><span class="n">I</span><span class="p">)</span>
<span class="n">_RE_HELP_SUBTOPIC_PARSE</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
<span class="sa">r</span><span class="s2">&quot;^(?P&lt;nesting&gt;\#{2,6})\s*?(?P&lt;name&gt;.*?)$&quot;</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">I</span> <span class="o">+</span> <span class="n">re</span><span class="o">.</span><span class="n">M</span><span class="p">)</span>
<span class="n">MAX_SUBTOPIC_NESTING</span> <span class="o">=</span> <span class="mi">5</span>
<div class="viewcode-block" id="help_search_with_index"><a class="viewcode-back" href="../../../api/evennia.help.utils.html#evennia.help.utils.help_search_with_index">[docs]</a><span class="k">def</span> <span class="nf">help_search_with_index</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">candidate_entries</span><span class="p">,</span> <span class="n">suggestion_maxnum</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">fields</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Lunr-powered fast index search and suggestion wrapper. See https://lunrjs.com/.</span>
<span class="sd"> Args:</span>
<span class="sd"> query (str): The query to search for.</span>
<span class="sd"> candidate_entries (list): This is the body of possible entities to search. Each</span>
<span class="sd"> must have a property `.search_index_entry` that returns a dict with all</span>
<span class="sd"> keys in the `fields` arg.</span>
<span class="sd"> suggestion_maxnum (int): How many matches to allow at most in a multi-match.</span>
<span class="sd"> fields (list, optional): A list of Lunr field mappings</span>
<span class="sd"> ``{&quot;field_name&quot;: str, &quot;boost&quot;: int}``. See the Lunr documentation</span>
<span class="sd"> for more details. The field name must exist in the dicts returned</span>
<span class="sd"> by `.search_index_entry` of the candidates. If not given, a default setup</span>
<span class="sd"> is used, prefering keys &gt; aliases &gt; category &gt; tags.</span>
<span class="sd"> Returns:</span>
<span class="sd"> tuple: A tuple (matches, suggestions), each a list, where the `suggestion_maxnum` limits</span>
<span class="sd"> how many suggestions are included.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_LUNR</span><span class="p">,</span> <span class="n">_LUNR_EXCEPTION</span><span class="p">,</span> <span class="n">_LUNR_BUILDER_PIPELINE</span><span class="p">,</span> <span class="n">_LUNR_GET_BUILDER</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_LUNR</span><span class="p">:</span>
<span class="c1"># we have to delay-load lunr because it messes with logging if it&#39;s imported</span>
<span class="c1"># before twisted&#39;s logging has been set up</span>
<span class="kn">from</span> <span class="nn">lunr</span> <span class="kn">import</span> <span class="n">lunr</span> <span class="k">as</span> <span class="n">_LUNR</span>
<span class="kn">from</span> <span class="nn">lunr.exceptions</span> <span class="kn">import</span> <span class="n">QueryParseError</span> <span class="k">as</span> <span class="n">_LUNR_EXCEPTION</span>
<span class="kn">from</span> <span class="nn">lunr</span> <span class="kn">import</span> <span class="n">get_default_builder</span> <span class="k">as</span> <span class="n">_LUNR_GET_BUILDER</span>
<span class="kn">from</span> <span class="nn">lunr</span> <span class="kn">import</span> <span class="n">stop_word_filter</span>
<span class="kn">from</span> <span class="nn">lunr.stemmer</span> <span class="kn">import</span> <span class="n">stemmer</span>
<span class="kn">from</span> <span class="nn">lunr.trimmer</span> <span class="kn">import</span> <span class="n">trimmer</span>
<span class="c1"># pre-create a lunr index-builder pipeline where we&#39;ve removed some of</span>
<span class="c1"># the stop-words from the default in lunr.</span>
<span class="n">stop_words</span> <span class="o">=</span> <span class="n">stop_word_filter</span><span class="o">.</span><span class="n">WORDS</span>
<span class="k">for</span> <span class="n">ignore_word</span> <span class="ow">in</span> <span class="n">_LUNR_STOP_WORD_FILTER_EXCEPTIONS</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">stop_words</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">ignore_word</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="n">custom_stop_words_filter</span> <span class="o">=</span> <span class="n">stop_word_filter</span><span class="o">.</span><span class="n">generate_stop_word_filter</span><span class="p">(</span><span class="n">stop_words</span><span class="p">)</span>
<span class="n">_LUNR_BUILDER_PIPELINE</span> <span class="o">=</span> <span class="p">(</span><span class="n">trimmer</span><span class="p">,</span> <span class="n">custom_stop_words_filter</span><span class="p">,</span> <span class="n">stemmer</span><span class="p">)</span>
<span class="n">indx</span> <span class="o">=</span> <span class="p">[</span><span class="n">cnd</span><span class="o">.</span><span class="n">search_index_entry</span> <span class="k">for</span> <span class="n">cnd</span> <span class="ow">in</span> <span class="n">candidate_entries</span><span class="p">]</span>
<span class="n">mapping</span> <span class="o">=</span> <span class="p">{</span><span class="n">indx</span><span class="p">[</span><span class="n">ix</span><span class="p">][</span><span class="s2">&quot;key&quot;</span><span class="p">]:</span> <span class="n">cand</span> <span class="k">for</span> <span class="n">ix</span><span class="p">,</span> <span class="n">cand</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">candidate_entries</span><span class="p">)}</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">fields</span><span class="p">:</span>
<span class="n">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;category&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;tags&quot;</span><span class="p">,</span> <span class="s2">&quot;boost&quot;</span><span class="p">:</span> <span class="mi">5</span><span class="p">},</span>
<span class="p">]</span>
<span class="c1"># build the search index</span>
<span class="n">builder</span> <span class="o">=</span> <span class="n">_LUNR_GET_BUILDER</span><span class="p">()</span>
<span class="n">builder</span><span class="o">.</span><span class="n">pipeline</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span>
<span class="n">builder</span><span class="o">.</span><span class="n">pipeline</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="o">*</span><span class="n">_LUNR_BUILDER_PIPELINE</span><span class="p">)</span>
<span class="n">search_index</span> <span class="o">=</span> <span class="n">_LUNR</span><span class="p">(</span>
<span class="n">ref</span><span class="o">=</span><span class="s2">&quot;key&quot;</span><span class="p">,</span>
<span class="n">fields</span><span class="o">=</span><span class="n">fields</span><span class="p">,</span>
<span class="n">documents</span><span class="o">=</span><span class="n">indx</span><span class="p">,</span>
<span class="n">builder</span><span class="o">=</span><span class="n">builder</span>
<span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">matches</span> <span class="o">=</span> <span class="n">search_index</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">query</span><span class="p">)[:</span><span class="n">suggestion_maxnum</span><span class="p">]</span>
<span class="k">except</span> <span class="n">_LUNR_EXCEPTION</span><span class="p">:</span>
<span class="c1"># this is a user-input problem</span>
<span class="n">matches</span> <span class="o">=</span> <span class="p">[]</span>
<span class="c1"># matches (objs), suggestions (strs)</span>
<span class="k">return</span> <span class="p">(</span>
<span class="p">[</span><span class="n">mapping</span><span class="p">[</span><span class="n">match</span><span class="p">[</span><span class="s2">&quot;ref&quot;</span><span class="p">]]</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">matches</span><span class="p">],</span>
<span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">match</span><span class="p">[</span><span class="s2">&quot;ref&quot;</span><span class="p">])</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">matches</span><span class="p">],</span> <span class="c1"># + f&quot; (score {match[&#39;score&#39;]})&quot;) # good debug</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="parse_entry_for_subcategories"><a class="viewcode-back" href="../../../api/evennia.help.utils.html#evennia.help.utils.parse_entry_for_subcategories">[docs]</a><span class="k">def</span> <span class="nf">parse_entry_for_subcategories</span><span class="p">(</span><span class="n">entry</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Parse a command docstring for special sub-category blocks:</span>
<span class="sd"> Args:</span>
<span class="sd"> entry (str): A help entry to parse</span>
<span class="sd"> Returns:</span>
<span class="sd"> dict: The dict is a mapping that splits the entry into subcategories. This</span>
<span class="sd"> will always hold a key `None` for the main help entry and</span>
<span class="sd"> zero or more keys holding the subcategories. Each is itself</span>
<span class="sd"> a dict with a key `None` for the main text of that subcategory</span>
<span class="sd"> followed by any sub-sub-categories down to a max-depth of 5.</span>
<span class="sd"> Example:</span>
<span class="sd"> ::</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="sd"> Main topic text</span>
<span class="sd"> # SUBTOPICS</span>
<span class="sd"> ## foo</span>
<span class="sd"> A subcategory of the main entry, accessible as `help topic foo`</span>
<span class="sd"> (or using /, like `help topic/foo`)</span>
<span class="sd"> ## bar</span>
<span class="sd"> Another subcategory, accessed as `help topic bar`</span>
<span class="sd"> (or `help topic/bar`)</span>
<span class="sd"> ### moo</span>
<span class="sd"> A subcategory of bar, accessed as `help bar moo`</span>
<span class="sd"> (or `help bar/moo`)</span>
<span class="sd"> #### dum</span>
<span class="sd"> A subcategory of moo, accessed `help bar moo dum`</span>
<span class="sd"> (or `help bar/moo/dum`)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="sd"> This will result in this returned entry structure:</span>
<span class="sd"> ::</span>
<span class="sd"> {</span>
<span class="sd"> None: &quot;Main topic text&quot;:</span>
<span class="sd"> &quot;foo&quot;: {</span>
<span class="sd"> None: &quot;main topic/foo text&quot;</span>
<span class="sd"> },</span>
<span class="sd"> &quot;bar&quot;: {</span>
<span class="sd"> None: &quot;Main topic/bar text&quot;,</span>
<span class="sd"> &quot;moo&quot;: {</span>
<span class="sd"> None: &quot;topic/bar/moo text&quot;</span>
<span class="sd"> &quot;dum&quot;: {</span>
<span class="sd"> None: &quot;topic/bar/moo/dum text&quot;</span>
<span class="sd"> }</span>
<span class="sd"> }</span>
<span class="sd"> }</span>
<span class="sd"> }</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">topic</span><span class="p">,</span> <span class="o">*</span><span class="n">subtopics</span> <span class="o">=</span> <span class="n">_RE_HELP_SUBTOPICS_START</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="n">maxsplit</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">structure</span> <span class="o">=</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="n">strip</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)}</span>
<span class="k">if</span> <span class="n">subtopics</span><span class="p">:</span>
<span class="n">subtopics</span> <span class="o">=</span> <span class="n">subtopics</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="k">return</span> <span class="n">structure</span>
<span class="n">keypath</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">current_nesting</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">subtopic</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># from evennia import set_trace;set_trace()</span>
<span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">_RE_HELP_SUBTOPIC_SPLIT</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">subtopics</span><span class="o">.</span><span class="n">strip</span><span class="p">()):</span>
<span class="n">subtopic_match</span> <span class="o">=</span> <span class="n">_RE_HELP_SUBTOPIC_PARSE</span><span class="o">.</span><span class="n">match</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="k">if</span> <span class="n">subtopic_match</span><span class="p">:</span>
<span class="c1"># a new sub(-sub..) category starts.</span>
<span class="n">mdict</span> <span class="o">=</span> <span class="n">subtopic_match</span><span class="o">.</span><span class="n">groupdict</span><span class="p">()</span>
<span class="n">subtopic</span> <span class="o">=</span> <span class="n">mdict</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</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">new_nesting</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">mdict</span><span class="p">[</span><span class="s1">&#39;nesting&#39;</span><span class="p">])</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">new_nesting</span> <span class="o">&gt;</span> <span class="n">MAX_SUBTOPIC_NESTING</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Can have max </span><span class="si">{</span><span class="n">MAX_SUBTOPIC_NESTING</span><span class="si">}</span><span class="s2"> levels of nested help subtopics.&quot;</span><span class="p">)</span>
<span class="n">nestdiff</span> <span class="o">=</span> <span class="n">new_nesting</span> <span class="o">-</span> <span class="n">current_nesting</span>
<span class="k">if</span> <span class="n">nestdiff</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># jumping back up in nesting</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">nestdiff</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">keypath</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">elif</span> <span class="n">nestdiff</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># don&#39;t add a deeper nesting but replace the current</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">keypath</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="n">keypath</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">subtopic</span><span class="p">)</span>
<span class="n">current_nesting</span> <span class="o">=</span> <span class="n">new_nesting</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># an entry belonging to a subtopic - find the nested location</span>
<span class="n">dct</span> <span class="o">=</span> <span class="n">structure</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">keypath</span> <span class="ow">and</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="n">structure</span><span class="p">[</span><span class="n">subtopic</span><span class="p">]</span> <span class="o">=</span> <span class="n">part</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">keypath</span><span class="p">:</span>
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">dct</span><span class="p">:</span>
<span class="n">dct</span> <span class="o">=</span> <span class="n">dct</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">dct</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="kc">None</span><span class="p">:</span> <span class="n">part</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">structure</span></div>
</pre></div>
<div class="clearer"></div>
</div>
</div>
</div>
<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">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
<a href="https://discord.gg/NecFePw">Discord</a> -
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
</li>
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="utils.html">1.0-dev (develop 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="clearer"></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 1.0-dev</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.help.utils</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2020, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>

View file

@ -934,7 +934,7 @@
<span class="c1"># Before the move, call eventual pre-commands.</span>
<span class="k">if</span> <span class="n">move_hooks</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">at_before_move</span><span class="p">(</span><span class="n">destination</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">at_before_move</span><span class="p">(</span><span class="n">destination</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="kc">False</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="n">logerr</span><span class="p">(</span><span class="n">errtxt</span> <span class="o">%</span> <span class="s2">&quot;at_before_move()&quot;</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
@ -946,7 +946,7 @@
<span class="c1"># Call hook on source location</span>
<span class="k">if</span> <span class="n">move_hooks</span> <span class="ow">and</span> <span class="n">source_location</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">source_location</span><span class="o">.</span><span class="n">at_object_leave</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">destination</span><span class="p">)</span>
<span class="n">source_location</span><span class="o">.</span><span class="n">at_object_leave</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">destination</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="n">logerr</span><span class="p">(</span><span class="n">errtxt</span> <span class="o">%</span> <span class="s2">&quot;at_object_leave()&quot;</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
@ -978,7 +978,7 @@
<span class="c1"># Perform eventual extra commands on the receiving location</span>
<span class="c1"># (the object has already arrived at this point)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">destination</span><span class="o">.</span><span class="n">at_object_receive</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">source_location</span><span class="p">)</span>
<span class="n">destination</span><span class="o">.</span><span class="n">at_object_receive</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">source_location</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="n">logerr</span><span class="p">(</span><span class="n">errtxt</span> <span class="o">%</span> <span class="s2">&quot;at_object_receive()&quot;</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
@ -987,7 +987,7 @@
<span class="c1"># (usually calling &#39;look&#39;)</span>
<span class="k">if</span> <span class="n">move_hooks</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_after_move</span><span class="p">(</span><span class="n">source_location</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">at_after_move</span><span class="p">(</span><span class="n">source_location</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="n">logerr</span><span class="p">(</span><span class="n">errtxt</span> <span class="o">%</span> <span class="s2">&quot;at_after_move&quot;</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>

View file

@ -60,6 +60,7 @@
<span class="kn">from</span> <span class="nn">evennia.utils.evmore</span> <span class="kn">import</span> <span class="n">EvMore</span>
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">all_from_module</span><span class="p">,</span>
<span class="n">variable_from_module</span><span class="p">,</span>
<span class="n">make_iter</span><span class="p">,</span>
<span class="n">is_iter</span><span class="p">,</span>
<span class="n">dbid_to_obj</span><span class="p">,</span>
@ -200,11 +201,30 @@
<span class="c1"># to remove a default prototype, override it with an empty dict.</span>
<span class="c1"># internally we store as (key, desc, locks, tags, prototype_dict)</span>
<span class="n">prots</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">variable_name</span><span class="p">,</span> <span class="n">prot</span> <span class="ow">in</span> <span class="n">all_from_module</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">prot</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
<span class="k">if</span> <span class="s2">&quot;prototype_key&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">prot</span><span class="p">:</span>
<span class="n">prot</span><span class="p">[</span><span class="s2">&quot;prototype_key&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">variable_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="n">prototype_list</span> <span class="o">=</span> <span class="n">variable_from_module</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="s2">&quot;PROTOTYPE_LIST&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">prototype_list</span><span class="p">:</span>
<span class="c1"># found mod.PROTOTYPE_LIST - this should be a list of valid</span>
<span class="c1"># prototype dicts that must have &#39;prototype_key&#39; set.</span>
<span class="k">for</span> <span class="n">prot</span> <span class="ow">in</span> <span class="n">prototype_list</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">prot</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_err</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Prototype read from </span><span class="si">{</span><span class="n">mod</span><span class="si">}</span><span class="s2">.PROTOTYPE_LIST &quot;</span>
<span class="sa">f</span><span class="s2">&quot;is not a dict (skipping): </span><span class="si">{</span><span class="n">prot</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">continue</span>
<span class="k">elif</span> <span class="s2">&quot;prototype_key&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">prot</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_err</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Prototype read from </span><span class="si">{</span><span class="n">mod</span><span class="si">}</span><span class="s2">.PROTOTYPE_LIST &quot;</span>
<span class="sa">f</span><span class="s2">&quot;is missing the &#39;prototype_key&#39; (skipping): </span><span class="si">{</span><span class="n">prot</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">continue</span>
<span class="n">prots</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">prot</span><span class="p">[</span><span class="s2">&quot;prototype_key&quot;</span><span class="p">],</span> <span class="n">homogenize_prototype</span><span class="p">(</span><span class="n">prot</span><span class="p">)))</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># load all global dicts in module as prototypes. If the prototype_key</span>
<span class="c1"># is not given, the variable name will be used.</span>
<span class="k">for</span> <span class="n">variable_name</span><span class="p">,</span> <span class="n">prot</span> <span class="ow">in</span> <span class="n">all_from_module</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">prot</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
<span class="k">if</span> <span class="s2">&quot;prototype_key&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">prot</span><span class="p">:</span>
<span class="n">prot</span><span class="p">[</span><span class="s2">&quot;prototype_key&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">variable_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="n">prots</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">prot</span><span class="p">[</span><span class="s2">&quot;prototype_key&quot;</span><span class="p">],</span> <span class="n">homogenize_prototype</span><span class="p">(</span><span class="n">prot</span><span class="p">)))</span>
<span class="c1"># assign module path to each prototype_key for easy reference</span>
<span class="n">_MODULE_PROTOTYPE_MODULES</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="n">prototype_key</span><span class="o">.</span><span class="n">lower</span><span class="p">():</span> <span class="n">mod</span> <span class="k">for</span> <span class="n">prototype_key</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">prots</span><span class="p">})</span>
<span class="c1"># make sure the prototype contains all meta info</span>

View file

@ -47,7 +47,9 @@
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timedelta</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
<span class="kn">from</span> <span class="nn">pickle</span> <span class="kn">import</span> <span class="n">PickleError</span>
<span class="kn">from</span> <span class="nn">twisted.internet.task</span> <span class="kn">import</span> <span class="n">deferLater</span>
<span class="kn">from</span> <span class="nn">twisted.internet.defer</span> <span class="kn">import</span> <span class="n">CancelledError</span> <span class="k">as</span> <span class="n">DefCancelledError</span>
<span class="kn">from</span> <span class="nn">evennia.server.models</span> <span class="kn">import</span> <span class="n">ServerConfig</span>
<span class="kn">from</span> <span class="nn">evennia.utils.logger</span> <span class="kn">import</span> <span class="n">log_err</span>
<span class="kn">from</span> <span class="nn">evennia.utils.dbserialize</span> <span class="kn">import</span> <span class="n">dbserialize</span><span class="p">,</span> <span class="n">dbunserialize</span>
@ -55,31 +57,213 @@
<span class="n">TASK_HANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<div class="viewcode-block" id="handle_error"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.handle_error">[docs]</a><span class="k">def</span> <span class="nf">handle_error</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Handle errors within deferred objects.&quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
<span class="c1"># suppress cancel errors</span>
<span class="k">if</span> <span class="n">arg</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">DefCancelledError</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">raise</span> <span class="n">arg</span></div>
<div class="viewcode-block" id="TaskHandlerTask"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask">[docs]</a><span class="k">class</span> <span class="nc">TaskHandlerTask</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;An object to represent a single TaskHandler task.</span>
<span class="sd"> Instance Attributes:</span>
<span class="sd"> task_id (int): the global id for this task</span>
<span class="sd"> deferred (deferred): a reference to this task&#39;s deferred</span>
<span class="sd"> Property Attributes:</span>
<span class="sd"> paused (bool): check if the deferred instance of a task has been paused.</span>
<span class="sd"> called(self): A task attribute to check if the deferred instance of a task has been called.</span>
<span class="sd"> Methods:</span>
<span class="sd"> pause(): Pause the callback of a task.</span>
<span class="sd"> unpause(): Process all callbacks made since pause() was called.</span>
<span class="sd"> do_task(): Execute the task (call its callback).</span>
<span class="sd"> call(): Call the callback of this task.</span>
<span class="sd"> remove(): Remove a task without executing it.</span>
<span class="sd"> cancel(): Stop a task from automatically executing.</span>
<span class="sd"> active(): Check if a task is active (has not been called yet).</span>
<span class="sd"> exists(): Check if a task exists.</span>
<span class="sd"> get_id(): Returns the global id for this task. For use with</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="TaskHandlerTask.__init__"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_id</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">task_id</span> <span class="o">=</span> <span class="n">task_id</span>
<span class="bp">self</span><span class="o">.</span><span class="n">deferred</span> <span class="o">=</span> <span class="n">TASK_HANDLER</span><span class="o">.</span><span class="n">get_deferred</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandlerTask.get_deferred"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.get_deferred">[docs]</a> <span class="k">def</span> <span class="nf">get_deferred</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the instance of the deferred the task id is using.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool or deferred: An instance of a deferred or False if there is no task with the id.</span>
<span class="sd"> None is returned if there is no deferred affiliated with this id.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">TASK_HANDLER</span><span class="o">.</span><span class="n">get_deferred</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">task_id</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandlerTask.pause"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.pause">[docs]</a> <span class="k">def</span> <span class="nf">pause</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Pause the callback of a task.</span>
<span class="sd"> To resume use TaskHandlerTask.unpause</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">deferred</span>
<span class="k">if</span> <span class="n">d</span><span class="p">:</span>
<span class="n">d</span><span class="o">.</span><span class="n">pause</span><span class="p">()</span></div>
<div class="viewcode-block" id="TaskHandlerTask.unpause"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.unpause">[docs]</a> <span class="k">def</span> <span class="nf">unpause</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Unpause a task, run the task if it has passed delay time.&quot;&quot;&quot;</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">deferred</span>
<span class="k">if</span> <span class="n">d</span><span class="p">:</span>
<span class="n">d</span><span class="o">.</span><span class="n">unpause</span><span class="p">()</span></div>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">paused</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;A task attribute to check if the deferred instance of a task has been paused.</span>
<span class="sd"> This exists to mock usage of a twisted deferred object.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool or None: True if the task was properly paused. None if the task does not have</span>
<span class="sd"> a deferred instance.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">deferred</span>
<span class="k">if</span> <span class="n">d</span><span class="p">:</span>
<span class="k">return</span> <span class="n">d</span><span class="o">.</span><span class="n">paused</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<div class="viewcode-block" id="TaskHandlerTask.do_task"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.do_task">[docs]</a> <span class="k">def</span> <span class="nf">do_task</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Execute the task (call its callback).</span>
<span class="sd"> If calling before timedelay, cancel the deferred instance affliated to this task.</span>
<span class="sd"> Remove the task from the dictionary of current tasks on a successful</span>
<span class="sd"> callback.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool or any: Set to `False` if the task does not exist in task</span>
<span class="sd"> handler. Otherwise it will be the return of the task&#39;s callback.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">TASK_HANDLER</span><span class="o">.</span><span class="n">do_task</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">task_id</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandlerTask.call"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.call">[docs]</a> <span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Call the callback of a task.</span>
<span class="sd"> Leave the task unaffected otherwise.</span>
<span class="sd"> This does not use the task&#39;s deferred instance.</span>
<span class="sd"> The only requirement is that the task exist in task handler.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool or any: Set to `False` if the task does not exist in task</span>
<span class="sd"> handler. Otherwise it will be the return of the task&#39;s callback.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">TASK_HANDLER</span><span class="o">.</span><span class="n">call_task</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">task_id</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandlerTask.remove"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.remove">[docs]</a> <span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Remove a task without executing it.</span>
<span class="sd"> Deletes the instance of the task&#39;s deferred.</span>
<span class="sd"> Args:</span>
<span class="sd"> task_id (int): an existing task ID.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if the removal completed successfully.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">TASK_HANDLER</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">task_id</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandlerTask.cancel"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.cancel">[docs]</a> <span class="k">def</span> <span class="nf">cancel</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Stop a task from automatically executing.</span>
<span class="sd"> This will not remove the task.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if the cancel completed successfully.</span>
<span class="sd"> False if the cancel did not complete successfully.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">TASK_HANDLER</span><span class="o">.</span><span class="n">cancel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">task_id</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandlerTask.active"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.active">[docs]</a> <span class="k">def</span> <span class="nf">active</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Check if a task is active (has not been called yet).</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if a task is active (has not been called yet). False if</span>
<span class="sd"> it is not (has been called) or if the task does not exist.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">TASK_HANDLER</span><span class="o">.</span><span class="n">active</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">task_id</span><span class="p">)</span></div>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">called</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A task attribute to check if the deferred instance of a task has been called.</span>
<span class="sd"> This exists to mock usage of a twisted deferred object.</span>
<span class="sd"> It will not set to True if Task.call has been called. This only happens if</span>
<span class="sd"> task&#39;s deferred instance calls the callback.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if the deferred instance of this task has called the callback.</span>
<span class="sd"> False if the deferred instnace of this task has not called the callback.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">deferred</span>
<span class="k">if</span> <span class="n">d</span><span class="p">:</span>
<span class="k">return</span> <span class="n">d</span><span class="o">.</span><span class="n">called</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<div class="viewcode-block" id="TaskHandlerTask.exists"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.exists">[docs]</a> <span class="k">def</span> <span class="nf">exists</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Check if a task exists.</span>
<span class="sd"> Most task handler methods check for existence for you.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True the task exists False if it does not.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">TASK_HANDLER</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">task_id</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandlerTask.get_id"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandlerTask.get_id">[docs]</a> <span class="k">def</span> <span class="nf">get_id</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Returns the global id for this task. For use with</span>
<span class="sd"> `evennia.scripts.taskhandler.TASK_HANDLER`.</span>
<span class="sd"> Returns:</span>
<span class="sd"> task_id (int): global task id for this task.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">task_id</span></div></div>
<div class="viewcode-block" id="TaskHandler"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler">[docs]</a><span class="k">class</span> <span class="nc">TaskHandler</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A light singleton wrapper allowing to access permanent tasks.</span>
<span class="sd">&quot;&quot;&quot;A light singleton wrapper allowing to access permanent tasks.</span>
<span class="sd"> When `utils.delay` is called, the task handler is used to create</span>
<span class="sd"> the task. If `utils.delay` is called with `persistent=True`, the</span>
<span class="sd"> task handler stores the new task and saves.</span>
<span class="sd"> the task.</span>
<span class="sd"> It&#39;s easier to access these tasks (should it be necessary) using</span>
<span class="sd"> `evennia.scripts.taskhandler.TASK_HANDLER`, which contains one</span>
<span class="sd"> instance of this class, and use its `add` and `remove` methods.</span>
<span class="sd"> Task handler will automatically remove uncalled but canceled from task</span>
<span class="sd"> handler. By default this will not occur until a canceled task</span>
<span class="sd"> has been uncalled for 60 second after the time it should have been called.</span>
<span class="sd"> To adjust this time use TASK_HANDLER.stale_timeout. If stale_timeout is 0</span>
<span class="sd"> stale tasks will not be automatically removed.</span>
<span class="sd"> This is not done on a timer. I is done as new tasks are added or the load method is called.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="TaskHandler.__init__"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">to_save</span> <span class="o">=</span> <span class="p">{}</span></div>
<span class="bp">self</span><span class="o">.</span><span class="n">to_save</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">clock</span> <span class="o">=</span> <span class="n">reactor</span>
<span class="c1"># number of seconds before an uncalled canceled task is removed from TaskHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stale_timeout</span> <span class="o">=</span> <span class="mi">60</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_now</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1"># used in unit testing to manually set now time</span></div>
<div class="viewcode-block" id="TaskHandler.load"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.load">[docs]</a> <span class="k">def</span> <span class="nf">load</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Load from the ServerConfig.</span>
<span class="sd"> Note:</span>
<span class="sd"> This should be automatically called when Evennia starts.</span>
<span class="sd"> It populates `self.tasks` according to the ServerConfig.</span>
<span class="sd"> This should be automatically called when Evennia starts.</span>
<span class="sd"> It populates `self.tasks` according to the ServerConfig.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">to_save</span> <span class="o">=</span> <span class="kc">False</span>
@ -100,16 +284,42 @@
<span class="k">continue</span>
<span class="n">callback</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">method</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="kc">True</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">stale_timeout</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span> <span class="c1"># cleanup stale tasks.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">clean_stale_tasks</span><span class="p">()</span>
<span class="k">if</span> <span class="n">to_save</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">()</span></div>
<div class="viewcode-block" id="TaskHandler.clean_stale_tasks"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.clean_stale_tasks">[docs]</a> <span class="k">def</span> <span class="nf">clean_stale_tasks</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;remove uncalled but canceled from task handler.</span>
<span class="sd"> By default this will not occur until a canceled task</span>
<span class="sd"> has been uncalled for 60 second after the time it should have been called.</span>
<span class="sd"> To adjust this time use TASK_HANDLER.stale_timeout.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">clean_ids</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">task_id</span><span class="p">,</span> <span class="p">(</span><span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">persistent</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">active</span><span class="p">(</span><span class="n">task_id</span><span class="p">):</span>
<span class="n">stale_date</span> <span class="o">=</span> <span class="n">date</span> <span class="o">+</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">stale_timeout</span><span class="p">)</span>
<span class="c1"># if a now time is provided use it (intended for unit testing)</span>
<span class="n">now</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_now</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_now</span> <span class="k">else</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="c1"># the task was canceled more than stale_timeout seconds ago</span>
<span class="k">if</span> <span class="n">now</span> <span class="o">&gt;</span> <span class="n">stale_date</span><span class="p">:</span>
<span class="n">clean_ids</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="k">for</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="n">clean_ids</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="TaskHandler.save"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.save">[docs]</a> <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Save the tasks in ServerConfig.&quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">task_id</span><span class="p">,</span> <span class="p">(</span><span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">for</span> <span class="n">task_id</span><span class="p">,</span> <span class="p">(</span><span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">persistent</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">persistent</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">callback</span><span class="p">,</span> <span class="s2">&quot;__self__&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
<span class="c1"># `callback` is an instance method</span>
@ -120,52 +330,71 @@
<span class="c1"># Check if callback can be pickled. args and kwargs have been checked</span>
<span class="n">safe_callback</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">dbserialize</span><span class="p">((</span><span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">))</span>
<span class="n">ServerConfig</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">conf</span><span class="p">(</span><span class="s2">&quot;delayed_tasks&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandler.add"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.add">[docs]</a> <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timedelay</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Add a new task.</span>
<span class="sd"> If the persistent kwarg is truthy:</span>
<span class="sd"> The callback, args and values for kwarg will be serialized. Type</span>
<span class="sd"> and attribute errors during the serialization will be logged,</span>
<span class="sd"> but will not throw exceptions.</span>
<span class="sd"> For persistent tasks do not use memory references in the callback</span>
<span class="sd"> function or arguments. After a restart those memory references are no</span>
<span class="sd"> longer accurate.</span>
<span class="sd"> Args:</span>
<span class="sd"> timedelay (int or float): time in seconds before calling the callback.</span>
<span class="sd"> callback (function or instance method): the callback itself</span>
<span class="sd"> any (any): any additional positional arguments to send to the callback</span>
<span class="sd"> *args: positional arguments to pass to callback.</span>
<span class="sd"> **kwargs: keyword arguments to pass to callback.</span>
<span class="sd"> - persistent (bool, optional): persist the task (stores it).</span>
<span class="sd"> Persistent key and value is removed from kwargs it will</span>
<span class="sd"> not be passed to callback.</span>
<span class="sd"> Returns:</span>
<span class="sd"> TaskHandlerTask: An object to represent a task.</span>
<span class="sd"> Reference evennia.scripts.taskhandler.TaskHandlerTask for complete details.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># set the completion time</span>
<span class="c1"># Only used on persistent tasks after a restart</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="n">delta</span> <span class="o">=</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=</span><span class="n">timedelay</span><span class="p">)</span>
<span class="n">comp_time</span> <span class="o">=</span> <span class="n">now</span> <span class="o">+</span> <span class="n">delta</span>
<span class="c1"># get an open task id</span>
<span class="n">used_ids</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
<span class="n">task_id</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">while</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="n">used_ids</span><span class="p">:</span>
<span class="n">task_id</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="c1"># record the task to the tasks dictionary</span>
<span class="n">persistent</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;persistent&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;persistent&quot;</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
<span class="k">del</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;persistent&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">persistent</span><span class="p">:</span>
<span class="n">safe_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">safe_kwargs</span> <span class="o">=</span> <span class="p">{}</span>
<span class="c1"># an unsaveable callback should immediately abort</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">dbserialize</span><span class="p">(</span><span class="n">callback</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">):</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">,</span> <span class="n">PickleError</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;the specified callback </span><span class="si">{}</span><span class="s2"> cannot be pickled. &quot;</span>
<span class="s2">&quot;It must be a top-level function in a module or an &quot;</span>
<span class="s2">&quot;instance method.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">callback</span><span class="p">)</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">safe_callback</span> <span class="o">=</span> <span class="n">callback</span>
<span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">dbserialize</span><span class="p">((</span><span class="n">date</span><span class="p">,</span> <span class="n">safe_callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">))</span>
<span class="n">ServerConfig</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">conf</span><span class="p">(</span><span class="s2">&quot;delayed_tasks&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandler.add"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.add">[docs]</a> <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timedelay</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Add a new persistent task in the configuration.</span>
<span class="sd"> Args:</span>
<span class="sd"> timedelay (int or float): time in sedconds before calling the callback.</span>
<span class="sd"> callback (function or instance method): the callback itself</span>
<span class="sd"> any (any): any additional positional arguments to send to the callback</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> persistent (bool, optional): persist the task (store it).</span>
<span class="sd"> any (any): additional keyword arguments to send to the callback</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">persistent</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;persistent&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="n">persistent</span><span class="p">:</span>
<span class="k">del</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;persistent&quot;</span><span class="p">]</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="n">delta</span> <span class="o">=</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=</span><span class="n">timedelay</span><span class="p">)</span>
<span class="c1"># Choose a free task_id</span>
<span class="n">safe_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">safe_kwargs</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">used_ids</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
<span class="n">task_id</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">while</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="n">used_ids</span><span class="p">:</span>
<span class="n">task_id</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span>
<span class="c1"># Check that args and kwargs contain picklable information</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">dbserialize</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">):</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">,</span> <span class="n">PickleError</span><span class="p">):</span>
<span class="n">log_err</span><span class="p">(</span>
<span class="s2">&quot;The positional argument </span><span class="si">{}</span><span class="s2"> cannot be &quot;</span>
<span class="s2">&quot;pickled and will not be present in the arguments &quot;</span>
@ -177,7 +406,7 @@
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">dbserialize</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">):</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">,</span> <span class="n">PickleError</span><span class="p">):</span>
<span class="n">log_err</span><span class="p">(</span>
<span class="s2">&quot;The </span><span class="si">{}</span><span class="s2"> keyword argument </span><span class="si">{}</span><span class="s2"> cannot be &quot;</span>
<span class="s2">&quot;pickled and will not be present in the arguments &quot;</span>
@ -186,59 +415,219 @@
<span class="k">else</span><span class="p">:</span>
<span class="n">safe_kwargs</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">now</span> <span class="o">+</span> <span class="n">delta</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">safe_args</span><span class="p">,</span> <span class="n">safe_kwargs</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">comp_time</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">safe_args</span><span class="p">,</span> <span class="n">safe_kwargs</span><span class="p">,</span> <span class="n">persistent</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="n">callback</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">do_task</span>
<span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">task_id</span><span class="p">]</span>
<span class="n">kwargs</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># this is a non-persitent task</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">comp_time</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">persistent</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">return</span> <span class="n">deferLater</span><span class="p">(</span><span class="n">reactor</span><span class="p">,</span> <span class="n">timedelay</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<span class="c1"># defer the task</span>
<span class="n">callback</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">do_task</span>
<span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">task_id</span><span class="p">]</span>
<span class="n">kwargs</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">deferLater</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">clock</span><span class="p">,</span> <span class="n">timedelay</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">d</span><span class="o">.</span><span class="n">addErrback</span><span class="p">(</span><span class="n">handle_error</span><span class="p">)</span>
<div class="viewcode-block" id="TaskHandler.remove"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.remove">[docs]</a> <span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_id</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Remove a persistent task without executing it.</span>
<span class="c1"># some tasks may complete before the deferred can be added</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="n">task</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="n">task</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">task</span><span class="p">)</span>
<span class="n">task</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">=</span> <span class="n">persistent</span>
<span class="n">task</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">=</span> <span class="n">d</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">task</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># the task already completed</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">stale_timeout</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">clean_stale_tasks</span><span class="p">()</span>
<span class="k">return</span> <span class="n">TaskHandlerTask</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandler.exists"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.exists">[docs]</a> <span class="k">def</span> <span class="nf">exists</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_id</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Check if a task exists.</span>
<span class="sd"> Most task handler methods check for existence for you.</span>
<span class="sd"> Args:</span>
<span class="sd"> task_id (int): an existing task ID.</span>
<span class="sd"> Note:</span>
<span class="sd"> A non-persistent task doesn&#39;t have a task_id, it is not stored</span>
<span class="sd"> in the TaskHandler.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True the task exists False if it does not.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="TaskHandler.active"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.active">[docs]</a> <span class="k">def</span> <span class="nf">active</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_id</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Check if a task is active (has not been called yet).</span>
<span class="sd"> Args:</span>
<span class="sd"> task_id (int): an existing task ID.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if a task is active (has not been called yet). False if</span>
<span class="sd"> it is not (has been called) or if the task does not exist.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="c1"># if the task has not been run, cancel it</span>
<span class="n">deferred</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_deferred</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="k">return</span> <span class="ow">not</span> <span class="p">(</span><span class="n">deferred</span> <span class="ow">and</span> <span class="n">deferred</span><span class="o">.</span><span class="n">called</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="TaskHandler.cancel"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.cancel">[docs]</a> <span class="k">def</span> <span class="nf">cancel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_id</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Stop a task from automatically executing.</span>
<span class="sd"> This will not remove the task.</span>
<span class="sd"> Args:</span>
<span class="sd"> task_id (int): an existing task ID.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if the cancel completed successfully.</span>
<span class="sd"> False if the cancel did not complete successfully.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="c1"># if the task has not been run, cancel it</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_deferred</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="k">if</span> <span class="n">d</span><span class="p">:</span> <span class="c1"># it is remotely possible for a task to not have a deferred</span>
<span class="k">if</span> <span class="n">d</span><span class="o">.</span><span class="n">called</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># the callback has not been called yet.</span>
<span class="n">d</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># this task has no deferred instance</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="TaskHandler.remove"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.remove">[docs]</a> <span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_id</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Remove a task without executing it.</span>
<span class="sd"> Deletes the instance of the task&#39;s deferred.</span>
<span class="sd"> Args:</span>
<span class="sd"> task_id (int): an existing task ID.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: True if the removal completed successfully.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">d</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># delete the task from the tasks dictionary</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="c1"># if the task has not been run, cancel it</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cancel</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="c1"># delete the task from the tasks dictionary</span>
<span class="c1"># remove the task from the persistent dictionary and ServerConfig</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">:</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">()</span> <span class="c1"># remove from ServerConfig.objects</span>
<span class="c1"># delete the instance of the deferred</span>
<span class="k">if</span> <span class="n">d</span><span class="p">:</span>
<span class="k">del</span> <span class="n">d</span>
<span class="k">return</span> <span class="kc">True</span></div>
<span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">()</span></div>
<div class="viewcode-block" id="TaskHandler.clear"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.clear">[docs]</a> <span class="k">def</span> <span class="nf">clear</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">save</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">cancel</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;clear all tasks.</span>
<span class="sd"> By default tasks are canceled and removed from the database also.</span>
<span class="sd"> Args:</span>
<span class="sd"> save=True (bool): Should changes to persistent tasks be saved to database.</span>
<span class="sd"> cancel=True (bool): Cancel scheduled tasks before removing it from task handler.</span>
<span class="sd"> Returns:</span>
<span class="sd"> True (bool): if the removal completed successfully.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="k">for</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
<span class="k">if</span> <span class="n">cancel</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cancel</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">to_save</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">if</span> <span class="n">save</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="TaskHandler.call_task"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.call_task">[docs]</a> <span class="k">def</span> <span class="nf">call_task</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_id</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Call the callback of a task.</span>
<span class="sd"> Leave the task unaffected otherwise.</span>
<span class="sd"> This does not use the task&#39;s deferred instance.</span>
<span class="sd"> The only requirement is that the task exist in task handler.</span>
<span class="sd"> Args:</span>
<span class="sd"> task_id (int): an existing task ID.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool or any: Set to `False` if the task does not exist in task</span>
<span class="sd"> handler. Otherwise it will be the return of the task&#39;s callback.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">persistent</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># the task does not exist</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">return</span> <span class="n">callback</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandler.do_task"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.do_task">[docs]</a> <span class="k">def</span> <span class="nf">do_task</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_id</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Execute the task (call its callback).</span>
<span class="sd"> If calling before timedelay cancel the deferred instance affliated to this task.</span>
<span class="sd"> Remove the task from the dictionary of current tasks on a successful</span>
<span class="sd"> callback.</span>
<span class="sd"> Args:</span>
<span class="sd"> task_id (int): a valid task ID.</span>
<span class="sd"> Note:</span>
<span class="sd"> This will also remove it from the list of current tasks.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool or any: Set to `False` if the task does not exist in task</span>
<span class="sd"> handler. Otherwise it will be the return of the task&#39;s callback.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">:</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_save</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span>
<span class="n">callback_return</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">persistent</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># the task does not exist</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">d</span><span class="p">:</span> <span class="c1"># it is remotely possible for a task to not have a deferred</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">d</span><span class="o">.</span><span class="n">called</span><span class="p">:</span> <span class="c1"># the task&#39;s deferred has not been called yet</span>
<span class="n">d</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span> <span class="c1"># cancel the automated callback</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># this task has no deferred, and should not be called</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="n">callback_return</span> <span class="o">=</span> <span class="n">callback</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">task_id</span><span class="p">)</span>
<span class="k">return</span> <span class="n">callback_return</span></div>
<span class="bp">self</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="n">callback</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="TaskHandler.get_deferred"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.get_deferred">[docs]</a> <span class="k">def</span> <span class="nf">get_deferred</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">task_id</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return the instance of the deferred the task id is using.</span>
<span class="sd"> Args:</span>
<span class="sd"> task_id (int): a valid task ID.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool or deferred: An instance of a deferred or False if there is no task with the id.</span>
<span class="sd"> None is returned if there is no deferred affiliated with this id.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">task_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">][</span><span class="mi">5</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span></div>
<div class="viewcode-block" id="TaskHandler.create_delays"><a class="viewcode-back" href="../../../api/evennia.scripts.taskhandler.html#evennia.scripts.taskhandler.TaskHandler.create_delays">[docs]</a> <span class="k">def</span> <span class="nf">create_delays</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Create the delayed tasks for the persistent tasks.</span>
<span class="sd"> Note:</span>
<span class="sd"> This method should be automatically called when Evennia starts.</span>
<span class="sd"> This method should be automatically called when Evennia starts.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="k">for</span> <span class="n">task_id</span><span class="p">,</span> <span class="p">(</span><span class="n">date</span><span class="p">,</span> <span class="n">callbac</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">for</span> <span class="n">task_id</span><span class="p">,</span> <span class="p">(</span><span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="kc">True</span><span class="p">,</span> <span class="kc">None</span>
<span class="n">seconds</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="n">date</span> <span class="o">-</span> <span class="n">now</span><span class="p">)</span><span class="o">.</span><span class="n">total_seconds</span><span class="p">())</span>
<span class="n">deferLater</span><span class="p">(</span><span class="n">reactor</span><span class="p">,</span> <span class="n">seconds</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">do_task</span><span class="p">,</span> <span class="n">task_id</span><span class="p">)</span></div></div>
<span class="n">d</span> <span class="o">=</span> <span class="n">deferLater</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">clock</span><span class="p">,</span> <span class="n">seconds</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">do_task</span><span class="p">,</span> <span class="n">task_id</span><span class="p">)</span>
<span class="n">d</span><span class="o">.</span><span class="n">addErrback</span><span class="p">(</span><span class="n">handle_error</span><span class="p">)</span>
<span class="c1"># some tasks may complete before the deferred can be added</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">task_id</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">tasks</span><span class="p">[</span><span class="n">task_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">date</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="kc">True</span><span class="p">,</span> <span class="n">d</span></div></div>
<span class="c1"># Create the soft singleton</span>

View file

@ -158,8 +158,12 @@
<span class="s2">&quot;settings.CYCLE_LOGFILES is unused and should be removed. &quot;</span>
<span class="s2">&quot;Use PORTAL/SERVER_LOG_DAY_ROTATION and PORTAL/SERVER_LOG_MAX_SIZE &quot;</span>
<span class="s2">&quot;to control log cycling.&quot;</span>
<span class="p">)</span></div>
<span class="p">)</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s2">&quot;CHANNEL_COMMAND_CLASS&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s2">&quot;CHANNEL_HANDLER_CLASS&quot;</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">DeprecationWarning</span><span class="p">(</span>
<span class="s2">&quot;settings.CHANNEL_HANDLER_CLASS and CHANNEL COMMAND_CLASS are &quot;</span>
<span class="s2">&quot;unused and should be removed. The ChannelHandler is no more; &quot;</span>
<span class="s2">&quot;channels are now handled by aliasing the default &#39;channel&#39; command.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="check_warnings"><a class="viewcode-back" href="../../../api/evennia.server.deprecations.html#evennia.server.deprecations.check_warnings">[docs]</a><span class="k">def</span> <span class="nf">check_warnings</span><span class="p">(</span><span class="n">settings</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>

View file

@ -173,10 +173,9 @@
<span class="n">goduser</span> <span class="o">=</span> <span class="n">get_god_account</span><span class="p">()</span>
<span class="n">channel_mudinfo</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_MUDINFO</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel_mudinfo</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;settings.CHANNEL_MUDINFO must be defined.&quot;</span><span class="p">)</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_channel</span><span class="p">(</span><span class="o">**</span><span class="n">channel_mudinfo</span><span class="p">)</span>
<span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">goduser</span><span class="p">)</span>
<span class="k">if</span> <span class="n">channel_mudinfo</span><span class="p">:</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_channel</span><span class="p">(</span><span class="o">**</span><span class="n">channel_mudinfo</span><span class="p">)</span>
<span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">goduser</span><span class="p">)</span>
<span class="n">channel_connectinfo</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_CONNECTINFO</span>
<span class="k">if</span> <span class="n">channel_connectinfo</span><span class="p">:</span>

View file

@ -120,11 +120,11 @@
<span class="n">puppet</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">puppet</span>
<span class="k">if</span> <span class="n">puppet</span><span class="p">:</span>
<span class="n">txt</span> <span class="o">=</span> <span class="n">puppet</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">nickreplace</span><span class="p">(</span>
<span class="n">txt</span><span class="p">,</span> <span class="n">categories</span><span class="o">=</span><span class="p">(</span><span class="s2">&quot;inputline&quot;</span><span class="p">,</span> <span class="s2">&quot;channel&quot;</span><span class="p">),</span> <span class="n">include_account</span><span class="o">=</span><span class="kc">True</span>
<span class="n">txt</span><span class="p">,</span> <span class="n">categories</span><span class="o">=</span><span class="p">(</span><span class="s2">&quot;inputline&quot;</span><span class="p">),</span> <span class="n">include_account</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="n">txt</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">account</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">nickreplace</span><span class="p">(</span>
<span class="n">txt</span><span class="p">,</span> <span class="n">categories</span><span class="o">=</span><span class="p">(</span><span class="s2">&quot;inputline&quot;</span><span class="p">,</span> <span class="s2">&quot;channel&quot;</span><span class="p">),</span> <span class="n">include_account</span><span class="o">=</span><span class="kc">False</span>
<span class="n">txt</span><span class="p">,</span> <span class="n">categories</span><span class="o">=</span><span class="p">(</span><span class="s2">&quot;inputline&quot;</span><span class="p">),</span> <span class="n">include_account</span><span class="o">=</span><span class="kc">False</span>
<span class="p">)</span>
<span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;options&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="n">cmdhandler</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="n">txt</span><span class="p">,</span> <span class="n">callertype</span><span class="o">=</span><span class="s2">&quot;session&quot;</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="n">session</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

View file

@ -82,6 +82,9 @@
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span> <span class="o">=</span> <span class="n">protocol</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;NOGOAHEAD&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span>
<span class="s2">&quot;NOPROMPTGOAHEAD&quot;</span>
<span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># Used to send a GA after a prompt line only, set in TTYPE (per client)</span>
<span class="c1"># tell the client that we prefer to suppress GA ...</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="o">.</span><span class="n">will</span><span class="p">(</span><span class="n">SUPPRESS_GA</span><span class="p">)</span><span class="o">.</span><span class="n">addCallbacks</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">will_suppress_ga</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">wont_suppress_ga</span><span class="p">)</span></div>

View file

@ -484,7 +484,9 @@
<span class="n">prompt</span> <span class="o">=</span> <span class="n">mxp_parse</span><span class="p">(</span><span class="n">prompt</span><span class="p">)</span>
<span class="n">prompt</span> <span class="o">=</span> <span class="n">to_bytes</span><span class="p">(</span><span class="n">prompt</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
<span class="n">prompt</span> <span class="o">=</span> <span class="n">prompt</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">IAC</span><span class="p">,</span> <span class="n">IAC</span> <span class="o">+</span> <span class="n">IAC</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="sa">b</span><span class="s2">&quot;</span><span class="se">\r\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">prompt</span> <span class="o">+=</span> <span class="n">IAC</span> <span class="o">+</span> <span class="n">GA</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">protocol_flags</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;NOPROMPTGOAHEAD&quot;</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol_flags</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;NOGOAHEAD&quot;</span><span class="p">,</span> <span class="kc">True</span><span class="p">)):</span>
<span class="n">prompt</span> <span class="o">+=</span> <span class="n">IAC</span> <span class="o">+</span> <span class="n">GA</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">mccp_compress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">prompt</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">echo</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>

View file

@ -273,7 +273,6 @@
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;localhost&quot;</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">setTcpKeepAlive</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">makeConnection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="p">)</span>
<span class="c1"># test suppress_ga</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;NOGOAHEAD&quot;</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">dataReceived</span><span class="p">(</span><span class="n">IAC</span> <span class="o">+</span> <span class="n">DONT</span> <span class="o">+</span> <span class="n">SUPPRESS_GA</span><span class="p">)</span>
@ -288,13 +287,15 @@
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;SCREENHEIGHT&quot;</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="mi">45</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">handshakes</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span>
<span class="c1"># test ttype</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;FORCEDENDLINE&quot;</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;TTYPE&quot;</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;ANSI&quot;</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">dataReceived</span><span class="p">(</span><span class="n">IAC</span> <span class="o">+</span> <span class="n">WILL</span> <span class="o">+</span> <span class="n">TTYPE</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">dataReceived</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">IAC</span><span class="p">,</span> <span class="n">SB</span><span class="p">,</span> <span class="n">TTYPE</span><span class="p">,</span> <span class="n">IS</span><span class="p">,</span> <span class="sa">b</span><span class="s2">&quot;MUDLET&quot;</span><span class="p">,</span> <span class="n">IAC</span><span class="p">,</span> <span class="n">SE</span><span class="p">]))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;XTERM256&quot;</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;CLIENTNAME&quot;</span><span class="p">],</span> <span class="s2">&quot;MUDLET&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;FORCEDENDLINE&quot;</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;NOGOAHEAD&quot;</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;NOPROMPTGOAHEAD&quot;</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">dataReceived</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">IAC</span><span class="p">,</span> <span class="n">SB</span><span class="p">,</span> <span class="n">TTYPE</span><span class="p">,</span> <span class="n">IS</span><span class="p">,</span> <span class="sa">b</span><span class="s2">&quot;XTERM&quot;</span><span class="p">,</span> <span class="n">IAC</span><span class="p">,</span> <span class="n">SE</span><span class="p">]))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">dataReceived</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">IAC</span><span class="p">,</span> <span class="n">SB</span><span class="p">,</span> <span class="n">TTYPE</span><span class="p">,</span> <span class="n">IS</span><span class="p">,</span> <span class="sa">b</span><span class="s2">&quot;MTTS 137&quot;</span><span class="p">,</span> <span class="n">IAC</span><span class="p">,</span> <span class="n">SE</span><span class="p">]))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proto</span><span class="o">.</span><span class="n">handshakes</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>

View file

@ -161,10 +161,11 @@
<span class="k">if</span> <span class="n">clientname</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;MUDLET&quot;</span><span class="p">):</span>
<span class="c1"># supports xterm256 stably since 1.1 (2010?)</span>
<span class="n">xterm256</span> <span class="o">=</span> <span class="n">clientname</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;MUDLET&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="s2">&quot;1.1&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;FORCEDENDLINE&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">clientname</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;TINTIN++&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;FORCEDENDLINE&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="c1"># Mudlet likes GA&#39;s on a prompt line for the prompt trigger to</span>
<span class="c1"># match, if it&#39;s not wanting NOGOAHEAD.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;NOGOAHEAD&quot;</span><span class="p">]:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;NOGOAHEAD&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">protocol</span><span class="o">.</span><span class="n">protocol_flags</span><span class="p">[</span><span class="s2">&quot;NOPROMPTGOAHEAD&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="p">(</span>
<span class="n">clientname</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;XTERM&quot;</span><span class="p">)</span>

View file

@ -78,7 +78,6 @@
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">get_evennia_version</span><span class="p">,</span> <span class="n">mod_import</span><span class="p">,</span> <span class="n">make_iter</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">logger</span>
<span class="kn">from</span> <span class="nn">evennia.comms</span> <span class="kn">import</span> <span class="n">channelhandler</span>
<span class="kn">from</span> <span class="nn">evennia.server.sessionhandler</span> <span class="kn">import</span> <span class="n">SESSIONS</span>
<span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="kn">import</span> <span class="n">gettext</span> <span class="k">as</span> <span class="n">_</span>
@ -185,12 +184,6 @@
<span class="k">if</span> <span class="n">_MAINTENANCE_COUNT</span> <span class="o">%</span> <span class="mi">5</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># check cache size every 5 minutes</span>
<span class="n">_FLUSH_CACHE</span><span class="p">(</span><span class="n">_IDMAPPER_CACHE_MAXSIZE</span><span class="p">)</span>
<span class="k">if</span> <span class="n">_MAINTENANCE_COUNT</span> <span class="o">%</span> <span class="mi">60</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># validate scripts every hour</span>
<span class="n">evennia</span><span class="o">.</span><span class="n">ScriptDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">validate</span><span class="p">()</span>
<span class="k">if</span> <span class="n">_MAINTENANCE_COUNT</span> <span class="o">%</span> <span class="mi">61</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># validate channels off-sync with scripts</span>
<span class="n">evennia</span><span class="o">.</span><span class="n">CHANNEL_HANDLER</span><span class="o">.</span><span class="n">update</span><span class="p">()</span>
<span class="k">if</span> <span class="n">_MAINTENANCE_COUNT</span> <span class="o">%</span> <span class="p">(</span><span class="mi">60</span> <span class="o">*</span> <span class="mi">7</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># drop database connection every 7 hrs to avoid default timeouts on MySQL</span>
<span class="c1"># (see https://github.com/evennia/evennia/issues/1376)</span>
@ -247,12 +240,6 @@
<span class="bp">self</span><span class="o">.</span><span class="n">start_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="c1"># initialize channelhandler</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">channelhandler</span><span class="o">.</span><span class="n">CHANNELHANDLER</span><span class="o">.</span><span class="n">update</span><span class="p">()</span>
<span class="k">except</span> <span class="n">OperationalError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;channelhandler couldn&#39;t update - db not set up&quot;</span><span class="p">)</span>
<span class="c1"># wrap the SIGINT handler to make sure we empty the threadpool</span>
<span class="c1"># even when we reload and we have long-running requests in queue.</span>
<span class="c1"># this is necessary over using Twisted&#39;s signal handler.</span>
@ -589,11 +576,10 @@
<span class="n">god_account</span> <span class="o">=</span> <span class="n">AccountDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># mudinfo</span>
<span class="n">mudinfo_chan</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_MUDINFO</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">mudinfo_chan</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;settings.CHANNEL_MUDINFO must be defined.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">ChannelDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="n">mudinfo_chan</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">]):</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">create_channel</span><span class="p">(</span><span class="o">**</span><span class="n">mudinfo_chan</span><span class="p">)</span>
<span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">god_account</span><span class="p">)</span>
<span class="k">if</span> <span class="n">mudinfo_chan</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">ChannelDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">db_key</span><span class="o">=</span><span class="n">mudinfo_chan</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">]):</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">create_channel</span><span class="p">(</span><span class="o">**</span><span class="n">mudinfo_chan</span><span class="p">)</span>
<span class="n">channel</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">god_account</span><span class="p">)</span>
<span class="c1"># connectinfo</span>
<span class="n">connectinfo_chan</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_MUDINFO</span>
<span class="k">if</span> <span class="n">connectinfo_chan</span><span class="p">:</span>

View file

@ -1037,7 +1037,8 @@
<span class="sd"> looked-after Attribute.</span>
<span class="sd"> default_access (bool, optional): If no `attrread` lock is set on</span>
<span class="sd"> object, this determines if the lock should then be passed or not.</span>
<span class="sd"> return_list (bool, optional):</span>
<span class="sd"> return_list (bool, optional): Always return a list, also if there is only</span>
<span class="sd"> one or zero matches found.</span>
<span class="sd"> Returns:</span>
<span class="sd"> result (any or list): One or more matches for keys and/or</span>
@ -1277,7 +1278,7 @@
<span class="n">_SA</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__setattr__</span>
<div class="viewcode-block" id="DbHolder"><a class="viewcode-back" href="../../../api/evennia.typeclasses.attributes.html#evennia.typeclasses.attributes.DbHolder">[docs]</a><span class="k">class</span> <span class="nc">DbHolder</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<div class="viewcode-block" id="DbHolder"><a class="viewcode-back" href="../../../api/evennia.typeclasses.attributes.html#evennia.typeclasses.attributes.DbHolder">[docs]</a><span class="k">class</span> <span class="nc">DbHolder</span><span class="p">:</span>
<span class="s2">&quot;Holder for allowing property access of attributes&quot;</span>
<div class="viewcode-block" id="DbHolder.__init__"><a class="viewcode-back" href="../../../api/evennia.typeclasses.attributes.html#evennia.typeclasses.attributes.DbHolder.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">manager_name</span><span class="o">=</span><span class="s2">&quot;attributes&quot;</span><span class="p">):</span>
@ -1333,8 +1334,10 @@
<span class="sd"> $N argument position (1-99)</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="n">_RE_OR</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;(?&lt;!</span><span class="se">\\</span><span class="s2">)\|&quot;</span><span class="p">)</span>
<span class="n">_RE_NICK_RE_ARG</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;arg([1-9][0-9]?)&quot;</span><span class="p">)</span>
<span class="n">_RE_NICK_ARG</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">(\$)([1-9][0-9]?)&quot;</span><span class="p">)</span>
<span class="n">_RE_NICK_TEMPLATE_ARG</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;(\$)([1-9][0-9]?)&quot;</span><span class="p">)</span>
<span class="n">_RE_NICK_RAW_ARG</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;(\$)([1-9][0-9]?)&quot;</span><span class="p">)</span>
<span class="n">_RE_NICK_SPACE</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2"> &quot;</span><span class="p">)</span>
@ -1342,45 +1345,72 @@
<span class="k">pass</span></div>
<div class="viewcode-block" id="initialize_nick_templates"><a class="viewcode-back" href="../../../api/evennia.typeclasses.attributes.html#evennia.typeclasses.attributes.initialize_nick_templates">[docs]</a><span class="k">def</span> <span class="nf">initialize_nick_templates</span><span class="p">(</span><span class="n">in_template</span><span class="p">,</span> <span class="n">out_template</span><span class="p">):</span>
<div class="viewcode-block" id="initialize_nick_templates"><a class="viewcode-back" href="../../../api/evennia.typeclasses.attributes.html#evennia.typeclasses.attributes.initialize_nick_templates">[docs]</a><span class="k">def</span> <span class="nf">initialize_nick_templates</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">replacement</span><span class="p">,</span> <span class="n">pattern_is_regex</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Initialize the nick templates for matching and remapping a string.</span>
<span class="sd"> Args:</span>
<span class="sd"> in_template (str): The template to be used for nick recognition.</span>
<span class="sd"> out_template (str): The template to be used to replace the string</span>
<span class="sd"> matched by the in_template.</span>
<span class="sd"> pattern (str): The pattern to be used for nick recognition. This will</span>
<span class="sd"> be parsed for shell patterns into a regex, unless `pattern_is_regex`</span>
<span class="sd"> is `True`, in which case it must be an already valid regex string. In</span>
<span class="sd"> this case, instead of `$N`, numbered arguments must instead be given</span>
<span class="sd"> as matching groups named as `argN`, such as `(?P&lt;arg1&gt;.+?)`.</span>
<span class="sd"> replacement (str): The template to be used to replace the string</span>
<span class="sd"> matched by the pattern. This can contain `$N` markers and is never</span>
<span class="sd"> parsed into a regex.</span>
<span class="sd"> pattern_is_regex (bool): If set, `pattern` is a full regex string</span>
<span class="sd"> instead of containing shell patterns.</span>
<span class="sd"> Returns:</span>
<span class="sd"> regex (regex): Regex to match against strings</span>
<span class="sd"> template (str): Template with markers ``{arg1}, {arg2}``, etc for</span>
<span class="sd"> replacement using the standard .format method.</span>
<span class="sd"> regex, template (str): Regex to match against strings and template</span>
<span class="sd"> with markers ``{arg1}, {arg2}``, etc for replacement using the standard</span>
<span class="sd"> `.format` method.</span>
<span class="sd"> Raises:</span>
<span class="sd"> evennia.typecalasses.attributes.NickTemplateInvalid: If the in/out</span>
<span class="sd"> template does not have a matching number of `$args`.</span>
<span class="sd"> Examples:</span>
<span class="sd"> - `pattern` (shell syntax): `&quot;grin $1&quot;`</span>
<span class="sd"> - `pattern` (regex): `&quot;grin (?P&lt;arg1.+?&gt;)&quot;`</span>
<span class="sd"> - `replacement`: `&quot;emote gives a wicked grin to $1&quot;`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># create the regex for in_template</span>
<span class="n">regex_string</span> <span class="o">=</span> <span class="n">fnmatch</span><span class="o">.</span><span class="n">translate</span><span class="p">(</span><span class="n">in_template</span><span class="p">)</span>
<span class="c1"># we must account for a possible line break coming over the wire</span>
<span class="c1"># create the regex from the pattern</span>
<span class="k">if</span> <span class="n">pattern_is_regex</span><span class="p">:</span>
<span class="c1"># Note that for a regex we can&#39;t validate in the way we do for the shell</span>
<span class="c1"># pattern, since you may have complex OR statements or optional arguments.</span>
<span class="c1"># NOTE-PYTHON3: fnmatch.translate format changed since Python2</span>
<span class="n">regex_string</span> <span class="o">=</span> <span class="n">regex_string</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="sa">r</span><span class="s2">&quot;(?:[\n\r]*?)\Z&quot;</span>
<span class="c1"># Explicit regex given from the onset - this already contains argN</span>
<span class="c1"># groups. we need to split out any | - separated parts so we can</span>
<span class="c1"># attach the line-break/ending extras all regexes require.</span>
<span class="n">pattern_regex_string</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">&quot;|&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="n">or_part</span> <span class="o">+</span> <span class="sa">r</span><span class="s2">&quot;(?:[\n\r]*?)\Z&quot;</span>
<span class="k">for</span> <span class="n">or_part</span> <span class="ow">in</span> <span class="n">_RE_OR</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">pattern</span><span class="p">))</span>
<span class="c1"># validate the templates</span>
<span class="n">regex_args</span> <span class="o">=</span> <span class="p">[</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">_RE_NICK_ARG</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="n">regex_string</span><span class="p">)]</span>
<span class="n">temp_args</span> <span class="o">=</span> <span class="p">[</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">_RE_NICK_TEMPLATE_ARG</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="n">out_template</span><span class="p">)]</span>
<span class="k">if</span> <span class="nb">set</span><span class="p">(</span><span class="n">regex_args</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">set</span><span class="p">(</span><span class="n">temp_args</span><span class="p">):</span>
<span class="c1"># We don&#39;t have the same $-tags in input/output.</span>
<span class="k">raise</span> <span class="n">NickTemplateInvalid</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Shell pattern syntax - convert $N to argN groups</span>
<span class="c1"># for the shell pattern we make sure we have matching $N on both sides</span>
<span class="n">pattern_args</span> <span class="o">=</span> <span class="p">[</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">_RE_NICK_RAW_ARG</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="n">pattern</span><span class="p">)]</span>
<span class="n">replacement_args</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">_RE_NICK_RAW_ARG</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="n">replacement</span><span class="p">)]</span>
<span class="k">if</span> <span class="nb">set</span><span class="p">(</span><span class="n">pattern_args</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">set</span><span class="p">(</span><span class="n">replacement_args</span><span class="p">):</span>
<span class="c1"># We don&#39;t have the same amount of argN/$N tags in input/output.</span>
<span class="k">raise</span> <span class="n">NickTemplateInvalid</span><span class="p">(</span><span class="s2">&quot;Nicks: Both in/out-templates must contain the same $N tags.&quot;</span><span class="p">)</span>
<span class="n">regex_string</span> <span class="o">=</span> <span class="n">_RE_NICK_SPACE</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">s+&quot;</span><span class="p">,</span> <span class="n">regex_string</span><span class="p">)</span>
<span class="n">regex_string</span> <span class="o">=</span> <span class="n">_RE_NICK_ARG</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="s2">&quot;(?P&lt;arg</span><span class="si">%s</span><span class="s2">&gt;.+?)&quot;</span> <span class="o">%</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span> <span class="n">regex_string</span><span class="p">)</span>
<span class="n">template_string</span> <span class="o">=</span> <span class="n">_RE_NICK_TEMPLATE_ARG</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="s2">&quot;{arg</span><span class="si">%s</span><span class="s2">}&quot;</span> <span class="o">%</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span> <span class="n">out_template</span><span class="p">)</span>
<span class="c1"># generate regex from shell pattern</span>
<span class="n">pattern_regex_string</span> <span class="o">=</span> <span class="n">fnmatch</span><span class="o">.</span><span class="n">translate</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span>
<span class="n">pattern_regex_string</span> <span class="o">=</span> <span class="n">_RE_NICK_SPACE</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">s+&quot;</span><span class="p">,</span> <span class="n">pattern_regex_string</span><span class="p">)</span>
<span class="n">pattern_regex_string</span> <span class="o">=</span> <span class="n">_RE_NICK_ARG</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span>
<span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="s2">&quot;(?P&lt;arg</span><span class="si">%s</span><span class="s2">&gt;.+?)&quot;</span> <span class="o">%</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span> <span class="n">pattern_regex_string</span><span class="p">)</span>
<span class="c1"># we must account for a possible line break coming over the wire</span>
<span class="n">pattern_regex_string</span> <span class="o">=</span> <span class="n">pattern_regex_string</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="sa">r</span><span class="s2">&quot;(?:[\n\r]*?)\Z&quot;</span>
<span class="k">return</span> <span class="n">regex_string</span><span class="p">,</span> <span class="n">template_string</span></div>
<span class="c1"># map the replacement to match the arg1 group-names, to make replacement easy</span>
<span class="n">replacement_string</span> <span class="o">=</span> <span class="n">_RE_NICK_RAW_ARG</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="s2">&quot;{arg</span><span class="si">%s</span><span class="s2">}&quot;</span> <span class="o">%</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span> <span class="n">replacement</span><span class="p">)</span>
<span class="k">return</span> <span class="n">pattern_regex_string</span><span class="p">,</span> <span class="n">replacement_string</span></div>
<div class="viewcode-block" id="parse_nick_template"><a class="viewcode-back" href="../../../api/evennia.typeclasses.attributes.html#evennia.typeclasses.attributes.parse_nick_template">[docs]</a><span class="k">def</span> <span class="nf">parse_nick_template</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="n">template_regex</span><span class="p">,</span> <span class="n">outtemplate</span><span class="p">):</span>
@ -1388,17 +1418,21 @@
<span class="sd"> Parse a text using a template and map it to another template</span>
<span class="sd"> Args:</span>
<span class="sd"> string (str): The input string to processj</span>
<span class="sd"> string (str): The input string to process</span>
<span class="sd"> template_regex (regex): A template regex created with</span>
<span class="sd"> initialize_nick_template.</span>
<span class="sd"> outtemplate (str): The template to which to map the matches</span>
<span class="sd"> produced by the template_regex. This should have $1, $2,</span>
<span class="sd"> etc to match the regex.</span>
<span class="sd"> etc to match the template-regex. Un-found $N-markers (possible if</span>
<span class="sd"> the regex has optional matching groups) are replaced with empty</span>
<span class="sd"> strings.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">match</span> <span class="o">=</span> <span class="n">template_regex</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">if</span> <span class="n">match</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="n">outtemplate</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">match</span><span class="o">.</span><span class="n">groupdict</span><span class="p">())</span>
<span class="n">matchdict</span> <span class="o">=</span> <span class="p">{</span><span class="n">key</span><span class="p">:</span> <span class="n">value</span> <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">match</span><span class="o">.</span><span class="n">groupdict</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
<span class="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="n">outtemplate</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">matchdict</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="n">string</span></div>
@ -1447,6 +1481,9 @@
<span class="sd"> a string.</span>
<span class="sd"> kwargs (any, optional): These are passed on to `AttributeHandler.get`.</span>
<span class="sd"> Returns:</span>
<span class="sd"> str or tuple: The nick replacement string or nick tuple.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">return_tuple</span> <span class="ow">or</span> <span class="s2">&quot;return_obj&quot;</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">key</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="o">**</span><span class="n">kwargs</span><span class="p">)</span>
@ -1460,24 +1497,46 @@
<span class="p">)</span>
<span class="k">return</span> <span class="kc">None</span></div>
<div class="viewcode-block" id="NickHandler.add"><a class="viewcode-back" href="../../../api/evennia.typeclasses.attributes.html#evennia.typeclasses.attributes.NickHandler.add">[docs]</a> <span class="k">def</span> <span class="nf">add</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">replacement</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">&quot;inputline&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<div class="viewcode-block" id="NickHandler.add"><a class="viewcode-back" href="../../../api/evennia.typeclasses.attributes.html#evennia.typeclasses.attributes.NickHandler.add">[docs]</a> <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">replacement</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="s2">&quot;inputline&quot;</span><span class="p">,</span> <span class="n">pattern_is_regex</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Add a new nick.</span>
<span class="sd"> Add a new nick, a mapping pattern -&gt; replacement.</span>
<span class="sd"> Args:</span>
<span class="sd"> key (str): A key (or template) for the nick to match for.</span>
<span class="sd"> replacement (str): The string (or template) to replace `key` with (the &quot;nickname&quot;).</span>
<span class="sd"> pattern (str): A pattern to match for. This will be parsed for</span>
<span class="sd"> shell patterns using the `fnmatch` library and can contain</span>
<span class="sd"> `$N`-markers to indicate the locations of arguments to catch. If</span>
<span class="sd"> `pattern_is_regex=True`, this must instead be a valid regular</span>
<span class="sd"> expression and the `$N`-markers must be named `argN` that matches</span>
<span class="sd"> numbered regex groups (see examples).</span>
<span class="sd"> replacement (str): The string (or template) to replace `key` with</span>
<span class="sd"> (the &quot;nickname&quot;). This may contain `$N` markers to indicate where to</span>
<span class="sd"> place the argument-matches</span>
<span class="sd"> category (str, optional): the category within which to</span>
<span class="sd"> retrieve the nick. The &quot;inputline&quot; means replacing data</span>
<span class="sd"> sent by the user.</span>
<span class="sd"> kwargs (any, optional): These are passed on to `AttributeHandler.get`.</span>
<span class="sd"> pattern_is_regex (bool): If `True`, the `pattern` will be parsed as a</span>
<span class="sd"> raw regex string. Instead of using `$N` markers in this string, one</span>
<span class="sd"> then must mark numbered arguments as a named regex-groupd named `argN`.</span>
<span class="sd"> For example, `(?P&lt;arg1&gt;.+?)` will match the behavior of using `$1`</span>
<span class="sd"> in the shell pattern.</span>
<span class="sd"> **kwargs (any, optional): These are passed on to `AttributeHandler.get`.</span>
<span class="sd"> Notes:</span>
<span class="sd"> For most cases, the shell-pattern is much shorter and easier. The</span>
<span class="sd"> regex pattern form can be useful for more complex matchings though,</span>
<span class="sd"> for example in order to add optional arguments, such as with</span>
<span class="sd"> `(?P&lt;argN&gt;.*?)`.</span>
<span class="sd"> Example:</span>
<span class="sd"> - pattern (default shell syntax): `&quot;gr $1 at $2&quot;`</span>
<span class="sd"> - pattern (with pattern_is_regex=True): `r&quot;gr (?P&lt;arg1&gt;.+?) at (?P&lt;arg2&gt;.+?)&quot;`</span>
<span class="sd"> - replacement: `&quot;emote With a flourish, $1 grins at $2.&quot;`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">category</span> <span class="o">==</span> <span class="s2">&quot;channel&quot;</span><span class="p">:</span>
<span class="n">nick_regex</span><span class="p">,</span> <span class="n">nick_template</span> <span class="o">=</span> <span class="n">initialize_nick_templates</span><span class="p">(</span><span class="n">key</span> <span class="o">+</span> <span class="s2">&quot; $1&quot;</span><span class="p">,</span> <span class="n">replacement</span> <span class="o">+</span> <span class="s2">&quot; $1&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">nick_regex</span><span class="p">,</span> <span class="n">nick_template</span> <span class="o">=</span> <span class="n">initialize_nick_templates</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">replacement</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="p">(</span><span class="n">nick_regex</span><span class="p">,</span> <span class="n">nick_template</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">replacement</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="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<span class="n">nick_regex</span><span class="p">,</span> <span class="n">nick_template</span> <span class="o">=</span> <span class="n">initialize_nick_templates</span><span class="p">(</span>
<span class="n">pattern</span><span class="p">,</span> <span class="n">replacement</span><span class="p">,</span> <span class="n">pattern_is_regex</span><span class="o">=</span><span class="n">pattern_is_regex</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="p">(</span><span class="n">nick_regex</span><span class="p">,</span> <span class="n">nick_template</span><span class="p">,</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">replacement</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="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="NickHandler.remove"><a class="viewcode-back" href="../../../api/evennia.typeclasses.attributes.html#evennia.typeclasses.attributes.NickHandler.remove">[docs]</a> <span class="k">def</span> <span class="nf">remove</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">category</span><span class="o">=</span><span class="s2">&quot;inputline&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>

View file

@ -74,7 +74,6 @@
<span class="n">_AccountDB</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_to_object</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_ChannelDB</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_channelhandler</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># limit symbol import from API</span>
@ -403,22 +402,21 @@
<div class="viewcode-block" id="create_message"><a class="viewcode-back" href="../../../api/evennia.utils.create.html#evennia.utils.create.create_message">[docs]</a><span class="k">def</span> <span class="nf">create_message</span><span class="p">(</span>
<span class="n">senderobj</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">channels</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">receivers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">locks</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">tags</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="kc">None</span>
<span class="p">):</span>
<span class="n">senderobj</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">receivers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">locks</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">tags</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">header</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create a new communication Msg. Msgs represent a unit of</span>
<span class="sd"> database-persistent communication between entites.</span>
<span class="sd"> Args:</span>
<span class="sd"> senderobj (Object or Account): The entity sending the Msg.</span>
<span class="sd"> senderobj (Object, Account, Script, str or list): The entity (or</span>
<span class="sd"> entities) sending the Msg. If a `str`, this is the id-string</span>
<span class="sd"> for an external sender type.</span>
<span class="sd"> message (str): Text with the message. Eventual headers, titles</span>
<span class="sd"> etc should all be included in this text string. Formatting</span>
<span class="sd"> will be retained.</span>
<span class="sd"> channels (Channel, key or list): A channel or a list of channels to</span>
<span class="sd"> send to. The channels may be actual channel objects or their</span>
<span class="sd"> unique key strings.</span>
<span class="sd"> receivers (Object, Account, str or list): An Account/Object to send</span>
<span class="sd"> to, or a list of them. May be Account objects or accountnames.</span>
<span class="sd"> receivers (Object, Account or list): An Account/Object to send</span>
<span class="sd"> to, or a list of them.</span>
<span class="sd"> locks (str): Lock definition string.</span>
<span class="sd"> tags (list): A list of tags or tuples `(tag, category)`.</span>
<span class="sd"> header (str): Mime-type or other optional information for the message</span>
@ -430,6 +428,12 @@
<span class="sd"> limit this as desired.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="s1">&#39;channels&#39;</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">DeprecationWarning</span><span class="p">(</span>
<span class="s2">&quot;create_message() does not accept &#39;channel&#39; kwarg anymore &quot;</span>
<span class="s2">&quot;- channels no longer accept Msg objects.&quot;</span>
<span class="p">)</span>
<span class="k">global</span> <span class="n">_Msg</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_Msg</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">evennia.comms.models</span> <span class="kn">import</span> <span class="n">Msg</span> <span class="k">as</span> <span class="n">_Msg</span>
@ -441,8 +445,6 @@
<span class="k">for</span> <span class="n">sender</span> <span class="ow">in</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">senderobj</span><span class="p">):</span>
<span class="n">new_message</span><span class="o">.</span><span class="n">senders</span> <span class="o">=</span> <span class="n">sender</span>
<span class="n">new_message</span><span class="o">.</span><span class="n">header</span> <span class="o">=</span> <span class="n">header</span>
<span class="k">for</span> <span class="n">channel</span> <span class="ow">in</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">channels</span><span class="p">):</span>
<span class="n">new_message</span><span class="o">.</span><span class="n">channels</span> <span class="o">=</span> <span class="n">channel</span>
<span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">receivers</span><span class="p">):</span>
<span class="n">new_message</span><span class="o">.</span><span class="n">receivers</span> <span class="o">=</span> <span class="n">receiver</span>
<span class="k">if</span> <span class="n">locks</span><span class="p">:</span>

View file

@ -1673,10 +1673,12 @@
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="n">_CMD_NOMATCH</span><span class="p">,</span> <span class="s2">&quot;yes&quot;</span><span class="p">,</span> <span class="s2">&quot;no&quot;</span><span class="p">,</span> <span class="s1">&#39;y&#39;</span><span class="p">,</span> <span class="s1">&#39;n&#39;</span><span class="p">,</span> <span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="s1">&#39;abort&#39;</span><span class="p">]</span>
<span class="n">arg_regex</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">&quot;^$&quot;</span>
<span class="k">def</span> <span class="nf">_clean</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_yes_no_question</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">YesNoQuestionCmdSet</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_clean</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="k">del</span> <span class="n">caller</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_yes_no_question</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">caller</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">has</span><span class="p">(</span><span class="n">YesNoQuestionCmdSet</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;account&quot;</span><span class="p">):</span>
<span class="n">caller</span><span class="o">.</span><span class="n">account</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">YesNoQuestionCmdSet</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">cmdset</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">YesNoQuestionCmdSet</span><span class="p">)</span>
<div class="viewcode-block" id="CmdYesNoQuestion.func"><a class="viewcode-back" href="../../../api/evennia.utils.evmenu.html#evennia.utils.evmenu.CmdYesNoQuestion.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="sd">&quot;&quot;&quot;This is called when user enters anything.&quot;&quot;&quot;</span>
@ -1687,6 +1689,10 @@
<span class="n">yes_no_question</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">account</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_yes_no_question</span>
<span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">account</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">yes_no_question</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_clean</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">inp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cmdname</span>
<span class="k">if</span> <span class="n">inp</span> <span class="o">==</span> <span class="n">_CMD_NOINPUT</span><span class="p">:</span>
@ -1699,7 +1705,7 @@
<span class="k">if</span> <span class="n">inp</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="s1">&#39;abort&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">yes_no_question</span><span class="o">.</span><span class="n">allow_abort</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;Aborted.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_clean</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_clean</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">caller</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_yes_no_question</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span>
@ -1719,12 +1725,13 @@
<span class="k">return</span>
<span class="c1"># cleanup</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_clean</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_clean</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="c1"># make sure to clean up cmdset if something goes wrong</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;|rError in ask_yes_no. Choice not confirmed (report to admin)|n&quot;</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">(</span><span class="s2">&quot;Error in ask_yes_no&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_clean</span><span class="p">()</span></div></div>
<span class="bp">self</span><span class="o">.</span><span class="n">_clean</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="k">raise</span></div></div>
<div class="viewcode-block" id="YesNoQuestionCmdSet"><a class="viewcode-back" href="../../../api/evennia.utils.evmenu.html#evennia.utils.evmenu.YesNoQuestionCmdSet">[docs]</a><span class="k">class</span> <span class="nc">YesNoQuestionCmdSet</span><span class="p">(</span><span class="n">CmdSet</span><span class="p">):</span>
@ -1744,8 +1751,8 @@
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdYesNoQuestion</span><span class="p">())</span></div></div>
<div class="viewcode-block" id="ask_yes_no"><a class="viewcode-back" href="../../../api/evennia.utils.evmenu.html#evennia.utils.evmenu.ask_yes_no">[docs]</a><span class="k">def</span> <span class="nf">ask_yes_no</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="n">prompt</span><span class="p">,</span> <span class="n">yes_action</span><span class="p">,</span> <span class="n">no_action</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">allow_abort</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<div class="viewcode-block" id="ask_yes_no"><a class="viewcode-back" href="../../../api/evennia.utils.evmenu.html#evennia.utils.evmenu.ask_yes_no">[docs]</a><span class="k">def</span> <span class="nf">ask_yes_no</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="n">prompt</span><span class="o">=</span><span class="s2">&quot;Yes or No </span><span class="si">{options}</span><span class="s2">?&quot;</span><span class="p">,</span> <span class="n">yes_action</span><span class="o">=</span><span class="s2">&quot;Yes&quot;</span><span class="p">,</span> <span class="n">no_action</span><span class="o">=</span><span class="s2">&quot;No&quot;</span><span class="p">,</span>
<span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">allow_abort</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">session</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A helper question for asking a simple yes/no question. This will cause</span>
<span class="sd"> the system to pause and wait for input from the player.</span>
@ -1762,8 +1769,9 @@
<span class="sd"> with `(caller, *args, **kwargs)` when the No-choice is made.</span>
<span class="sd"> If a string, this string will be echoed back to the caller.</span>
<span class="sd"> default (str optional): This is what the user will get if they just press the</span>
<span class="sd"> return key without giving any input. One of &#39;N&#39;, &#39;Y&#39;, &#39;A&#39; or &#39;None&#39;</span>
<span class="sd"> for no default. If &#39;A&#39; is given, `allow_abort` is auto-set.</span>
<span class="sd"> return key without giving any input. One of &#39;N&#39;, &#39;Y&#39;, &#39;A&#39; or `None`</span>
<span class="sd"> for no default (an explicit choice must be given). If &#39;A&#39; (abort)</span>
<span class="sd"> is given, `allow_abort` kwarg is ignored and assumed set.</span>
<span class="sd"> allow_abort (bool, optional): If set, the &#39;A(bort)&#39; option is available</span>
<span class="sd"> (a third option meaning neither yes or no but just exits the prompt).</span>
<span class="sd"> session (Session, optional): This allows to specify the</span>
@ -1771,10 +1779,11 @@
<span class="sd"> is an Account in multisession modes greater than 2. The session is</span>
<span class="sd"> then updated by the command and is available (for example in</span>
<span class="sd"> callbacks) through `caller.ndb._yes_no_question.session`.</span>
<span class="sd"> *args, **kwargs: These are passed into the callables.</span>
<span class="sd"> *args: Additional arguments passed on into callables.</span>
<span class="sd"> **kwargs: Additional keyword args passed on into callables.</span>
<span class="sd"> Raises:</span>
<span class="sd"> RuntimeError, FooError: If default and allow_abort clashes.</span>
<span class="sd"> RuntimeError, FooError: If default and `allow_abort` clashes.</span>
<span class="sd"> Example:</span>
<span class="sd"> ::</span>
@ -1821,6 +1830,7 @@
<span class="n">prompt</span> <span class="o">=</span> <span class="n">prompt</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">options</span><span class="o">=</span><span class="n">options</span><span class="p">)</span>
<span class="n">caller</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_yes_no_question</span> <span class="o">=</span> <span class="n">_Prompt</span><span class="p">()</span>
<span class="n">caller</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_yes_no_question</span><span class="o">.</span><span class="n">prompt</span> <span class="o">=</span> <span class="n">prompt</span>
<span class="n">caller</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_yes_no_question</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">session</span>
<span class="n">caller</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_yes_no_question</span><span class="o">.</span><span class="n">prompt</span> <span class="o">=</span> <span class="n">prompt</span>
<span class="n">caller</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">_yes_no_question</span><span class="o">.</span><span class="n">default</span> <span class="o">=</span> <span class="n">default</span>

View file

@ -399,12 +399,14 @@
<span class="n">_CHANNEL_LOG_NUM_TAIL_LINES</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CHANNEL_LOG_NUM_TAIL_LINES</span>
<span class="n">num_lines_to_append</span> <span class="o">=</span> <span class="n">_CHANNEL_LOG_NUM_TAIL_LINES</span>
<div class="viewcode-block" id="EvenniaLogFile.rotate"><a class="viewcode-back" href="../../../api/evennia.utils.logger.html#evennia.utils.logger.EvenniaLogFile.rotate">[docs]</a> <span class="k">def</span> <span class="nf">rotate</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="EvenniaLogFile.rotate"><a class="viewcode-back" href="../../../api/evennia.utils.logger.html#evennia.utils.logger.EvenniaLogFile.rotate">[docs]</a> <span class="k">def</span> <span class="nf">rotate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num_lines_to_append</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Rotates our log file and appends some number of lines from</span>
<span class="sd"> the previous log to the start of the new one.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">append_tail</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">num_lines_to_append</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="n">append_tail</span> <span class="o">=</span> <span class="p">(</span><span class="n">num_lines_to_append</span>
<span class="k">if</span> <span class="n">num_lines_to_append</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
<span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">num_lines_to_append</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">append_tail</span><span class="p">:</span>
<span class="n">logfile</span><span class="o">.</span><span class="n">LogFile</span><span class="o">.</span><span class="n">rotate</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span>
@ -514,6 +516,43 @@
<span class="n">deferToThread</span><span class="p">(</span><span class="n">callback</span><span class="p">,</span> <span class="n">filehandle</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span><span class="o">.</span><span class="n">addErrback</span><span class="p">(</span><span class="n">errback</span><span class="p">)</span></div>
<div class="viewcode-block" id="log_file_exists"><a class="viewcode-back" href="../../../api/evennia.utils.logger.html#evennia.utils.logger.log_file_exists">[docs]</a><span class="k">def</span> <span class="nf">log_file_exists</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s2">&quot;game.log&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Determine if a log-file already exists.</span>
<span class="sd"> Args:</span>
<span class="sd"> filename (str): The filename (within the log-dir).</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool: If the log file exists or not.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_LOGDIR</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_LOGDIR</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="n">_LOGDIR</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">LOG_DIR</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_LOGDIR</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
<span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span></div>
<div class="viewcode-block" id="rotate_log_file"><a class="viewcode-back" href="../../../api/evennia.utils.logger.html#evennia.utils.logger.rotate_log_file">[docs]</a><span class="k">def</span> <span class="nf">rotate_log_file</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s2">&quot;game.log&quot;</span><span class="p">,</span> <span class="n">num_lines_to_append</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Force-rotate a log-file, without</span>
<span class="sd"> Args:</span>
<span class="sd"> filename (str): The log file, located in settings.LOG_DIR.</span>
<span class="sd"> num_lines_to_append (int, optional): Include N number of</span>
<span class="sd"> lines from previous file in new one. If `None`, use default.</span>
<span class="sd"> Set to 0 to include no lines.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">log_file_exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
<span class="n">file_handle</span> <span class="o">=</span> <span class="n">_open_log_file</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="k">if</span> <span class="n">file_handle</span><span class="p">:</span>
<span class="n">file_handle</span><span class="o">.</span><span class="n">rotate</span><span class="p">(</span><span class="n">num_lines_to_append</span><span class="o">=</span><span class="n">num_lines_to_append</span><span class="p">)</span></div>
<div class="viewcode-block" id="tail_log_file"><a class="viewcode-back" href="../../../api/evennia.utils.logger.html#evennia.utils.logger.tail_log_file">[docs]</a><span class="k">def</span> <span class="nf">tail_log_file</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">nlines</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return the tail of the log file.</span>

View file

@ -48,7 +48,7 @@
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">validatorfuncs</span>
<div class="viewcode-block" id="BaseOption"><a class="viewcode-back" href="../../../api/evennia.utils.optionclasses.html#evennia.utils.optionclasses.BaseOption">[docs]</a><span class="k">class</span> <span class="nc">BaseOption</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<div class="viewcode-block" id="BaseOption"><a class="viewcode-back" href="../../../api/evennia.utils.optionclasses.html#evennia.utils.optionclasses.BaseOption">[docs]</a><span class="k">class</span> <span class="nc">BaseOption</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Abstract Class to deal with encapsulating individual Options. An Option has</span>
<span class="sd"> a name/key, a description to display in relevant commands and menus, and a</span>

View file

@ -47,7 +47,7 @@
<span class="n">_SA</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__setattr__</span>
<div class="viewcode-block" id="InMemorySaveHandler"><a class="viewcode-back" href="../../../api/evennia.utils.optionhandler.html#evennia.utils.optionhandler.InMemorySaveHandler">[docs]</a><span class="k">class</span> <span class="nc">InMemorySaveHandler</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<div class="viewcode-block" id="InMemorySaveHandler"><a class="viewcode-back" href="../../../api/evennia.utils.optionhandler.html#evennia.utils.optionhandler.InMemorySaveHandler">[docs]</a><span class="k">class</span> <span class="nc">InMemorySaveHandler</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Fallback SaveHandler, implementing a minimum of the required save mechanism</span>
<span class="sd"> and storing data in memory.</span>
@ -64,7 +64,7 @@
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="OptionHandler"><a class="viewcode-back" href="../../../api/evennia.utils.optionhandler.html#evennia.utils.optionhandler.OptionHandler">[docs]</a><span class="k">class</span> <span class="nc">OptionHandler</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<div class="viewcode-block" id="OptionHandler"><a class="viewcode-back" href="../../../api/evennia.utils.optionhandler.html#evennia.utils.optionhandler.OptionHandler">[docs]</a><span class="k">class</span> <span class="nc">OptionHandler</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is a generic Option handler. Retrieve options either as properties on</span>
<span class="sd"> this handler or by using the .get method.</span>
@ -99,6 +99,7 @@
<span class="sd"> A common one to pass would be AttributeHandler.get.</span>
<span class="sd"> save_kwargs (any): Optional extra kwargs to pass into `savefunc` above.</span>
<span class="sd"> load_kwargs (any): Optional extra kwargs to pass into `loadfunc` above.</span>
<span class="sd"> Notes:</span>
<span class="sd"> Both loadfunc and savefunc must be specified. If only one is given, the other</span>
<span class="sd"> will be ignored and in-memory storage will be used.</span>

View file

@ -210,16 +210,18 @@
<span class="k">return</span> <span class="n">to_str</span><span class="p">(</span><span class="n">text</span><span class="p">)</span></div>
<div class="viewcode-block" id="dedent"><a class="viewcode-back" href="../../../api/evennia.utils.utils.html#evennia.contrib.tutorial_examples.red_button.dedent">[docs]</a><span class="k">def</span> <span class="nf">dedent</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">baseline_index</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="dedent"><a class="viewcode-back" href="../../../api/evennia.utils.utils.html#evennia.contrib.tutorial_examples.red_button.dedent">[docs]</a><span class="k">def</span> <span class="nf">dedent</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">baseline_index</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Safely clean all whitespace at the left of a paragraph.</span>
<span class="sd"> Args:</span>
<span class="sd"> text (str): The text to dedent.</span>
<span class="sd"> baseline_index (int or None, optional): Which row to use as a &#39;base&#39;</span>
<span class="sd"> baseline_index (int, optional): Which row to use as a &#39;base&#39;</span>
<span class="sd"> for the indentation. Lines will be dedented to this level but</span>
<span class="sd"> no further. If None, indent so as to completely deindent the</span>
<span class="sd"> least indented text.</span>
<span class="sd"> indent (int, optional): If given, force all lines to this indent.</span>
<span class="sd"> This bypasses `baseline_index`.</span>
<span class="sd"> Returns:</span>
<span class="sd"> text (str): Dedented string.</span>
@ -232,7 +234,12 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">text</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="n">baseline_index</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="n">indent</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">lines</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">split</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="n">ind</span> <span class="o">=</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="n">indent</span>
<span class="n">indline</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">ind</span>
<span class="k">return</span> <span class="n">ind</span> <span class="o">+</span> <span class="n">indline</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">baseline_index</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">textwrap</span><span class="o">.</span><span class="n">dedent</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">lines</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
@ -1068,7 +1075,7 @@
<div class="viewcode-block" id="delay"><a class="viewcode-back" href="../../../api/evennia.utils.utils.html#evennia.contrib.tutorial_examples.red_button.delay">[docs]</a><span class="k">def</span> <span class="nf">delay</span><span class="p">(</span><span class="n">timedelay</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Delay the return of a value.</span>
<span class="sd"> Delay the calling of a callback (function).</span>
<span class="sd"> Args:</span>
<span class="sd"> timedelay (int or float): The delay in seconds</span>
@ -1076,24 +1083,35 @@
<span class="sd"> after `timedelay` seconds.</span>
<span class="sd"> *args: Will be used as arguments to callback</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> persistent (bool): Make the delay persistent over a reboot or reload.</span>
<span class="sd"> any: Any other keywords will be use as keyword arguments to callback.</span>
<span class="sd"> persistent (bool, optional): Should make the delay persistent</span>
<span class="sd"> over a reboot or reload. Defaults to False.</span>
<span class="sd"> any (any): Will be used as keyword arguments to callback.</span>
<span class="sd"> Returns:</span>
<span class="sd"> deferred: Will fire with callback after `timedelay` seconds. Note that</span>
<span class="sd"> if `timedelay()` is used in the</span>
<span class="sd"> commandhandler callback chain, the callback chain can be</span>
<span class="sd"> defined directly in the command body and don&#39;t need to be</span>
<span class="sd"> specified here.</span>
<span class="sd"> deferred or int: If ``persistent`` kwarg is `False`, return deferred</span>
<span class="sd"> that will fire with callback after `timedelay` seconds. Note that</span>
<span class="sd"> if `timedelay()` is used in the commandhandler callback chain, the</span>
<span class="sd"> callback chain can be defined directly in the command body and</span>
<span class="sd"> don&#39;t need to be specified here. Reference twisted.internet.defer.Deferred.</span>
<span class="sd"> If persistent kwarg is set, return the task&#39;s ID as an integer. This is</span>
<span class="sd"> intended for use with ``evennia.scripts.taskhandler.TASK_HANDLER``</span>
<span class="sd"> `.do_task` and `.remove` methods.</span>
<span class="sd"> Notes:</span>
<span class="sd"> The task handler (`evennia.scripts.taskhandler.TASK_HANDLER`) will</span>
<span class="sd"> be called for persistent or non-persistent tasks.</span>
<span class="sd"> If persistent is set to True, the callback, its arguments</span>
<span class="sd"> and other keyword arguments will be saved in the database,</span>
<span class="sd"> and other keyword arguments will be saved (serialized) in the database,</span>
<span class="sd"> assuming they can be. The callback will be executed even after</span>
<span class="sd"> a server restart/reload, taking into account the specified delay</span>
<span class="sd"> (and server down time).</span>
<span class="sd"> Keep in mind that persistent tasks arguments and callback should not</span>
<span class="sd"> use memory references.</span>
<span class="sd"> If persistent is set to True the delay function will return an int</span>
<span class="sd"> which is the task&#39;s id itended for use with TASK_HANDLER&#39;s do_task</span>
<span class="sd"> and remove methods.</span>
<span class="sd"> All task&#39;s whose time delays have passed will be called on server startup.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_TASK_HANDLER</span>
@ -1370,18 +1388,19 @@
<span class="sd"> already imported module object (e.g. `models`)</span>
<span class="sd"> Returns:</span>
<span class="sd"> variables (dict): A dict of {variablename: variable} for all</span>
<span class="sd"> dict: A dict of {variablename: variable} for all</span>
<span class="sd"> variables in the given module.</span>
<span class="sd"> Notes:</span>
<span class="sd"> Ignores modules and variable names starting with an underscore.</span>
<span class="sd"> Ignores modules and variable names starting with an underscore, as well</span>
<span class="sd"> as variables imported into the module from other modules.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">mod</span> <span class="o">=</span> <span class="n">mod_import</span><span class="p">(</span><span class="n">module</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">mod</span><span class="p">:</span>
<span class="k">return</span> <span class="p">{}</span>
<span class="c1"># make sure to only return variables actually defined in this</span>
<span class="c1"># module if available (try to avoid not imports)</span>
<span class="c1"># module if available (try to avoid imports)</span>
<span class="n">members</span> <span class="o">=</span> <span class="n">getmembers</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">predicate</span><span class="o">=</span><span class="k">lambda</span> <span class="n">obj</span><span class="p">:</span> <span class="n">getmodule</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="kc">None</span><span class="p">))</span>
<span class="k">return</span> <span class="nb">dict</span><span class="p">((</span><span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">members</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">))</span></div>
@ -1869,7 +1888,7 @@
<span class="k">return</span> <span class="n">d0</span> <span class="o">+</span> <span class="n">d1</span></div>
<div class="viewcode-block" id="format_grid"><a class="viewcode-back" href="../../../api/evennia.utils.utils.html#evennia.contrib.tutorial_examples.red_button.format_grid">[docs]</a><span class="k">def</span> <span class="nf">format_grid</span><span class="p">(</span><span class="n">elements</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">78</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="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="format_grid"><a class="viewcode-back" href="../../../api/evennia.utils.utils.html#evennia.contrib.tutorial_examples.red_button.format_grid">[docs]</a><span class="k">def</span> <span class="nf">format_grid</span><span class="p">(</span><span class="n">elements</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">78</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="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This helper function makes a &#39;grid&#39; output, where it distributes the given</span>
<span class="sd"> string-elements as evenly as possible to fill out the given width.</span>
@ -1888,84 +1907,118 @@
<span class="sd"> decorations in the grid, such as horizontal bars.</span>
<span class="sd"> Returns:</span>
<span class="sd"> gridstr: The grid as a list of ready-formatted rows. We return it</span>
<span class="sd"> list: The grid as a list of ready-formatted rows. We return it</span>
<span class="sd"> like this to make it easier to insert decorations between rows, such</span>
<span class="sd"> as horizontal bars.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">_minimal_rows</span><span class="p">(</span><span class="n">elements</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Minimalistic distribution with minimal spacing, good for single-line</span>
<span class="sd"> grids but will look messy over many lines.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">rows</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;&quot;</span><span class="p">]</span>
<span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="n">elements</span><span class="p">:</span>
<span class="n">rowlen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">rows</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">elen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">element</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rowlen</span> <span class="o">+</span> <span class="n">elen</span> <span class="o">&lt;=</span> <span class="n">width</span><span class="p">:</span>
<span class="n">rows</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="n">element</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">element</span><span class="p">)</span>
<span class="k">return</span> <span class="n">rows</span>
<span class="k">def</span> <span class="nf">_weighted_rows</span><span class="p">(</span><span class="n">elements</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Dynamic-space, good for making even columns in a multi-line grid but</span>
<span class="sd"> will look strange for a single line.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">wls</span> <span class="o">=</span> <span class="p">[</span><span class="nb">len</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span> <span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">elements</span><span class="p">]</span>
<span class="n">wls_percentile</span> <span class="o">=</span> <span class="p">[</span><span class="n">wl</span> <span class="k">for</span> <span class="n">iw</span><span class="p">,</span> <span class="n">wl</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">wls</span><span class="p">)</span> <span class="k">if</span> <span class="n">iw</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">verbatim_elements</span><span class="p">]</span>
<span class="k">if</span> <span class="n">wls_percentile</span><span class="p">:</span>
<span class="c1"># get the nth percentile as a good representation of average width</span>
<span class="n">averlen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">percentile</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">wls_percentile</span><span class="p">),</span> <span class="mf">0.9</span><span class="p">))</span> <span class="o">+</span> <span class="mi">2</span> <span class="c1"># include extra space</span>
<span class="n">aver_per_row</span> <span class="o">=</span> <span class="n">width</span> <span class="o">//</span> <span class="n">averlen</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># no adjustable rows, just keep all as-is</span>
<span class="n">aver_per_row</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">aver_per_row</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># one line per row, output directly since this is trivial</span>
<span class="c1"># we use rstrip here to remove extra spaces added by sep</span>
<span class="k">return</span> <span class="p">[</span>
<span class="n">crop</span><span class="p">(</span><span class="n">element</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(),</span> <span class="n">width</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</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">element</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()))</span>
<span class="k">for</span> <span class="n">iel</span><span class="p">,</span> <span class="n">element</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">elements</span><span class="p">)</span>
<span class="p">]</span>
<span class="n">indices</span> <span class="o">=</span> <span class="p">[</span><span class="n">averlen</span> <span class="o">*</span> <span class="n">ind</span> <span class="k">for</span> <span class="n">ind</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">aver_per_row</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)]</span>
<span class="n">rows</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">ic</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">row</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">for</span> <span class="n">ie</span><span class="p">,</span> <span class="n">element</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">elements</span><span class="p">):</span>
<span class="n">wl</span> <span class="o">=</span> <span class="n">wls</span><span class="p">[</span><span class="n">ie</span><span class="p">]</span>
<span class="n">lrow</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="n">debug</span> <span class="o">=</span> <span class="n">row</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="s2">&quot;.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lrow</span> <span class="o">+</span> <span class="n">wl</span> <span class="o">&gt;</span> <span class="n">width</span><span class="p">:</span>
<span class="c1"># this slot extends outside grid, move to next line</span>
<span class="n">row</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="n">lrow</span><span class="p">)</span>
<span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="k">if</span> <span class="n">wl</span> <span class="o">&gt;=</span> <span class="n">width</span><span class="p">:</span>
<span class="c1"># remove sep if this fills the entire line</span>
<span class="n">element</span> <span class="o">=</span> <span class="n">element</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">crop</span><span class="p">(</span><span class="n">element</span><span class="p">,</span> <span class="n">width</span><span class="p">)</span>
<span class="n">ic</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">elif</span> <span class="n">ic</span> <span class="o">&gt;=</span> <span class="n">aver_per_row</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># no more slots available on this line</span>
<span class="n">row</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="n">width</span> <span class="o">-</span> <span class="n">lrow</span><span class="p">))</span>
<span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">crop</span><span class="p">(</span><span class="n">element</span><span class="p">,</span> <span class="n">width</span><span class="p">)</span>
<span class="n">ic</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">while</span> <span class="n">lrow</span> <span class="o">&gt;</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">indices</span><span class="p">[</span><span class="n">ic</span><span class="p">]):</span>
<span class="c1"># slot too wide, extend into adjacent slot</span>
<span class="n">ic</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">row</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">indices</span><span class="p">[</span><span class="n">ic</span><span class="p">]</span> <span class="o">-</span> <span class="n">lrow</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="c1"># we extended past edge of grid, crop or move to next line</span>
<span class="k">if</span> <span class="n">ic</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">crop</span><span class="p">(</span><span class="n">element</span><span class="p">,</span> <span class="n">width</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">row</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">width</span> <span class="o">-</span> <span class="n">lrow</span><span class="p">)</span>
<span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="n">ic</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># add a new slot</span>
<span class="n">row</span> <span class="o">+=</span> <span class="n">element</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">averlen</span> <span class="o">-</span> <span class="n">wl</span><span class="p">)</span>
<span class="n">ic</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">ie</span> <span class="o">&gt;=</span> <span class="n">nelements</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># last element, make sure to store</span>
<span class="n">row</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</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">row</span><span class="p">))</span>
<span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="k">return</span> <span class="n">rows</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">elements</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">verbatim_elements</span><span class="p">:</span>
<span class="n">verbatim_elements</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">nelements</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">elements</span><span class="p">)</span>
<span class="c1"># add sep to all but the very last element</span>
<span class="n">elements</span> <span class="o">=</span> <span class="p">[</span><span class="n">elements</span><span class="p">[</span><span class="n">ie</span><span class="p">]</span> <span class="o">+</span> <span class="n">sep</span> <span class="k">for</span> <span class="n">ie</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">nelements</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)]</span> <span class="o">+</span> <span class="p">[</span><span class="n">elements</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]]</span>
<span class="n">wls</span> <span class="o">=</span> <span class="p">[</span><span class="nb">len</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span> <span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">elements</span><span class="p">]</span>
<span class="n">wls_percentile</span> <span class="o">=</span> <span class="p">[</span><span class="n">wl</span> <span class="k">for</span> <span class="n">iw</span><span class="p">,</span> <span class="n">wl</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">wls</span><span class="p">)</span> <span class="k">if</span> <span class="n">iw</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">verbatim_elements</span><span class="p">]</span>
<span class="c1"># from pudb import debugger</span>
<span class="c1"># debugger.Debugger().set_trace()</span>
<span class="c1"># get the nth percentile as a good representation of average width</span>
<span class="n">averlen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">percentile</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">wls_percentile</span><span class="p">),</span> <span class="mf">0.9</span><span class="p">))</span> <span class="o">+</span> <span class="mi">2</span> <span class="c1"># include extra space</span>
<span class="n">aver_per_row</span> <span class="o">=</span> <span class="n">width</span> <span class="o">//</span> <span class="n">averlen</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nb">sum</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">element</span><span class="p">)</span> <span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="n">elements</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="n">width</span><span class="p">:</span>
<span class="c1"># grid fits in one line</span>
<span class="k">return</span> <span class="n">_minimal_rows</span><span class="p">(</span><span class="n">elements</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># full multi-line grid</span>
<span class="k">return</span> <span class="n">_weighted_rows</span><span class="p">(</span><span class="n">elements</span><span class="p">)</span></div>
<span class="k">if</span> <span class="n">aver_per_row</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># one line per row, output directly since this is trivial</span>
<span class="c1"># we use rstrip here to remove extra spaces added by sep</span>
<span class="k">return</span> <span class="p">[</span>
<span class="n">crop</span><span class="p">(</span><span class="n">element</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(),</span> <span class="n">width</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</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">element</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()))</span>
<span class="k">for</span> <span class="n">iel</span><span class="p">,</span> <span class="n">element</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">elements</span><span class="p">)</span>
<span class="p">]</span>
<span class="n">indices</span> <span class="o">=</span> <span class="p">[</span><span class="n">averlen</span> <span class="o">*</span> <span class="n">ind</span> <span class="k">for</span> <span class="n">ind</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">aver_per_row</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)]</span>
<span class="n">rows</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">ic</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">row</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">for</span> <span class="n">ie</span><span class="p">,</span> <span class="n">element</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">elements</span><span class="p">):</span>
<span class="n">wl</span> <span class="o">=</span> <span class="n">wls</span><span class="p">[</span><span class="n">ie</span><span class="p">]</span>
<span class="n">lrow</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="n">debug</span> <span class="o">=</span> <span class="n">row</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="s2">&quot;.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lrow</span> <span class="o">+</span> <span class="n">wl</span> <span class="o">&gt;</span> <span class="n">width</span><span class="p">:</span>
<span class="c1"># this slot extends outside grid, move to next line</span>
<span class="n">row</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="n">lrow</span><span class="p">)</span>
<span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="k">if</span> <span class="n">wl</span> <span class="o">&gt;=</span> <span class="n">width</span><span class="p">:</span>
<span class="c1"># remove sep if this fills the entire line</span>
<span class="n">element</span> <span class="o">=</span> <span class="n">element</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">crop</span><span class="p">(</span><span class="n">element</span><span class="p">,</span> <span class="n">width</span><span class="p">)</span>
<span class="n">ic</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">elif</span> <span class="n">ic</span> <span class="o">&gt;=</span> <span class="n">aver_per_row</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># no more slots available on this line</span>
<span class="n">row</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="n">width</span> <span class="o">-</span> <span class="n">lrow</span><span class="p">))</span>
<span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">crop</span><span class="p">(</span><span class="n">element</span><span class="p">,</span> <span class="n">width</span><span class="p">)</span>
<span class="n">ic</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">while</span> <span class="n">lrow</span> <span class="o">&gt;</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">indices</span><span class="p">[</span><span class="n">ic</span><span class="p">]):</span>
<span class="c1"># slot too wide, extend into adjacent slot</span>
<span class="n">ic</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">row</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">indices</span><span class="p">[</span><span class="n">ic</span><span class="p">]</span> <span class="o">-</span> <span class="n">lrow</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="c1"># we extended past edge of grid, crop or move to next line</span>
<span class="k">if</span> <span class="n">ic</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">row</span> <span class="o">=</span> <span class="n">crop</span><span class="p">(</span><span class="n">element</span><span class="p">,</span> <span class="n">width</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">row</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">width</span> <span class="o">-</span> <span class="n">lrow</span><span class="p">)</span>
<span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="n">ic</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># add a new slot</span>
<span class="n">row</span> <span class="o">+=</span> <span class="n">element</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">averlen</span> <span class="o">-</span> <span class="n">wl</span><span class="p">)</span>
<span class="n">ic</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">ie</span> <span class="o">&gt;=</span> <span class="n">nelements</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># last element, make sure to store</span>
<span class="n">row</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</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">row</span><span class="p">))</span>
<span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
<span class="k">return</span> <span class="n">rows</span></div>
<div class="viewcode-block" id="get_evennia_pids"><a class="viewcode-back" href="../../../api/evennia.utils.utils.html#evennia.contrib.tutorial_examples.red_button.get_evennia_pids">[docs]</a><span class="k">def</span> <span class="nf">get_evennia_pids</span><span class="p">():</span>

View file

@ -73,7 +73,6 @@
<li><a href="evennia/commands/default/tests.html">evennia.commands.default.tests</a></li>
<li><a href="evennia/commands/default/unloggedin.html">evennia.commands.default.unloggedin</a></li>
<li><a href="evennia/comms/admin.html">evennia.comms.admin</a></li>
<li><a href="evennia/comms/channelhandler.html">evennia.comms.channelhandler</a></li>
<li><a href="evennia/comms/comms.html">evennia.comms.comms</a></li>
<li><a href="evennia/comms/managers.html">evennia.comms.managers</a></li>
<li><a href="evennia/comms/models.html">evennia.comms.models</a></li>
@ -137,8 +136,10 @@
<li><a href="evennia/contrib/unixcommand.html">evennia.contrib.unixcommand</a></li>
<li><a href="evennia/contrib/wilderness.html">evennia.contrib.wilderness</a></li>
<li><a href="evennia/help/admin.html">evennia.help.admin</a></li>
<li><a href="evennia/help/filehelp.html">evennia.help.filehelp</a></li>
<li><a href="evennia/help/manager.html">evennia.help.manager</a></li>
<li><a href="evennia/help/models.html">evennia.help.models</a></li>
<li><a href="evennia/help/utils.html">evennia.help.utils</a></li>
<li><a href="evennia/locks/lockfuncs.html">evennia.locks.lockfuncs</a></li>
<li><a href="evennia/locks/lockhandler.html">evennia.locks.lockhandler</a></li>
<li><a href="evennia/objects/admin.html">evennia.objects.admin</a></li>