evennia/docs/0.x/api/evennia.utils.batchprocessors.html
2023-12-20 19:10:09 +01:00

403 lines
No EOL
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>evennia.utils.batchprocessors &#8212; Evennia 0.9.5 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 0.9.5</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.utils.batchprocessors</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="module-evennia.utils.batchprocessors">
<span id="evennia-utils-batchprocessors"></span><h1>evennia.utils.batchprocessors<a class="headerlink" href="#module-evennia.utils.batchprocessors" title="Permalink to this headline"></a></h1>
<p>This module contains the core methods for the Batch-command- and
Batch-code-processors respectively. In short, these are two different
ways to build a game world using a normal text-editor without having
to do so on the fly in-game. They also serve as an automatic backup
so you can quickly recreate a world also after a server reset. The
functions in this module is meant to form the backbone of a system
called and accessed through game commands.</p>
<p>The Batch-command processor is the simplest. It simply runs a list of
in-game commands in sequence by reading them from a text file. The
advantage of this is that the builder only need to remember the normal
in-game commands. They are also executing with full permission checks
etc, making it relatively safe for builders to use. The drawback is
that in-game there is really a builder-character walking around
building things, and it can be important to create rooms and objects
in the right order, so the character can move between them. Also
objects that affects players (such as mobs, dark rooms etc) will
affect the building character too, requiring extra care to turn
off/on.</p>
<p>The Batch-code processor is a more advanced system that accepts full
Python code, executing in chunks. The advantage of this is much more
power; practically anything imaginable can be coded and handled using
the batch-code processor. There is no in-game character that moves and
that can be affected by what is being built - the database is
populated on the fly. The drawback is safety and entry threshold - the
code is executed as would any server code, without mud-specific
permission-checks, and you have full access to modifying objects
etc. You also need to know Python and Evennias API. Hence its
recommended that the batch-code processor is limited only to
superusers or highly trusted staff.</p>
<section id="batch-command-processor-file-syntax">
<h2>Batch-Command processor file syntax<a class="headerlink" href="#batch-command-processor-file-syntax" title="Permalink to this headline"></a></h2>
<p>The batch-command processor accepts batchcommand files e.g
<strong>batch.ev</strong>, containing a sequence of valid Evennia commands in a
simple format. The engine runs each command in sequence, as if they
had been run at the game prompt.</p>
<p>Each Evennia command must be delimited by a line comment to mark its
end. This way entire game worlds can be created and planned offline; it is
especially useful in order to create long room descriptions where a
real offline text editor is often much better than any online text
editor or prompt.</p>
<p>There is only one batchcommand-specific entry to use in a batch-command
files (all others are just like in-game commands):</p>
<ul class="simple">
<li><p><strong>#INSERT path.batchcmdfile</strong> - this as the first entry on a line will
import and run a batch.ev file in this position, as if it was
written in this file.</p></li>
</ul>
<p>Example of batch.ev file:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># batch file</span>
<span class="c1"># all lines starting with # are comments; they also indicate</span>
<span class="c1"># that a command definition is over.</span>
<span class="nd">@create</span> <span class="n">box</span>
<span class="c1"># this comment ends the @create command.</span>
<span class="nd">@set</span> <span class="n">box</span><span class="o">/</span><span class="n">desc</span> <span class="o">=</span> <span class="n">A</span> <span class="n">large</span> <span class="n">box</span><span class="o">.</span>
<span class="n">Inside</span> <span class="n">are</span> <span class="n">some</span> <span class="n">scattered</span> <span class="n">piles</span> <span class="n">of</span> <span class="n">clothing</span><span class="o">.</span>
<span class="n">It</span> <span class="n">seems</span> <span class="n">the</span> <span class="n">bottom</span> <span class="n">of</span> <span class="n">the</span> <span class="n">box</span> <span class="ow">is</span> <span class="n">a</span> <span class="n">bit</span> <span class="n">loose</span><span class="o">.</span>
<span class="c1"># Again, this comment indicates the @set command is over. Note how</span>
<span class="c1"># the description could be freely added. Excess whitespace on a line</span>
<span class="c1"># is ignored. An empty line in the command definition is parsed as a</span>
<span class="c1"># (so two empty lines becomes a new paragraph).</span>
<span class="nd">@teleport</span> <span class="c1">#221</span>
<span class="c1"># (Assuming #221 is a warehouse or something.)</span>
<span class="c1"># (remember, this comment ends the @teleport command! Don&#39;f forget it)</span>
<span class="c1"># Example of importing another file at this point.</span>
<span class="c1">#INSERT examples.batch</span>
<span class="nd">@drop</span> <span class="n">box</span>
<span class="c1"># Done, the box is in the warehouse! (this last comment is not necessary to</span>
<span class="c1"># close the @drop command since it&#39;s the end of the file)</span>
</pre></div>
</div>
<p>An example batch file is <strong>contrib/examples/batch_example.ev</strong>.</p>
</section>
<section id="batch-code-processor-file-syntax">
<h2>Batch-Code processor file syntax<a class="headerlink" href="#batch-code-processor-file-syntax" title="Permalink to this headline"></a></h2>
<p>The Batch-code processor accepts full python modules (e.g. <strong>batch.py</strong>)
that looks identical to normal Python files. The difference from
importing and running any Python module is that the batch-code module
is loaded as a file and executed directly, so changes to the file will
apply immediately without a server &#64;reload.</p>
<p>Optionally, one can add some special commented tokens to split the
execution of the code for the benefit of the batchprocessors
interactive- and debug-modes. This allows to conveniently step through
the code and re-run sections of it easily during development.</p>
<p>Code blocks are marked by commented tokens alone on a line:</p>
<ul class="simple">
<li><p><strong>#HEADER</strong> - This denotes code that should be pasted at the top of all
other code. Multiple HEADER statements - regardless of where
it exists in the file - is the same as one big block.
Observe that changes to variables made in one block is not
preserved between blocks!</p></li>
<li><p><strong>#CODE</strong> - This designates a code block that will be executed like a
stand-alone piece of code together with any HEADER(s)
defined. It is mainly used as a way to mark stop points for
the interactive mode of the batchprocessor. If no CODE block
is defined in the module, the entire module (including HEADERS)
is assumed to be a CODE block.</p></li>
<li><p><strong>#INSERT path.filename</strong> - This imports another batch_code.py file and
runs it in the given position. The inserted file will retain
its own HEADERs which will not be mixed with the headers of
this file.</p></li>
</ul>
<p>Importing works as normal. The following variables are automatically
made available in the script namespace.</p>
<ul class="simple">
<li><p><strong>caller</strong> - The object executing the batchscript</p></li>
<li><p><strong>DEBUG</strong> - This is a boolean marking if the batchprocessor is running
in debug mode. It can be checked to e.g. delete created objects
when running a CODE block multiple times during testing.
(avoids creating a slew of same-named db objects)</p></li>
</ul>
<p>Example batch.py file:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#HEADER</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">create</span>
<span class="kn">from</span> <span class="nn">types</span> <span class="kn">import</span> <span class="n">basetypes</span>
<span class="n">GOLD</span> <span class="o">=</span> <span class="mi">10</span>
<span class="c1">#CODE</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">basetypes</span><span class="o">.</span><span class="n">Object</span><span class="p">)</span>
<span class="n">obj2</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">basetypes</span><span class="o">.</span><span class="n">Object</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">location</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">location</span>
<span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">gold</span> <span class="o">=</span> <span class="n">GOLD</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;The object was created!&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">obj</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="n">obj2</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="c1">#INSERT another_batch_file</span>
<span class="c1">#CODE</span>
<span class="n">script</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_script</span><span class="p">()</span>
</pre></div>
</div>
<hr class="docutils" />
<dl class="py function">
<dt id="evennia.utils.batchprocessors.read_batchfile">
<code class="sig-prename descclassname">evennia.utils.batchprocessors.</code><code class="sig-name descname">read_batchfile</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">pythonpath</span></em>, <em class="sig-param"><span class="n">file_ending</span><span class="o">=</span><span class="default_value">'.py'</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/utils/batchprocessors.html#read_batchfile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.utils.batchprocessors.read_batchfile" title="Permalink to this definition"></a></dt>
<dd><p>This reads the contents of a batch-file. Filename is considered
to be a python path to a batch file relative the directory
specified in <strong>settings.py</strong>.</p>
<p>file_ending specify which batchfile ending should be assumed (.ev
or .py). The ending should not be included in the python path.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>pythonpath</strong> (<em>str</em>) A dot-python path to a file.</p></li>
<li><p><strong>file_ending</strong> (<em>str</em>) The file ending of this file (.ev or .py)</p></li>
</ul>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p><em>str</em> The text content of the batch file.</p>
</dd>
<dt class="field-odd">Raises</dt>
<dd class="field-odd"><p><strong>IOError</strong> If problems reading file.</p>
</dd>
</dl>
</dd></dl>
<dl class="py class">
<dt id="evennia.utils.batchprocessors.BatchCommandProcessor">
<em class="property">class </em><code class="sig-prename descclassname">evennia.utils.batchprocessors.</code><code class="sig-name descname">BatchCommandProcessor</code><a class="reference internal" href="../_modules/evennia/utils/batchprocessors.html#BatchCommandProcessor"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.utils.batchprocessors.BatchCommandProcessor" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>This class implements a batch-command processor.</p>
<dl class="py method">
<dt id="evennia.utils.batchprocessors.BatchCommandProcessor.parse_file">
<code class="sig-name descname">parse_file</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">pythonpath</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/utils/batchprocessors.html#BatchCommandProcessor.parse_file"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.utils.batchprocessors.BatchCommandProcessor.parse_file" title="Permalink to this definition"></a></dt>
<dd><p>This parses the lines of a batchfile according to the following
rules:</p>
<ol class="arabic simple">
<li><p><strong>#</strong> at the beginning of a line marks the end of the command before
it. It is also a comment and any number of # can exist on
subsequent lines (but not inside comments).</p></li>
<li><p><strong>#INSERT</strong> at the beginning of a line imports another
batch-cmd file file and pastes it into the batch file as if
it was written there.</p></li>
<li><p>Commands are placed alone at the beginning of a line and their
arguments are considered to be everything following (on any
number of lines) until the next comment line beginning with #.</p></li>
<li><p>Newlines are ignored in command definitions</p></li>
<li><p>A completely empty line in a command line definition is condered
a newline (so two empty lines is a paragraph).</p></li>
<li><p>Excess spaces and indents inside arguments are stripped.</p></li>
</ol>
</dd></dl>
</dd></dl>
<dl class="py function">
<dt id="evennia.utils.batchprocessors.tb_filename">
<code class="sig-prename descclassname">evennia.utils.batchprocessors.</code><code class="sig-name descname">tb_filename</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">tb</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/utils/batchprocessors.html#tb_filename"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.utils.batchprocessors.tb_filename" title="Permalink to this definition"></a></dt>
<dd><p>Helper to get filename from traceback</p>
</dd></dl>
<dl class="py function">
<dt id="evennia.utils.batchprocessors.tb_iter">
<code class="sig-prename descclassname">evennia.utils.batchprocessors.</code><code class="sig-name descname">tb_iter</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">tb</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/utils/batchprocessors.html#tb_iter"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.utils.batchprocessors.tb_iter" title="Permalink to this definition"></a></dt>
<dd><p>Traceback iterator.</p>
</dd></dl>
<dl class="py class">
<dt id="evennia.utils.batchprocessors.BatchCodeProcessor">
<em class="property">class </em><code class="sig-prename descclassname">evennia.utils.batchprocessors.</code><code class="sig-name descname">BatchCodeProcessor</code><a class="reference internal" href="../_modules/evennia/utils/batchprocessors.html#BatchCodeProcessor"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.utils.batchprocessors.BatchCodeProcessor" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>This implements a batch-code processor</p>
<dl class="py method">
<dt id="evennia.utils.batchprocessors.BatchCodeProcessor.parse_file">
<code class="sig-name descname">parse_file</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">pythonpath</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/utils/batchprocessors.html#BatchCodeProcessor.parse_file"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.utils.batchprocessors.BatchCodeProcessor.parse_file" title="Permalink to this definition"></a></dt>
<dd><p>This parses the lines of a batchfile according to the following
rules:</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>pythonpath</strong> (<em>str</em>) The dot-python path to the file.</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p><p><em>codeblocks (list)</em> </p>
<dl class="simple">
<dt>A list of all #CODE blocks, each with</dt><dd><p>prepended #HEADER data. If no #CODE blocks were found,
this will be a list of one element.</p>
</dd>
</dl>
</p>
</dd>
</dl>
<p class="rubric">Notes</p>
<ol class="arabic simple">
<li><dl class="simple">
<dt>Code before a #CODE/HEADER block are considered part of</dt><dd><p>the first code/header block or is the ONLY block if no
#CODE/HEADER blocks are defined.</p>
</dd>
</dl>
</li>
<li><p>Lines starting with #HEADER starts a header block (ends other blocks)</p></li>
<li><p>Lines starting with #CODE begins a code block (ends other blocks)</p></li>
<li><p>Lines starting with #INSERT are on form #INSERT filename. Code from
this file are processed with their headers <em>separately</em> before
being inserted at the point of the #INSERT.</p></li>
<li><p>Code after the last block is considered part of the last header/code
block</p></li>
</ol>
</dd></dl>
<dl class="py method">
<dt id="evennia.utils.batchprocessors.BatchCodeProcessor.code_exec">
<code class="sig-name descname">code_exec</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">code</span></em>, <em class="sig-param"><span class="n">extra_environ</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">debug</span><span class="o">=</span><span class="default_value">False</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/utils/batchprocessors.html#BatchCodeProcessor.code_exec"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.utils.batchprocessors.BatchCodeProcessor.code_exec" title="Permalink to this definition"></a></dt>
<dd><p>Execute a single code block, including imports and appending
global vars.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>code</strong> (<em>str</em>) Code to run.</p></li>
<li><p><strong>extra_environ</strong> (<em>dict</em>) Environment variables to run with code.</p></li>
<li><p><strong>debug</strong> (<em>bool</em><em>, </em><em>optional</em>) Set the DEBUG variable in the execution
namespace.</p></li>
</ul>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p><em>err (str or None)</em> An error code or None (ok).</p>
</dd>
</dl>
</dd></dl>
</dd></dl>
</section>
</section>
<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>
<p><h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">evennia.utils.batchprocessors</a><ul>
<li><a class="reference internal" href="#batch-command-processor-file-syntax">Batch-Command processor file syntax</a></li>
<li><a class="reference internal" href="#batch-code-processor-file-syntax">Batch-Code processor file syntax</a></li>
</ul>
</li>
</ul>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/api/evennia.utils.batchprocessors.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
<a href="https://discord.gg/NecFePw">Discord</a> -
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
</li>
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="../../1.0-dev/api/evennia.utils.batchprocessors.html">1.0-dev (develop branch)</a></li>
<li><a href="evennia.utils.batchprocessors.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 0.9.5</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.utils.batchprocessors</a></li>
</ul>
</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>