mirror of
https://github.com/evennia/evennia.git
synced 2026-03-20 23:06:31 +01:00
Updated the typeclasses/ directory modules to use Google style docstrings, as per #709.
This commit is contained in:
parent
b9043a9e95
commit
8e554ef8f6
5 changed files with 726 additions and 185 deletions
|
|
@ -5,10 +5,18 @@ from evennia.typeclasses.models import Attribute, Tag
|
|||
|
||||
|
||||
class TagAdmin(admin.ModelAdmin):
|
||||
"""
|
||||
A django Admin wrapper for Tags.
|
||||
|
||||
"""
|
||||
fields = ('db_key', 'db_category', 'db_data')
|
||||
|
||||
|
||||
class TagInline(admin.TabularInline):
|
||||
"""
|
||||
A handler for inline Tags.
|
||||
|
||||
"""
|
||||
# Set this to the through model of your desired M2M when subclassing.
|
||||
model = None
|
||||
raw_id_fields = ('tag',)
|
||||
|
|
@ -17,7 +25,8 @@ class TagInline(admin.TabularInline):
|
|||
|
||||
class AttributeInline(admin.TabularInline):
|
||||
"""
|
||||
Inline creation of player attributes
|
||||
Inline creation of player attributes.j
|
||||
|
||||
"""
|
||||
# Set this to the through model of your desired M2M when subclassing.
|
||||
model = None
|
||||
|
|
@ -50,7 +59,8 @@ class AttributeInline(admin.TabularInline):
|
|||
|
||||
class AttributeAdmin(ModelAdmin):
|
||||
"""
|
||||
Defines how to display the attributes
|
||||
Defines how to display the attributes.
|
||||
|
||||
"""
|
||||
search_fields = ('db_key', 'db_strvalue', 'db_value')
|
||||
list_display = ('db_key', 'db_strvalue', 'db_value')
|
||||
|
|
|
|||
|
|
@ -39,15 +39,17 @@ class Attribute(SharedMemoryModel):
|
|||
attributes on the fly as we like.
|
||||
|
||||
The Attribute class defines the following properties:
|
||||
key - primary identifier.
|
||||
lock_storage - perm strings.
|
||||
obj - which object the attribute is defined on.
|
||||
date_created - when the attribute was created.
|
||||
value - the data stored in the attribute, in pickled form
|
||||
using wrappers to be able to store/retrieve models.
|
||||
strvalue - string-only data. This data is not pickled and is
|
||||
thus faster to search for in the database.
|
||||
category - optional character string for grouping the Attribute.
|
||||
- key (str): Primary identifier.
|
||||
- lock_storage (str): Perm strings.
|
||||
- model (str): A string defining the model this is connected to. This
|
||||
is a natural_key, like "objects.objectdb"
|
||||
- date_created (datetime): When the attribute was created.
|
||||
- value (any): The data stored in the attribute, in pickled form
|
||||
using wrappers to be able to store/retrieve models.
|
||||
- strvalue (str): String-only data. This data is not pickled and
|
||||
is thus faster to search for in the database.
|
||||
- category (str): Optional character string for grouping the
|
||||
Attribute.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -76,7 +78,7 @@ class Attribute(SharedMemoryModel):
|
|||
db_model = models.CharField(
|
||||
'model', max_length=32, db_index=True, blank=True, null=True,
|
||||
help_text="Which model of object this attribute is attached to (A "
|
||||
"natural key like 'objects.dbobject'). You should not change "
|
||||
"natural key like 'objects.objectdb'). You should not change "
|
||||
"this value unless you know what you are doing.")
|
||||
# subclass of Attribute (None or nick)
|
||||
db_attrtype = models.CharField(
|
||||
|
|
@ -166,18 +168,20 @@ class Attribute(SharedMemoryModel):
|
|||
Determines if another object has permission to access.
|
||||
|
||||
Args:
|
||||
accessing_obj (object): object trying to access this one.
|
||||
access_type (optional): type of access sought.
|
||||
default (optional): what to return if no lock of access_type was found
|
||||
|
||||
Kwargs:
|
||||
**kwargs: passed to `at_access` hook along with `result`.
|
||||
accessing_obj (object): Entity trying to access this one.
|
||||
access_type (str, optional): Type of access sought, see
|
||||
the lock documentation.
|
||||
default (bool, optional): What result to return if no lock
|
||||
of access_type was found. The default, `False`, means a lockdown
|
||||
policy, only allowing explicit access.
|
||||
kwargs (any, optional): Not used; here to make the API consistent with
|
||||
other access calls.
|
||||
|
||||
Returns:
|
||||
result:
|
||||
result (bool): If the lock was passed or not.
|
||||
|
||||
"""
|
||||
result = self.locks.check(accessing_obj, access_type=access_type, default=default)
|
||||
#self.at_access(result, **kwargs)
|
||||
return result
|
||||
|
||||
|
||||
|
|
@ -196,7 +200,7 @@ class AttributeHandler(object):
|
|||
_attrtype = None
|
||||
|
||||
def __init__(self, obj):
|
||||
"Initialize handler"
|
||||
"Initialize handler."
|
||||
self.obj = obj
|
||||
self._objid = obj.id
|
||||
self._model = to_str(obj.__dbclass__.__name__.lower())
|
||||
|
|
@ -216,7 +220,16 @@ class AttributeHandler(object):
|
|||
Checks if the given Attribute (or list of Attributes) exists on
|
||||
the object.
|
||||
|
||||
If an iterable is given, returns list of booleans.
|
||||
Args:
|
||||
key (str or iterable): The Attribute key or keys to check for.
|
||||
category (str): Limit the check to Attributes with this
|
||||
category (note, that `None` is the default category).
|
||||
|
||||
Returns:
|
||||
has_attribute (bool or list): If the Attribute exists on
|
||||
this object or not. If `key` was given as an iterable then
|
||||
the return is a list of booleans.
|
||||
|
||||
"""
|
||||
if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE:
|
||||
self._recache()
|
||||
|
|
@ -228,21 +241,38 @@ class AttributeHandler(object):
|
|||
|
||||
def get(self, key=None, category=None, default=None, return_obj=False,
|
||||
strattr=False, raise_exception=False, accessing_obj=None,
|
||||
default_access=True, not_found_none=False):
|
||||
default_access=True):
|
||||
"""
|
||||
Returns the value of the given Attribute or list of Attributes.
|
||||
`strattr` will cause the string-only value field instead of the normal
|
||||
pickled field data. Use to get back values from Attributes added with
|
||||
the `strattr` keyword.
|
||||
Get the Attribute.
|
||||
|
||||
If `return_obj=True`, return the matching Attribute object
|
||||
instead. Returns `default` if no matches (or [ ] if `key` was a list
|
||||
with no matches). If `raise_exception=True`, failure to find a
|
||||
match will raise `AttributeError` instead.
|
||||
Args:
|
||||
key (str or list, optional): the attribute identifier or
|
||||
multiple attributes to get. if a list of keys, the
|
||||
method will return a list.
|
||||
category (str, optional): the category within which to
|
||||
retrieve attribute(s).
|
||||
default (any, optional): The value to return if an
|
||||
Attribute was not defined.
|
||||
return_obj (bool, optional): If set, the return is not the value of the
|
||||
Attribute but the Attribute object itself.
|
||||
strattr (bool, optional): Return the `strvalue` field of
|
||||
the Attribute rather than the usual `value`, this is a
|
||||
string-only value for quick database searches.
|
||||
raise_exception (bool, optional): When an Attribute is not
|
||||
found, the return from this is usually `default`. If this
|
||||
is set, an exception is raised instead.
|
||||
accessing_obj (object, optional): If set, an `attrread`
|
||||
permission lock will be checked before returning each
|
||||
looked-after Attribute.
|
||||
|
||||
Returns:
|
||||
result (any, Attribute or list): A list of varying type depending
|
||||
on the arguments given.
|
||||
|
||||
Raises:
|
||||
AttributeError: If `raise_exception` is set and no matching Attribute
|
||||
was found matching `key`.
|
||||
|
||||
If `accessing_obj` is given, its `attrread` permission lock will be
|
||||
checked before displaying each looked-after Attribute. If no
|
||||
`accessing_obj` is given, no check will be done.
|
||||
"""
|
||||
|
||||
class RetDefault(object):
|
||||
|
|
@ -288,12 +318,21 @@ class AttributeHandler(object):
|
|||
"""
|
||||
Add attribute to object, with optional `lockstring`.
|
||||
|
||||
If `strattr` is set, the `db_strvalue` field will be used (no pickling).
|
||||
Use the `get()` method with the `strattr` keyword to get it back.
|
||||
Args:
|
||||
key (str): An Attribute name to add.
|
||||
value (any or str): The value of the Attribute. If
|
||||
`strattr` keyword is set, this *must* be a string.
|
||||
category (str, optional): The category for the Attribute.
|
||||
The default `None` is the normal category used.
|
||||
lockstring (str, optional): A lock string limiting access
|
||||
to the attribute.
|
||||
accessing_obj (object, optional): An entity to check for
|
||||
the `attrcreate` access-type. If not passing, this method
|
||||
will be exited.
|
||||
default_access (bool, optional): What access to grant if
|
||||
`accessing_obj` is given but no lock of the type
|
||||
`attrcreate` is defined on the Attribute in question.
|
||||
|
||||
If `accessing_obj` is given, `self.obj`'s `attrcreate` lock access
|
||||
will be checked against it. If no `accessing_obj` is given, no check
|
||||
will be done.
|
||||
"""
|
||||
if accessing_obj and not self.obj.access(accessing_obj,
|
||||
self._attrcreate, default=default_access):
|
||||
|
|
@ -334,11 +373,27 @@ class AttributeHandler(object):
|
|||
strattr=False, accessing_obj=None, default_access=True):
|
||||
"""
|
||||
Batch-version of `add()`. This is more efficient than
|
||||
repeat-calling add.
|
||||
repeat-calling add when having many Attributes to add.
|
||||
|
||||
`key` and `value` must be sequences of the same length, each
|
||||
representing a key-value pair.
|
||||
Args:
|
||||
key (list): A list of Attribute names to add.
|
||||
value (list): A list of values. It must match the `key`
|
||||
list. If `strattr` keyword is set, all entries *must* be
|
||||
strings.
|
||||
category (str, optional): The category for the Attribute.
|
||||
The default `None` is the normal category used.
|
||||
lockstring (str, optional): A lock string limiting access
|
||||
to the attribute.
|
||||
accessing_obj (object, optional): An entity to check for
|
||||
the `attrcreate` access-type. If not passing, this method
|
||||
will be exited.
|
||||
default_access (bool, optional): What access to grant if
|
||||
`accessing_obj` is given but no lock of the type
|
||||
`attrcreate` is defined on the Attribute in question.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If `key` and `value` lists are not of the
|
||||
same lengths.
|
||||
"""
|
||||
if accessing_obj and not self.obj.access(accessing_obj,
|
||||
self._attrcreate, default=default_access):
|
||||
|
|
@ -390,8 +445,24 @@ class AttributeHandler(object):
|
|||
"""
|
||||
Remove attribute or a list of attributes from object.
|
||||
|
||||
If `accessing_obj` is given, will check against the `attredit` lock.
|
||||
If not given, this check is skipped.
|
||||
Args:
|
||||
key (str): An Attribute key to remove.
|
||||
raise_exception (bool, optional): If set, not finding the
|
||||
Attribute to delete will raise an exception instead of
|
||||
just quietly failing.
|
||||
category (str, optional): The category within which to
|
||||
remove the Attribute.
|
||||
accessing_obj (object, optional): An object to check
|
||||
against the `attredit` lock. If not given, the check will
|
||||
be skipped.
|
||||
default_access (bool, optional): The fallback access to
|
||||
grant if `accessing_obj` is given but there is no
|
||||
`attredit` lock set on the Attribute in question.
|
||||
|
||||
Raises:
|
||||
AttributeError: If `raise_exception` is set and no matching Attribute
|
||||
was found matching `key`.
|
||||
|
||||
"""
|
||||
if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE:
|
||||
self._recache()
|
||||
|
|
@ -409,9 +480,17 @@ class AttributeHandler(object):
|
|||
|
||||
def clear(self, category=None, accessing_obj=None, default_access=True):
|
||||
"""
|
||||
Remove all Attributes on this object. If `accessing_obj` is
|
||||
given, check the `attredit` lock on each Attribute before
|
||||
continuing. If not given, skip check.
|
||||
Remove all Attributes on this object.
|
||||
|
||||
Args:
|
||||
category (str, optional): If given, clear only Attributes
|
||||
of this category.
|
||||
accessing_obj (object, optional): If given, check the
|
||||
`attredit` lock on each Attribute before continuing.
|
||||
default_access (bool, optional): Use this permission as
|
||||
fallback if `access_obj` is given but there is no lock of
|
||||
type `attredit` on the Attribute in question.
|
||||
|
||||
"""
|
||||
if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE:
|
||||
self._recache()
|
||||
|
|
@ -426,9 +505,18 @@ class AttributeHandler(object):
|
|||
"""
|
||||
Return all Attribute objects on this object.
|
||||
|
||||
If `accessing_obj` is given, check the `attrread` lock on
|
||||
each attribute before returning them. If not given, this
|
||||
check is skipped.
|
||||
Args:
|
||||
accessing_obj (object, optional): Check the `attrread`
|
||||
lock on each attribute before returning them. If not
|
||||
given, this check is skipped.
|
||||
default_access (bool, optional): Use this permission as a
|
||||
fallback if `accessing_obj` is given but one or more
|
||||
Attributes has no lock of type `attrread` defined on them.
|
||||
|
||||
Returns:
|
||||
Attributes (list): All the Attribute objects (note: Not
|
||||
their values!) in the handler.
|
||||
|
||||
"""
|
||||
if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE:
|
||||
self._recache()
|
||||
|
|
@ -442,31 +530,92 @@ class AttributeHandler(object):
|
|||
|
||||
class NickHandler(AttributeHandler):
|
||||
"""
|
||||
Handles the addition and removal of Nicks
|
||||
(uses Attributes' `strvalue` and `category` fields)
|
||||
Handles the addition and removal of Nicks. Nicks are special
|
||||
versions of Attributes with an `_attrtype` hardcoded to `nick`.
|
||||
They also always use the `strvalue` fields for their data.
|
||||
|
||||
Nicks are stored as Attributes
|
||||
with categories `nick_<nicktype>`
|
||||
"""
|
||||
_attrtype = "nick"
|
||||
|
||||
def has(self, key, category="inputline"):
|
||||
"""
|
||||
Args:
|
||||
key (str or iterable): The Nick key or keys to check for.
|
||||
category (str): Limit the check to Nicks with this
|
||||
category (note, that `None` is the default category).
|
||||
|
||||
Returns:
|
||||
has_nick (bool or list): If the Nick exists on this object
|
||||
or not. If `key` was given as an iterable then the return
|
||||
is a list of booleans.
|
||||
|
||||
"""
|
||||
return super(NickHandler, self).has(key, category=category)
|
||||
|
||||
def get(self, key=None, category="inputline", **kwargs):
|
||||
"Get the replacement value matching the given key and category"
|
||||
"""
|
||||
Get the replacement value matching the given key and category
|
||||
|
||||
Args:
|
||||
key (str or list, optional): the attribute identifier or
|
||||
multiple attributes to get. if a list of keys, the
|
||||
method will return a list.
|
||||
category (str, optional): the category within which to
|
||||
retrieve the nick. The "inputline" means replacing data
|
||||
sent by the user.
|
||||
kwargs (any, optional): These are passed on to `AttributeHandler.get`.
|
||||
|
||||
"""
|
||||
return super(NickHandler, self).get(key=key, category=category, strattr=True, **kwargs)
|
||||
|
||||
def add(self, key, replacement, category="inputline", **kwargs):
|
||||
"Add a new nick"
|
||||
"""
|
||||
Add a new nick.
|
||||
|
||||
Args:
|
||||
key (str): A key for the nick to match for.
|
||||
replacement (str): The string to replace `key` with (the "nickname").
|
||||
category (str, optional): the category within which to
|
||||
retrieve the nick. The "inputline" means replacing data
|
||||
sent by the user.
|
||||
kwargs (any, optional): These are passed on to `AttributeHandler.get`.
|
||||
|
||||
"""
|
||||
super(NickHandler, self).add(key, replacement, category=category, strattr=True, **kwargs)
|
||||
|
||||
def remove(self, key, category="inputline", **kwargs):
|
||||
"Remove Nick with matching category"
|
||||
"""
|
||||
Remove Nick with matching category.
|
||||
|
||||
Args:
|
||||
key (str): A key for the nick to match for.
|
||||
category (str, optional): the category within which to
|
||||
removethe nick. The "inputline" means replacing data
|
||||
sent by the user.
|
||||
kwargs (any, optional): These are passed on to `AttributeHandler.get`.
|
||||
|
||||
"""
|
||||
super(NickHandler, self).remove(key, category=category, **kwargs)
|
||||
|
||||
def nickreplace(self, raw_string, categories=("inputline", "channel"), include_player=True):
|
||||
"Replace entries in raw_string with nick replacement"
|
||||
"""
|
||||
Apply nick replacement of entries in raw_string with nick replacement.
|
||||
|
||||
Args:
|
||||
raw_string (str): The string in which to perform nick
|
||||
replacement.
|
||||
categories (tuple, optional): Replacement categories in
|
||||
which to perform the replacement, such as "inputline",
|
||||
"channel" etc.
|
||||
include_player (bool, optional): Also include replacement
|
||||
with nicks stored on the Player level.
|
||||
kwargs (any, optional): Not used.
|
||||
|
||||
Returns:
|
||||
string (str): A string with matching keys replaced with
|
||||
their nick equivalents.
|
||||
|
||||
"""
|
||||
raw_string
|
||||
obj_nicks, player_nicks = [], []
|
||||
for category in make_iter(categories):
|
||||
|
|
@ -491,35 +640,83 @@ class NAttributeHandler(object):
|
|||
for the `AttributeHandler`.
|
||||
"""
|
||||
def __init__(self, obj):
|
||||
"initialized on the object"
|
||||
"""
|
||||
Initialized on the object
|
||||
"""
|
||||
self._store = {}
|
||||
self.obj = weakref.proxy(obj)
|
||||
|
||||
def has(self, key):
|
||||
"Check if object has this attribute or not"
|
||||
"""
|
||||
Check if object has this attribute or not.
|
||||
|
||||
Args:
|
||||
key (str): The Nattribute key to check.
|
||||
|
||||
Returns:
|
||||
has_nattribute (bool): If Nattribute is set or not.
|
||||
|
||||
"""
|
||||
return key in self._store
|
||||
|
||||
def get(self, key):
|
||||
"Returns named key value"
|
||||
"""
|
||||
Get the named key value.
|
||||
|
||||
Args:
|
||||
key (str): The Nattribute key to get.
|
||||
|
||||
Returns:
|
||||
the value of the Nattribute.
|
||||
|
||||
"""
|
||||
return self._store.get(key, None)
|
||||
|
||||
def add(self, key, value):
|
||||
"Add new key and value"
|
||||
"""
|
||||
Add new key and value.
|
||||
|
||||
Args:
|
||||
key (str): The name of Nattribute to add.
|
||||
value (any): The value to store.
|
||||
|
||||
"""
|
||||
self._store[key] = value
|
||||
self.obj.set_recache_protection()
|
||||
|
||||
def remove(self, key):
|
||||
"Remove key from storage"
|
||||
"""
|
||||
Remove Nattribute from storage.
|
||||
|
||||
Args:
|
||||
key (str): The name of the Nattribute to remove.
|
||||
|
||||
"""
|
||||
if key in self._store:
|
||||
del self._store[key]
|
||||
self.obj.set_recache_protection(self._store)
|
||||
|
||||
def clear(self):
|
||||
"Remove all nattributes from handler"
|
||||
"""
|
||||
Remove all NAttributes from handler.
|
||||
|
||||
"""
|
||||
self._store = {}
|
||||
|
||||
def all(self, return_tuples=False):
|
||||
"List all keys or (keys, values) stored, except _keys"
|
||||
"""
|
||||
List the contents of the handler.
|
||||
|
||||
Args:
|
||||
return_tuples (bool, optional): Defines if the Nattributes
|
||||
are returns as a list of keys or as a list of `(key, value)`.
|
||||
|
||||
Returns:
|
||||
nattributes (list): A list of keys `[key, key, ...]` or a
|
||||
list of tuples `[(key, value), ...]` depending on the
|
||||
setting of `return_tuples`.
|
||||
|
||||
"""
|
||||
if return_tuples:
|
||||
return [(key, value) for (key, value) in self._store.items() if not key.startswith("_")]
|
||||
return [key for key in self._store if not key.startswith("_")]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
This implements the common managers that are used by the
|
||||
abstract models in dbobjects.py (and which are thus shared by
|
||||
all Attributes and TypedObjects).
|
||||
|
||||
"""
|
||||
from functools import update_wrapper
|
||||
from django.db.models import Q
|
||||
|
|
@ -18,8 +19,8 @@ _Tag = None
|
|||
|
||||
def returns_typeclass_list(method):
|
||||
"""
|
||||
Decorator: Always returns a list, even
|
||||
if it is empty.
|
||||
Decorator: Always returns a list, even if it is empty.
|
||||
|
||||
"""
|
||||
def func(self, *args, **kwargs):
|
||||
self.__doc__ = method.__doc__
|
||||
|
|
@ -34,7 +35,8 @@ def returns_typeclass_list(method):
|
|||
|
||||
def returns_typeclass(method):
|
||||
"""
|
||||
Decorator: Returns a single match or None
|
||||
Decorator: Returns a single typeclass match or None.
|
||||
|
||||
"""
|
||||
def func(self, *args, **kwargs):
|
||||
self.__doc__ = method.__doc__
|
||||
|
|
@ -47,6 +49,7 @@ def returns_typeclass(method):
|
|||
class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||
"""
|
||||
Common ObjectManager for all dbobjects.
|
||||
|
||||
"""
|
||||
# common methods for all typed managers. These are used
|
||||
# in other methods. Returns querysets.
|
||||
|
|
@ -61,16 +64,24 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
|
||||
Attrs:
|
||||
key (str, optional): The attribute's key 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 `strvalue`.
|
||||
strvalue (str, optional): The str-value to search for. Most Attributes
|
||||
will not have strvalue set. This is mutually exclusive to the `value`
|
||||
keyword and will take precedence if given.
|
||||
obj (Object, optional): On which object the Attribute to search for is.
|
||||
attrype (str, optional): An attribute-type to search for. By default this
|
||||
is either `None` (normal Attributes) or `"nick"`.
|
||||
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
|
||||
`strvalue`.
|
||||
strvalue (str, optional): The str-value to search for.
|
||||
Most Attributes will not have strvalue set. This is
|
||||
mutually exclusive to the `value` keyword and will take
|
||||
precedence if given.
|
||||
obj (Object, optional): On which object the Attribute to
|
||||
search for is.
|
||||
attrype (str, optional): An attribute-type to search for.
|
||||
By default this is either `None` (normal Attributes) or
|
||||
`"nick"`.
|
||||
|
||||
Returns:
|
||||
attributes (list): The matching Attributes.
|
||||
|
||||
"""
|
||||
query = [("attribute__db_attrtype", attrtype)]
|
||||
|
|
@ -88,13 +99,51 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
return [th.attribute for th in self.model.db_attributes.through.objects.filter(**dict(query))]
|
||||
|
||||
def get_nick(self, key=None, category=None, value=None, strvalue=None, obj=None):
|
||||
"""
|
||||
Get a nick, in parallel to `get_attribute`.
|
||||
|
||||
Attrs:
|
||||
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
|
||||
is not a very efficient operation since it will query for a pickled
|
||||
entity. Mutually exclusive to `strvalue`.
|
||||
strvalue (str, optional): The str-value to search for. Most Attributes
|
||||
will not have strvalue set. This is mutually exclusive to the `value`
|
||||
keyword and will take precedence if given.
|
||||
obj (Object, optional): On which object the Attribute to search for is.
|
||||
|
||||
Returns:
|
||||
nicks (list): The matching Nicks.
|
||||
|
||||
"""
|
||||
return self.get_attribute(key=key, category=category, value=value, strvalue=strvalue, obj=obj)
|
||||
|
||||
@returns_typeclass_list
|
||||
def get_by_attribute(self, key=None, category=None, value=None, strvalue=None, attrtype=None):
|
||||
"""
|
||||
Return objects having attributes with the given key, category, value,
|
||||
strvalue or combination of those criteria.
|
||||
Return objects having attributes with the given key, category,
|
||||
value, strvalue or combination of those criteria.
|
||||
|
||||
Args:
|
||||
key (str, optional): The attribute's key to search for
|
||||
category (str, optional): The category of the attribute
|
||||
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
|
||||
`strvalue`.
|
||||
strvalue (str, optional): The str-value to search for.
|
||||
Most Attributes will not have strvalue set. This is
|
||||
mutually exclusive to the `value` keyword and will take
|
||||
precedence if given.
|
||||
attrype (str, optional): An attribute-type to search for.
|
||||
By default this is either `None` (normal Attributes) or
|
||||
`"nick"`.
|
||||
|
||||
Returns:
|
||||
obj (list): Objects having the matching Attributes.
|
||||
|
||||
"""
|
||||
query = [("db_attributes__db_attrtype", attrtype)]
|
||||
if key:
|
||||
|
|
@ -109,7 +158,19 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
return self.filter(**dict(query))
|
||||
|
||||
def get_by_nick(self, key=None, nick=None, category="inputline"):
|
||||
"Get object based on its key or nick."
|
||||
"""
|
||||
Get object based on its key or nick.
|
||||
|
||||
Args:
|
||||
key (str, optional): The attribute's key to search for
|
||||
nick (str, optional): The nickname to search for
|
||||
category (str, optional): The category of the nick
|
||||
to search for.
|
||||
|
||||
Returns:
|
||||
obj (list): Objects having the matching Nicks.
|
||||
|
||||
"""
|
||||
return self.get_by_attribute(key=key, category=category, strvalue=nick, attrtype="nick")
|
||||
|
||||
# Tag manager methods
|
||||
|
|
@ -119,9 +180,20 @@ 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.
|
||||
|
||||
tagtype - one of None (normal tags), "alias" or "permission"
|
||||
global_search - include all possible tags, not just tags on
|
||||
this object
|
||||
Attrs:
|
||||
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),
|
||||
"alias" or "permission"
|
||||
global_search (bool, optional): Include all possible tags,
|
||||
not just tags on this object
|
||||
|
||||
Returns:
|
||||
tag (list): The matching Tags.
|
||||
|
||||
"""
|
||||
global _Tag
|
||||
if not _Tag:
|
||||
|
|
@ -148,9 +220,33 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
return [th.tag for th in self.model.db_tags.through.objects.filter(**dict(query))]
|
||||
|
||||
def get_permission(self, key=None, category=None, obj=None):
|
||||
"""
|
||||
Get a permission from the database.
|
||||
|
||||
Args:
|
||||
key (str, optional): The permission's identifier.
|
||||
category (str, optional): The permission's category.
|
||||
obj (object, optional): The object on which this Tag is set.
|
||||
|
||||
Returns:
|
||||
permission (list): Permission objects.
|
||||
|
||||
"""
|
||||
return self.get_tag(key=key, category=category, obj=obj, tagtype="permission")
|
||||
|
||||
def get_alias(self, key=None, category=None, obj=None):
|
||||
"""
|
||||
Get an alias from the database.
|
||||
|
||||
Args:
|
||||
key (str, optional): The permission's identifier.
|
||||
category (str, optional): The permission's category.
|
||||
obj (object, optional): The object on which this Tag is set.
|
||||
|
||||
Returns:
|
||||
alias (list): Alias objects.
|
||||
|
||||
"""
|
||||
return self.get_tag(key=key, category=category, obj=obj, tagtype="alias")
|
||||
|
||||
@returns_typeclass_list
|
||||
|
|
@ -165,6 +261,8 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
tagtype (str or None, optional): 'type' of Tag, by default
|
||||
this is either `None` (a normal Tag), `alias` or
|
||||
`permission`.
|
||||
Returns:
|
||||
objects (list): Objects with matching tag.
|
||||
"""
|
||||
query = [("db_tags__db_tagtype", tagtype)]
|
||||
if key:
|
||||
|
|
@ -174,19 +272,55 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
return self.filter(**dict(query))
|
||||
|
||||
def get_by_permission(self, key=None, category=None):
|
||||
"""
|
||||
Return objects having permissions with a given key or category or
|
||||
combination of the two.
|
||||
|
||||
Args:
|
||||
key (str, optional): Permissions key. Not case sensitive.
|
||||
category (str, optional): Permission category. Not case sensitive.
|
||||
Returns:
|
||||
objects (list): Objects with matching permission.
|
||||
"""
|
||||
return self.get_by_tag(key=key, category=category, tagtype="permission")
|
||||
|
||||
def get_by_alias(self, key=None, category=None):
|
||||
"""
|
||||
Return objects having aliases with a given key or category or
|
||||
combination of the two.
|
||||
|
||||
Args:
|
||||
key (str, optional): Alias key. Not case sensitive.
|
||||
category (str, optional): Alias category. Not case sensitive.
|
||||
Returns:
|
||||
objects (list): Objects with matching alias.
|
||||
"""
|
||||
return self.get_by_tag(key=key, category=category, tagtype="alias")
|
||||
|
||||
def create_tag(self, key=None, category=None, data=None, tagtype=None):
|
||||
"""
|
||||
Create a new Tag of the base type associated with this typedobject.
|
||||
This makes sure to create case-insensitive tags. If the exact same
|
||||
tag configuration (key+category+tagtype) exists on the model, a
|
||||
new tag will not be created, but an old one returned. A data
|
||||
keyword is not part of the uniqueness of the tag and setting one
|
||||
on an existing tag will overwrite the old data field.
|
||||
Create a new Tag of the base type associated with this
|
||||
object. This makes sure to create case-insensitive tags.
|
||||
If the exact same tag configuration (key+category+tagtype)
|
||||
exists on the model, a new tag will not be created, but an old
|
||||
one returned.
|
||||
|
||||
|
||||
Args:
|
||||
key (str, optional): Tag key. Not case sensitive.
|
||||
category (str, optional): Tag category. Not case sensitive.
|
||||
data (str, optional): Extra information about the tag.
|
||||
tagtype (str or None, optional): 'type' of Tag, by default
|
||||
this is either `None` (a normal Tag), `alias` or
|
||||
`permission`.
|
||||
|
||||
Notes:
|
||||
The `data` field is not part of the uniqueness of the tag:
|
||||
Setting `data` on an existing tag will overwrite the old
|
||||
data field. It is intended only as a way to carry
|
||||
information about the tag (like a help text), not to carry
|
||||
any information about the tagged objects themselves.
|
||||
|
||||
"""
|
||||
data = str(data) if data is not None else None
|
||||
# try to get old tag
|
||||
|
|
@ -213,11 +347,20 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
|
||||
def dbref(self, dbref, reqhash=True):
|
||||
"""
|
||||
Valid forms of dbref (database reference number)
|
||||
are either a string '#N' or an integer N.
|
||||
Output is the integer part.
|
||||
reqhash - require input to be on form "#N" to be
|
||||
identified as a dbref
|
||||
Determing if input is a valid dbref.
|
||||
|
||||
Args:
|
||||
dbref (str or int): A possible dbref.
|
||||
reqhash (bool, optional): If the "#" is required for this
|
||||
to be considered a valid hash.
|
||||
|
||||
Returns:
|
||||
dbref (int or None): The integer part of the dbref.
|
||||
|
||||
Notes:
|
||||
Valid forms of dbref (database reference number) are
|
||||
either a string '#N' or an integer N.
|
||||
|
||||
"""
|
||||
if reqhash and not (isinstance(dbref, basestring) and dbref.startswith("#")):
|
||||
return None
|
||||
|
|
@ -233,7 +376,14 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
@returns_typeclass
|
||||
def get_id(self, dbref):
|
||||
"""
|
||||
Find object with given dbref
|
||||
Find object with given dbref.
|
||||
|
||||
Args:
|
||||
dbref (str or int): The id to search for.
|
||||
|
||||
Returns:
|
||||
object (TypedObject): The matched object.
|
||||
|
||||
"""
|
||||
dbref = self.dbref(dbref, reqhash=False)
|
||||
try:
|
||||
|
|
@ -244,15 +394,30 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
|
||||
def dbref_search(self, dbref):
|
||||
"""
|
||||
Alias to get_id
|
||||
Alias to get_id.
|
||||
|
||||
Args:
|
||||
dbref (str or int): The id to search for.
|
||||
|
||||
Returns:
|
||||
object (TypedObject): The matched object.
|
||||
|
||||
"""
|
||||
return self.get_id(dbref)
|
||||
|
||||
@returns_typeclass_list
|
||||
def get_dbref_range(self, min_dbref=None, max_dbref=None):
|
||||
"""
|
||||
Return all objects inside and including the
|
||||
given boundaries.
|
||||
Get objects within a certain range of dbrefs.
|
||||
|
||||
Args:
|
||||
min_dbref (int): Start of dbref range.
|
||||
max_dbref (int): End of dbref range (inclusive)
|
||||
|
||||
Returns:
|
||||
objects (list): TypedObjects with dbrefs within
|
||||
the given dbref ranges.
|
||||
|
||||
"""
|
||||
retval = super(TypedObjectManager, self).all()
|
||||
if min_dbref is not None:
|
||||
|
|
@ -263,9 +428,14 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
|
||||
def object_totals(self):
|
||||
"""
|
||||
Returns a dictionary with all the typeclasses active in-game
|
||||
as well as the number of such objects defined (i.e. the number
|
||||
of database object having that typeclass set on themselves).
|
||||
Get info about database statistics.
|
||||
|
||||
Returns:
|
||||
census (dict): A dictionary `{typeclass_path: number, ...}` with
|
||||
all the typeclasses active in-game as well as the number
|
||||
of such objects defined (i.e. the number of database
|
||||
object having that typeclass set on themselves).
|
||||
|
||||
"""
|
||||
dbtotals = {}
|
||||
typeclass_paths = set(self.values_list('db_typeclass_path', flat=True))
|
||||
|
|
@ -281,12 +451,18 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
certain typeclass. If location is set, limit search to objects
|
||||
in that location.
|
||||
|
||||
typeclass - a typeclass class or a python path to a typeclass
|
||||
include_children - return objects with given typeclass and all
|
||||
children inheriting from this typeclass.
|
||||
include_parents - return objects with given typeclass and all
|
||||
parents to this typeclass
|
||||
The include_children/parents keywords are mutually exclusive.
|
||||
Args:
|
||||
typeclass (str or class): A typeclass class or a python path to a typeclass.
|
||||
include_children (bool, optional): Return objects with
|
||||
given typeclass *and* all children inheriting from this
|
||||
typeclass. Mutuall exclusive to `include_parents`.
|
||||
include_parents (bool, optional): Return objects with
|
||||
given typeclass *and* all parents to this typeclass.
|
||||
Mutually exclusive to `include_children`.
|
||||
|
||||
Returns:
|
||||
objects (list): The objects found with the given typeclasses.
|
||||
|
||||
"""
|
||||
|
||||
if callable(typeclass):
|
||||
|
|
@ -319,11 +495,29 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
|||
|
||||
|
||||
class TypeclassManager(TypedObjectManager):
|
||||
"""
|
||||
Manager for the typeclasses. The main purpose of this manager is
|
||||
to limit database queries to the given typeclass despite all
|
||||
typeclasses technically being defined in the same core database
|
||||
model.
|
||||
|
||||
"""
|
||||
|
||||
def get(self, **kwargs):
|
||||
"""
|
||||
Overload the standard get. This will limit itself to only
|
||||
return the current typeclass.
|
||||
|
||||
Kwargs:
|
||||
kwargs (any): These are passed on as normal arguments
|
||||
to the default django get method
|
||||
Returns:
|
||||
object (object): The object found.
|
||||
|
||||
Raises:
|
||||
ObjectNotFound: The exact name of this exception depends
|
||||
on the model base used.
|
||||
|
||||
"""
|
||||
kwargs.update({"db_typeclass_path":self.model.path})
|
||||
return super(TypedObjectManager, self).get(**kwargs)
|
||||
|
|
@ -332,19 +526,33 @@ class TypeclassManager(TypedObjectManager):
|
|||
"""
|
||||
Overload of the standard filter function. This filter will
|
||||
limit itself to only the current typeclass.
|
||||
|
||||
Kwargs:
|
||||
kwargs (any): These are passed on as normal arguments
|
||||
to the default django filter method.
|
||||
Returns:
|
||||
objects (list): The objects found.
|
||||
|
||||
"""
|
||||
kwargs.update({"db_typeclass_path":self.model.path})
|
||||
return super(TypedObjectManager, self).filter(**kwargs)
|
||||
|
||||
def all(self, **kwargs):
|
||||
"""
|
||||
Overload method to return all matches, filtering for typeclass
|
||||
Overload method to return all matches, filtering for typeclass.
|
||||
|
||||
Kwargs:
|
||||
kwargs (any): These are passed on as normal arguments
|
||||
to the default django all method (usually none are given).
|
||||
Returns:
|
||||
objects (list): The objects found.
|
||||
|
||||
"""
|
||||
return super(TypedObjectManager, self).all(**kwargs).filter(db_typeclass_path=self.model.path)
|
||||
|
||||
def _get_subclasses(self, cls):
|
||||
"""
|
||||
Recursively get all subclasses to a class
|
||||
Recursively get all subclasses to a class.
|
||||
"""
|
||||
all_subclasses = cls.__subclasses__()
|
||||
for subclass in all_subclasses:
|
||||
|
|
@ -353,8 +561,19 @@ class TypeclassManager(TypedObjectManager):
|
|||
|
||||
def get_family(self, **kwargs):
|
||||
"""
|
||||
Variation of get that not only returns the current
|
||||
typeclass but also all subclasses of that typeclass.
|
||||
Variation of get that not only returns the current typeclass
|
||||
but also all subclasses of that typeclass.
|
||||
|
||||
Kwargs:
|
||||
kwargs (any): These are passed on as normal arguments
|
||||
to the default django get method.
|
||||
Returns:
|
||||
objects (list): The objects found.
|
||||
|
||||
Raises:
|
||||
ObjectNotFound: The exact name of this exception depends
|
||||
on the model base used.
|
||||
|
||||
"""
|
||||
paths = [self.model.path] + ["%s.%s" % (cls.__module__, cls.__name__)
|
||||
for cls in self._get_subclasses(self.model)]
|
||||
|
|
@ -365,6 +584,13 @@ class TypeclassManager(TypedObjectManager):
|
|||
"""
|
||||
Variation of filter that allows results both from typeclass
|
||||
and from subclasses of typeclass
|
||||
|
||||
Kwargs:
|
||||
kwargs (any): These are passed on as normal arguments
|
||||
to the default django filter method.
|
||||
Returns:
|
||||
objects (list): The objects found.
|
||||
|
||||
"""
|
||||
# query, including all subclasses
|
||||
paths = [self.model.path] + ["%s.%s" % (cls.__module__, cls.__name__)
|
||||
|
|
@ -376,6 +602,13 @@ class TypeclassManager(TypedObjectManager):
|
|||
"""
|
||||
Return all matches, allowing matches from all subclasses of
|
||||
the typeclass.
|
||||
|
||||
Kwargs:
|
||||
kwargs (any): These are passed on as normal arguments
|
||||
to the default django all method (usually none are given).
|
||||
Returns:
|
||||
objects (list): The objects found.
|
||||
|
||||
"""
|
||||
paths = [self.model.path] + ["%s.%s" % (cls.__module__, cls.__name__)
|
||||
for cls in self._get_subclasses(self.model)]
|
||||
|
|
|
|||
|
|
@ -371,10 +371,16 @@ class TypedObject(SharedMemoryModel):
|
|||
loaded) typeclass - can be a class object or the python path
|
||||
to such an object to match against.
|
||||
|
||||
typeclass - a class or the full python path to the class
|
||||
exact - returns true only
|
||||
if the object's type is exactly this typeclass, ignoring
|
||||
parents.
|
||||
Args:
|
||||
typeclass (str or class): A class or the full python path
|
||||
to the class to check.
|
||||
exact (bool, optional): Returns true only if the object's
|
||||
type is exactly this typeclass, ignoring parents.
|
||||
|
||||
Returns:
|
||||
is_typeclass (bool): If this typeclass matches the given
|
||||
typeclass.
|
||||
|
||||
"""
|
||||
if isinstance(typeclass, basestring):
|
||||
typeclass = [typeclass] + ["%s.%s" % (prefix, typeclass) for prefix in settings.TYPECLASS_PATHS]
|
||||
|
|
@ -405,24 +411,24 @@ class TypedObject(SharedMemoryModel):
|
|||
to create a new object and just swap the player over to
|
||||
that one instead.
|
||||
|
||||
Arguments:
|
||||
new_typeclass (path/classobj) - type to switch to
|
||||
clean_attributes (bool/list) - will delete all attributes
|
||||
stored on this object (but not any
|
||||
of the database fields such as name or
|
||||
location). You can't get attributes back,
|
||||
but this is often the safest bet to make
|
||||
sure nothing in the new typeclass clashes
|
||||
with the old one. If you supply a list,
|
||||
only those named attributes will be cleared.
|
||||
run_start_hooks - trigger the start hooks of the object, as if
|
||||
it was created for the first time.
|
||||
no_default - if this is active, the swapper will not allow for
|
||||
swapping to a default typeclass in case the given
|
||||
one fails for some reason. Instead the old one
|
||||
will be preserved.
|
||||
Args:
|
||||
new_typeclass (str or classobj): Type to switch to.
|
||||
clean_attributes (bool or list, optional): Will delete all
|
||||
attributes stored on this object (but not any of the
|
||||
database fields such as name or location). You can't get
|
||||
attributes back, but this is often the safest bet to make
|
||||
sure nothing in the new typeclass clashes with the old
|
||||
one. If you supply a list, only those named attributes
|
||||
will be cleared.
|
||||
run_start_hooks (bool, optional): Trigger the start hooks
|
||||
of the object, as if it was created for the first time.
|
||||
no_default (bool, optiona): If set, the swapper will not
|
||||
allow for swapping to a default typeclass in case the
|
||||
given one fails for some reason. Instead the old one will
|
||||
be preserved.
|
||||
Returns:
|
||||
boolean True/False depending on if the swap worked or not.
|
||||
result (bool): True/False depending on if the swap worked
|
||||
or not.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -470,12 +476,15 @@ class TypedObject(SharedMemoryModel):
|
|||
Args:
|
||||
accessing_obj (str): Object trying to access this one.
|
||||
access_type (str, optional): Type of access sought.
|
||||
default (bool, optional): What to return if no lock of access_type was found
|
||||
no_superuser_bypass (bool, optional): Turn off the superuser lock bypass (be careful with this one).
|
||||
default (bool, optional): What to return if no lock of
|
||||
access_type was found
|
||||
no_superuser_bypass (bool, optional): Turn off the
|
||||
superuser lock bypass (be careful with this one).
|
||||
|
||||
Kwargs:
|
||||
kwargs (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.
|
||||
kwargs (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.
|
||||
|
||||
"""
|
||||
return self.locks.check(accessing_obj, access_type=access_type, default=default,
|
||||
|
|
@ -483,8 +492,15 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
def check_permstring(self, permstring):
|
||||
"""
|
||||
This explicitly checks if we hold particular permission without
|
||||
involving any locks.
|
||||
This explicitly checks if we hold particular permission
|
||||
without involving any locks.
|
||||
|
||||
Args:
|
||||
permstring (str): The permission string to check against.
|
||||
|
||||
Returns:
|
||||
result (bool): If the permstring is passed or not.
|
||||
|
||||
"""
|
||||
if hasattr(self, "player"):
|
||||
if self.player and self.player.is_superuser:
|
||||
|
|
@ -512,11 +528,16 @@ class TypedObject(SharedMemoryModel):
|
|||
#
|
||||
|
||||
def _deleted(self, *args, **kwargs):
|
||||
"Scrambling method for already deleted objects"
|
||||
"""
|
||||
Scrambling method for already deleted objects
|
||||
"""
|
||||
raise ObjectDoesNotExist("This object was already deleted!")
|
||||
|
||||
def delete(self):
|
||||
"Cleaning up handlers on the typeclass level"
|
||||
"""
|
||||
Cleaning up handlers on the typeclass level
|
||||
|
||||
"""
|
||||
global TICKER_HANDLER
|
||||
if not TICKER_HANDLER:
|
||||
from evennia.scripts.tickerhandler import TICKER_HANDLER
|
||||
|
|
@ -615,16 +636,20 @@ class TypedObject(SharedMemoryModel):
|
|||
Displays the name of the object in a viewer-aware manner.
|
||||
|
||||
Args:
|
||||
looker (TypedObject): The object or player that is looking at/getting inforamtion for this object.
|
||||
looker (TypedObject): The object or player that is looking
|
||||
at/getting inforamtion for this object.
|
||||
|
||||
Returns:
|
||||
A string containing the name of the object, including the DBREF if this user is privileged to control
|
||||
said object.
|
||||
name (str): A string containing the name of the object,
|
||||
including the DBREF if this user is privileged to control
|
||||
said object.
|
||||
|
||||
Notes:
|
||||
This function could be extended to change how object names
|
||||
appear to users in character, but be wary. This function does not change an object's keys or
|
||||
aliases when searching, and is expected to produce something useful for builders.
|
||||
appear to users in character, but be wary. This function
|
||||
does not change an object's keys or aliases when
|
||||
searching, and is expected to produce something useful for
|
||||
builders.
|
||||
|
||||
"""
|
||||
if self.access(looker, access_type='controls'):
|
||||
|
|
@ -633,18 +658,22 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
def get_extra_info(self, looker, **kwargs):
|
||||
"""
|
||||
Used when an object is in a list of ambiguous objects as an additional
|
||||
information tag.
|
||||
Used when an object is in a list of ambiguous objects as an
|
||||
additional information tag.
|
||||
|
||||
For instance, if you had potions which could have varying levels of liquid
|
||||
left in them, you might want to display how many drinks are left in each when
|
||||
selecting which to drop, but not in your normal inventory listing.
|
||||
For instance, if you had potions which could have varying
|
||||
levels of liquid left in them, you might want to display how
|
||||
many drinks are left in each when selecting which to drop, but
|
||||
not in your normal inventory listing.
|
||||
|
||||
Args:
|
||||
looker (TypedObject): The object or player that is looking at/getting information for this object.
|
||||
looker (TypedObject): The object or player that is looking
|
||||
at/getting information for this object.
|
||||
|
||||
Returns:
|
||||
A string with disambiguating information, conventionally with a leading space.
|
||||
info (str): A string with disambiguating information,
|
||||
conventionally with a leading space.
|
||||
|
||||
"""
|
||||
|
||||
if self.location == looker:
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
"""
|
||||
Tags are entities that are attached to objects like Attributes but
|
||||
which are unique to an individual object - any number of objects
|
||||
can have the same Tag attached to them.
|
||||
Tags are entities that are attached to objects in the same way as
|
||||
Attributes. But contrary to Attributes, which are unique to an
|
||||
individual object, a single Tag can be attached to any number of
|
||||
objects at the same time.
|
||||
|
||||
Tags are used for tagging, obviously, but the data structure
|
||||
is also used for storing Aliases and Permissions. This module
|
||||
contains the respective handlers.
|
||||
Tags are used for tagging, obviously, but the data structure is also
|
||||
used for storing Aliases and Permissions. This module contains the
|
||||
respective handlers.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -24,24 +25,26 @@ _TYPECLASS_AGGRESSIVE_CACHE = settings.TYPECLASS_AGGRESSIVE_CACHE
|
|||
|
||||
class Tag(models.Model):
|
||||
"""
|
||||
Tags are quick markers for objects in-game. An typeobject
|
||||
can have any number of tags, stored via its db_tags property.
|
||||
Tagging similar objects will make it easier to quickly locate the
|
||||
group later (such as when implementing zones). The main advantage
|
||||
of tagging as opposed to using Attributes is speed; a tag is very
|
||||
Tags are quick markers for objects in-game. An typeobject can have
|
||||
any number of tags, stored via its db_tags property. Tagging
|
||||
similar objects will make it easier to quickly locate the group
|
||||
later (such as when implementing zones). The main advantage of
|
||||
tagging as opposed to using Attributes is speed; a tag is very
|
||||
limited in what data it can hold, and the tag key+category is
|
||||
indexed for efficient lookup in the database. Tags are shared between
|
||||
objects - a new tag is only created if the key+category combination
|
||||
did not previously exist, making them unsuitable for storing
|
||||
object-related data (for this a full Attribute
|
||||
should be used).
|
||||
The 'db_data' field is intended as a documentation
|
||||
field for the tag itself, such as to document what this tag+category
|
||||
stands for and display that in a web interface or similar.
|
||||
indexed for efficient lookup in the database. Tags are shared
|
||||
between objects - a new tag is only created if the key+category
|
||||
combination did not previously exist, making them unsuitable for
|
||||
storing object-related data (for this a full Attribute should be
|
||||
used).
|
||||
|
||||
The 'db_data' field is intended as a documentation field for the
|
||||
tag itself, such as to document what this tag+category stands for
|
||||
and display that in a web interface or similar.
|
||||
|
||||
The main default use for Tags is to implement Aliases for objects.
|
||||
this uses the 'aliases' tag category, which is also checked by the
|
||||
default search functions of Evennia to allow quick searches by alias.
|
||||
|
||||
"""
|
||||
db_key = models.CharField('key', max_length=255, null=True,
|
||||
help_text="tag identifier", db_index=True)
|
||||
|
|
@ -74,15 +77,20 @@ class Tag(models.Model):
|
|||
class TagHandler(object):
|
||||
"""
|
||||
Generic tag-handler. Accessed via TypedObject.tags.
|
||||
|
||||
"""
|
||||
_m2m_fieldname = "db_tags"
|
||||
_tagtype = None
|
||||
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
Tags are stored internally in the TypedObject.db_tags m2m field
|
||||
with an tag.db_model based on the obj the taghandler is stored on
|
||||
and with a tagtype given by self.handlertype
|
||||
Tags are stored internally in the TypedObject.db_tags m2m
|
||||
field with an tag.db_model based on the obj the taghandler is
|
||||
stored on and with a tagtype given by self.handlertype
|
||||
|
||||
Args:
|
||||
obj (object): The object on which the handler is set.
|
||||
|
||||
"""
|
||||
self.obj = obj
|
||||
self._objid = obj.id
|
||||
|
|
@ -90,7 +98,10 @@ class TagHandler(object):
|
|||
self._cache = None
|
||||
|
||||
def _recache(self):
|
||||
"Cache all tags of this object"
|
||||
"""
|
||||
Cache all tags of this object.
|
||||
|
||||
"""
|
||||
query = {"%s__id" % self._model : self._objid,
|
||||
"tag__db_tagtype" : self._tagtype}
|
||||
tagobjs = [conn.tag for conn in getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)]
|
||||
|
|
@ -99,7 +110,23 @@ class TagHandler(object):
|
|||
tagobj) for tagobj in tagobjs)
|
||||
|
||||
def add(self, tag=None, category=None, data=None):
|
||||
"Add a new tag to the handler. Tag is a string or a list of strings."
|
||||
"""
|
||||
Add a new tag to the handler.
|
||||
|
||||
Args:
|
||||
tag (str or list): The name of the tag to add. If a list,
|
||||
add several Tags.
|
||||
category (str, optional): Category of Tag. `None` is the default category.
|
||||
data (str, optional): Info text about the tag(s) added.
|
||||
This can not be used to store object-unique info but only
|
||||
eventual info about the text itself.
|
||||
|
||||
Notes:
|
||||
If the tag + category combination matches an already
|
||||
existing Tag object, this will be re-used and no new Tag
|
||||
will be created.
|
||||
|
||||
"""
|
||||
if not tag:
|
||||
return
|
||||
for tagstr in make_iter(tag):
|
||||
|
|
@ -121,9 +148,21 @@ class TagHandler(object):
|
|||
|
||||
def get(self, key, category=None, return_tagobj=False):
|
||||
"""
|
||||
Get the tag for the given key or list of tags. If
|
||||
return_data=True, return the matching Tag objects instead.
|
||||
Returns a single tag if a unique match, otherwise a list
|
||||
Get the tag for the given key or list of tags.
|
||||
|
||||
Args:
|
||||
key (str or list): The tag or tags to retrieve.
|
||||
category (str, optional): The Tag category to limit the
|
||||
request to. Note that `None` is the valid, default
|
||||
category.
|
||||
return_tagobj (bool, optional): Return the Tag object itself
|
||||
instead of a string representation of the Tag.
|
||||
|
||||
Returns:
|
||||
tags (str, TagObject or list): The matches, either string
|
||||
representations of the tags or the Tag objects themselves
|
||||
depending on `return_tagobj`.
|
||||
|
||||
"""
|
||||
if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE:
|
||||
self._recache()
|
||||
|
|
@ -135,7 +174,16 @@ class TagHandler(object):
|
|||
return ret[0] if len(ret) == 1 else ret
|
||||
|
||||
def remove(self, key, category=None):
|
||||
"Remove a tag from the handler based ond key and category."
|
||||
"""
|
||||
Remove a tag from the handler based ond key and category.
|
||||
|
||||
Args:
|
||||
key (str or list): The tag or tags to retrieve.
|
||||
category (str, optional): The Tag category to limit the
|
||||
request to. Note that `None` is the valid, default
|
||||
category.
|
||||
|
||||
"""
|
||||
for key in make_iter(key):
|
||||
if not (key or key.strip()): # we don't allow empty tags
|
||||
continue
|
||||
|
|
@ -151,8 +199,13 @@ class TagHandler(object):
|
|||
|
||||
def clear(self, category=None):
|
||||
"""
|
||||
Remove all tags from the handle. Optionally, only remove those within
|
||||
a certain category.
|
||||
Remove all tags from the handler.
|
||||
|
||||
Args:
|
||||
category (str, optional): The Tag category to limit the
|
||||
request to. Note that `None` is the valid, default
|
||||
category.
|
||||
|
||||
"""
|
||||
if not category:
|
||||
getattr(self.obj, self._m2m_fieldname).clear()
|
||||
|
|
@ -163,8 +216,19 @@ class TagHandler(object):
|
|||
def all(self, category=None, return_key_and_category=False):
|
||||
"""
|
||||
Get all tags in this handler.
|
||||
If category is given, return only Tags with this category. If
|
||||
return_keys_and_categories is set, return a list of tuples [(key, category), ...]
|
||||
|
||||
Args:
|
||||
category (str, optional): The Tag category to limit the
|
||||
request to. Note that `None` is the valid, default
|
||||
category.
|
||||
return_key_and_category (bool, optional): Return a list of
|
||||
tuples `[(key, category), ...]`.
|
||||
|
||||
Returns:
|
||||
tags (list): A list of tag keys `[tagkey, tagkey, ...]` or
|
||||
a list of tuples `[(key, category), ...]` if
|
||||
`return_key_and_category` is set.
|
||||
|
||||
"""
|
||||
if self._cache is None or not _TYPECLASS_AGGRESSIVE_CACHE:
|
||||
self._recache()
|
||||
|
|
@ -191,9 +255,17 @@ class TagHandler(object):
|
|||
|
||||
|
||||
class AliasHandler(TagHandler):
|
||||
"""
|
||||
A handler for the Alias Tag type.
|
||||
|
||||
"""
|
||||
_tagtype = "alias"
|
||||
|
||||
|
||||
class PermissionHandler(TagHandler):
|
||||
"""
|
||||
A handler for the Permission Tag type.
|
||||
|
||||
"""
|
||||
_tagtype = "permission"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue