diff --git a/docs/Makefile b/docs/Makefile index 37f7b3a781..de813e0401 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -12,7 +12,7 @@ SPHINXMULTIVERSION ?= sphinx-multiversion SPHINXAPIDOC ?= sphinx-apidoc SPHINXAPIDOCOPTS = --tocfile evennia-api --module-first --force -d 6 --separate --templatedir=$(SOURCEDIR)/_templates/ SPHINXAPIDOCENV = members,undoc-members,show-inheritance -SPHINXAPIDOCEXCLUDE = ../*/migrations/* ../evennia/game_template/* ../*/*/tests/* +SPHINXAPIDOCEXCLUDE = ../*/migrations/* ../evennia/game_template/* ../evennia/*/tests/* ../evennia/*/tests.py EVDIR ?= $(realpath ../evennia) EVGAMEDIR ?= $(realpath ../../gamedir) diff --git a/docs/source/api/evennia.accounts.rst b/docs/source/api/evennia.accounts.rst index 63a7edbc79..08b689d3c1 100644 --- a/docs/source/api/evennia.accounts.rst +++ b/docs/source/api/evennia.accounts.rst @@ -17,4 +17,3 @@ Modules evennia.accounts.bots evennia.accounts.manager evennia.accounts.models - evennia.accounts.tests diff --git a/docs/source/api/evennia.accounts.tests.rst b/docs/source/api/evennia.accounts.tests.rst deleted file mode 100644 index 1aa7640fb8..0000000000 --- a/docs/source/api/evennia.accounts.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -evennia.accounts.tests -============================= - -.. automodule:: evennia.accounts.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/evennia.commands.rst b/docs/source/api/evennia.commands.rst index 43419d4ff4..56cd32e4b0 100644 --- a/docs/source/api/evennia.commands.rst +++ b/docs/source/api/evennia.commands.rst @@ -17,7 +17,6 @@ Modules evennia.commands.cmdset evennia.commands.cmdsethandler evennia.commands.command - evennia.commands.tests Packages/folders ---------------- diff --git a/docs/source/api/evennia.commands.tests.rst b/docs/source/api/evennia.commands.tests.rst deleted file mode 100644 index af5f164c8f..0000000000 --- a/docs/source/api/evennia.commands.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -evennia.commands.tests -============================= - -.. automodule:: evennia.commands.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/evennia.comms.rst b/docs/source/api/evennia.comms.rst index 777560096a..5c3761d59f 100644 --- a/docs/source/api/evennia.comms.rst +++ b/docs/source/api/evennia.comms.rst @@ -17,4 +17,3 @@ Modules evennia.comms.comms evennia.comms.managers evennia.comms.models - evennia.comms.tests diff --git a/docs/source/api/evennia.comms.tests.rst b/docs/source/api/evennia.comms.tests.rst deleted file mode 100644 index dcc9d1d061..0000000000 --- a/docs/source/api/evennia.comms.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -evennia.comms.tests -========================== - -.. automodule:: evennia.comms.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/evennia.contrib.rst b/docs/source/api/evennia.contrib.rst index 3406e880d0..3158a80541 100644 --- a/docs/source/api/evennia.contrib.rst +++ b/docs/source/api/evennia.contrib.rst @@ -36,7 +36,6 @@ Modules evennia.contrib.slow_exit evennia.contrib.talking_npc evennia.contrib.test_traits - evennia.contrib.tests evennia.contrib.traits evennia.contrib.tree_select evennia.contrib.unixcommand diff --git a/docs/source/api/evennia.contrib.tests.rst b/docs/source/api/evennia.contrib.tests.rst deleted file mode 100644 index 5fb97fd250..0000000000 --- a/docs/source/api/evennia.contrib.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -evennia.contrib.tests -============================ - -.. automodule:: evennia.contrib.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/evennia.locks.rst b/docs/source/api/evennia.locks.rst index 9b16771f9a..a3836b60ef 100644 --- a/docs/source/api/evennia.locks.rst +++ b/docs/source/api/evennia.locks.rst @@ -14,4 +14,3 @@ Modules evennia.locks.lockfuncs evennia.locks.lockhandler - evennia.locks.tests diff --git a/docs/source/api/evennia.locks.tests.rst b/docs/source/api/evennia.locks.tests.rst deleted file mode 100644 index c4d4af7591..0000000000 --- a/docs/source/api/evennia.locks.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -evennia.locks.tests -========================== - -.. automodule:: evennia.locks.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/evennia.objects.rst b/docs/source/api/evennia.objects.rst index 971e1e5490..5d79d16c61 100644 --- a/docs/source/api/evennia.objects.rst +++ b/docs/source/api/evennia.objects.rst @@ -16,4 +16,3 @@ Modules evennia.objects.manager evennia.objects.models evennia.objects.objects - evennia.objects.tests diff --git a/docs/source/api/evennia.objects.tests.rst b/docs/source/api/evennia.objects.tests.rst deleted file mode 100644 index d487265cd2..0000000000 --- a/docs/source/api/evennia.objects.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -evennia.objects.tests -============================ - -.. automodule:: evennia.objects.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/evennia.prototypes.rst b/docs/source/api/evennia.prototypes.rst index 25a09dcc1f..0c26fff595 100644 --- a/docs/source/api/evennia.prototypes.rst +++ b/docs/source/api/evennia.prototypes.rst @@ -16,4 +16,3 @@ Modules evennia.prototypes.protfuncs evennia.prototypes.prototypes evennia.prototypes.spawner - evennia.prototypes.tests diff --git a/docs/source/api/evennia.prototypes.tests.rst b/docs/source/api/evennia.prototypes.tests.rst deleted file mode 100644 index 93ab94c9e0..0000000000 --- a/docs/source/api/evennia.prototypes.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -evennia.prototypes.tests -=============================== - -.. automodule:: evennia.prototypes.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/evennia.scripts.rst b/docs/source/api/evennia.scripts.rst index 2798c346e6..14c154ba09 100644 --- a/docs/source/api/evennia.scripts.rst +++ b/docs/source/api/evennia.scripts.rst @@ -19,5 +19,4 @@ Modules evennia.scripts.scripthandler evennia.scripts.scripts evennia.scripts.taskhandler - evennia.scripts.tests evennia.scripts.tickerhandler diff --git a/docs/source/api/evennia.scripts.tests.rst b/docs/source/api/evennia.scripts.tests.rst deleted file mode 100644 index 2307ec7de7..0000000000 --- a/docs/source/api/evennia.scripts.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -evennia.scripts.tests -============================ - -.. automodule:: evennia.scripts.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/evennia.typeclasses.rst b/docs/source/api/evennia.typeclasses.rst index 970dd374c2..1f3c8e7ce2 100644 --- a/docs/source/api/evennia.typeclasses.rst +++ b/docs/source/api/evennia.typeclasses.rst @@ -17,4 +17,3 @@ Modules evennia.typeclasses.managers evennia.typeclasses.models evennia.typeclasses.tags - evennia.typeclasses.tests diff --git a/docs/source/api/evennia.typeclasses.tests.rst b/docs/source/api/evennia.typeclasses.tests.rst deleted file mode 100644 index 40dc3e9bbf..0000000000 --- a/docs/source/api/evennia.typeclasses.tests.rst +++ /dev/null @@ -1,7 +0,0 @@ -evennia.typeclasses.tests -================================ - -.. automodule:: evennia.typeclasses.tests - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/conf.py b/docs/source/conf.py index 31944b430d..8a3e97328d 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -255,11 +255,28 @@ def autodoc_post_process_docstring(app, what, name, obj, options, lines): return "::\n\n {}".format( "\n ".join(lne for lne in code.split("\n"))) + underline_map = { + 1: "-", + 2: "=", + 3: '^', + 4: '"', + } + + def _sub_header(match): + # add underline to convert a markdown #header to ReST + groupdict = match.groupdict() + hashes, title = groupdict["hashes"], groupdict["title"] + title = title.strip() + lvl = min(max(1, len(hashes)), 4) + return f"{title}\n" + (underline_map[lvl] * len(title)) + doc = "\n".join(lines) doc = re.sub(r"```python\s*\n+(.*?)```", _sub_codeblock, doc, flags=re.MULTILINE + re.DOTALL) doc = re.sub(r"```", "", doc, flags=re.MULTILINE) doc = re.sub(r"`{1}", "**", doc, flags=re.MULTILINE) + doc = re.sub(r"^(?P#{1,2})\s*?(?P.*?)$", _sub_header, doc, flags=re.MULTILINE) + newlines = doc.split("\n") # we must modify lines in-place lines[:] = newlines[:] diff --git a/evennia/server/sessionhandler.py b/evennia/server/sessionhandler.py index 141aaefd66..fe1f844896 100644 --- a/evennia/server/sessionhandler.py +++ b/evennia/server/sessionhandler.py @@ -4,12 +4,12 @@ sessions of users connecting to the server. There are two similar but separate stores of sessions: - - ServerSessionHandler - this stores generic game sessions - for the game. These sessions has no knowledge about - how they are connected to the world. - - PortalSessionHandler - this stores sessions created by - twisted protocols. These are dumb connectors that - handle network communication but holds no game info. +- ServerSessionHandler - this stores generic game sessions + for the game. These sessions has no knowledge about + how they are connected to the world. +- PortalSessionHandler - this stores sessions created by + twisted protocols. These are dumb connectors that + handle network communication but holds no game info. """ import time @@ -156,21 +156,20 @@ class SessionHandler(dict): Args: session (Session): The relevant session instance. - kwargs (dict) Each keyword represents a - send-instruction, with the keyword itself being the name + kwargs (dict) Each keyword represents a send-instruction, with the keyword itself being the name of the instruction (like "text"). Suitable values for each keyword are: - - arg -> [[arg], {}] - - [args] -> [[args], {}] - - {kwargs} -> [[], {kwargs}] - - [args, {kwargs}] -> [[arg], {kwargs}] - - [[args], {kwargs}] -> [[args], {kwargs}] + - arg -> [[arg], {}] + - [args] -> [[args], {}] + - {kwargs} -> [[], {kwargs}] + - [args, {kwargs}] -> [[arg], {kwargs}] + - [[args], {kwargs}] -> [[args], {kwargs}] Returns: kwargs (dict): A cleaned dictionary of cmdname:[[args],{kwargs}] pairs, - where the keys, args and kwargs have all been converted to - send-safe entities (strings or numbers), and inlinefuncs have been - applied. + where the keys, args and kwargs have all been converted to + send-safe entities (strings or numbers), and inlinefuncs have been + applied. """ options = kwargs.pop("options", None) or {} @@ -809,9 +808,9 @@ class ServerSessionHandler(SessionHandler): def call_inputfuncs(self, session, **kwargs): """ - Split incoming data into its inputfunc counterparts. - This should be called by the serversession.data_in - as sessionhandler.call_inputfunc(self, **kwargs). + Split incoming data into its inputfunc counterparts. This should be + called by the `serversession.data_in` as + `sessionhandler.call_inputfunc(self, **kwargs)`. We also intercept OOB communication here. @@ -819,8 +818,8 @@ class ServerSessionHandler(SessionHandler): sessions (Session): Session. Keyword args: - kwargs (any): Incoming data from protocol on - the form `{"commandname": ((args), {kwargs}),...}` + any (tuple): Incoming data from protocol, each + on the form `commandname=((args), {kwargs})`. """ diff --git a/evennia/server/signals.py b/evennia/server/signals.py index fd96becc6f..38e8c40d43 100644 --- a/evennia/server/signals.py +++ b/evennia/server/signals.py @@ -1,21 +1,23 @@ """ -This module brings Django Signals into Evennia. These are events that -can be subscribed to by importing a given Signal and using the -following code. +This module brings Django Signals into Evennia. These are events that can be +subscribed to by importing a given Signal and using the following code. +```python THIS_SIGNAL.connect(callback, sender_object) +``` -When other code calls THIS_SIGNAL.send(sender, **kwargs), the callback -will be triggered. +When other code calls `THIS_SIGNAL.send(sender, **kwargs)`, the callback will +be triggered. -Callbacks must be in the following format: +Callbacks must be on the following format: +```python def my_callback(sender, **kwargs): - ... + # ... +``` -This is used on top of hooks to make certain features easier to -add to contribs without necessitating a full takeover of hooks -that may be in high demand. +This is used on top of hooks to make certain features easier to add to contribs +without necessitating a full takeover of hooks that may be in high demand. """ from django.dispatch import Signal diff --git a/evennia/typeclasses/attributes.py b/evennia/typeclasses/attributes.py index 687315e181..05957de1bf 100644 --- a/evennia/typeclasses/attributes.py +++ b/evennia/typeclasses/attributes.py @@ -578,36 +578,38 @@ class IAttributeBackend: def do_batch_finish(self, attr_objs): """ - Called only by batch_add. Used for handling database operations and/or caching complications. + Called only by batch_add. Used for handling database operations and/or + caching complications. Args: attr_objs (list of IAttribute): The Attributes created/updated thus far. + """ raise NotImplementedError() def batch_add(self, *args, **kwargs): """ - Batch-version of `add()`. This is more efficient than - repeat-calling add when having many Attributes to add. + Batch-version of `.add()`. This is more efficient than repeat-calling + `.add` when having many Attributes to add. Args: - indata (list): List of tuples of varying length representing the + *args (tuple): Tuples of varying length representing the Attribute to add to this object. Supported tuples are - - `(key, value)` - - `(key, value, category)` - - `(key, value, category, lockstring)` - - `(key, value, category, lockstring, default_access)` + + - (key, value) + - (key, value, category) + - (key, value, category, lockstring) + - (key, value, category, lockstring, default_access) Raises: RuntimeError: If trying to pass a non-iterable as argument. Notes: - The indata tuple order matters, so if you want a lockstring - but no category, set the category to `None`. This method - does not have the ability to check editing permissions like - normal .add does, and is mainly used internally. It does not - use the normal self.add but apply the Attributes directly - to the database. + The indata tuple order matters, so if you want a lockstring but no + category, set the category to `None`. This method does not have the + ability to check editing permissions and is mainly used internally. + It does not use the normal `self.add` but applies the Attributes + directly to the database. """ new_attrobjs = [] @@ -1092,12 +1094,13 @@ class AttributeHandler: repeat-calling add when having many Attributes to add. Args: - indata (list): List of tuples of varying length representing the + *args (tuple): Tuples of varying length representing the Attribute to add to this object. Supported tuples are - - `(key, value)` - - `(key, value, category)` - - `(key, value, category, lockstring)` - - `(key, value, category, lockstring, default_access)` + + - (key, value) + - (key, value, category) + - (key, value, category, lockstring) + - (key, value, category, lockstring, default_access) Keyword args: strattr (bool): If `True`, value must be a string. This @@ -1306,12 +1309,12 @@ def initialize_nick_templates(in_template, out_template): Returns: regex (regex): Regex to match against strings - template (str): Template with markers {arg1}, {arg2}, etc for - replacement using the standard .format method. + template (str): Template with markers ``{arg1}, {arg2}``, etc for + replacement using the standard .format method. Raises: NickTemplateInvalid: If the in/out template does not have a matching - number of $args. + number of `$args`. """ diff --git a/evennia/typeclasses/managers.py b/evennia/typeclasses/managers.py index ae432512cc..b82965e9bc 100644 --- a/evennia/typeclasses/managers.py +++ b/evennia/typeclasses/managers.py @@ -34,14 +34,12 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): self, key=None, category=None, value=None, strvalue=None, obj=None, attrtype=None, **kwargs ): """ - Return Attribute objects by key, by category, by value, by - strvalue, by object (it is stored on) or with a combination of - those criteria. + Return Attribute objects by key, by category, by value, by strvalue, by + object (it is stored on) or with a combination of those criteria. - Attrs: + Args: key (str, optional): The attribute's key to search for - category (str, optional): The category of the attribute(s) - to search for. + category (str, optional): The category of the attribute(s) to search for. value (str, optional): The attribute value to search for. Note that this is not a very efficient operation since it will query for a pickled entity. Mutually exclusive to @@ -55,10 +53,10 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): attrype (str, optional): An attribute-type to search for. By default this is either `None` (normal Attributes) or `"nick"`. - kwargs (any): Currently unused. Reserved for future use. + **kwargs (any): Currently unused. Reserved for future use. Returns: - attributes (list): The matching Attributes. + list: The matching Attributes. """ dbmodel = self.model.__dbclass__.__name__.lower() @@ -84,7 +82,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): """ Get a nick, in parallel to `get_attribute`. - Attrs: + Args: key (str, optional): The nicks's key to search for category (str, optional): The category of the nicks(s) to search for. value (str, optional): The attribute value to search for. Note that this @@ -170,13 +168,13 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): Return Tag objects by key, by category, by object (it is stored on) or with a combination of those criteria. - Attrs: + Args: key (str, optional): The Tag's key to search for category (str, optional): The Tag of the attribute(s) to search for. obj (Object, optional): On which object the Tag to search for is. - tagtype (str, optional): One of None (normal tags), + tagtype (str, optional): One of `None` (normal tags), "alias" or "permission" global_search (bool, optional): Include all possible tags, not just tags on this object diff --git a/evennia/typeclasses/models.py b/evennia/typeclasses/models.py index 9e87249429..4f8dc5116e 100644 --- a/evennia/typeclasses/models.py +++ b/evennia/typeclasses/models.py @@ -578,7 +578,7 @@ class TypedObject(SharedMemoryModel): superuser lock bypass (be careful with this one). Keyword args: - kwargs (any): Ignored, but is there to make the api + kwar (any): Ignored, but is there to make the api consistent with the object-typeclass method access, which use it to feed to its hook methods. @@ -667,14 +667,19 @@ class TypedObject(SharedMemoryModel): def __db_get(self): """ Attribute handler wrapper. Allows for the syntax + + ```python obj.db.attrname = value - and + # and value = obj.db.attrname - and + # and del obj.db.attrname - and - all_attr = obj.db.all() (unless there is an attribute - named 'all', in which case that will be returned instead). + # and + all_attr = obj.db.all() + # (unless there is an attribute + # named 'all', in which case that will be returned instead). + ``` + """ try: return self._db_holder @@ -844,26 +849,32 @@ class TypedObject(SharedMemoryModel): Returns the URI path for a View that allows users to view details for this object. - ex. Oscar (Character) = '/characters/oscar/1/' - - For this to work, the developer must have defined a named view somewhere - in urls.py that follows the format 'modelname-action', so in this case - a named view of 'character-detail' would be referenced by this method. - - ex. - url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$', - CharDetailView.as_view(), name='character-detail') - - If no View has been created and defined in urls.py, returns an - HTML anchor. - - This method is naive and simply returns a path. Securing access to - the actual view and limiting who can view this object is the developer's - responsibility. - Returns: path (str): URI path to object detail page, if defined. + Examples: + + ```python + Oscar (Character) = '/characters/oscar/1/' + ``` + + For this to work, the developer must have defined a named view somewhere + in urls.py that follows the format 'modelname-action', so in this case + a named view of 'character-detail' would be referenced by this method. + + + ```python + url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$', + CharDetailView.as_view(), name='character-detail') + ``` + + If no View has been created and defined in urls.py, returns an + HTML anchor. + + This method is naive and simply returns a path. Securing access to + the actual view and limiting who can view this object is the + developer's responsibility. + """ try: return reverse( @@ -878,25 +889,31 @@ class TypedObject(SharedMemoryModel): Returns the URI path for a View that allows users to puppet a specific object. - ex. Oscar (Character) = '/characters/oscar/1/puppet/' - - For this to work, the developer must have defined a named view somewhere - in urls.py that follows the format 'modelname-action', so in this case - a named view of 'character-puppet' would be referenced by this method. - - ex. - url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/puppet/$', - CharPuppetView.as_view(), name='character-puppet') - - If no View has been created and defined in urls.py, returns an - HTML anchor. - - This method is naive and simply returns a path. Securing access to - the actual view and limiting who can view this object is the developer's - responsibility. - Returns: - path (str): URI path to object puppet page, if defined. + str: URI path to object puppet page, if defined. + + Examples: + + ```python + Oscar (Character) = '/characters/oscar/1/puppet/' + ``` + + For this to work, the developer must have defined a named view somewhere + in urls.py that follows the format 'modelname-action', so in this case + a named view of 'character-puppet' would be referenced by this method. + + ```python + url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/puppet/$', + CharPuppetView.as_view(), name='character-puppet') + ``` + + If no View has been created and defined in urls.py, returns an + HTML anchor. + + This method is naive and simply returns a path. Securing access to + the actual view and limiting who can view this object is the developer's + responsibility. + """ try: @@ -912,25 +929,31 @@ class TypedObject(SharedMemoryModel): Returns the URI path for a View that allows users to update this object. - ex. Oscar (Character) = '/characters/oscar/1/change/' - - For this to work, the developer must have defined a named view somewhere - in urls.py that follows the format 'modelname-action', so in this case - a named view of 'character-update' would be referenced by this method. - - ex. - url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/change/$', - CharUpdateView.as_view(), name='character-update') - - If no View has been created and defined in urls.py, returns an - HTML anchor. - - This method is naive and simply returns a path. Securing access to - the actual view and limiting who can modify objects is the developer's - responsibility. - Returns: - path (str): URI path to object update page, if defined. + str: URI path to object update page, if defined. + + Examples: + + ```python + Oscar (Character) = '/characters/oscar/1/change/' + ``` + + For this to work, the developer must have defined a named view somewhere + in urls.py that follows the format 'modelname-action', so in this case + a named view of 'character-update' would be referenced by this method. + + ```python + url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/change/$', + CharUpdateView.as_view(), name='character-update') + ``` + + If no View has been created and defined in urls.py, returns an + HTML anchor. + + This method is naive and simply returns a path. Securing access to + the actual view and limiting who can modify objects is the developer's + responsibility. + """ try: @@ -945,26 +968,33 @@ class TypedObject(SharedMemoryModel): """ Returns the URI path for a View that allows users to delete this object. - ex. Oscar (Character) = '/characters/oscar/1/delete/' - - For this to work, the developer must have defined a named view somewhere - in urls.py that follows the format 'modelname-action', so in this case - a named view of 'character-detail' would be referenced by this method. - - ex. - url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/delete/$', - CharDeleteView.as_view(), name='character-delete') - - If no View has been created and defined in urls.py, returns an - HTML anchor. - - This method is naive and simply returns a path. Securing access to - the actual view and limiting who can delete this object is the developer's - responsibility. - Returns: path (str): URI path to object deletion page, if defined. + Examples: + + ```python + Oscar (Character) = '/characters/oscar/1/delete/' + ``` + + For this to work, the developer must have defined a named view + somewhere in urls.py that follows the format 'modelname-action', so + in this case a named view of 'character-detail' would be referenced + by this method. + + ```python + url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/delete/$', + CharDeleteView.as_view(), name='character-delete') + ``` + + If no View has been created and defined in urls.py, returns an HTML + anchor. + + This method is naive and simply returns a path. Securing access to + the actual view and limiting who can delete this object is the + developer's responsibility. + + """ try: return reverse( diff --git a/evennia/utils/ansi.py b/evennia/utils/ansi.py index cc4cf3dcd0..5c8eed5820 100644 --- a/evennia/utils/ansi.py +++ b/evennia/utils/ansi.py @@ -5,9 +5,12 @@ Use the codes defined in ANSIPARSER in your text to apply colour to text according to the ANSI standard. Examples: - This is |rRed text|n and this is normal again. -Mostly you should not need to call parse_ansi() explicitly; +```python +"This is |rRed text|n and this is normal again." +``` + +Mostly you should not need to call `parse_ansi()` explicitly; it is run by Evennia just before returning data to/from the user. Depreciated example forms are available by extending the ansi mapping. @@ -982,13 +985,11 @@ class ANSIString(str, metaclass=ANSIMeta): sep (str): The separator to split the string on. reverse (boolean): Whether to split the string on the last occurrence of the separator rather than the first. + Returns: - result (tuple): - prefix (ANSIString): The part of the string before the - separator - sep (ANSIString): The separator itself - postfix (ANSIString): The part of the string after the - separator. + ANSIString: The part of the string before the separator + ANSIString: The separator itself + ANSIString: The part of the string after the separator. """ if hasattr(sep, "_clean_string"): @@ -1288,18 +1289,21 @@ class ANSIString(str, metaclass=ANSIMeta): one. NOTE: This should always be used for joining strings when ANSIStrings - are involved. Otherwise color information will be discarded by - python, due to details in the C implementation of strings. + are involved. Otherwise color information will be discarded by python, + due to details in the C implementation of strings. Args: iterable (list of strings): A list of strings to join together + Returns: - result (ANSIString): A single string with all of the iterable's - contents concatenated, with this string between each. For - example: - ANSIString(', ').join(['up', 'right', 'left', 'down']) - ...Would return: - ANSIString('up, right, left, down') + ANSIString: A single string with all of the iterable's + contents concatenated, with this string between each. + + Examples: + :: + + >>> ANSIString(', ').join(['up', 'right', 'left', 'down']) + ANSIString('up, right, left, down') """ result = ANSIString("") diff --git a/evennia/utils/batchprocessors.py b/evennia/utils/batchprocessors.py index abceb9cd4a..63c87e2389 100644 --- a/evennia/utils/batchprocessors.py +++ b/evennia/utils/batchprocessors.py @@ -1,23 +1,21 @@ """ 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. +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. -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. +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. The Batch-code processor is a more advanced system that accepts full Python code, executing in chunks. The advantage of this is much more @@ -31,7 +29,7 @@ etc. You also need to know Python and Evennia's API. Hence it's recommended that the batch-code processor is limited only to superusers or highly trusted staff. -Batch-command processor file syntax +# Batch-command processor file syntax The batch-command processor accepts 'batchcommand files' e.g `batch.ev`, containing a sequence of valid Evennia commands in a @@ -41,64 +39,64 @@ had been run at the game prompt. Each Evennia command must be delimited by a line comment to mark its end. -``` -#INSERT path.batchcmdfile - 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. -``` +:: + + look + # delimiting comment + create/drop box + # another required comment + +One can also inject another batchcmdfile: + +:: + + #INSERT path.batchcmdfile 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. -Example of batch.ev file: ----------------------------- +## Example of batch.ev file: -``` -# batch file -# all lines starting with # are comments; they also indicate -# that a command definition is over. +:: -@create box + # batch file + # all lines starting with # are comments; they also indicate + # that a command definition is over. -# this comment ends the @create command. + create box -@set box/desc = A large box. + # this comment ends the @create command. -Inside are some scattered piles of clothing. + set box/desc = A large box. + + Inside are some scattered piles of clothing. -It seems the bottom of the box is a bit loose. + It seems the bottom of the box is a bit loose. -# Again, this comment indicates the @set command is over. Note how -# the description could be freely added. Excess whitespace on a line -# is ignored. An empty line in the command definition is parsed as a \n -# (so two empty lines becomes a new paragraph). + # Again, this comment indicates the @set command is over. Note how + # the description could be freely added. Excess whitespace on a line + # is ignored. An empty line in the command definition is parsed as a \n + # (so two empty lines becomes a new paragraph). -@teleport #221 + teleport #221 -# (Assuming #221 is a warehouse or something.) -# (remember, this comment ends the @teleport command! Don'f forget it) + # (Assuming #221 is a warehouse or something.) + # (remember, this comment ends the @teleport command! Don'f forget it) -# Example of importing another file at this point. -#IMPORT examples.batch + # Example of importing another file at this point. + #IMPORT examples.batch -@drop box + drop box -# Done, the box is in the warehouse! (this last comment is not necessary to -# close the @drop command since it's the end of the file) -``` - -------------------------- + # Done, the box is in the warehouse! (this last comment is not necessary to + # close the drop command since it's the end of the file) An example batch file is `contrib/examples/batch_example.ev`. - -========================================================================== - - -Batch-code processor file syntax +# Batch-code processor file syntax The Batch-code processor accepts full python modules (e.g. `batch.py`) that looks identical to normal Python files. The difference from @@ -113,62 +111,61 @@ the code and re-run sections of it easily during development. Code blocks are marked by commented tokens alone on a line: -#HEADER - 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! -#CODE - 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. -#INSERT path.filename - 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. +- `#HEADER` - 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! +- `#CODE` - 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. +- `#INSERT path.filename` - 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. Importing works as normal. The following variables are automatically made available in the script namespace. -- `caller` - The object executing the batchscript +- `caller` - The object executing the batchscript - `DEBUG` - 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) +## Example batch.py file -Example batch.py file ------------------------------------ +:: -``` -#HEADER + #HEADER -from django.conf import settings -from evennia.utils import create -from types import basetypes + from django.conf import settings + from evennia.utils import create + from types import basetypes -GOLD = 10 + GOLD = 10 -#CODE + #CODE -obj = create.create_object(basetypes.Object) -obj2 = create.create_object(basetypes.Object) -obj.location = caller.location -obj.db.gold = GOLD -caller.msg("The object was created!") + obj = create.create_object(basetypes.Object) + obj2 = create.create_object(basetypes.Object) + obj.location = caller.location + obj.db.gold = GOLD + caller.msg("The object was created!") -if DEBUG: - obj.delete() - obj2.delete() + if DEBUG: + obj.delete() + obj2.delete() -#INSERT another_batch_file + #INSERT another_batch_file -#CODE + #CODE + + script = create.create_script() -script = create.create_script() -``` """ import re import codecs