evennia/docs/1.0-dev/_modules/evennia/commands/default/comms.html
2021-10-26 21:41:11 +02:00

2455 lines
No EOL
298 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.commands.default.comms &#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>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math|output_area"}})</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.commands.default.comms</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.commands.default.comms</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Communication commands:</span>
<span class="sd">- channel</span>
<span class="sd">- page</span>
<span class="sd">- irc/rss/grapevine linking</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.comms.models</span> <span class="kn">import</span> <span class="n">Msg</span>
<span class="kn">from</span> <span class="nn">evennia.accounts.models</span> <span class="kn">import</span> <span class="n">AccountDB</span>
<span class="kn">from</span> <span class="nn">evennia.accounts</span> <span class="kn">import</span> <span class="n">bots</span>
<span class="kn">from</span> <span class="nn">evennia.locks.lockhandler</span> <span class="kn">import</span> <span class="n">LockException</span>
<span class="kn">from</span> <span class="nn">evennia.comms.comms</span> <span class="kn">import</span> <span class="n">DefaultChannel</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">logger</span><span class="p">,</span> <span class="n">utils</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="p">,</span> <span class="n">strip_unsafe_input</span>
<span class="kn">from</span> <span class="nn">evennia.utils.evmenu</span> <span class="kn">import</span> <span class="n">ask_yes_no</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">CHANNEL_DEFAULT_TYPECLASS</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">BASE_CHANNEL_TYPECLASS</span><span class="p">,</span> <span class="n">fallback</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">FALLBACK_CHANNEL_TYPECLASS</span><span class="p">)</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;CmdChannel&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdObjectChannel&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdAddCom&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdDelCom&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdAllCom&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdCdestroy&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdCBoot&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdCWho&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdChannelCreate&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdClock&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdCdesc&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdPage&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdIRC2Chan&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdIRCStatus&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdRSS2Chan&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdGrapevine2Chan&quot;</span><span class="p">,</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="c1"># helper functions to make it easier to override the main CmdChannel</span>
<span class="c1"># command and to keep the legacy addcom etc commands around.</span>
<div class="viewcode-block" id="CmdChannel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel">[docs]</a><span class="k">class</span> <span class="nc">CmdChannel</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"> Use and manage in-game channels.</span>
<span class="sd"> Usage:</span>
<span class="sd"> channel channelname &lt;msg&gt;</span>
<span class="sd"> channel channel name = &lt;msg&gt;</span>
<span class="sd"> channel (show all subscription)</span>
<span class="sd"> channel/all (show available channels)</span>
<span class="sd"> channel/alias channelname = alias[;alias...]</span>
<span class="sd"> channel/unalias alias</span>
<span class="sd"> channel/who channelname</span>
<span class="sd"> channel/history channelname [= index]</span>
<span class="sd"> channel/sub channelname [= alias[;alias...]]</span>
<span class="sd"> channel/unsub channelname[,channelname, ...]</span>
<span class="sd"> channel/mute channelname[,channelname,...]</span>
<span class="sd"> channel/unmute channelname[,channelname,...]</span>
<span class="sd"> channel/create channelname[;alias;alias[:typeclass]] [= description]</span>
<span class="sd"> channel/destroy channelname [= reason]</span>
<span class="sd"> channel/desc channelname = description</span>
<span class="sd"> channel/lock channelname = lockstring</span>
<span class="sd"> channel/unlock channelname = lockstring</span>
<span class="sd"> channel/ban channelname (list bans)</span>
<span class="sd"> channel/ban[/quiet] channelname[, channelname, ...] = subscribername [: reason]</span>
<span class="sd"> channel/unban[/quiet] channelname[, channelname, ...] = subscribername</span>
<span class="sd"> channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]</span>
<span class="sd"> # subtopics</span>
<span class="sd"> ## sending</span>
<span class="sd"> Usage: channel channelname msg</span>
<span class="sd"> channel channel name = msg (with space in channel name)</span>
<span class="sd"> This sends a message to the channel. Note that you will rarely use this</span>
<span class="sd"> command like this; instead you can use the alias</span>
<span class="sd"> channelname &lt;msg&gt;</span>
<span class="sd"> channelalias &lt;msg&gt;</span>
<span class="sd"> For example</span>
<span class="sd"> public Hello World</span>
<span class="sd"> pub Hello World</span>
<span class="sd"> (this shortcut doesn&#39;t work for aliases containing spaces)</span>
<span class="sd"> See channel/alias for help on setting channel aliases.</span>
<span class="sd"> ## alias and unalias</span>
<span class="sd"> Usage: channel/alias channel = alias[;alias[;alias...]]</span>
<span class="sd"> channel/unalias alias</span>
<span class="sd"> channel - this will list your subs and aliases to each channel</span>
<span class="sd"> Set one or more personal aliases for referencing a channel. For example:</span>
<span class="sd"> channel/alias warrior&#39;s guild = warrior;wguild;warchannel;warrior guild</span>
<span class="sd"> You can now send to the channel using all of these:</span>
<span class="sd"> warrior&#39;s guild Hello</span>
<span class="sd"> warrior Hello</span>
<span class="sd"> wguild Hello</span>
<span class="sd"> warchannel Hello</span>
<span class="sd"> Note that this will not work if the alias has a space in it. So the</span>
<span class="sd"> &#39;warrior guild&#39; alias must be used with the `channel` command:</span>
<span class="sd"> channel warrior guild = Hello</span>
<span class="sd"> Channel-aliases can be removed one at a time, using the &#39;/unalias&#39; switch.</span>
<span class="sd"> ## who</span>
<span class="sd"> Usage: channel/who channelname</span>
<span class="sd"> List the channel&#39;s subscribers. Shows who are currently offline or are</span>
<span class="sd"> muting the channel. Subscribers who are &#39;muting&#39; will not see messages sent</span>
<span class="sd"> to the channel (use channel/mute to mute a channel).</span>
<span class="sd"> ## history</span>
<span class="sd"> Usage: channel/history channel [= index]</span>
<span class="sd"> This will display the last |c20|n lines of channel history. By supplying an</span>
<span class="sd"> index number, you will step that many lines back before viewing those 20 lines.</span>
<span class="sd"> For example:</span>
<span class="sd"> channel/history public = 35</span>
<span class="sd"> will go back 35 lines and show the previous 20 lines from that point (so</span>
<span class="sd"> lines -35 to -55).</span>
<span class="sd"> ## sub and unsub</span>
<span class="sd"> Usage: channel/sub channel [=alias[;alias;...]]</span>
<span class="sd"> channel/unsub channel</span>
<span class="sd"> This subscribes you to a channel and optionally assigns personal shortcuts</span>
<span class="sd"> for you to use to send to that channel (see aliases). When you unsub, all</span>
<span class="sd"> your personal aliases will also be removed.</span>
<span class="sd"> ## mute and unmute</span>
<span class="sd"> Usage: channel/mute channelname</span>
<span class="sd"> channel/unmute channelname</span>
<span class="sd"> Muting silences all output from the channel without actually</span>
<span class="sd"> un-subscribing. Other channel members will see that you are muted in the /who</span>
<span class="sd"> list. Sending a message to the channel will automatically unmute you.</span>
<span class="sd"> ## create and destroy</span>
<span class="sd"> Usage: channel/create channelname[;alias;alias[:typeclass]] [= description]</span>
<span class="sd"> channel/destroy channelname [= reason]</span>
<span class="sd"> Creates a new channel (or destroys one you control). You will automatically</span>
<span class="sd"> join the channel you create and everyone will be kicked and loose all aliases</span>
<span class="sd"> to a destroyed channel.</span>
<span class="sd"> ## lock and unlock</span>
<span class="sd"> Usage: channel/lock channelname = lockstring</span>
<span class="sd"> channel/unlock channelname = lockstring</span>
<span class="sd"> Note: this is an admin command.</span>
<span class="sd"> A lockstring is on the form locktype:lockfunc(). Channels understand three</span>
<span class="sd"> locktypes:</span>
<span class="sd"> listen - who may listen or join the channel.</span>
<span class="sd"> send - who may send messages to the channel</span>
<span class="sd"> control - who controls the channel. This is usually the one creating</span>
<span class="sd"> the channel.</span>
<span class="sd"> Common lockfuncs are all() and perm(). To make a channel everyone can</span>
<span class="sd"> listen to but only builders can talk on, use this:</span>
<span class="sd"> listen:all()</span>
<span class="sd"> send: perm(Builders)</span>
<span class="sd"> ## boot and ban</span>
<span class="sd"> Usage:</span>
<span class="sd"> channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]</span>
<span class="sd"> channel/ban channelname[, channelname, ...] = subscribername [: reason]</span>
<span class="sd"> channel/unban channelname[, channelname, ...] = subscribername</span>
<span class="sd"> channel/unban channelname</span>
<span class="sd"> channel/ban channelname (list bans)</span>
<span class="sd"> Booting will kick a named subscriber from channel(s) temporarily. The</span>
<span class="sd"> &#39;reason&#39; will be passed to the booted user. Unless the /quiet switch is</span>
<span class="sd"> used, the channel will also be informed of the action. A booted user is</span>
<span class="sd"> still able to re-connect, but they&#39;ll have to set up their aliases again.</span>
<span class="sd"> Banning will blacklist a user from (re)joining the provided channels. It</span>
<span class="sd"> will then proceed to boot them from those channels if they were connected.</span>
<span class="sd"> The &#39;reason&#39; and `/quiet` works the same as for booting.</span>
<span class="sd"> Example:</span>
<span class="sd"> boot mychannel1 = EvilUser : Kicking you to cool down a bit.</span>
<span class="sd"> ban mychannel1,mychannel2= EvilUser : Was banned for spamming.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;channel&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;chan&quot;</span><span class="p">,</span> <span class="s2">&quot;channels&quot;</span><span class="p">]</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="c1"># these cmd: lock controls access to the channel command itself</span>
<span class="c1"># the admin: lock controls access to /boot/ban/unban switches</span>
<span class="c1"># the manage: lock controls access to /create/destroy/desc/lock/unlock switches</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:not pperm(channel_banned);admin:all();manage:all();changelocks:perm(Admin)&quot;</span>
<span class="n">switch_options</span> <span class="o">=</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="s2">&quot;history&quot;</span><span class="p">,</span> <span class="s2">&quot;sub&quot;</span><span class="p">,</span> <span class="s2">&quot;unsub&quot;</span><span class="p">,</span> <span class="s2">&quot;mute&quot;</span><span class="p">,</span> <span class="s2">&quot;unmute&quot;</span><span class="p">,</span> <span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="s2">&quot;unalias&quot;</span><span class="p">,</span>
<span class="s2">&quot;create&quot;</span><span class="p">,</span> <span class="s2">&quot;destroy&quot;</span><span class="p">,</span> <span class="s2">&quot;desc&quot;</span><span class="p">,</span> <span class="s2">&quot;lock&quot;</span><span class="p">,</span> <span class="s2">&quot;unlock&quot;</span><span class="p">,</span> <span class="s2">&quot;boot&quot;</span><span class="p">,</span> <span class="s2">&quot;ban&quot;</span><span class="p">,</span> <span class="s2">&quot;unban&quot;</span><span class="p">,</span> <span class="s2">&quot;who&quot;</span><span class="p">,)</span>
<span class="c1"># disable this in child command classes if wanting on-character channels</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdChannel.search_channel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.search_channel">[docs]</a> <span class="k">def</span> <span class="nf">search_channel</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">exact</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">handle_errors</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper function for searching for a single channel with some error</span>
<span class="sd"> handling.</span>
<span class="sd"> Args:</span>
<span class="sd"> channelname (str): Name, alias #dbref or partial name/alias to search</span>
<span class="sd"> for.</span>
<span class="sd"> exact (bool, optional): If an exact or fuzzy-match of the name should be done.</span>
<span class="sd"> Note that even for a fuzzy match, an exactly given, unique channel name</span>
<span class="sd"> will always be returned.</span>
<span class="sd"> handle_errors (bool): If true, use `self.msg` to report errors if</span>
<span class="sd"> there are non/multiple matches. If so, the return will always be</span>
<span class="sd"> a single match or None.</span>
<span class="sd"> Returns:</span>
<span class="sd"> object, list or None: If `handle_errors` is `True`, this is either a found Channel</span>
<span class="sd"> or `None`. Otherwise it&#39;s a list of zero, one or more channels found.</span>
<span class="sd"> Notes:</span>
<span class="sd"> The &#39;listen&#39; and &#39;control&#39; accesses are checked before returning.</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="c1"># first see if this is a personal alias</span>
<span class="n">channelname</span> <span class="o">=</span> <span class="n">caller</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">key</span><span class="o">=</span><span class="n">channelname</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="ow">or</span> <span class="n">channelname</span>
<span class="c1"># always try the exact match first.</span>
<span class="n">channels</span> <span class="o">=</span> <span class="n">CHANNEL_DEFAULT_TYPECLASS</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">channel_search</span><span class="p">(</span><span class="n">channelname</span><span class="p">,</span> <span class="n">exact</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channels</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">exact</span><span class="p">:</span>
<span class="c1"># try fuzzy matching as well</span>
<span class="n">channels</span> <span class="o">=</span> <span class="n">CHANNEL_DEFAULT_TYPECLASS</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">channel_search</span><span class="p">(</span><span class="n">channelname</span><span class="p">,</span> <span class="n">exact</span><span class="o">=</span><span class="n">exact</span><span class="p">)</span>
<span class="c1"># check permissions</span>
<span class="n">channels</span> <span class="o">=</span> <span class="p">[</span><span class="n">channel</span> <span class="k">for</span> <span class="n">channel</span> <span class="ow">in</span> <span class="n">channels</span>
<span class="k">if</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="s1">&#39;listen&#39;</span><span class="p">)</span> <span class="ow">or</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="s1">&#39;control&#39;</span><span class="p">)]</span>
<span class="k">if</span> <span class="n">handle_errors</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channels</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No channel found matching &#39;</span><span class="si">{</span><span class="n">channelname</span><span class="si">}</span><span class="s2">&#39; &quot;</span>
<span class="s2">&quot;(could also be due to missing access).&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">channels</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</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;Multiple possible channel matches/alias for &quot;</span>
<span class="s2">&quot;&#39;</span><span class="si">{channelname}</span><span class="s2">&#39;:</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">))</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">return</span> <span class="n">channels</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">if</span> <span class="ow">not</span> <span class="n">channels</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">channels</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">channels</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="n">channels</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span></div>
<div class="viewcode-block" id="CmdChannel.msg_channel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.msg_channel">[docs]</a> <span class="k">def</span> <span class="nf">msg_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="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"> Send a message to a given channel. This will check the &#39;send&#39;</span>
<span class="sd"> permission on the channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to send to.</span>
<span class="sd"> message (str): The message to send.</span>
<span class="sd"> **kwargs: Unused by default. These kwargs will be passed into</span>
<span class="sd"> all channel messaging hooks for custom overriding.</span>
<span class="sd"> &quot;&quot;&quot;</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="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;send&quot;</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="sa">f</span><span class="s2">&quot;You are not allowed to send messages to channel </span><span class="si">{</span><span class="n">channel</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># avoid unsafe tokens in message</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">strip_unsafe_input</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</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">message</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="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="CmdChannel.get_channel_history"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.get_channel_history">[docs]</a> <span class="k">def</span> <span class="nf">get_channel_history</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="n">start_index</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> View a channel&#39;s history.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to access.</span>
<span class="sd"> message (str): The message to send.</span>
<span class="sd"> **kwargs: Unused by default. These kwargs will be passed into</span>
<span class="sd"> all channel messaging hooks for custom overriding.</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">log_file</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">get_log_filename</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="c1"># asynchronously tail the log file</span>
<span class="n">tail_log_file</span><span class="p">(</span><span class="n">log_file</span><span class="p">,</span> <span class="n">start_index</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></div>
<div class="viewcode-block" id="CmdChannel.sub_to_channel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.sub_to_channel">[docs]</a> <span class="k">def</span> <span class="nf">sub_to_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"> Subscribe to a channel. Note that all permissions should</span>
<span class="sd"> be checked before this step.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to access.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if connection failed. If False,</span>
<span class="sd"> the second part is an error string.</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="k">if</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="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;Already listening to channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span>
<span class="c1"># this sets up aliases in post_join_channel by default</span>
<span class="n">result</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="n">caller</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span><span class="p">,</span> <span class="s2">&quot;&quot;</span> <span class="k">if</span> <span class="n">result</span> <span class="k">else</span> <span class="sa">f</span><span class="s2">&quot;Were not allowed to subscribe to channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.unsub_from_channel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.unsub_from_channel">[docs]</a> <span class="k">def</span> <span class="nf">unsub_from_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="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Un-Subscribe to a channel. Note that all permissions should</span>
<span class="sd"> be checked before this step.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to unsub from.</span>
<span class="sd"> **kwargs: Passed on to nick removal.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if un-connection succeeded. If False,</span>
<span class="sd"> the second part is an error string.</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="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="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;Not listening to channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span>
<span class="c1"># this will also clean aliases</span>
<span class="n">result</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="n">caller</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span><span class="p">,</span> <span class="s2">&quot;&quot;</span> <span class="k">if</span> <span class="n">result</span> <span class="k">else</span> <span class="sa">f</span><span class="s2">&quot;Could not unsubscribe from channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.add_alias"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.add_alias">[docs]</a> <span class="k">def</span> <span class="nf">add_alias</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="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"> Add a new alias (nick) for the user to use with this channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to alias.</span>
<span class="sd"> alias (str): The personal alias to use for this channel.</span>
<span class="sd"> **kwargs: If given, passed into nicks.add.</span>
<span class="sd"> Note:</span>
<span class="sd"> We add two nicks - one is a plain `alias -&gt; channel.key` that</span>
<span class="sd"> we 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_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">channel</span><span class="o">.</span><span class="n">add_user_channel_alias</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">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="CmdChannel.remove_alias"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.remove_alias">[docs]</a> <span class="k">def</span> <span class="nf">remove_alias</span><span class="p">(</span><span class="bp">self</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 an alias from a channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> alias (str, optional): The alias to remove.</span>
<span class="sd"> The channel will be reverse-determined from the</span>
<span class="sd"> alias, if it exists.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if removal succeeded. If False,</span>
<span class="sd"> the second part is an error string.</span>
<span class="sd"> **kwargs: If given, passed into nicks.get/add.</span>
<span class="sd"> Note:</span>
<span class="sd"> This will remove two nicks - the plain channel alias and the templated</span>
<span class="sd"> nick used for easily sending messages to the channel.</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">caller</span><span class="o">.</span><span class="n">nicks</span><span class="o">.</span><span class="n">has</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">DefaultChannel</span><span class="o">.</span><span class="n">remove_user_channel_alias</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">alias</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="s2">&quot;No such alias was defined.&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.get_channel_aliases"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.get_channel_aliases">[docs]</a> <span class="k">def</span> <span class="nf">get_channel_aliases</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 a user&#39;s aliases for a given channel. The user is retrieved</span>
<span class="sd"> through self.caller.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to act on.</span>
<span class="sd"> Returns:</span>
<span class="sd"> list: A list of zero, one or more alias-strings.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">chan_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">lower</span><span class="p">()</span>
<span class="n">nicktuples</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</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="k">if</span> <span class="n">nicktuples</span><span class="p">:</span>
<span class="k">return</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">return</span> <span class="p">[]</span></div>
<div class="viewcode-block" id="CmdChannel.mute_channel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.mute_channel">[docs]</a> <span class="k">def</span> <span class="nf">mute_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"> Temporarily mute a channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to alias.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if muting successful. If False,</span>
<span class="sd"> the second part is an error string.</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">mute</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="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;Channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> was already muted.&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.unmute_channel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.unmute_channel">[docs]</a> <span class="k">def</span> <span class="nf">unmute_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"> Unmute a channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to alias.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if unmuting successful. If False,</span>
<span class="sd"> the second part is an error string.</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">unmute</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="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;Channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> was already unmuted.&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.create_channel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.create_channel">[docs]</a> <span class="k">def</span> <span class="nf">create_channel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">description</span><span class="p">,</span> <span class="n">typeclass</span><span class="o">=</span><span class="kc">None</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="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create a new channel. Its name must not previously exist</span>
<span class="sd"> (users can alias as needed). Will also connect to the</span>
<span class="sd"> new channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> name (str): The new channel name/key.</span>
<span class="sd"> description (str): This is used in listings.</span>
<span class="sd"> aliases (list): A list of strings - alternative aliases for the channel</span>
<span class="sd"> (not to be confused with per-user aliases; these are available for</span>
<span class="sd"> everyone).</span>
<span class="sd"> Returns:</span>
<span class="sd"> channel, str: new_channel, &quot;&quot; if creation successful. If False,</span>
<span class="sd"> the second part is an error string.</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="k">if</span> <span class="n">typeclass</span><span class="p">:</span>
<span class="n">typeclass</span> <span class="o">=</span> <span class="n">class_from_module</span><span class="p">(</span><span class="n">typeclass</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">typeclass</span> <span class="o">=</span> <span class="n">CHANNEL_DEFAULT_TYPECLASS</span>
<span class="k">if</span> <span class="n">typeclass</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">channel_search</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">exact</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;Channel </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2"> already exists.&quot;</span>
<span class="c1"># set up the new channel</span>
<span class="n">lockstring</span> <span class="o">=</span> <span class="s2">&quot;send:all();listen:all();control:id(</span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="n">caller</span><span class="o">.</span><span class="n">id</span>
<span class="n">new_chan</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="n">name</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">desc</span><span class="o">=</span><span class="n">description</span><span class="p">,</span> <span class="n">locks</span><span class="o">=</span><span class="n">lockstring</span><span class="p">,</span> <span class="n">typeclass</span><span class="o">=</span><span class="n">typeclass</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sub_to_channel</span><span class="p">(</span><span class="n">new_chan</span><span class="p">)</span>
<span class="k">return</span> <span class="n">new_chan</span><span class="p">,</span> <span class="s2">&quot;&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.destroy_channel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.destroy_channel">[docs]</a> <span class="k">def</span> <span class="nf">destroy_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="n">message</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Destroy an existing channel. Access should be checked before</span>
<span class="sd"> calling this function.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to alias.</span>
<span class="sd"> message (str, optional): Final message to send onto the channel</span>
<span class="sd"> before destroying it. If not given, a default message is</span>
<span class="sd"> used. Set to the empty string for no message.</span>
<span class="sd"> if typeclass:</span>
<span class="sd"> pass</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">channel_key</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">key</span>
<span class="k">if</span> <span class="n">message</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">message</span> <span class="o">=</span> <span class="p">(</span><span class="sa">f</span><span class="s2">&quot;|rChannel </span><span class="si">{</span><span class="n">channel_key</span><span class="si">}</span><span class="s2"> is being destroyed. &quot;</span>
<span class="s2">&quot;Make sure to clean any channel aliases.|n&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">message</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">message</span><span class="p">,</span> <span class="n">senders</span><span class="o">=</span><span class="n">caller</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">channel</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_sec</span><span class="p">(</span>
<span class="s2">&quot;Channel </span><span class="si">{}</span><span class="s2"> was deleted by </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">channel_key</span><span class="p">,</span> <span class="n">caller</span><span class="p">)</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="CmdChannel.set_lock"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.set_lock">[docs]</a> <span class="k">def</span> <span class="nf">set_lock</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="n">lockstring</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Set a lockstring on a channel. Permissions must have been</span>
<span class="sd"> checked before this call.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to operate on.</span>
<span class="sd"> lockstring (str): A lockstring on the form &#39;type:lockfunc();...&#39;</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if setting lock was successful. If False,</span>
<span class="sd"> the second part is an error string.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</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="n">lockstring</span><span class="p">)</span>
<span class="k">except</span> <span class="n">LockException</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="n">err</span>
<span class="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.unset_lock"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.unset_lock">[docs]</a> <span class="k">def</span> <span class="nf">unset_lock</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="n">lockstring</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Remove locks in a lockstring on a channel. Permissions must have been</span>
<span class="sd"> checked before this call.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to operate on.</span>
<span class="sd"> lockstring (str): A lockstring on the form &#39;type:lockfunc();...&#39;</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if setting lock was successful. If False,</span>
<span class="sd"> the second part is an error string.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">channel</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">lockstring</span><span class="p">)</span>
<span class="k">except</span> <span class="n">LockException</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="n">err</span>
<span class="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.set_desc"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.set_desc">[docs]</a> <span class="k">def</span> <span class="nf">set_desc</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="n">description</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Set a channel description. This is shown in listings etc.</span>
<span class="sd"> Args:</span>
<span class="sd"> caller (Object or Account): The entity performing the action.</span>
<span class="sd"> channel (Channel): The channel to operate on.</span>
<span class="sd"> description (str): A short description of the channel.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if setting lock was successful. If False,</span>
<span class="sd"> the second part is an error string.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">channel</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="n">description</span></div>
<div class="viewcode-block" id="CmdChannel.boot_user"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.boot_user">[docs]</a> <span class="k">def</span> <span class="nf">boot_user</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="n">target</span><span class="p">,</span> <span class="n">quiet</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">reason</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Boot a user from a channel, with optional reason. This will</span>
<span class="sd"> also remove all their aliases for this channel.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to operate on.</span>
<span class="sd"> target (Object or Account): The entity to boot.</span>
<span class="sd"> quiet (bool, optional): Whether or not to announce to channel.</span>
<span class="sd"> reason (str, optional): A reason for the boot.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if setting lock was successful. If False,</span>
<span class="sd"> the second part is an error string.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</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">target</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">target</span><span class="si">}</span><span class="s2"> is not connected to channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span>
<span class="c1"># find all of target&#39;s nicks linked to this channel and delete them</span>
<span class="k">for</span> <span class="n">nick</span> <span class="ow">in</span> <span class="p">[</span>
<span class="n">nick</span>
<span class="k">for</span> <span class="n">nick</span> <span class="ow">in</span> <span class="n">target</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="ow">or</span> <span class="p">[]</span>
<span class="k">if</span> <span class="n">nick</span><span class="o">.</span><span class="n">value</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">channel</span><span class="o">.</span><span class="n">key</span>
<span class="p">]:</span>
<span class="n">nick</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="n">channel</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
<span class="n">reason</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot; Reason: </span><span class="si">{</span><span class="n">reason</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="n">reason</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="n">target</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;You were booted from channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> by </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</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">reason</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">quiet</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="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> was booted from channel by </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</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">reason</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_sec</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Channel Boot: </span><span class="si">{</span><span class="n">target</span><span class="si">}</span><span class="s2"> (Channel: </span><span class="si">{</span><span class="n">channel</span><span class="si">}</span><span class="s2">, &quot;</span>
<span class="sa">f</span><span class="s2">&quot;Reason: </span><span class="si">{</span><span class="n">reason</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="si">}</span><span class="s2">, Caller: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.ban_user"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.ban_user">[docs]</a> <span class="k">def</span> <span class="nf">ban_user</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="n">target</span><span class="p">,</span> <span class="n">quiet</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">reason</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Ban a user from a channel, by locking them out. This will also</span>
<span class="sd"> boot them, if they are currently connected.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to operate on.</span>
<span class="sd"> target (Object or Account): The entity to ban</span>
<span class="sd"> quiet (bool, optional): Whether or not to announce to channel.</span>
<span class="sd"> reason (str, optional): A reason for the ban</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if banning was successful. If False,</span>
<span class="sd"> the second part is an error string.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">boot_user</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">quiet</span><span class="o">=</span><span class="n">quiet</span><span class="p">,</span> <span class="n">reason</span><span class="o">=</span><span class="n">reason</span><span class="p">)</span>
<span class="k">if</span> <span class="n">channel</span><span class="o">.</span><span class="n">ban</span><span class="p">(</span><span class="n">target</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">target</span><span class="si">}</span><span class="s2"> is already banned from this channel.&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.unban_user"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.unban_user">[docs]</a> <span class="k">def</span> <span class="nf">unban_user</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="n">target</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Un-Ban a user from a channel. This will not reconnect them</span>
<span class="sd"> to the channel, just allow them to connect again (assuming</span>
<span class="sd"> they have the suitable &#39;listen&#39; lock like everyone else).</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to operate on.</span>
<span class="sd"> target (Object or Account): The entity to unban</span>
<span class="sd"> Returns:</span>
<span class="sd"> bool, str: True, None if unbanning was successful. If False,</span>
<span class="sd"> the second part is an error string.</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">unban</span><span class="p">(</span><span class="n">target</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">target</span><span class="si">}</span><span class="s2"> was not previously banned from this channel.&quot;</span></div>
<div class="viewcode-block" id="CmdChannel.channel_list_bans"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.channel_list_bans">[docs]</a> <span class="k">def</span> <span class="nf">channel_list_bans</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"> Show a channel&#39;s bans.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to operate on.</span>
<span class="sd"> Returns:</span>
<span class="sd"> list: A list of strings, each the name of a banned user.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">[</span><span class="n">banned</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">banned</span> <span class="ow">in</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="CmdChannel.channel_list_who"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.channel_list_who">[docs]</a> <span class="k">def</span> <span class="nf">channel_list_who</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"> Show a list of online people is subscribing to a channel. This will check</span>
<span class="sd"> the &#39;control&#39; permission of `caller` to determine if only online users</span>
<span class="sd"> should be returned or everyone.</span>
<span class="sd"> Args:</span>
<span class="sd"> channel (Channel): The channel to operate on.</span>
<span class="sd"> Returns:</span>
<span class="sd"> list: A list of prepared strings, with name + markers for if they are</span>
<span class="sd"> muted or offline.</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">mute_list</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">channel</span><span class="o">.</span><span class="n">mutelist</span><span class="p">)</span>
<span class="n">online_list</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">online</span><span class="p">()</span>
<span class="k">if</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="s1">&#39;control&#39;</span><span class="p">):</span>
<span class="c1"># for those with channel control, show also offline users</span>
<span class="n">all_subs</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</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="k">else</span><span class="p">:</span>
<span class="c1"># for others, only show online users</span>
<span class="n">all_subs</span> <span class="o">=</span> <span class="n">online_list</span>
<span class="n">who_list</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">subscriber</span> <span class="ow">in</span> <span class="n">all_subs</span><span class="p">:</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">subscriber</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="n">conditions</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;muting&quot;</span> <span class="k">if</span> <span class="n">subscriber</span> <span class="ow">in</span> <span class="n">mute_list</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;offline&quot;</span> <span class="k">if</span> <span class="n">subscriber</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">online_list</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">conditions</span> <span class="o">=</span> <span class="p">[</span><span class="n">cond</span> <span class="k">for</span> <span class="n">cond</span> <span class="ow">in</span> <span class="n">conditions</span> <span class="k">if</span> <span class="n">cond</span><span class="p">]</span>
<span class="n">cond_text</span> <span class="o">=</span> <span class="s2">&quot;(&quot;</span> <span class="o">+</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">conditions</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;)&quot;</span> <span class="k">if</span> <span class="n">conditions</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="n">who_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">name</span><span class="si">}{</span><span class="n">cond_text</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">who_list</span></div>
<div class="viewcode-block" id="CmdChannel.list_channels"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.list_channels">[docs]</a> <span class="k">def</span> <span class="nf">list_channels</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">channelcls</span><span class="o">=</span><span class="n">CHANNEL_DEFAULT_TYPECLASS</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return a available channels.</span>
<span class="sd"> Args:</span>
<span class="sd"> channelcls (Channel, optional): The channel-class to query on. Defaults</span>
<span class="sd"> to the default channel class from settings.</span>
<span class="sd"> Returns:</span>
<span class="sd"> tuple: A tuple `(subbed_chans, available_chans)` with the channels</span>
<span class="sd"> currently subscribed to, and those we have &#39;listen&#39; access to but</span>
<span class="sd"> don&#39;t actually sub to yet.</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">subscribed_channels</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">channelcls</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_subscriptions</span><span class="p">(</span><span class="n">caller</span><span class="p">))</span>
<span class="n">unsubscribed_available_channels</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">chan</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channelcls</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="k">if</span> <span class="n">chan</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">subscribed_channels</span> <span class="ow">and</span> <span class="n">chan</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;listen&quot;</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">return</span> <span class="n">subscribed_channels</span><span class="p">,</span> <span class="n">unsubscribed_available_channels</span></div>
<div class="viewcode-block" id="CmdChannel.display_subbed_channels"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.display_subbed_channels">[docs]</a> <span class="k">def</span> <span class="nf">display_subbed_channels</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subscribed</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Display channels subscribed to.</span>
<span class="sd"> Args:</span>
<span class="sd"> subscribed (list): List of subscribed channels</span>
<span class="sd"> Returns:</span>
<span class="sd"> EvTable: Table to display.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">comtable</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span>
<span class="s2">&quot;channel&quot;</span><span class="p">,</span>
<span class="s2">&quot;my aliases&quot;</span><span class="p">,</span>
<span class="s2">&quot;locks&quot;</span><span class="p">,</span>
<span class="s2">&quot;description&quot;</span><span class="p">,</span>
<span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span><span class="p">,</span>
<span class="n">maxwidth</span><span class="o">=</span><span class="n">_DEFAULT_WIDTH</span>
<span class="p">)</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">subscribed</span><span class="p">:</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;-&quot;</span>
<span class="k">if</span> <span class="n">chan</span><span class="o">.</span><span class="n">access</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="s2">&quot;control&quot;</span><span class="p">):</span>
<span class="n">locks</span> <span class="o">=</span> <span class="n">chan</span><span class="o">.</span><span class="n">locks</span>
<span class="n">my_aliases</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="bp">self</span><span class="o">.</span><span class="n">get_channel_aliases</span><span class="p">(</span><span class="n">chan</span><span class="p">))</span>
<span class="n">comtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="o">*</span><span class="p">(</span><span class="s2">&quot;</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">chan</span><span class="o">.</span><span class="n">key</span><span class="p">,</span>
<span class="s2">&quot;(</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;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">chan</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">if</span> <span class="n">chan</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">else</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
<span class="n">my_aliases</span><span class="p">,</span>
<span class="n">locks</span><span class="p">,</span>
<span class="n">chan</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span><span class="p">))</span>
<span class="k">return</span> <span class="n">comtable</span></div>
<div class="viewcode-block" id="CmdChannel.display_all_channels"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.display_all_channels">[docs]</a> <span class="k">def</span> <span class="nf">display_all_channels</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subscribed</span><span class="p">,</span> <span class="n">available</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Display all available channels</span>
<span class="sd"> Args:</span>
<span class="sd"> subscribed (list): List of subscribed channels</span>
<span class="sd"> Returns:</span>
<span class="sd"> EvTable: Table to display.</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">comtable</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span>
<span class="s2">&quot;sub&quot;</span><span class="p">,</span>
<span class="s2">&quot;channel&quot;</span><span class="p">,</span>
<span class="s2">&quot;aliases&quot;</span><span class="p">,</span>
<span class="s2">&quot;my aliases&quot;</span><span class="p">,</span>
<span class="s2">&quot;description&quot;</span><span class="p">,</span>
<span class="n">maxwidth</span><span class="o">=</span><span class="n">_DEFAULT_WIDTH</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">channels</span> <span class="o">=</span> <span class="n">subscribed</span> <span class="o">+</span> <span class="n">available</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="k">if</span> <span class="n">chan</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">subscribed</span><span class="p">:</span>
<span class="n">substatus</span> <span class="o">=</span> <span class="s2">&quot;|rNo|n&quot;</span>
<span class="k">elif</span> <span class="n">caller</span> <span class="ow">in</span> <span class="n">chan</span><span class="o">.</span><span class="n">mutelist</span><span class="p">:</span>
<span class="n">substatus</span> <span class="o">=</span> <span class="s2">&quot;|rMuting|n&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">substatus</span> <span class="o">=</span> <span class="s2">&quot;|gYes|n&quot;</span>
<span class="n">my_aliases</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="bp">self</span><span class="o">.</span><span class="n">get_channel_aliases</span><span class="p">(</span><span class="n">chan</span><span class="p">))</span>
<span class="n">comtable</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="o">*</span><span class="p">(</span><span class="n">substatus</span><span class="p">,</span>
<span class="n">chan</span><span class="o">.</span><span class="n">key</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">chan</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">if</span> <span class="n">chan</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">else</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">my_aliases</span><span class="p">,</span>
<span class="n">chan</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span><span class="p">))</span>
<span class="n">comtable</span><span class="o">.</span><span class="n">reformat_column</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="mi">8</span><span class="p">)</span>
<span class="k">return</span> <span class="n">comtable</span></div>
<div class="viewcode-block" id="CmdChannel.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannel.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"> Main functionality of command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># from evennia import set_trace;set_trace()</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">switches</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span>
<span class="n">channel_names</span> <span class="o">=</span> <span class="p">[</span><span class="n">name</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhslist</span> <span class="k">if</span> <span class="n">name</span><span class="p">]</span>
<span class="c1">#from evennia import set_trace;set_trace()</span>
<span class="k">if</span> <span class="s1">&#39;all&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># show all available channels</span>
<span class="n">subscribed</span><span class="p">,</span> <span class="n">available</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">list_channels</span><span class="p">()</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">display_all_channels</span><span class="p">(</span><span class="n">subscribed</span><span class="p">,</span> <span class="n">available</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;</span><span class="se">\n</span><span class="s2">|wAvailable channels|n (use no argument to &quot;</span>
<span class="sa">f</span><span class="s2">&quot;only show your subscriptions)</span><span class="se">\n</span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channel_names</span><span class="p">:</span>
<span class="c1"># empty arg show only subscribed channels</span>
<span class="n">subscribed</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">list_channels</span><span class="p">()</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">display_subbed_channels</span><span class="p">(</span><span class="n">subscribed</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;</span><span class="se">\n</span><span class="s2">|wChannel subscriptions|n &quot;</span>
<span class="sa">f</span><span class="s2">&quot;(use |w/all|n to see all available):</span><span class="se">\n</span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage[/switches]: channel [= message]&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;create&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># create a new channel</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">caller</span><span class="p">,</span> <span class="s2">&quot;manage&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have access to use channel/create.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">config</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">config</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;To create: channel/create name[;aliases][:typeclass] [= description]&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">name</span><span class="p">,</span> <span class="o">*</span><span class="n">typeclass</span> <span class="o">=</span> <span class="n">config</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>
<span class="n">typeclass</span> <span class="o">=</span> <span class="n">typeclass</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">typeclass</span> <span class="k">else</span> <span class="kc">None</span>
<span class="n">name</span><span class="p">,</span> <span class="o">*</span><span class="n">aliases</span> <span class="o">=</span> <span class="n">name</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="n">description</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span>
<span class="n">chan</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_channel</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">description</span><span class="p">,</span> <span class="n">typeclass</span><span class="o">=</span><span class="n">typeclass</span><span class="p">,</span> <span class="n">aliases</span><span class="o">=</span><span class="n">aliases</span><span class="p">)</span>
<span class="k">if</span> <span class="n">chan</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Created (and joined) new channel &#39;</span><span class="si">{</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39;.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;unalias&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># remove a personal alias (no channel needed)</span>
<span class="n">alias</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="k">if</span> <span class="ow">not</span> <span class="n">alias</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;Specify the alias to remove as channel/unalias &lt;alias&gt;&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">remove_alias</span><span class="p">(</span><span class="n">alias</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Removed your channel alias &#39;</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&#39;.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">possible_lhs_message</span> <span class="o">=</span> <span class="s2">&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">rhs</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="ow">and</span> <span class="s2">&quot; &quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="c1"># since we want to support messaging with `channel name text` (for</span>
<span class="c1"># channels without a space in their name), we need to check if the</span>
<span class="c1"># first &#39;channel name&#39; is in fact &#39;channelname text&#39;</span>
<span class="n">no_rhs_channel_name</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="mi">0</span><span class="p">]</span>
<span class="n">possible_lhs_message</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="nb">len</span><span class="p">(</span><span class="n">no_rhs_channel_name</span><span class="p">):]</span>
<span class="k">if</span> <span class="n">possible_lhs_message</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;=&#39;</span><span class="p">:</span>
<span class="n">possible_lhs_message</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">channel_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">no_rhs_channel_name</span><span class="p">)</span>
<span class="n">channels</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">channel_name</span> <span class="ow">in</span> <span class="n">channel_names</span><span class="p">:</span>
<span class="c1"># find a channel by fuzzy-matching. This also checks</span>
<span class="c1"># &#39;listen/control&#39; perms.</span>
<span class="n">found_channels</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_channel</span><span class="p">(</span><span class="n">channel_name</span><span class="p">,</span> <span class="n">exact</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">handle_errors</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">found_channels</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="sa">f</span><span class="s2">&quot;No channel found matching &#39;</span><span class="si">{</span><span class="n">channel_name</span><span class="si">}</span><span class="s2">&#39; &quot;</span>
<span class="s2">&quot;(could also be due to missing access).&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">found_channels</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</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;Multiple possible channel matches/alias for &quot;</span>
<span class="s2">&quot;&#39;</span><span class="si">{channel_name}</span><span class="s2">&#39;:</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">+</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">found_channels</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">channels</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">found_channels</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channels</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="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">errors</span><span class="p">))</span>
<span class="k">return</span>
<span class="c1"># we have at least one channel at this point</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">channels</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">switches</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="c1"># send message to channel</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="k">elif</span> <span class="n">channel</span> <span class="ow">and</span> <span class="n">possible_lhs_message</span><span class="p">:</span>
<span class="c1"># called on the form channelname message without =</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">possible_lhs_message</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># inspect a given channel</span>
<span class="n">subscribed</span><span class="p">,</span> <span class="n">available</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">list_channels</span><span class="p">()</span>
<span class="k">if</span> <span class="n">channel</span> <span class="ow">in</span> <span class="n">subscribed</span><span class="p">:</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">display_subbed_channels</span><span class="p">([</span><span class="n">channel</span><span class="p">])</span>
<span class="n">header</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Channel |w</span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">|n&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">header</span><span class="si">}</span><span class="se">\n</span><span class="s2">(use |w</span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> &lt;msg&gt;|n (or a channel-alias) &quot;</span>
<span class="sa">f</span><span class="s2">&quot;to chat and the &#39;channel&#39; command &quot;</span>
<span class="sa">f</span><span class="s2">&quot;to customize)</span><span class="se">\n</span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">channel</span> <span class="ow">in</span> <span class="n">available</span><span class="p">:</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">display_all_channels</span><span class="p">([],</span> <span class="p">[</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="s2">&quot;</span><span class="se">\n</span><span class="s2">|wNot subscribed to this channel|n (use /list to &quot;</span>
<span class="sa">f</span><span class="s2">&quot;show all subscriptions)</span><span class="se">\n</span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;history&#39;</span> <span class="ow">in</span> <span class="n">switches</span> <span class="ow">or</span> <span class="s1">&#39;hist&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># view channel history</span>
<span class="n">index</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span> <span class="ow">or</span> <span class="mi">0</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">index</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="nb">int</span><span class="p">(</span><span class="n">index</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">ValueError</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;The history index (describing how many lines to go back) &quot;</span>
<span class="s2">&quot;must be an integer &gt;= 0.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">get_channel_history</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">start_index</span><span class="o">=</span><span class="n">index</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;sub&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># subscribe to a channel</span>
<span class="n">aliases</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">rhs</span><span class="p">:</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">alias</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">alias</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;;&quot;</span><span class="p">))</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sub_to_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">aliases</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_alias</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">alias</span><span class="p">)</span>
<span class="n">alias_txt</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">aliases</span><span class="p">)</span>
<span class="n">alias_txt</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot; using alias(es) </span><span class="si">{</span><span class="n">alias_txt</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="n">aliases</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You are now subscribed &quot;</span>
<span class="sa">f</span><span class="s2">&quot;to the channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}{</span><span class="n">alias_txt</span><span class="si">}</span><span class="s2">. Use /alias to &quot;</span>
<span class="s2">&quot;add additional aliases for referring to the channel.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;unsub&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># un-subscribe from a channel</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">unsub_from_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;You un-subscribed from channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">. &quot;</span>
<span class="s2">&quot;All aliases were cleared.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;alias&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># create a new personal alias for a channel</span>
<span class="n">alias</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">alias</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;Specify the alias as channel/alias channelname = alias&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_alias</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">alias</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Added/updated your alias &#39;</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&#39; for channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;mute&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># mute a given channel</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mute_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Muted channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;unmute&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># unmute a given channel</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">unmute_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Un-muted channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;destroy&#39;</span> <span class="ow">in</span> <span class="n">switches</span> <span class="ow">or</span> <span class="s1">&#39;delete&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># destroy a channel we control</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">caller</span><span class="p">,</span> <span class="s2">&quot;manage&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have access to use channel/destroy.&quot;</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;control&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can only delete channels you control.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">reason</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span> <span class="ow">or</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">_perform_delete</span><span class="p">(</span><span class="n">caller</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">destroy_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">message</span><span class="o">=</span><span class="n">reason</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> was successfully deleted.&quot;</span><span class="p">)</span>
<span class="n">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="sa">f</span><span class="s2">&quot;Are you sure you want to delete channel &#39;</span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; &quot;</span>
<span class="s2">&quot;(make sure name is correct!)?</span><span class="se">\n</span><span class="s2">This will disconnect and &quot;</span>
<span class="s2">&quot;remove all users&#39; aliases. </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="n">_perform_delete</span><span class="p">,</span>
<span class="n">no_action</span><span class="o">=</span><span class="s2">&quot;Aborted.&quot;</span><span class="p">,</span>
<span class="n">default</span><span class="o">=</span><span class="s2">&quot;N&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="s1">&#39;desc&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># set channel description</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">caller</span><span class="p">,</span> <span class="s2">&quot;manage&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have access to use channel/desc.&quot;</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;control&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can only change description of channels you control.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">desc</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: /desc channel = description&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">set_desc</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">desc</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;Updated channel description.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="s1">&#39;lock&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># add a lockstring to channel</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">caller</span><span class="p">,</span> <span class="s2">&quot;changelocks&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have access to use channel/lock.&quot;</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;control&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You need &#39;control&#39;-access to change locks on this channel.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">lockstring</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">lockstring</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: channel/lock channelname = lockstring&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">set_lock</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</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;Added/updated lock on channel.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Could not add/update lock: </span><span class="si">{</span><span class="n">err</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;unlock&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># remove/update lockstring from channel</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">caller</span><span class="p">,</span> <span class="s2">&quot;changelocks&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have access to use channel/unlock.&quot;</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;control&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You need &#39;control&#39;-access to change locks on this channel.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">lockstring</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">lockstring</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: channel/unlock channelname = lockstring&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">unset_lock</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</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;Removed lock from channel.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Could not remove lock: </span><span class="si">{</span><span class="n">err</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;boot&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># boot a user from channel(s)</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">caller</span><span class="p">,</span> <span class="s2">&quot;admin&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have access to use channel/boot.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: channel/boot channel[,channel,...] = username [:reason]&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">target_str</span><span class="p">,</span> <span class="o">*</span><span class="n">reason</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</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>
<span class="n">reason</span> <span class="o">=</span> <span class="n">reason</span><span class="p">[</span><span class="mi">0</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">reason</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">chan</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;control&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="sa">f</span><span class="s2">&quot;You need &#39;control&#39;-access to boot a user from </span><span class="si">{</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># the target must be a member of all given channels</span>
<span class="n">target</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">target_str</span><span class="p">,</span> <span class="n">candidates</span><span class="o">=</span><span class="n">chan</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">target</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot boot &#39;</span><span class="si">{</span><span class="n">target_str</span><span class="si">}</span><span class="s2">&#39; - not in channel </span><span class="si">{</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">def</span> <span class="nf">_boot_user</span><span class="p">(</span><span class="n">caller</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">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">boot_user</span><span class="p">(</span><span class="n">chan</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">quiet</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">reason</span><span class="o">=</span><span class="n">reason</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Booted </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> from channel </span><span class="si">{</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot boot </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> from channel </span><span class="si">{</span><span class="n">chan</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">err</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">channames</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">chan</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">)</span>
<span class="n">reasonwarn</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;. Also note that your reason will be echoed to the channel&quot;</span>
<span class="k">if</span> <span class="n">reason</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="n">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="sa">f</span><span class="s2">&quot;Are you sure you want to boot user </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> from &quot;</span>
<span class="sa">f</span><span class="s2">&quot;channel(s) </span><span class="si">{</span><span class="n">channames</span><span class="si">}</span><span class="s2"> (make sure name/channels are correct</span><span class="si">{</span><span class="n">reasonwarn</span><span class="si">}</span><span class="s2">). &quot;</span>
<span class="s2">&quot;</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="n">_boot_user</span><span class="p">,</span>
<span class="n">no_action</span><span class="o">=</span><span class="s2">&quot;Aborted.&quot;</span><span class="p">,</span>
<span class="n">default</span><span class="o">=</span><span class="s2">&quot;Y&quot;</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;ban&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># ban a user from channel(s)</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">caller</span><span class="p">,</span> <span class="s2">&quot;admin&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have access to use channel/ban.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="c1"># view bans for channels</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;control&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="sa">f</span><span class="s2">&quot;You need &#39;control&#39;-access to view bans on channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">bans</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;Channel bans &quot;</span>
<span class="s2">&quot;(to ban, use channel/ban channel[,channel,...] = username [:reason]&quot;</span><span class="p">]</span>
<span class="n">bans</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">channel_list_bans</span><span class="p">(</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="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">bans</span><span class="p">))</span>
<span class="k">return</span>
<span class="n">target_str</span><span class="p">,</span> <span class="o">*</span><span class="n">reason</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</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>
<span class="n">reason</span> <span class="o">=</span> <span class="n">reason</span><span class="p">[</span><span class="mi">0</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">reason</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="c1"># the target must be a member of all given channels</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">chan</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;control&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="sa">f</span><span class="s2">&quot;You don&#39;t have access to ban users on channel </span><span class="si">{</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">target</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">target_str</span><span class="p">,</span> <span class="n">candidates</span><span class="o">=</span><span class="n">chan</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">target</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot ban &#39;</span><span class="si">{</span><span class="n">target_str</span><span class="si">}</span><span class="s2">&#39; - not in channel </span><span class="si">{</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">def</span> <span class="nf">_ban_user</span><span class="p">(</span><span class="n">caller</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">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ban_user</span><span class="p">(</span><span class="n">chan</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">quiet</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">reason</span><span class="o">=</span><span class="n">reason</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Banned </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> from channel </span><span class="si">{</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Cannot boot </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> from channel </span><span class="si">{</span><span class="n">chan</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">err</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">channames</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">chan</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">)</span>
<span class="n">reasonwarn</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;. Also note that your reason will be echoed to the channel&quot;</span>
<span class="k">if</span> <span class="n">reason</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="n">ask_yes_no</span><span class="p">(</span>
<span class="n">caller</span><span class="p">,</span>
<span class="sa">f</span><span class="s2">&quot;Are you sure you want to ban user </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> from &quot;</span>
<span class="sa">f</span><span class="s2">&quot;channel(s) </span><span class="si">{</span><span class="n">channames</span><span class="si">}</span><span class="s2"> (make sure name/channels are correct</span><span class="si">{</span><span class="n">reasonwarn</span><span class="si">}</span><span class="s2">) &quot;</span>
<span class="s2">&quot;</span><span class="si">{options}</span><span class="s2">?&quot;</span><span class="p">,</span>
<span class="n">_ban_user</span><span class="p">,</span>
<span class="s2">&quot;Aborted.&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s1">&#39;unban&#39;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># unban a previously banned user from channel</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">caller</span><span class="p">,</span> <span class="s2">&quot;admin&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have access to use channel/unban.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">target_str</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">target_str</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: channel[,channel,...] = user&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">banlists</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="c1"># the target must be a member of all given channels</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">chan</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;control&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="sa">f</span><span class="s2">&quot;You don&#39;t have access to unban users on channel </span><span class="si">{</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">banlists</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">chan</span><span class="o">.</span><span class="n">banlist</span><span class="p">)</span>
<span class="n">target</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">target_str</span><span class="p">,</span> <span class="n">candidates</span><span class="o">=</span><span class="n">banlists</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">target</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;Could not find a banned user &#39;</span><span class="si">{target_str}</span><span class="s2">&#39; in given channel(s).&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">unban_user</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">target</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Un-banned </span><span class="si">{</span><span class="n">target_str</span><span class="si">}</span><span class="s2"> from channel </span><span class="si">{</span><span class="n">chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;who&quot;</span> <span class="ow">in</span> <span class="n">switches</span><span class="p">:</span>
<span class="c1"># view who&#39;s a member of a channel</span>
<span class="n">who_list</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">&quot;Subscribed to </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">:&quot;</span><span class="p">]</span>
<span class="n">who_list</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">channel_list_who</span><span class="p">(</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="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">who_list</span><span class="p">))</span>
<span class="k">return</span></div></div>
<span class="c1"># a channel-command parent for use with Characters/Objects.</span>
<div class="viewcode-block" id="CmdObjectChannel"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdObjectChannel">[docs]</a><span class="k">class</span> <span class="nc">CmdObjectChannel</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="CmdAddCom"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdAddCom">[docs]</a><span class="k">class</span> <span class="nc">CmdAddCom</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Add a channel alias and/or subscribe to a channel</span>
<span class="sd"> Usage:</span>
<span class="sd"> addcom [alias=] &lt;channel&gt;</span>
<span class="sd"> Joins a given channel. If alias is given, this will allow you to</span>
<span class="sd"> refer to the channel by this alias rather than the full channel</span>
<span class="sd"> name. Subsequent calls of this command can be used to add multiple</span>
<span class="sd"> aliases to an already joined channel.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;addcom&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;aliaschan&quot;</span><span class="p">,</span> <span class="s2">&quot;chanalias&quot;</span><span class="p">]</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:not pperm(channel_banned)&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdAddCom.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdAddCom.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;Implement the command&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">args</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">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: addcom [alias =] channelname.&quot;</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">rhs</span><span class="p">:</span>
<span class="c1"># rhs holds the channelname</span>
<span class="n">channelname</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span>
<span class="n">alias</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span>
<span class="k">else</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">args</span>
<span class="n">alias</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_channel</span><span class="p">(</span><span class="n">channelname</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="k">return</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;&quot;</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="c1"># we want to connect as well.</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sub_to_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="c1"># if this would have returned True, the account is connected</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;You now listen to the channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">: You are not allowed to join this channel.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</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="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;You unmute channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;You are already connected to channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">alias</span><span class="p">:</span>
<span class="c1"># create a nick and add it to the caller.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_alias</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">alias</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; You can now refer to the channel </span><span class="si">{</span><span class="n">channel</span><span class="si">}</span><span class="s2"> with the alias &#39;</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&#39;.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot; No alias added.&quot;</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="p">)</span></div></div>
<div class="viewcode-block" id="CmdDelCom"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdDelCom">[docs]</a><span class="k">class</span> <span class="nc">CmdDelCom</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> remove a channel alias and/or unsubscribe from channel</span>
<span class="sd"> Usage:</span>
<span class="sd"> delcom &lt;alias or channel&gt;</span>
<span class="sd"> delcom/all &lt;channel&gt;</span>
<span class="sd"> If the full channel name is given, unsubscribe from the</span>
<span class="sd"> channel. If an alias is given, remove the alias but don&#39;t</span>
<span class="sd"> unsubscribe. If the &#39;all&#39; switch is used, remove all aliases</span>
<span class="sd"> for that channel.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;delcom&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;delaliaschan&quot;</span><span class="p">,</span> <span class="s2">&quot;delchanalias&quot;</span><span class="p">]</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:not perm(channel_banned)&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdDelCom.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdDelCom.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;Implementing the command. &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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: delcom &lt;alias or channel&gt;&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">ostring</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">lower</span><span class="p">()</span><span class="o">.</span><span class="n">strip</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">search_channel</span><span class="p">(</span><span class="n">ostring</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="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="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You are not listening to that channel.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">ostring</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">lower</span><span class="p">():</span>
<span class="c1"># an exact channel name - unsubscribe</span>
<span class="n">delnicks</span> <span class="o">=</span> <span class="s2">&quot;all&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span>
<span class="c1"># find all nicks linked to this channel and delete them</span>
<span class="k">if</span> <span class="n">delnicks</span><span class="p">:</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_channel_aliases</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
<span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">aliases</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove_alias</span><span class="p">(</span><span class="n">alias</span><span class="p">)</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">unsub_from_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="n">wipednicks</span> <span class="o">=</span> <span class="s2">&quot; Eventual aliases were removed.&quot;</span> <span class="k">if</span> <span class="n">delnicks</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;You stop listening to channel &#39;</span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39;.</span><span class="si">{</span><span class="n">wipednicks</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># we are removing a channel nick</span>
<span class="bp">self</span><span class="o">.</span><span class="n">remove_alias</span><span class="p">(</span><span class="n">ostring</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Any alias &#39;</span><span class="si">{</span><span class="n">ostring</span><span class="si">}</span><span class="s2">&#39; for channel </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> was cleared.&quot;</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdAllCom"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdAllCom">[docs]</a><span class="k">class</span> <span class="nc">CmdAllCom</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> perform admin operations on all channels</span>
<span class="sd"> Usage:</span>
<span class="sd"> allcom [on | off | who | destroy]</span>
<span class="sd"> Allows the user to universally turn off or on all channels they are on, as</span>
<span class="sd"> well as perform a &#39;who&#39; for all channels they are on. Destroy deletes all</span>
<span class="sd"> channels that you control.</span>
<span class="sd"> Without argument, works like comlist.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;allcom&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># important to not inherit parent&#39;s aliases</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd: not pperm(channel_banned)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdAllCom.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdAllCom.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;Runs the function&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">args</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">args</span><span class="p">:</span>
<span class="n">subscribed</span><span class="p">,</span> <span class="n">available</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">list_channels</span><span class="p">()</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">display_all_channels</span><span class="p">(</span><span class="n">subscribed</span><span class="p">,</span> <span class="n">available</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;</span><span class="se">\n</span><span class="s2">|wAvailable channels:</span><span class="se">\n</span><span class="si">{table}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">args</span> <span class="o">==</span> <span class="s2">&quot;on&quot;</span><span class="p">:</span>
<span class="c1"># get names of all channels available to listen to</span>
<span class="c1"># and activate them all</span>
<span class="n">channels</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">chan</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">CHANNEL_DEFAULT_TYPECLASS</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="k">if</span> <span class="n">chan</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;listen&quot;</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">for</span> <span class="n">channel</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">execute_cmd</span><span class="p">(</span><span class="s2">&quot;addcom </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">key</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">args</span> <span class="o">==</span> <span class="s2">&quot;off&quot;</span><span class="p">:</span>
<span class="c1"># get names all subscribed channels and disconnect from them all</span>
<span class="n">channels</span> <span class="o">=</span> <span class="n">CHANNEL_DEFAULT_TYPECLASS</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_subscriptions</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="k">for</span> <span class="n">channel</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">execute_cmd</span><span class="p">(</span><span class="s2">&quot;delcom </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">key</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">args</span> <span class="o">==</span> <span class="s2">&quot;destroy&quot;</span><span class="p">:</span>
<span class="c1"># destroy all channels you control</span>
<span class="n">channels</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">chan</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">CHANNEL_DEFAULT_TYPECLASS</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="k">if</span> <span class="n">chan</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;control&quot;</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">for</span> <span class="n">channel</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">execute_cmd</span><span class="p">(</span><span class="s2">&quot;cdestroy </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">key</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">args</span> <span class="o">==</span> <span class="s2">&quot;who&quot;</span><span class="p">:</span>
<span class="c1"># run a who, listing the subscribers on visible channels.</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|CChannel subscriptions|n&quot;</span>
<span class="n">channels</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">chan</span>
<span class="k">for</span> <span class="n">chan</span> <span class="ow">in</span> <span class="n">CHANNEL_DEFAULT_TYPECLASS</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="k">if</span> <span class="n">chan</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;listen&quot;</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">channels</span><span class="p">:</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;No channels.&quot;</span>
<span class="k">for</span> <span class="n">channel</span> <span class="ow">in</span> <span class="n">channels</span><span class="p">:</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|w</span><span class="si">%s</span><span class="s2">:|n</span><span class="se">\n</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">channel</span><span class="o">.</span><span class="n">wholist</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">strip</span><span class="p">())</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># wrong input</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: allcom on | off | who | clear&quot;</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdCdestroy"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdCdestroy">[docs]</a><span class="k">class</span> <span class="nc">CmdCdestroy</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> destroy a channel you created</span>
<span class="sd"> Usage:</span>
<span class="sd"> cdestroy &lt;channel&gt;</span>
<span class="sd"> Destroys a channel that you control.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;cdestroy&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd: not pperm(channel_banned)&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdCdestroy.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdCdestroy.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;Destroy objects cleanly.&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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: cdestroy &lt;channelname&gt;&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_channel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</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="s2">&quot;Could not find channel </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">args</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;control&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You are not allowed to do that.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">channel_key</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">key</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">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> is being destroyed. Make sure to change your aliases.&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">destroy_channel</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">message</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;Channel &#39;</span><span class="si">%s</span><span class="s2">&#39; was destroyed.&quot;</span> <span class="o">%</span> <span class="n">channel_key</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_sec</span><span class="p">(</span>
<span class="s2">&quot;Channel Deleted: </span><span class="si">%s</span><span class="s2"> (Caller: </span><span class="si">%s</span><span class="s2">, IP: </span><span class="si">%s</span><span class="s2">).&quot;</span>
<span class="o">%</span> <span class="p">(</span><span class="n">channel_key</span><span class="p">,</span> <span class="n">caller</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">address</span><span class="p">)</span>
<span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdCBoot"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdCBoot">[docs]</a><span class="k">class</span> <span class="nc">CmdCBoot</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> kick an account from a channel you control</span>
<span class="sd"> Usage:</span>
<span class="sd"> cboot[/quiet] &lt;channel&gt; = &lt;account&gt; [:reason]</span>
<span class="sd"> Switch:</span>
<span class="sd"> quiet - don&#39;t notify the channel</span>
<span class="sd"> Kicks an account or object from a channel you control.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;cboot&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;quiet&quot;</span><span class="p">,)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd: not pperm(channel_banned)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdCBoot.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdCBoot.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;implement the function&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">args</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Usage: cboot[/quiet] &lt;channel&gt; = &lt;account&gt; [:reason]&quot;</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="p">)</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_channel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhs</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="k">return</span>
<span class="n">reason</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="s2">&quot;:&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="n">target</span><span class="p">,</span> <span class="n">reason</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</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>
<span class="n">is_account</span> <span class="o">=</span> <span class="n">target</span><span class="o">.</span><span class="n">strip</span><span class="p">()</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">searchstring</span> <span class="o">=</span> <span class="n">target</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&quot;*&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">is_account</span> <span class="o">=</span> <span class="n">target</span><span class="o">.</span><span class="n">strip</span><span class="p">()</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">searchstring</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&quot;*&quot;</span><span class="p">)</span>
<span class="n">target</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">searchstring</span><span class="p">,</span> <span class="n">account</span><span class="o">=</span><span class="n">is_account</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">target</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">reason</span><span class="p">:</span>
<span class="n">reason</span> <span class="o">=</span> <span class="s2">&quot; (reason: </span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="n">reason</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="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;control&quot;</span><span class="p">):</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;You don&#39;t control this channel.&quot;</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="p">)</span>
<span class="k">return</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">boot_user</span><span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">quiet</span><span class="o">=</span><span class="s1">&#39;quiet&#39;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Booted </span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> from </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_sec</span><span class="p">(</span>
<span class="s2">&quot;Channel Boot: </span><span class="si">%s</span><span class="s2"> (Channel: </span><span class="si">%s</span><span class="s2">, Reason: </span><span class="si">%s</span><span class="s2">, Caller: </span><span class="si">%s</span><span class="s2">, IP: </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">caller</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">reason</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="bp">self</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">address</span><span class="p">)</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdCWho"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdCWho">[docs]</a><span class="k">class</span> <span class="nc">CmdCWho</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> show who is listening to a channel</span>
<span class="sd"> Usage:</span>
<span class="sd"> cwho &lt;channel&gt;</span>
<span class="sd"> List who is connected to a given channel you have access to.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;cwho&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd: not pperm(channel_banned)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdCWho.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdCWho.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;implement function&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">args</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Usage: cwho &lt;channel&gt;&quot;</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="p">)</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_channel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhs</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="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="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;listen&quot;</span><span class="p">):</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;You can&#39;t access this channel.&quot;</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="p">)</span>
<span class="k">return</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|CChannel subscriptions|n&quot;</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">|w</span><span class="si">%s</span><span class="s2">:|n</span><span class="se">\n</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">channel</span><span class="o">.</span><span class="n">wholist</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">strip</span><span class="p">())</span></div></div>
<div class="viewcode-block" id="CmdChannelCreate"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannelCreate">[docs]</a><span class="k">class</span> <span class="nc">CmdChannelCreate</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> create a new channel</span>
<span class="sd"> Usage:</span>
<span class="sd"> ccreate &lt;new channel&gt;[;alias;alias...] = description</span>
<span class="sd"> Creates a new channel owned by you.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;ccreate&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="s2">&quot;channelcreate&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:not pperm(channel_banned) and pperm(Player)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdChannelCreate.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdChannelCreate.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;Implement the command&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">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage ccreate &lt;channelname&gt;[;alias;alias..] = description&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="n">description</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span>
<span class="n">lhs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span>
<span class="n">channame</span> <span class="o">=</span> <span class="n">lhs</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="s2">&quot;;&quot;</span> <span class="ow">in</span> <span class="n">lhs</span><span class="p">:</span>
<span class="n">channame</span><span class="p">,</span> <span class="n">aliases</span> <span class="o">=</span> <span class="n">lhs</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="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="n">alias</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">alias</span> <span class="ow">in</span> <span class="n">aliases</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;;&quot;</span><span class="p">)]</span>
<span class="n">new_chan</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_channel</span><span class="p">(</span><span class="n">channame</span><span class="p">,</span> <span class="n">description</span><span class="p">,</span> <span class="n">aliases</span><span class="o">=</span><span class="n">aliases</span><span class="p">)</span>
<span class="k">if</span> <span class="n">new_chan</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Created channel </span><span class="si">{</span><span class="n">new_chan</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2"> and connected to it.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdClock"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdClock">[docs]</a><span class="k">class</span> <span class="nc">CmdClock</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> change channel locks of a channel you control</span>
<span class="sd"> Usage:</span>
<span class="sd"> clock &lt;channel&gt; [= &lt;lockstring&gt;]</span>
<span class="sd"> Changes the lock access restrictions of a channel. If no</span>
<span class="sd"> lockstring was given, view the current lock definitions.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;clock&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;clock&quot;</span><span class="p">]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:not pperm(channel_banned) and perm(Admin)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdClock.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdClock.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;run the function&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">args</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Usage: clock channel [= lockstring]&quot;</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="p">)</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_channel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhs</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="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="c1"># no =, so just view the current locks</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Current locks on </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="se">\n</span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">locks</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># we want to add/change a lock.</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="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;control&quot;</span><span class="p">):</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;You don&#39;t control this channel.&quot;</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="p">)</span>
<span class="k">return</span>
<span class="c1"># Try to add the lock</span>
<span class="n">success</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">set_lock</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">success</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Lock(s) applied. Current locks on </span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">:</span><span class="se">\n</span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">locks</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">err</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdCdesc"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdCdesc">[docs]</a><span class="k">class</span> <span class="nc">CmdCdesc</span><span class="p">(</span><span class="n">CmdChannel</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> describe a channel you control</span>
<span class="sd"> Usage:</span>
<span class="sd"> cdesc &lt;channel&gt; = &lt;description&gt;</span>
<span class="sd"> Changes the description of the channel as shown in</span>
<span class="sd"> channel lists.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;cdesc&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:not pperm(channel_banned)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdCdesc.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdCdesc.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;Implement command&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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: cdesc &lt;channel&gt; = &lt;description&gt;&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_channel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhs</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="k">return</span>
<span class="c1"># check permissions</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;control&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You cannot admin this channel.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">set_desc</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Description of channel &#39;</span><span class="si">{</span><span class="n">channel</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; set to &#39;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="si">}</span><span class="s2">&#39;.&quot;</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdPage"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdPage">[docs]</a><span class="k">class</span> <span class="nc">CmdPage</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"> send a private message to another account</span>
<span class="sd"> Usage:</span>
<span class="sd"> page &lt;account&gt; &lt;message&gt;</span>
<span class="sd"> page[/switches] [&lt;account&gt;,&lt;account&gt;,... = &lt;message&gt;]</span>
<span class="sd"> tell &#39;&#39;</span>
<span class="sd"> page &lt;number&gt;</span>
<span class="sd"> Switches:</span>
<span class="sd"> last - shows who you last messaged</span>
<span class="sd"> list - show your last &lt;number&gt; of tells/pages (default)</span>
<span class="sd"> Send a message to target user (if online). If no argument is given, you</span>
<span class="sd"> will get a list of your latest messages. The equal sign is needed for</span>
<span class="sd"> multiple targets or if sending to target with space in the name.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;page&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;tell&quot;</span><span class="p">]</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;last&quot;</span><span class="p">,</span> <span class="s2">&quot;list&quot;</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:not pperm(page_banned)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<span class="c1"># this is used by the COMMAND_DEFAULT_CLASS parent</span>
<span class="n">account_caller</span> <span class="o">=</span> <span class="kc">True</span>
<div class="viewcode-block" id="CmdPage.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdPage.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;Implement function using the Msg methods&quot;&quot;&quot;</span>
<span class="c1"># Since account_caller is set above, this will be an Account.</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="c1"># get the messages we&#39;ve sent (not to channels)</span>
<span class="n">pages_we_sent</span> <span class="o">=</span> <span class="n">Msg</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_messages_by_sender</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="c1"># get last messages we&#39;ve got</span>
<span class="n">pages_we_got</span> <span class="o">=</span> <span class="n">Msg</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_messages_by_receiver</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="n">targets</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">number</span> <span class="o">=</span> <span class="p">[],</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span>
<span class="k">if</span> <span class="s2">&quot;last&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="k">if</span> <span class="n">pages_we_sent</span><span class="p">:</span>
<span class="n">recv</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">obj</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">pages_we_sent</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">receivers</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You last paged |c</span><span class="si">%s</span><span class="s2">|n:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">recv</span><span class="p">,</span> <span class="n">pages_we_sent</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">message</span><span class="p">))</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You haven&#39;t paged anyone yet.&quot;</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">args</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="k">for</span> <span class="n">target</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhslist</span><span class="p">:</span>
<span class="n">target_obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">target_obj</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">targets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">target_obj</span><span class="p">)</span>
<span class="n">message</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">target</span><span class="p">,</span> <span class="o">*</span><span class="n">message</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">4</span><span class="p">)</span>
<span class="k">if</span> <span class="n">target</span> <span class="ow">and</span> <span class="n">target</span><span class="o">.</span><span class="n">isnumeric</span><span class="p">():</span>
<span class="c1"># a number to specify a historic page</span>
<span class="n">number</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">target</span><span class="p">:</span>
<span class="n">target_obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">quiet</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="n">target_obj</span><span class="p">:</span>
<span class="c1"># a proper target</span>
<span class="n">targets</span> <span class="o">=</span> <span class="p">[</span><span class="n">target_obj</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">message</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># a message with a space in it - put it back together</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">target</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span> <span class="o">+</span> <span class="p">(</span><span class="n">message</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">message</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># a single-word message</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">message</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">pages</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">pages_we_sent</span><span class="p">)</span> <span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="n">pages_we_got</span><span class="p">)</span>
<span class="n">pages</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">pages</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">page</span><span class="p">:</span> <span class="n">page</span><span class="o">.</span><span class="n">date_created</span><span class="p">)</span>
<span class="k">if</span> <span class="n">message</span><span class="p">:</span>
<span class="c1"># send a message</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">targets</span><span class="p">:</span>
<span class="c1"># no target given - send to last person we paged</span>
<span class="k">if</span> <span class="n">pages_we_sent</span><span class="p">:</span>
<span class="n">targets</span> <span class="o">=</span> <span class="n">pages_we_sent</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">receivers</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Who do you want page?&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">header</span> <span class="o">=</span> <span class="s2">&quot;|wAccount|n |c</span><span class="si">%s</span><span class="s2">|n |wpages:|n&quot;</span> <span class="o">%</span> <span class="n">caller</span><span class="o">.</span><span class="n">key</span>
<span class="k">if</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;</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">caller</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">message</span><span class="o">.</span><span class="n">strip</span><span class="p">(</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="c1"># create the persistent message object</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">message</span><span class="p">,</span> <span class="n">receivers</span><span class="o">=</span><span class="n">targets</span><span class="p">)</span>
<span class="c1"># tell the accounts they got a message.</span>
<span class="n">received</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">rstrings</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">target</span> <span class="ow">in</span> <span class="n">targets</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">target</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;msg&quot;</span><span class="p">):</span>
<span class="n">rstrings</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;You are not allowed to page </span><span class="si">{</span><span class="n">target</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
<span class="k">continue</span>
<span class="n">target</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">header</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="nb">hasattr</span><span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="s2">&quot;sessions&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">target</span><span class="o">.</span><span class="n">sessions</span><span class="o">.</span><span class="n">count</span><span class="p">():</span>
<span class="n">received</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;|C</span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">|n&quot;</span><span class="p">)</span>
<span class="n">rstrings</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">received</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="si">}</span><span class="s2"> is offline. They will see your message &quot;</span>
<span class="s2">&quot;if they list their pages later.&quot;</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">received</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;|c</span><span class="si">{</span><span class="n">target</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">|n&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rstrings</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;</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">rstrings</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You paged </span><span class="si">%s</span><span class="s2"> with: &#39;</span><span class="si">%s</span><span class="s2">&#39;.&quot;</span> <span class="o">%</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">received</span><span class="p">),</span> <span class="n">message</span><span class="p">))</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># no message to send</span>
<span class="k">if</span> <span class="n">number</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">pages</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">number</span><span class="p">:</span>
<span class="n">lastpages</span> <span class="o">=</span> <span class="n">pages</span><span class="p">[</span><span class="o">-</span><span class="n">number</span><span class="p">:]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">lastpages</span> <span class="o">=</span> <span class="n">pages</span>
<span class="n">to_template</span> <span class="o">=</span> <span class="s2">&quot;|w</span><span class="si">{date}{clr}</span><span class="s2"> </span><span class="si">{sender}</span><span class="s2">|nto</span><span class="si">{clr}{receiver}</span><span class="s2">|n:&gt; </span><span class="si">{message}</span><span class="s2">&quot;</span>
<span class="n">from_template</span> <span class="o">=</span> <span class="s2">&quot;|w</span><span class="si">{date}{clr}</span><span class="s2"> </span><span class="si">{receiver}</span><span class="s2">|nfrom</span><span class="si">{clr}{sender}</span><span class="s2">|n:&lt; </span><span class="si">{message}</span><span class="s2">&quot;</span>
<span class="n">listing</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">prev_selfsend</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">for</span> <span class="n">page</span> <span class="ow">in</span> <span class="n">lastpages</span><span class="p">:</span>
<span class="n">multi_send</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">page</span><span class="o">.</span><span class="n">senders</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span>
<span class="n">multi_recv</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">page</span><span class="o">.</span><span class="n">receivers</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span>
<span class="n">sending</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">senders</span>
<span class="c1"># self-messages all look like sends, so we assume they always</span>
<span class="c1"># come in close pairs and treat the second of the pair as the recv.</span>
<span class="n">selfsend</span> <span class="o">=</span> <span class="n">sending</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">receivers</span>
<span class="k">if</span> <span class="n">selfsend</span><span class="p">:</span>
<span class="k">if</span> <span class="n">prev_selfsend</span><span class="p">:</span>
<span class="c1"># this is actually a receive of a self-message</span>
<span class="n">sending</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">prev_selfsend</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">prev_selfsend</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">clr</span> <span class="o">=</span> <span class="s2">&quot;|c&quot;</span> <span class="k">if</span> <span class="n">sending</span> <span class="k">else</span> <span class="s2">&quot;|g&quot;</span>
<span class="n">sender</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;|n,</span><span class="si">{</span><span class="n">clr</span><span class="si">}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">senders</span><span class="p">)</span>
<span class="n">receiver</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;|n,</span><span class="si">{</span><span class="n">clr</span><span class="si">}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">obj</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">receivers</span><span class="p">])</span>
<span class="k">if</span> <span class="n">sending</span><span class="p">:</span>
<span class="n">template</span> <span class="o">=</span> <span class="n">to_template</span>
<span class="n">sender</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">sender</span><span class="si">}</span><span class="s2"> &quot;</span> <span class="k">if</span> <span class="n">multi_send</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="n">receiver</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot; </span><span class="si">{</span><span class="n">receiver</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="n">multi_recv</span> <span class="k">else</span> <span class="sa">f</span><span class="s2">&quot; </span><span class="si">{</span><span class="n">receiver</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">template</span> <span class="o">=</span> <span class="n">from_template</span>
<span class="n">receiver</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">receiver</span><span class="si">}</span><span class="s2"> &quot;</span> <span class="k">if</span> <span class="n">multi_recv</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="n">sender</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot; </span><span class="si">{</span><span class="n">sender</span><span class="si">}</span><span class="s2"> &quot;</span> <span class="k">if</span> <span class="n">multi_send</span> <span class="k">else</span> <span class="sa">f</span><span class="s2">&quot; </span><span class="si">{</span><span class="n">sender</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="n">listing</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="n">template</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">date</span><span class="o">=</span><span class="n">utils</span><span class="o">.</span><span class="n">datetime_format</span><span class="p">(</span><span class="n">page</span><span class="o">.</span><span class="n">date_created</span><span class="p">),</span>
<span class="n">clr</span><span class="o">=</span><span class="n">clr</span><span class="p">,</span>
<span class="n">sender</span><span class="o">=</span><span class="n">sender</span><span class="p">,</span>
<span class="n">receiver</span><span class="o">=</span><span class="n">receiver</span><span class="p">,</span>
<span class="n">message</span><span class="o">=</span><span class="n">page</span><span class="o">.</span><span class="n">message</span><span class="p">,</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="n">lastpages</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">join</span><span class="p">(</span><span class="n">listing</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lastpages</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Your latest pages:</span><span class="se">\n</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">lastpages</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;You haven&#39;t paged anyone yet.&quot;</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="p">)</span>
<span class="k">return</span></div></div>
<span class="k">def</span> <span class="nf">_list_bots</span><span class="p">(</span><span class="n">cmd</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper function to produce a list of all IRC bots.</span>
<span class="sd"> Args:</span>
<span class="sd"> cmd (Command): Instance of the Bot command.</span>
<span class="sd"> Returns:</span>
<span class="sd"> bots (str): A table of bots or an error message.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ircbots</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">bot</span> <span class="k">for</span> <span class="n">bot</span> <span class="ow">in</span> <span class="n">AccountDB</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_is_bot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">username__startswith</span><span class="o">=</span><span class="s2">&quot;ircbot-&quot;</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">if</span> <span class="n">ircbots</span><span class="p">:</span>
<span class="n">table</span> <span class="o">=</span> <span class="n">cmd</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span>
<span class="s2">&quot;|w#dbref|n&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wbotname|n&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wev-channel|n&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wirc-channel|n&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wSSL|n&quot;</span><span class="p">,</span>
<span class="n">maxwidth</span><span class="o">=</span><span class="n">_DEFAULT_WIDTH</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">for</span> <span class="n">ircbot</span> <span class="ow">in</span> <span class="n">ircbots</span><span class="p">:</span>
<span class="n">ircinfo</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">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_channel</span><span class="p">,</span>
<span class="n">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_network</span><span class="p">,</span>
<span class="n">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_port</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">table</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="s2">&quot;#</span><span class="si">%i</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">ircbot</span><span class="o">.</span><span class="n">id</span><span class="p">,</span>
<span class="n">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_botname</span><span class="p">,</span>
<span class="n">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">,</span>
<span class="n">ircinfo</span><span class="p">,</span>
<span class="n">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_ssl</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">table</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;No irc bots found.&quot;</span>
<div class="viewcode-block" id="CmdIRC2Chan"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdIRC2Chan">[docs]</a><span class="k">class</span> <span class="nc">CmdIRC2Chan</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"> Link an evennia channel to an external IRC channel</span>
<span class="sd"> Usage:</span>
<span class="sd"> irc2chan[/switches] &lt;evennia_channel&gt; = &lt;ircnetwork&gt; &lt;port&gt; &lt;#irchannel&gt; &lt;botname&gt;[:typeclass]</span>
<span class="sd"> irc2chan/delete botname|#dbid</span>
<span class="sd"> Switches:</span>
<span class="sd"> /delete - this will delete the bot and remove the irc connection</span>
<span class="sd"> to the channel. Requires the botname or #dbid as input.</span>
<span class="sd"> /remove - alias to /delete</span>
<span class="sd"> /disconnect - alias to /delete</span>
<span class="sd"> /list - show all irc&lt;-&gt;evennia mappings</span>
<span class="sd"> /ssl - use an SSL-encrypted connection</span>
<span class="sd"> Example:</span>
<span class="sd"> irc2chan myircchan = irc.dalnet.net 6667 #mychannel evennia-bot</span>
<span class="sd"> irc2chan public = irc.freenode.net 6667 #evgaming #evbot:accounts.mybot.MyBot</span>
<span class="sd"> This creates an IRC bot that connects to a given IRC network and</span>
<span class="sd"> channel. If a custom typeclass path is given, this will be used</span>
<span class="sd"> instead of the default bot class.</span>
<span class="sd"> The bot will relay everything said in the evennia channel to the</span>
<span class="sd"> IRC channel and vice versa. The bot will automatically connect at</span>
<span class="sd"> server start, so this command need only be given once. The</span>
<span class="sd"> /disconnect switch will permanently delete the bot. To only</span>
<span class="sd"> temporarily deactivate it, use the |wservices|n command instead.</span>
<span class="sd"> Provide an optional bot class path to use a custom bot.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;irc2chan&quot;</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;delete&quot;</span><span class="p">,</span> <span class="s2">&quot;remove&quot;</span><span class="p">,</span> <span class="s2">&quot;disconnect&quot;</span><span class="p">,</span> <span class="s2">&quot;list&quot;</span><span class="p">,</span> <span class="s2">&quot;ssl&quot;</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:serversetting(IRC_ENABLED) and pperm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<div class="viewcode-block" id="CmdIRC2Chan.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdIRC2Chan.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;Setup the irc-channel mapping&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">settings</span><span class="o">.</span><span class="n">IRC_ENABLED</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;IRC is not enabled. You need to activate it in game/settings.py.&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">string</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;list&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="c1"># show all connections</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">_list_bots</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;disconnect&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">or</span> <span class="s2">&quot;remove&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">or</span> <span class="s2">&quot;delete&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="n">botname</span> <span class="o">=</span> <span class="s2">&quot;ircbot-</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">lhs</span>
<span class="n">matches</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">filter</span><span class="p">(</span><span class="n">db_is_bot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="n">botname</span><span class="p">)</span>
<span class="n">dbref</span> <span class="o">=</span> <span class="n">utils</span><span class="o">.</span><span class="n">dbref</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">matches</span> <span class="ow">and</span> <span class="n">dbref</span><span class="p">:</span>
<span class="c1"># try dbref match</span>
<span class="n">matches</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">filter</span><span class="p">(</span><span class="n">db_is_bot</span><span class="o">=</span><span class="kc">True</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">matches</span><span class="p">:</span>
<span class="n">matches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;IRC connection destroyed.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;IRC connection/bot could not be removed, does it exist?&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;Usage: irc2chan[/switches] &lt;evennia_channel&gt; =&quot;</span>
<span class="s2">&quot; &lt;ircnetwork&gt; &lt;port&gt; &lt;#irchannel&gt; &lt;botname&gt;[:typeclass]&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="p">)</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span>
<span class="bp">self</span><span class="o">.</span><span class="n">rhs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</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="c1"># to avoid Python comment issues</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">irc_network</span><span class="p">,</span> <span class="n">irc_port</span><span class="p">,</span> <span class="n">irc_channel</span><span class="p">,</span> <span class="n">irc_botname</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="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">rhs</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
<span class="p">]</span>
<span class="n">irc_channel</span> <span class="o">=</span> <span class="s2">&quot;#</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">irc_channel</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;IRC bot definition &#39;</span><span class="si">%s</span><span class="s2">&#39; is not valid.&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</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="p">)</span>
<span class="k">return</span>
<span class="n">botclass</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="s2">&quot;:&quot;</span> <span class="ow">in</span> <span class="n">irc_botname</span><span class="p">:</span>
<span class="n">irc_botname</span><span class="p">,</span> <span class="n">botclass</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="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">irc_botname</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">2</span><span class="p">)]</span>
<span class="n">botname</span> <span class="o">=</span> <span class="s2">&quot;ircbot-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">irc_botname</span>
<span class="c1"># If path given, use custom bot otherwise use default.</span>
<span class="n">botclass</span> <span class="o">=</span> <span class="n">botclass</span> <span class="k">if</span> <span class="n">botclass</span> <span class="k">else</span> <span class="n">bots</span><span class="o">.</span><span class="n">IRCBot</span>
<span class="n">irc_ssl</span> <span class="o">=</span> <span class="s2">&quot;ssl&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span>
<span class="c1"># create a new bot</span>
<span class="n">bot</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">filter</span><span class="p">(</span><span class="n">username__iexact</span><span class="o">=</span><span class="n">botname</span><span class="p">)</span>
<span class="k">if</span> <span class="n">bot</span><span class="p">:</span>
<span class="c1"># re-use an existing bot</span>
<span class="n">bot</span> <span class="o">=</span> <span class="n">bot</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">bot</span><span class="o">.</span><span class="n">is_bot</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;Account &#39;</span><span class="si">%s</span><span class="s2">&#39; already exists and is not a bot.&quot;</span> <span class="o">%</span> <span class="n">botname</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">bot</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_account</span><span class="p">(</span><span class="n">botname</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">typeclass</span><span class="o">=</span><span class="n">botclass</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="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;|rError, could not create the bot:|n &#39;</span><span class="si">%s</span><span class="s2">&#39;.&quot;</span> <span class="o">%</span> <span class="n">err</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">bot</span><span class="o">.</span><span class="n">start</span><span class="p">(</span>
<span class="n">ev_channel</span><span class="o">=</span><span class="n">channel</span><span class="p">,</span>
<span class="n">irc_botname</span><span class="o">=</span><span class="n">irc_botname</span><span class="p">,</span>
<span class="n">irc_channel</span><span class="o">=</span><span class="n">irc_channel</span><span class="p">,</span>
<span class="n">irc_network</span><span class="o">=</span><span class="n">irc_network</span><span class="p">,</span>
<span class="n">irc_port</span><span class="o">=</span><span class="n">irc_port</span><span class="p">,</span>
<span class="n">irc_ssl</span><span class="o">=</span><span class="n">irc_ssl</span><span class="p">,</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;Connection created. Starting IRC bot.&quot;</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdIRCStatus"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdIRCStatus">[docs]</a><span class="k">class</span> <span class="nc">CmdIRCStatus</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"> Check and reboot IRC bot.</span>
<span class="sd"> Usage:</span>
<span class="sd"> ircstatus [#dbref ping | nicklist | reconnect]</span>
<span class="sd"> If not given arguments, will return a list of all bots (like</span>
<span class="sd"> irc2chan/list). The &#39;ping&#39; argument will ping the IRC network to</span>
<span class="sd"> see if the connection is still responsive. The &#39;nicklist&#39; argument</span>
<span class="sd"> (aliases are &#39;who&#39; and &#39;users&#39;) will return a list of users on the</span>
<span class="sd"> remote IRC channel. Finally, &#39;reconnect&#39; will force the client to</span>
<span class="sd"> disconnect and reconnect again. This may be a last resort if the</span>
<span class="sd"> client has silently lost connection (this may happen if the remote</span>
<span class="sd"> network experience network issues). During the reconnection</span>
<span class="sd"> messages sent to either channel will be lost.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;ircstatus&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:serversetting(IRC_ENABLED) and perm(ircstatus) or perm(Builder))&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<div class="viewcode-block" id="CmdIRCStatus.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdIRCStatus.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;Handles the functioning of the command.&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">args</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">_list_bots</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">return</span>
<span class="c1"># should always be on the form botname option</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">split</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Usage: ircstatus [#dbref ping||nicklist||reconnect]&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">botname</span><span class="p">,</span> <span class="n">option</span> <span class="o">=</span> <span class="n">args</span>
<span class="k">if</span> <span class="n">option</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;ping&quot;</span><span class="p">,</span> <span class="s2">&quot;users&quot;</span><span class="p">,</span> <span class="s2">&quot;reconnect&quot;</span><span class="p">,</span> <span class="s2">&quot;nicklist&quot;</span><span class="p">,</span> <span class="s2">&quot;who&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Not a valid option.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">matches</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">utils</span><span class="o">.</span><span class="n">dbref</span><span class="p">(</span><span class="n">botname</span><span class="p">):</span>
<span class="n">matches</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">filter</span><span class="p">(</span><span class="n">db_is_bot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="n">utils</span><span class="o">.</span><span class="n">dbref</span><span class="p">(</span><span class="n">botname</span><span class="p">))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">matches</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;No matching IRC-bot found. Use ircstatus without arguments to list active bots.&quot;</span>
<span class="p">)</span>
<span class="k">return</span>
<span class="n">ircbot</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="n">channel</span> <span class="o">=</span> <span class="n">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_channel</span>
<span class="n">network</span> <span class="o">=</span> <span class="n">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_network</span>
<span class="n">port</span> <span class="o">=</span> <span class="n">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_port</span>
<span class="n">chtext</span> <span class="o">=</span> <span class="s2">&quot;IRC bot &#39;</span><span class="si">%s</span><span class="s2">&#39; on channel </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">ircbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">irc_botname</span><span class="p">,</span>
<span class="n">channel</span><span class="p">,</span>
<span class="n">network</span><span class="p">,</span>
<span class="n">port</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">option</span> <span class="o">==</span> <span class="s2">&quot;ping&quot;</span><span class="p">:</span>
<span class="c1"># check connection by sending outself a ping through the server.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Pinging through </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="n">chtext</span><span class="p">)</span>
<span class="n">ircbot</span><span class="o">.</span><span class="n">ping</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="k">elif</span> <span class="n">option</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;users&quot;</span><span class="p">,</span> <span class="s2">&quot;nicklist&quot;</span><span class="p">,</span> <span class="s2">&quot;who&quot;</span><span class="p">):</span>
<span class="c1"># retrieve user list. The bot must handles the echo since it&#39;s</span>
<span class="c1"># an asynchronous call.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Requesting nicklist from </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="p">,</span> <span class="n">network</span><span class="p">,</span> <span class="n">port</span><span class="p">))</span>
<span class="n">ircbot</span><span class="o">.</span><span class="n">get_nicklist</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="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">check_lockstring</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="s2">&quot;dummy:perm(ircstatus) or perm(Developer)&quot;</span>
<span class="p">):</span>
<span class="c1"># reboot the client</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Forcing a disconnect + reconnect of </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="n">chtext</span><span class="p">)</span>
<span class="n">ircbot</span><span class="o">.</span><span class="n">reconnect</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">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You don&#39;t have permission to force-reload the IRC bot.&quot;</span><span class="p">)</span></div></div>
<span class="c1"># RSS connection</span>
<div class="viewcode-block" id="CmdRSS2Chan"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdRSS2Chan">[docs]</a><span class="k">class</span> <span class="nc">CmdRSS2Chan</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"> link an evennia channel to an external RSS feed</span>
<span class="sd"> Usage:</span>
<span class="sd"> rss2chan[/switches] &lt;evennia_channel&gt; = &lt;rss_url&gt;</span>
<span class="sd"> Switches:</span>
<span class="sd"> /disconnect - this will stop the feed and remove the connection to the</span>
<span class="sd"> channel.</span>
<span class="sd"> /remove - &quot;</span>
<span class="sd"> /list - show all rss-&gt;evennia mappings</span>
<span class="sd"> Example:</span>
<span class="sd"> rss2chan rsschan = http://code.google.com/feeds/p/evennia/updates/basic</span>
<span class="sd"> This creates an RSS reader that connects to a given RSS feed url. Updates</span>
<span class="sd"> will be echoed as a title and news link to the given channel. The rate of</span>
<span class="sd"> updating is set with the RSS_UPDATE_INTERVAL variable in settings (default</span>
<span class="sd"> is every 10 minutes).</span>
<span class="sd"> When disconnecting you need to supply both the channel and url again so as</span>
<span class="sd"> to identify the connection uniquely.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;rss2chan&quot;</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;disconnect&quot;</span><span class="p">,</span> <span class="s2">&quot;remove&quot;</span><span class="p">,</span> <span class="s2">&quot;list&quot;</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:serversetting(RSS_ENABLED) and pperm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<div class="viewcode-block" id="CmdRSS2Chan.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdRSS2Chan.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;Setup the rss-channel mapping&quot;&quot;&quot;</span>
<span class="c1"># checking we have all we need</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">settings</span><span class="o">.</span><span class="n">RSS_ENABLED</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;RSS is not enabled. You need to activate it in game/settings.py.&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">string</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">feedparser</span>
<span class="k">assert</span> <span class="n">feedparser</span> <span class="c1"># to avoid checker error of not being used</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;RSS requires python-feedparser (https://pypi.python.org/pypi/feedparser).&quot;</span>
<span class="s2">&quot; Install before continuing.&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="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;list&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="c1"># show all connections</span>
<span class="n">rssbots</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">bot</span>
<span class="k">for</span> <span class="n">bot</span> <span class="ow">in</span> <span class="n">AccountDB</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_is_bot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">username__startswith</span><span class="o">=</span><span class="s2">&quot;rssbot-&quot;</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">if</span> <span class="n">rssbots</span><span class="p">:</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span>
<span class="s2">&quot;|wdbid|n&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wupdate rate|n&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wev-channel&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wRSS feed URL|n&quot;</span><span class="p">,</span>
<span class="n">border</span><span class="o">=</span><span class="s2">&quot;cells&quot;</span><span class="p">,</span>
<span class="n">maxwidth</span><span class="o">=</span><span class="n">_DEFAULT_WIDTH</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">for</span> <span class="n">rssbot</span> <span class="ow">in</span> <span class="n">rssbots</span><span class="p">:</span>
<span class="n">table</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span>
<span class="n">rssbot</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">rssbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">rss_rate</span><span class="p">,</span> <span class="n">rssbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">,</span> <span class="n">rssbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">rss_url</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">table</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;No rss bots found.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;disconnect&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">or</span> <span class="s2">&quot;remove&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">or</span> <span class="s2">&quot;delete&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="n">botname</span> <span class="o">=</span> <span class="s2">&quot;rssbot-</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">lhs</span>
<span class="n">matches</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">filter</span><span class="p">(</span><span class="n">db_is_bot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">db_key</span><span class="o">=</span><span class="n">botname</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">matches</span><span class="p">:</span>
<span class="c1"># try dbref match</span>
<span class="n">matches</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">filter</span><span class="p">(</span><span class="n">db_is_bot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="nb">id</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">lstrip</span><span class="p">(</span><span class="s2">&quot;#&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="n">matches</span><span class="p">:</span>
<span class="n">matches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;RSS connection destroyed.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;RSS connection/bot could not be removed, does it exist?&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Usage: rss2chan[/switches] &lt;evennia_channel&gt; = &lt;rss url&gt;&quot;</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="p">)</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span>
<span class="n">url</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span>
<span class="n">botname</span> <span class="o">=</span> <span class="s2">&quot;rssbot-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">url</span>
<span class="n">bot</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">filter</span><span class="p">(</span><span class="n">username__iexact</span><span class="o">=</span><span class="n">botname</span><span class="p">)</span>
<span class="k">if</span> <span class="n">bot</span><span class="p">:</span>
<span class="c1"># re-use existing bot</span>
<span class="n">bot</span> <span class="o">=</span> <span class="n">bot</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">bot</span><span class="o">.</span><span class="n">is_bot</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;Account &#39;</span><span class="si">%s</span><span class="s2">&#39; already exists and is not a bot.&quot;</span> <span class="o">%</span> <span class="n">botname</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># create a new bot</span>
<span class="n">bot</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_account</span><span class="p">(</span><span class="n">botname</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">typeclass</span><span class="o">=</span><span class="n">bots</span><span class="o">.</span><span class="n">RSSBot</span><span class="p">)</span>
<span class="n">bot</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="n">ev_channel</span><span class="o">=</span><span class="n">channel</span><span class="p">,</span> <span class="n">rss_url</span><span class="o">=</span><span class="n">url</span><span class="p">,</span> <span class="n">rss_rate</span><span class="o">=</span><span class="mi">10</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;RSS reporter created. Fetching RSS.&quot;</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdGrapevine2Chan"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdGrapevine2Chan">[docs]</a><span class="k">class</span> <span class="nc">CmdGrapevine2Chan</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"> Link an Evennia channel to an exteral Grapevine channel</span>
<span class="sd"> Usage:</span>
<span class="sd"> grapevine2chan[/switches] &lt;evennia_channel&gt; = &lt;grapevine_channel&gt;</span>
<span class="sd"> grapevine2chan/disconnect &lt;connection #id&gt;</span>
<span class="sd"> Switches:</span>
<span class="sd"> /list - (or no switch): show existing grapevine &lt;-&gt; Evennia</span>
<span class="sd"> mappings and available grapevine chans</span>
<span class="sd"> /remove - alias to disconnect</span>
<span class="sd"> /delete - alias to disconnect</span>
<span class="sd"> Example:</span>
<span class="sd"> grapevine2chan mygrapevine = gossip</span>
<span class="sd"> This creates a link between an in-game Evennia channel and an external</span>
<span class="sd"> Grapevine channel. The game must be registered with the Grapevine network</span>
<span class="sd"> (register at https://grapevine.haus) and the GRAPEVINE_* auth information</span>
<span class="sd"> must be added to game settings.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;grapevine2chan&quot;</span>
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;disconnect&quot;</span><span class="p">,</span> <span class="s2">&quot;remove&quot;</span><span class="p">,</span> <span class="s2">&quot;delete&quot;</span><span class="p">,</span> <span class="s2">&quot;list&quot;</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:serversetting(GRAPEVINE_ENABLED) and pperm(Developer)&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;Comms&quot;</span>
<div class="viewcode-block" id="CmdGrapevine2Chan.func"><a class="viewcode-back" href="../../../../api/evennia.commands.default.comms.html#evennia.commands.default.comms.CmdGrapevine2Chan.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;Setup the Grapevine channel mapping&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">settings</span><span class="o">.</span><span class="n">GRAPEVINE_ENABLED</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;Set GRAPEVINE_ENABLED=True in settings to enable.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;list&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="c1"># show all connections</span>
<span class="n">gwbots</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">bot</span>
<span class="k">for</span> <span class="n">bot</span> <span class="ow">in</span> <span class="n">AccountDB</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_is_bot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">username__startswith</span><span class="o">=</span><span class="s2">&quot;grapevinebot-&quot;</span>
<span class="p">)</span>
<span class="p">]</span>
<span class="k">if</span> <span class="n">gwbots</span><span class="p">:</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">styled_table</span><span class="p">(</span>
<span class="s2">&quot;|wdbid|n&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wev-channel&quot;</span><span class="p">,</span>
<span class="s2">&quot;|wgw-channel|n&quot;</span><span class="p">,</span>
<span class="n">border</span><span class="o">=</span><span class="s2">&quot;cells&quot;</span><span class="p">,</span>
<span class="n">maxwidth</span><span class="o">=</span><span class="n">_DEFAULT_WIDTH</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">for</span> <span class="n">gwbot</span> <span class="ow">in</span> <span class="n">gwbots</span><span class="p">:</span>
<span class="n">table</span><span class="o">.</span><span class="n">add_row</span><span class="p">(</span><span class="n">gwbot</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">gwbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">ev_channel</span><span class="p">,</span> <span class="n">gwbot</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">grapevine_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">table</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;No grapevine bots found.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="s2">&quot;disconnect&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">or</span> <span class="s2">&quot;remove&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">or</span> <span class="s2">&quot;delete&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
<span class="n">botname</span> <span class="o">=</span> <span class="s2">&quot;grapevinebot-</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">lhs</span>
<span class="n">matches</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">filter</span><span class="p">(</span><span class="n">db_is_bot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">db_key</span><span class="o">=</span><span class="n">botname</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">matches</span><span class="p">:</span>
<span class="c1"># try dbref match</span>
<span class="n">matches</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">filter</span><span class="p">(</span><span class="n">db_is_bot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="nb">id</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">lstrip</span><span class="p">(</span><span class="s2">&quot;#&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="n">matches</span><span class="p">:</span>
<span class="n">matches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Grapevine connection destroyed.&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Grapevine connection/bot could not be removed, does it exist?&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;Usage: grapevine2chan[/switches] &lt;evennia_channel&gt; = &lt;grapevine_channel&gt;&quot;</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="p">)</span>
<span class="k">return</span>
<span class="n">channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span>
<span class="n">grapevine_channel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span>
<span class="n">botname</span> <span class="o">=</span> <span class="s2">&quot;grapewinebot-</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="p">,</span> <span class="n">grapevine_channel</span><span class="p">)</span>
<span class="n">bot</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">filter</span><span class="p">(</span><span class="n">username__iexact</span><span class="o">=</span><span class="n">botname</span><span class="p">)</span>
<span class="k">if</span> <span class="n">bot</span><span class="p">:</span>
<span class="c1"># re-use existing bot</span>
<span class="n">bot</span> <span class="o">=</span> <span class="n">bot</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">bot</span><span class="o">.</span><span class="n">is_bot</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;Account &#39;</span><span class="si">%s</span><span class="s2">&#39; already exists and is not a bot.&quot;</span> <span class="o">%</span> <span class="n">botname</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Reusing bot &#39;</span><span class="si">%s</span><span class="s2">&#39; (</span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">botname</span><span class="p">,</span> <span class="n">bot</span><span class="o">.</span><span class="n">dbref</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># create a new bot</span>
<span class="n">bot</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_account</span><span class="p">(</span><span class="n">botname</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">typeclass</span><span class="o">=</span><span class="n">bots</span><span class="o">.</span><span class="n">GrapevineBot</span><span class="p">)</span>
<span class="n">bot</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="n">ev_channel</span><span class="o">=</span><span class="n">channel</span><span class="p">,</span> <span class="n">grapevine_channel</span><span class="o">=</span><span class="n">grapevine_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="sa">f</span><span class="s2">&quot;Grapevine connection created </span><span class="si">{</span><span class="n">channel</span><span class="si">}</span><span class="s2"> &lt;-&gt; </span><span class="si">{</span><span class="n">grapevine_channel</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span></div></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="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="comms.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.95/index.html">0.95 (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.commands.default.comms</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>