PEP8 cleanup of the entire codebase. Unchanged are many cases of too-long lines, partly because of the rewrite they would require but also because splitting many lines up would make the code harder to read. Also the third-party libraries (idmapper, prettytable etc) were not cleaned.

This commit is contained in:
Griatch 2013-11-14 19:31:17 +01:00
parent 30b7d2a405
commit 1ae17bcbe4
154 changed files with 5613 additions and 4054 deletions

View file

@ -1,140 +1,138 @@
#
# This sets up how models are displayed
# in the web admin interface.
#
from django import forms
from django.conf import settings
from django.contrib import admin
from src.typeclasses.models import Attribute, Tag
from src.objects.models import ObjectDB
class AttributeInline(admin.TabularInline):
# This class is currently not used, because PickleField objects are not editable.
# It's here for us to ponder making a way that allows them to be edited.
model = Attribute
fields = ('db_key', 'db_value')
extra = 0
class TagInline(admin.TabularInline):
model = ObjectDB.db_tags.through
raw_id_fields = ('tag',)
extra = 0
class TagAdmin(admin.ModelAdmin):
fields = ('db_key', 'db_category', 'db_data')
class ObjectCreateForm(forms.ModelForm):
"This form details the look of the fields"
class Meta:
model = ObjectDB
db_key = forms.CharField(label="Name/Key",
widget=forms.TextInput(attrs={'size':'78'}),
help_text="Main identifier, like 'apple', 'strong guy', 'Elizabeth' etc. If creating a Character, check so the name is unique among characters!",)
db_typeclass_path = forms.CharField(label="Typeclass",
initial=settings.BASE_OBJECT_TYPECLASS,
widget=forms.TextInput(attrs={'size':'78'}),
help_text="This defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass. If you are creating a Character you should use the typeclass defined by settings.BASE_CHARACTER_TYPECLASS or one derived from that.")
#db_permissions = forms.CharField(label="Permissions",
# initial=settings.PERMISSION_PLAYER_DEFAULT,
# required=False,
# widget=forms.TextInput(attrs={'size':'78'}),
# help_text="a comma-separated list of text strings checked by certain locks. They are mainly of use for Character objects. Character permissions overload permissions defined on a controlling Player. Most objects normally don't have any permissions defined.")
db_cmdset_storage = forms.CharField(label="CmdSet",
initial="",
required=False,
widget=forms.TextInput(attrs={'size':'78'}),
help_text="Most non-character objects don't need a cmdset and can leave this field blank.")
raw_id_fields = ('db_destination', 'db_location', 'db_home')
class ObjectEditForm(ObjectCreateForm):
"Form used for editing. Extends the create one with more fields"
db_lock_storage = forms.CharField(label="Locks",
required=False,
widget=forms.Textarea(attrs={'cols':'100', 'rows':'2'}),
help_text="In-game lock definition string. If not given, defaults will be used. This string should be on the form <i>type:lockfunction(args);type2:lockfunction2(args);...")
class ObjectDBAdmin(admin.ModelAdmin):
list_display = ('id', 'db_key', 'db_player', 'db_typeclass_path')
list_display_links = ('id', 'db_key')
ordering = ['db_player', 'db_typeclass_path', 'id']
search_fields = ['^db_key', 'db_typeclass_path']
raw_id_fields = ('db_destination', 'db_location', 'db_home')
save_as = True
save_on_top = True
list_select_related = True
list_filter = ('db_typeclass_path',)
#list_filter = ('db_permissions', 'db_typeclass_path')
# editing fields setup
form = ObjectEditForm
fieldsets = (
(None, {
'fields': (('db_key','db_typeclass_path'), ('db_lock_storage', ),
('db_location', 'db_home'), 'db_destination','db_cmdset_storage'
)}),
)
#fieldsets = (
# (None, {
# 'fields': (('db_key','db_typeclass_path'), ('db_permissions', 'db_lock_storage'),
# ('db_location', 'db_home'), 'db_destination','db_cmdset_storage'
# )}),
# )
#deactivated temporarily, they cause empty objects to be created in admin
inlines = [TagInline]
# Custom modification to give two different forms wether adding or not.
add_form = ObjectCreateForm
add_fieldsets = (
(None, {
'fields': (('db_key','db_typeclass_path'),
('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
)}),
)
#add_fieldsets = (
# (None, {
# 'fields': (('db_key','db_typeclass_path'), 'db_permissions',
# ('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
# )}),
# )
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
return super(ObjectDBAdmin, self).get_fieldsets(request, obj)
def get_form(self, request, obj=None, **kwargs):
"""
Use special form during creation
"""
defaults = {}
if obj is None:
defaults.update({
'form': self.add_form,
'fields': admin.util.flatten_fieldsets(self.add_fieldsets),
})
defaults.update(kwargs)
return super(ObjectDBAdmin, self).get_form(request, obj, **defaults)
def save_model(self, request, obj, form, change):
obj.save()
if not change:
# adding a new object
obj = obj.typeclass
obj.basetype_setup()
obj.basetype_posthook_setup()
obj.at_object_creation()
obj.at_init()
admin.site.register(ObjectDB, ObjectDBAdmin)
admin.site.register(Tag, TagAdmin)
#
# This sets up how models are displayed
# in the web admin interface.
#
from django import forms
from django.conf import settings
from django.contrib import admin
from src.typeclasses.models import Attribute, Tag
from src.objects.models import ObjectDB
class AttributeInline(admin.TabularInline):
# This class is currently not used, because PickleField objects are
# not editable. It's here for us to ponder making a way that allows
# them to be edited.
model = Attribute
fields = ('db_key', 'db_value')
extra = 0
class TagInline(admin.TabularInline):
model = ObjectDB.db_tags.through
raw_id_fields = ('tag',)
extra = 0
class TagAdmin(admin.ModelAdmin):
fields = ('db_key', 'db_category', 'db_data')
class ObjectCreateForm(forms.ModelForm):
"This form details the look of the fields"
class Meta:
model = ObjectDB
db_key = forms.CharField(label="Name/Key",
widget=forms.TextInput(attrs={'size': '78'}),
help_text="Main identifier, like 'apple', 'strong guy', 'Elizabeth' etc. If creating a Character, check so the name is unique among characters!",)
db_typeclass_path = forms.CharField(label="Typeclass",
initial=settings.BASE_OBJECT_TYPECLASS,
widget=forms.TextInput(attrs={'size': '78'}),
help_text="This defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass. If you are creating a Character you should use the typeclass defined by settings.BASE_CHARACTER_TYPECLASS or one derived from that.")
db_cmdset_storage = forms.CharField(label="CmdSet",
initial="",
required=False,
widget=forms.TextInput(attrs={'size': '78'}),
help_text="Most non-character objects don't need a cmdset and can leave this field blank.")
raw_id_fields = ('db_destination', 'db_location', 'db_home')
class ObjectEditForm(ObjectCreateForm):
"Form used for editing. Extends the create one with more fields"
db_lock_storage = forms.CharField(label="Locks",
required=False,
widget=forms.Textarea(attrs={'cols':'100', 'rows':'2'}),
help_text="In-game lock definition string. If not given, defaults will be used. This string should be on the form <i>type:lockfunction(args);type2:lockfunction2(args);...")
class ObjectDBAdmin(admin.ModelAdmin):
list_display = ('id', 'db_key', 'db_player', 'db_typeclass_path')
list_display_links = ('id', 'db_key')
ordering = ['db_player', 'db_typeclass_path', 'id']
search_fields = ['^db_key', 'db_typeclass_path']
raw_id_fields = ('db_destination', 'db_location', 'db_home')
save_as = True
save_on_top = True
list_select_related = True
list_filter = ('db_typeclass_path',)
#list_filter = ('db_permissions', 'db_typeclass_path')
# editing fields setup
form = ObjectEditForm
fieldsets = (
(None, {
'fields': (('db_key','db_typeclass_path'), ('db_lock_storage', ),
('db_location', 'db_home'), 'db_destination','db_cmdset_storage'
)}),
)
#fieldsets = (
# (None, {
# 'fields': (('db_key','db_typeclass_path'), ('db_permissions', 'db_lock_storage'),
# ('db_location', 'db_home'), 'db_destination','db_cmdset_storage'
# )}),
# )
#deactivated temporarily, they cause empty objects to be created in admin
inlines = [TagInline]
# Custom modification to give two different forms wether adding or not.
add_form = ObjectCreateForm
add_fieldsets = (
(None, {
'fields': (('db_key','db_typeclass_path'),
('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
)}),
)
#add_fieldsets = (
# (None, {
# 'fields': (('db_key','db_typeclass_path'), 'db_permissions',
# ('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
# )}),
# )
def get_fieldsets(self, request, obj=None):
if not obj:
return self.add_fieldsets
return super(ObjectDBAdmin, self).get_fieldsets(request, obj)
def get_form(self, request, obj=None, **kwargs):
"""
Use special form during creation
"""
defaults = {}
if obj is None:
defaults.update({
'form': self.add_form,
'fields': admin.util.flatten_fieldsets(self.add_fieldsets),
})
defaults.update(kwargs)
return super(ObjectDBAdmin, self).get_form(request, obj, **defaults)
def save_model(self, request, obj, form, change):
obj.save()
if not change:
# adding a new object
obj = obj.typeclass
obj.basetype_setup()
obj.basetype_posthook_setup()
obj.at_object_creation()
obj.at_init()
admin.site.register(ObjectDB, ObjectDBAdmin)
admin.site.register(Tag, TagAdmin)

View file

@ -21,6 +21,7 @@ _ATTR = None
_AT_MULTIMATCH_INPUT = utils.variable_from_module(*settings.SEARCH_AT_MULTIMATCH_INPUT.rsplit('.', 1))
class ObjectManager(TypedObjectManager):
"""
This ObjectManager implementes methods for searching
@ -43,7 +44,8 @@ class ObjectManager(TypedObjectManager):
get_objs_with_db_property_match
get_objs_with_key_or_alias
get_contents
object_search (interface to many of the above methods, equivalent to ev.search_object)
object_search (interface to many of the above methods,
equivalent to ev.search_object)
copy_object
"""
@ -93,8 +95,8 @@ class ObjectManager(TypedObjectManager):
@returns_typeclass_list
def get_objs_with_attr(self, attribute_name, candidates=None):
"""
Returns all objects having the given attribute_name defined at all. Location
should be a valid location object.
Returns all objects having the given attribute_name defined at all.
Location should be a valid location object.
"""
cand_restriction = candidates != None and Q(objattribute__db_obj__pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
return list(self.filter(cand_restriction & Q(objattribute__db_key=attribute_name)))
@ -178,10 +180,11 @@ class ObjectManager(TypedObjectManager):
return self.filter(db_location=location).exclude(exclude_restriction)
@returns_typeclass_list
def get_objs_with_key_or_alias(self, ostring, exact=True, candidates=None, typeclasses=None):
def get_objs_with_key_or_alias(self, ostring, exact=True,
candidates=None, typeclasses=None):
"""
Returns objects based on key or alias match. Will also do fuzzy matching based on
the utils.string_partial_matching function.
Returns objects based on key or alias match. Will also do fuzzy
matching based on the utils.string_partial_matching function.
candidates - list of candidate objects to restrict on
typeclasses - list of typeclass path strings to restrict on
"""
@ -191,7 +194,8 @@ class ObjectManager(TypedObjectManager):
else:
return []
if is_iter(candidates) and not len(candidates):
# if candidates is an empty iterable there can be no matches. Exit early.
# if candidates is an empty iterable there can be no matches
# Exit early.
return []
# build query objects
@ -231,33 +235,42 @@ class ObjectManager(TypedObjectManager):
candidates=None,
exact=True):
"""
Search as an object globally or in a list of candidates and return results. The result is always an Object.
Always returns a list.
Search as an object globally or in a list of candidates and return
results. The result is always an Object. Always returns a list.
Arguments:
searchdata: (str or obj) The entity to match for. This is usually a key string but may also be an object itself.
By default (if not attribute_name is set), this will search object.key and object.aliases in order. Can also
be on the form #dbref, which will, if exact=True be matched against primary key.
attribute_name: (str): Use this named ObjectAttribute to match searchdata against, instead
of the defaults. If this is the name of a database field (with or without the db_ prefix), that
will be matched too.
typeclass (str or TypeClass): restrict matches to objects having this typeclass. This will help
speed up global searches.
candidates (list obj ObjectDBs): If supplied, search will only be performed among the candidates
in this list. A common list of candidates is the contents of the current location searched.
exact (bool): Match names/aliases exactly or partially. Partial matching matches the
beginning of words in the names/aliases, using a matching routine to separate
multiple matches in names with multiple components (so "bi sw" will match
"Big sword"). Since this is more expensive than exact matching, it is
recommended to be used together with the objlist keyword to limit the number
of possibilities. This value has no meaning if searching for attributes/properties.
searchdata: (str or obj) The entity to match for. This is usually a
key string but may also be an object itself. By default (if
not attribute_name is set), this will search object.key and
object.aliases in order. Can also be on the form #dbref,
which will, if exact=True be matched against primary key.
attribute_name: (str): Use this named ObjectAttribute to match
searchdata against, instead of the defaults. If this is
the name of a database field (with or without the db_ prefix),
that will be matched too.
typeclass (str or TypeClass): restrict matches to objects having this
typeclass. This will help speed up global searches.
candidates (list obj ObjectDBs): If supplied, search will only be
performed among the candidates in this list. A common list
of candidates is the contents of the current location
searched.
exact (bool): Match names/aliases exactly or partially. Partial
matching matches the beginning of words in the names/aliases,
using a matching routine to separate multiple matches in
names with multiple components (so "bi sw" will match
"Big sword"). Since this is more expensive than exact
matching, it is recommended to be used together with the
objlist keyword to limit the number of possibilities. This
value has no meaning if searching for attributes/properties.
Returns:
A list of matching objects (or a list with one unique match)
"""
def _searcher(searchdata, candidates, typeclass, exact=False):
"Helper method for searching objects. typeclass is only used for global searching (no candidates)"
"""
Helper method for searching objects. typeclass is only used
for global searching (no candidates)
"""
if attribute_name:
# attribute/property search (always exact).
matches = self.get_objs_with_db_property_value(attribute_name, searchdata, candidates=candidates, typeclasses=typeclass)
@ -285,10 +298,11 @@ class ObjectManager(TypedObjectManager):
# Convenience check to make sure candidates are really dbobjs
candidates = [cand.dbobj for cand in make_iter(candidates) if cand]
if typeclass:
candidates = [cand for cand in candidates if _GA(cand, "db_typeclass_path") in typeclass]
candidates = [cand for cand in candidates
if _GA(cand, "db_typeclass_path") in typeclass]
dbref = not attribute_name and exact and self.dbref(searchdata)
if dbref != None:
if dbref is not None:
# Easiest case - dbref matching (always exact)
dbref_match = self.dbref_search(dbref)
if dbref_match:
@ -299,17 +313,19 @@ class ObjectManager(TypedObjectManager):
# Search through all possibilities.
match_number = None
# always run first check exact - we don't want partial matches if on the form of 1-keyword etc.
# always run first check exact - we don't want partial matches
# if on the form of 1-keyword etc.
matches = _searcher(searchdata, candidates, typeclass, exact=True)
if not matches:
# no matches found - check if we are dealing with N-keyword query - if so, strip it.
# no matches found - check if we are dealing with N-keyword
# query - if so, strip it.
match_number, searchdata = _AT_MULTIMATCH_INPUT(searchdata)
# run search again, with the exactness set by call
if match_number != None or not exact:
if match_number is not None or not exact:
matches = _searcher(searchdata, candidates, typeclass, exact=exact)
# deal with result
if len(matches) > 1 and match_number != None:
if len(matches) > 1 and match_number is not None:
# multiple matches, but a number was given to separate them
try:
matches = [matches[match_number]]
@ -324,11 +340,12 @@ class ObjectManager(TypedObjectManager):
def copy_object(self, original_object, new_key=None,
new_location=None, new_home=None,
new_permissions=None, new_locks=None, new_aliases=None, new_destination=None):
new_permissions=None, new_locks=None,
new_aliases=None, new_destination=None):
"""
Create and return a new object as a copy of the original object. All will
be identical to the original except for the arguments given specifically
to this method.
Create and return a new object as a copy of the original object. All
will be identical to the original except for the arguments given
specifically to this method.
original_object (obj) - the object to make a copy from
new_key (str) - name the copy differently from the original.
@ -358,9 +375,14 @@ class ObjectManager(TypedObjectManager):
# create new object
from src.utils import create
from src.scripts.models import ScriptDB
new_object = create.create_object(typeclass_path, key=new_key, location=new_location,
home=new_home, permissions=new_permissions,
locks=new_locks, aliases=new_aliases, destination=new_destination)
new_object = create.create_object(typeclass_path,
key=new_key,
location=new_location,
home=new_home,
permissions=new_permissions,
locks=new_locks,
aliases=new_aliases,
destination=new_destination)
if not new_object:
return None
@ -381,7 +403,6 @@ class ObjectManager(TypedObjectManager):
return new_object
def clear_all_sessids(self):
"""
Clear the db_sessid field of all objects having also the db_player field

View file

@ -18,17 +18,15 @@ import traceback
from django.db import models
from django.conf import settings
from src.typeclasses.models import TypedObject, TagHandler, NickHandler, AliasHandler, AttributeHandler
from src.server.caches import get_prop_cache, set_prop_cache
from src.typeclasses.typeclass import TypeClass
from src.typeclasses.models import (TypedObject, TagHandler, NickHandler,
AliasHandler, AttributeHandler)
from src.objects.manager import ObjectManager
from src.players.models import PlayerDB
from src.commands.cmdsethandler import CmdSetHandler
from src.commands import cmdhandler
from src.scripts.scripthandler import ScriptHandler
from src.utils import logger
from src.utils.utils import make_iter, to_str, to_unicode, variable_from_module, inherits_from
from src.utils.utils import make_iter, to_str, to_unicode, variable_from_module
from django.utils.translation import ugettext as _
@ -46,6 +44,7 @@ _ME = _("me")
_SELF = _("self")
_HERE = _("here")
#------------------------------------------------------------
#
# ObjectDB
@ -98,9 +97,10 @@ class ObjectDB(TypedObject):
# db_key (also 'name' works), db_typeclass_path, db_date_created,
# db_permissions
#
# These databse fields (including the inherited ones) should normally be set
# using their corresponding wrapper properties, named same as the field, but without
# the db_* prefix (e.g. the db_key field is set with self.key instead). The wrappers
# These databse fields (including the inherited ones) should normally be
# managed by their corresponding wrapper properties, named same as the
# field, but without the db_* prefix (e.g. the db_key field is set with
# self.key instead). The wrappers are created at the metaclass level and
# will automatically save and cache the data more efficiently.
# If this is a character object, the player is connected here.
@ -112,7 +112,7 @@ class ObjectDB(TypedObject):
# The location in the game world. Since this one is likely
# to change often, we set this with the 'location' property
# to transparently handle Typeclassing.
db_location = models.ForeignKey('self', related_name="locations_set",db_index=True,
db_location = models.ForeignKey('self', related_name="locations_set", db_index=True,
blank=True, null=True, verbose_name='game location')
# a safety location, this usually don't change much.
db_home = models.ForeignKey('self', related_name="homes_set",
@ -158,13 +158,19 @@ class ObjectDB(TypedObject):
# seems very sensitive to caching, so leaving it be for now. /Griatch
#@property
def __cmdset_storage_get(self):
"Getter. Allows for value = self.name. Returns a list of cmdset_storage."
"""
Getter. Allows for value = self.name.
Returns a list of cmdset_storage.
"""
storage = _GA(self, "db_cmdset_storage")
# we need to check so storage is not None
return [path.strip() for path in storage.split(',')] if storage else []
return [path.strip() for path in storage.split(',')] if storage else []
#@cmdset_storage.setter
def __cmdset_storage_set(self, value):
"Setter. Allows for self.name = value. Stores as a comma-separated string."
"""
Setter. Allows for self.name = value.
Stores as a comma-separated string.
"""
_SA(self, "db_cmdset_storage", ",".join(str(val).strip() for val in make_iter(value)))
_GA(self, "save")()
#@cmdset_storage.deleter
@ -236,14 +242,13 @@ class ObjectDB(TypedObject):
if exi.destination]
exits = property(__exits_get)
#
# Main Search method
#
def search(self, searchdata,
global_search=False,
use_nicks=True, # should this default to off?
use_nicks=True, # should this default to off?
typeclass=None,
location=None,
attribute_name=None,
@ -259,33 +264,46 @@ class ObjectDB(TypedObject):
Inputs:
searchdata (str or obj): Primary search criterion. Will be matched against object.key (with object.aliases second)
unless the keyword attribute_name specifies otherwise. Special strings:
#<num> - search by unique dbref. This is always a global search.
searchdata (str or obj): Primary search criterion. Will be matched
against object.key (with object.aliases second) unless
the keyword attribute_name specifies otherwise.
Special strings:
#<num> - search by unique dbref. This is always
a global search.
me,self - self-reference to this object
<num>-<string> - can be used to differentiate between multiple same-named matches
global_search (bool): Search all objects globally. This is overruled by "location" keyword.
use_nicks (bool): Use nickname-replace (nicktype "object") on the search string
typeclass (str or Typeclass, or list of either): Limit search only to Objects with this typeclass. May
be a list of typeclasses for a broader search.
location (Object): Specify a location to search, if different from the self's given location
plus its contents. This can also be a list of locations.
attribute_name (str): Define which property to search. If set, no key+alias search will be performed. This can be used to
search database fields (db_ will be automatically appended), and if that fails, it will try to
return objects having Attributes with this name and value equal to searchdata. A special
use is to search for "key" here if you want to do a key-search without including aliases.
quiet (bool) - don't display default error messages - return multiple matches as a list and
no matches as None. If not set (default), will echo error messages and return None.
exact (bool) - if unset (default) - prefers to match to beginning of string rather than not matching
at all. If set, requires exact mathing of entire string.
<num>-<string> - can be used to differentiate
between multiple same-named matches
global_search (bool): Search all objects globally. This is overruled
by "location" keyword.
use_nicks (bool): Use nickname-replace (nicktype "object") on the
search string
typeclass (str or Typeclass, or list of either): Limit search only
to Objects with this typeclass. May be a list of typeclasses
for a broader search.
location (Object): Specify a location to search, if different from the
self's given location plus its contents. This can also
be a list of locations.
attribute_name (str): Define which property to search. If set, no
key+alias search will be performed. This can be used to
search database fields (db_ will be automatically
appended), and if that fails, it will try to return
objects having Attributes with this name and value
equal to searchdata. A special use is to search for
"key" here if you want to do a key-search without
including aliases.
quiet (bool) - don't display default error messages - return multiple
matches as a list and no matches as None. If not
set (default), will echo error messages and return None.
exact (bool) - if unset (default) - prefers to match to beginning of
string rather than not matching at all. If set, requires
exact mathing of entire string.
Returns:
quiet=False (default):
no match or multimatch:
auto-echoes errors to self.msg, then returns None
(results are handled by modules set by settings.SEARCH_AT_RESULT
and settings.SEARCH_AT_MULTIMATCH_INPUT)
auto-echoes errors to self.msg, then returns None
(results are handled by settings.SEARCH_AT_RESULT
and settings.SEARCH_AT_MULTIMATCH_INPUT)
match:
a unique object match
quiet=True:
@ -315,8 +333,10 @@ class ObjectDB(TypedObject):
break
candidates=None
if global_search or (is_string and searchdata.startswith("#") and len(searchdata) > 1 and searchdata[1:].isdigit()):
# only allow exact matching if searching the entire database or unique #dbrefs
if(global_search or (is_string and searchdata.startswith("#") and
len(searchdata) > 1 and searchdata[1:].isdigit())):
# only allow exact matching if searching the entire database
# or unique #dbrefs
exact = True
elif location:
# location(s) were given
@ -324,13 +344,15 @@ class ObjectDB(TypedObject):
for obj in make_iter(location):
candidates.extend([o.dbobj for o in obj.contents])
else:
# local search. Candidates are self.contents, self.location and self.location.contents
# local search. Candidates are self.contents, self.location
# and self.location.contents
location = self.location
candidates = self.contents
if location:
candidates = candidates + [location] + location.contents
else:
candidates.append(self) # normally we are included in location.contents
# normally we are included in location.contents
candidates.append(self)
# db manager expects database objects
candidates = [obj.dbobj for obj in candidates]
@ -360,23 +382,24 @@ class ObjectDB(TypedObject):
def execute_cmd(self, raw_string, sessid=None):
"""
Do something as this object. This method is a copy of the execute_cmd method on the
session. This is never called normally, it's only used when wanting specifically to
let an object be the caller of a command. It makes use of nicks of eventual connected
players as well.
Do something as this object. This method is a copy of the execute_
cmd method on the session. This is never called normally, it's only
used when wanting specifically to let an object be the caller of a
command. It makes use of nicks of eventual connected players as well.
Argument:
raw_string (string) - raw command input
sessid (int) - optional session id to return results to
Returns Deferred - this is an asynchronous Twisted object that will
not fire until the command has actually finished executing. To overload
this one needs to attach callback functions to it, with addCallback(function).
This function will be called with an eventual return value from the command
execution.
not fire until the command has actually finished executing. To
overload this one needs to attach callback functions to it, with
addCallback(function). This function will be called with an
eventual return value from the command execution.
This return is not used at all by Evennia by default, but might be useful
for coders intending to implement some sort of nested command structure.
This return is not used at all by Evennia by default, but might
be useful for coders intending to implement some sort of nested
command structure.
"""
# nick replacement - we require full-word matching.
@ -384,7 +407,8 @@ class ObjectDB(TypedObject):
raw_string = to_unicode(raw_string)
raw_list = raw_string.split(None)
raw_list = [" ".join(raw_list[:i+1]) for i in range(len(raw_list)) if raw_list[:i+1]]
raw_list = [" ".join(raw_list[:i + 1]) for i in range(len(raw_list))
if raw_list[:i + 1]]
# fetch the nick data efficiently
nicks = self.db_attributes.filter(db_category__in=("nick_inputline", "nick_channel"))
if self.has_player:
@ -416,7 +440,6 @@ class ObjectDB(TypedObject):
if "data" in kwargs:
# deprecation warning
from src.utils import logger
logger.log_depmsg("ObjectDB.msg(): 'data'-dict keyword is deprecated. Use **kwargs instead.")
data = kwargs.pop("data")
if isinstance(data, dict):
@ -437,7 +460,8 @@ class ObjectDB(TypedObject):
"""
Emits something to all objects inside an object.
exclude is a list of objects not to send to. See self.msg() for more info.
exclude is a list of objects not to send to. See self.msg() for
more info.
"""
contents = _GA(self, "contents")
if exclude:
@ -454,22 +478,27 @@ class ObjectDB(TypedObject):
Moves this object to a new location. Note that if <destination> is an
exit object (i.e. it has "destination"!=None), the move_to will
happen to this destination and -not- into the exit object itself, unless
use_destination=False. Note that no lock checks are done by this function,
such things are assumed to have been handled before calling move_to.
use_destination=False. Note that no lock checks are done by this
function, such things are assumed to have been handled before calling
move_to.
destination: (Object) Reference to the object to move to. This
can also be an exit object, in which case the destination
property is used as destination.
quiet: (bool) If true, don't emit left/arrived messages.
emit_to_obj: (Object) object to receive error messages
use_destination (bool): Default is for objects to use the "destination" property
of destinations as the target to move to. Turning off this
keyword allows objects to move "inside" exit objects.
to_none - allow destination to be None. Note that no hooks are run when moving
to a None location. If you want to run hooks, run them manually.
use_destination (bool): Default is for objects to use the "destination"
property of destinations as the target to move to.
Turning off this keyword allows objects to move
"inside" exit objects.
to_none - allow destination to be None. Note that no hooks are run when
moving to a None location. If you want to run hooks,
run them manually (and make sure they can manage None
locations).
Returns True/False depending on if there were problems with the move. This method
may also return various error messages to the emit_to_obj.
Returns True/False depending on if there were problems with the move.
This method may also return various error messages to the
emit_to_obj.
"""
def logerr(string=""):
trc = traceback.format_exc()
@ -633,11 +662,13 @@ class ObjectDB(TypedObject):
def copy(self, new_key=None):
"""
Makes an identical copy of this object. If you want to customize the copy by
changing some settings, use ObjectDB.object.copy_object() directly.
Makes an identical copy of this object. If you want to customize the
copy by changing some settings, use ObjectDB.object.copy_object()
directly.
new_key (string) - new key/name of copied object. If new_key is not specified, the copy will be named
<old_key>_copy by default.
new_key (string) - new key/name of copied object. If new_key is not
specified, the copy will be named <old_key>_copy
by default.
Returns: Object (copy of this one)
"""
def find_clone_key():
@ -650,7 +681,8 @@ class ObjectDB(TypedObject):
key = _GA(self, "key")
num = 1
for obj in (obj for obj in self.location.contents
if obj.key.startswith(key) and obj.key.lstrip(key).isdigit()):
if obj.key.startswith(key) and
obj.key.lstrip(key).isdigit()):
num += 1
return "%s%03i" % (key, num)
new_key = new_key or find_clone_key()
@ -705,7 +737,7 @@ class ObjectDB(TypedObject):
_GA(self, "clear_exits")()
# Clear out any non-exit objects located within the object
_GA(self, "clear_contents")()
old_loc = _GA(self, "location")
#old_loc = _GA(self, "location")
# Perform the deletion of the object
super(ObjectDB, self).delete()
# clear object's old location's content cache of this object

View file

@ -25,6 +25,7 @@ _GA = object.__getattribute__
_SA = object.__setattr__
_DA = object.__delattr__
#
# Base class to inherit from.
#
@ -55,41 +56,53 @@ class Object(TypeClass):
key (string) - name of object
name (string) - same as key
aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings.
aliases (list of strings) - aliases to the object. Will be saved to
database as AliasDB entries but returned as strings.
dbref (int, read-only) - unique #id-number. Also "id" can be used.
dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class
typeclass (Object, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch.
dbobj (Object, read-only) - link to database model. dbobj.typeclass
points back to this class
typeclass (Object, read-only) - this links back to this class as an
identified only. Use self.swap_typeclass() to switch.
date_created (string) - time stamp of object creation
permissions (list of strings) - list of permission strings
player (Player) - controlling player (if any, only set together with sessid below)
sessid (int, read-only) - session id (if any, only set together with player above)
player (Player) - controlling player (if any, only set together with
sessid below)
sessid (int, read-only) - session id (if any, only set together with
player above)
location (Object) - current location. Is None if this is a room
home (Object) - safety start-location
sessions (list of Sessions, read-only) - returns all sessions connected to this object
sessions (list of Sessions, read-only) - returns all sessions
connected to this object
has_player (bool, read-only)- will only return *connected* players
contents (list of Objects, read-only) - returns all objects inside this object (including exits)
exits (list of Objects, read-only) - returns all exits from this object, if any
contents (list of Objects, read-only) - returns all objects inside
this object (including exits)
exits (list of Objects, read-only) - returns all exits from this
object, if any
destination (Object) - only set if this object is an exit.
is_superuser (bool, read-only) - True/False if this user is a superuser
* Handlers available
locks - lock-handler: use locks.add() to add new lock strings
db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr
ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data
db - attribute-handler: store/retrieve database attributes on this
self.db.myattr=val, val=self.db.myattr
ndb - non-persistent attribute handler: same as db but does not
create a database entry when storing data
scripts - script-handler. Add new scripts to object with scripts.add()
cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object
nicks - nick-handler. New nicks with nicks.add().
* Helper methods (see src.objects.objects.py for full headers)
search(ostring, global_search=False, global_dbref=False, attribute_name=None,
use_nicks=True, location=None, ignore_errors=False, player=False)
search(ostring, global_search=False, global_dbref=False,
attribute_name=None, use_nicks=True, location=None,
ignore_errors=False, player=False)
execute_cmd(raw_string)
msg(message, **kwargs)
msg_contents(message, exclude=None, from_obj=None, **kwargs)
move_to(destination, quiet=False, emit_to_obj=None, use_destination=True, to_none=False)
move_to(destination, quiet=False, emit_to_obj=None,
use_destination=True, to_none=False)
copy(new_key=None)
delete()
is_typeclass(typeclass, exact=False)
@ -99,42 +112,73 @@ class Object(TypeClass):
* Hook methods
basetype_setup() - only called once, used for behind-the-scenes setup. Normally not modified.
basetype_posthook_setup() - customization in basetype, after the object has been created; Normally not modified.
basetype_setup() - only called once, used for behind-the-scenes
setup. Normally not modified.
basetype_posthook_setup() - customization in basetype, after the
object has been created; Normally not modified.
at_object_creation() - only called once, when object is first created. Object customizations go here.
at_object_delete() - called just before deleting an object. If returning False, deletion is aborted. Note that all objects
inside a deleted object are automatically moved to their <home>, they don't need to be removed here.
at_object_creation() - only called once, when object is first created.
Object customizations go here.
at_object_delete() - called just before deleting an object. If
returning False, deletion is aborted. Note that
all objects inside a deleted object are
automatically moved to their <home>, they don't
need to be removed here.
at_init() - called whenever typeclass is cached from memory, at least once every server restart/reload
at_cmdset_get() - this is called just before the command handler requests a cmdset from this objecth
at_pre_puppet(player)- (player-controlled objects only) called just before puppeting
at_post_puppet() - (player-controlled objects only) called just after completing connection player<->object
at_pre_unpuppet() - (player-controlled objects only) called just before un-puppeting
at_post_unpuppet(player) - (player-controlled objects only) called just after disconnecting player<->object link
at_init() called whenever typeclass is cached from
memory, at least once every server restart/reload
at_cmdset_get() - this is called just before the command
handler requests a cmdset from this objecth
at_pre_puppet(player)- (player-controlled objects only) called just
before puppeting
at_post_puppet() - (player-controlled objects only) called just
after completing connection player<->object
at_pre_unpuppet() - (player-controlled objects only) called just
before un-puppeting
at_post_unpuppet(player) (player-controlled objects only) called
just after disconnecting player<->object link
at_server_reload() - called before server is reloaded
at_server_shutdown() - called just before server is fully shut down
at_before_move(destination) - called just before moving object to the destination. If returns False, move is cancelled.
announce_move_from(destination) - called in old location, just before move, if obj.move_to() has quiet=False
announce_move_to(source_location) - called in new location, just after move, if obj.move_to() has quiet=False
at_after_move(source_location) - always called after a move has been successfully performed.
at_object_leave(obj, target_location) - called when an object leaves this object in any fashion
at_object_receive(obj, source_location) - called when this object receives another object
at_before_move(destination) called just before moving
object to the destination. If returns
False, move is cancelled.
announce_move_from(destination) - called in old location, just before
move, if obj.move_to() has
quiet=False
announce_move_to(source_location) - called in new location,
just after move, if obj.move_to()
has quiet=False
at_after_move(source_location) - always called after a move
has been successfully performed.
at_object_leave(obj, target_location) - called when an object leaves
this object in any fashion
at_object_receive(obj, source_location) - called when this object
receives another object
at_before_traverse(traversing_object) - (exit-objects only) called just before an object traverses this object
at_after_traverse(traversing_object, source_location) - (exit-objects only) called just after a traversal has happened.
at_failed_traverse(traversing_object) - (exit-objects only) called if traversal fails and property err_traverse is not defined.
at_before_traverse(traversing_object) - (exit-objects only) called
just before an object
traverses this object
at_after_traverse(traversing_object, source_location) - (exit-objects
only) called just after a traversal has happened.
at_failed_traverse(traversing_object) - (exit-objects only) called
if traversal fails and property err_traverse is not defined.
at_msg_receive(self, msg, from_obj=None, data=None) - called when a message (via self.msg()) is sent to this obj.
If returns false, aborts send.
at_msg_send(self, msg, to_obj=None, data=None) - called when this objects sends a message to someone via self.msg().
at_msg_receive(self, msg, from_obj=None, data=None) - called when a
message (via self.msg()) is sent to this obj.
If returns false, aborts send.
at_msg_send(self, msg, to_obj=None, data=None) - called when this
objects sends a message to someone via self.msg().
return_appearance(looker) - describes this object. Used by "look" command by default
at_desc(looker=None) - called by 'look' whenever the appearance is requested.
at_get(getter) - called after object has been picked up. Does not stop pickup.
return_appearance(looker) - describes this object. Used by "look"
command by default
at_desc(looker=None) - called by 'look' whenever the appearance
is requested.
at_get(getter) - called after object has been picked up.
Does not stop pickup.
at_drop(dropper) - called when this object has been dropped.
at_say(speaker, message) - by default, called if an object inside this object speaks
at_say(speaker, message) - by default, called if an object inside
this object speaks
"""
super(Object, self).__init__(dbobj)
@ -159,30 +203,41 @@ class Object(TypeClass):
Inputs:
ostring (str): Primary search criterion. Will be matched against object.key (with object.aliases second)
unless the keyword attribute_name specifies otherwise. Special strings:
#<num> - search by unique dbref. This is always a global search.
ostring (str): Primary search criterion. Will be matched against
object.key (with object.aliases second)
unless the keyword attribute_name specifies otherwise.
Special strings:
#<num> - search by unique dbref. This is always a
global search.
me,self - self-reference to this object
<num>-<string> - can be used to differentiate between multiple same-named matches
global_search (bool): Search all objects globally. This is overruled by "location" keyword.
use_nicks (bool): Use nickname-replace (nicktype "object") on the search string
typeclass (str or Typeclass): Limit search only to Objects with this typeclass. May be a list of typeclasses
for a broader search.
location (Object): Specify a location to search, if different from the self's given location
<num>-<string> - can be used to differentiate between
multiple same-named matches
global_search (bool): Search all objects globally. This is overruled
by "location" keyword.
use_nicks (bool): Use nickname-replace (nicktype "object") on the
search string
typeclass (str or Typeclass): Limit search only to Objects with this
typeclass. May be a list of typeclasses for a
broader search.
location (Object): Specify a location to search, if different from the
self's given location
plus its contents. This can also be a list of locations.
attribute_name (str): Use this named Attribute to match ostring against, instead of object.key.
quiet (bool) - don't display default error messages - return multiple matches as a list and
no matches as None. If not set (default), will echo error messages and return None.
exact (bool) - if unset (default) - prefers to match to beginning of string rather than not matching
at all. If set, requires exact mathing of entire string.
attribute_name (str): Use this named Attribute to match ostring against,
instead of object.key.
quiet (bool) - don't display default error messages - return multiple
matches as a list and no matches as None. If not
set (default), will echo error messages and return None.
exact (bool) - if unset (default) - prefers to match to beginning of
string rather than not matching at all. If set,
requires exact mathing of entire string.
Returns:
quiet=False (default):
no match or multimatch:
auto-echoes errors to self.msg, then returns None
(results are handled by modules set by settings.SEARCH_AT_RESULT
and settings.SEARCH_AT_MULTIMATCH_INPUT)
(results are handled by settings.SEARCH_AT_RESULT
and settings.SEARCH_AT_MULTIMATCH_INPUT)
match:
a unique object match
quiet=True:
@ -209,16 +264,18 @@ class Object(TypeClass):
Argument:
raw_string (string) - raw command input
sessid (int) - id of session executing the command. This sets the sessid property on the command.
sessid (int) - id of session executing the command. This sets the
sessid property on the command.
Returns Deferred - this is an asynchronous Twisted object that will
not fire until the command has actually finished executing. To overload
this one needs to attach callback functions to it, with addCallback(function).
This function will be called with an eventual return value from the command
execution.
not fire until the command has actually finished executing. To
overload this one needs to attach callback functions to it, with
addCallback(function). This function will be called with an
eventual return value from the command execution.
This return is not used at all by Evennia by default, but might be useful
for coders intending to implement some sort of nested command structure.
This return is not used at all by Evennia by default, but might be
useful for coders intending to implement some sort of nested
command structure.
"""
return self.dbobj.execute_cmd(raw_string, sessid=sessid)
@ -233,48 +290,59 @@ class Object(TypeClass):
sessid: optional session target. If sessid=0, the session will
default to self.sessid or from_obj.sessid.
"""
self.dbobj.msg(text=text, **kwargs)#message, from_obj=from_obj, data=data, sessid=0)
self.dbobj.msg(text=text, **kwargs)
def msg_contents(self, text=None, exclude=None, from_obj=None, **kwargs):
"""
Emits something to all objects inside an object.
exclude is a list of objects not to send to. See self.msg() for more info.
exclude is a list of objects not to send to. See self.msg() for
more info.
"""
self.dbobj.msg_contents(text, exclude=exclude, from_obj=from_obj, **kwargs)
self.dbobj.msg_contents(text, exclude=exclude,
from_obj=from_obj, **kwargs)
def move_to(self, destination, quiet=False,
emit_to_obj=None, use_destination=True, to_none=False):
"""
Moves this object to a new location. Note that if <destination> is an
exit object (i.e. it has "destination"!=None), the move_to will
happen to this destination and -not- into the exit object itself, unless
use_destination=False. Note that no lock checks are done by this function,
such things are assumed to have been handled before calling move_to.
happen to this destination and -not- into the exit object itself,
unless use_destination=False. Note that no lock checks are done by
this function, such things are assumed to have been handled before
calling move_to.
destination: (Object) Reference to the object to move to. This
can also be an exit object, in which case the destination
property is used as destination.
quiet: (bool) If true, don't emit left/arrived messages.
emit_to_obj: (Object) object to receive error messages
use_destination (bool): Default is for objects to use the "destination" property
of destinations as the target to move to. Turning off this
keyword allows objects to move "inside" exit objects.
to_none - allow destination to be None. Note that no hooks are run when moving
to a None location. If you want to run hooks, run them manually.
Returns True/False depending on if there were problems with the move. This method
may also return various error messages to the emit_to_obj.
use_destination (bool): Default is for objects to use the "destination"
property of destinations as the target to move to.
Turning off this keyword allows objects to move
"inside" exit objects.
to_none - allow destination to be None. Note that no hooks are run
when moving to a None location. If you want to run hooks, run
them manually (and make sure the hooks can handle a None
location).
Returns True/False depending on if there were problems with the move.
This method may also return various error messages to the
emit_to_obj.
"""
return self.dbobj.move_to(destination, quiet=quiet,
emit_to_obj=emit_to_obj, use_destination=use_destination)
emit_to_obj=emit_to_obj,
use_destination=use_destination)
def copy(self, new_key=None):
"""
Makes an identical copy of this object. If you want to customize the copy by
changing some settings, use ObjectDB.object.copy_object() directly.
Makes an identical copy of this object. If you want to customize the
copy by changing some settings, use ObjectDB.object.copy_object()
directly.
new_key (string) - new key/name of copied object. If new_key is not specified, the copy will be named
new_key (string) - new key/name of copied object. If new_key is not
specified, the copy will be named
<old_key>_copy by default.
Returns: Object (copy of this one)
"""
@ -293,7 +361,6 @@ class Object(TypeClass):
"""
return self.dbobj.delete()
# methods inherited from the typeclass system
def is_typeclass(self, typeclass, exact=False):
@ -347,18 +414,20 @@ class Object(TypeClass):
"""
return self.dbobj.swap_typeclass(new_typeclass, clean_attributes=clean_attributes, no_default=no_default)
return self.dbobj.swap_typeclass(new_typeclass,
clean_attributes=clean_attributes, no_default=no_default)
def access(self, accessing_obj, access_type='read', default=False):
"""
Determines if another object has permission to access this object in whatever way.
Determines if another object has permission to access this object in
whatever way.
accessing_obj (Object)- object trying to access this one
access_type (string) - type of access sought
default (bool) - what to return if no lock of access_type was found
This function will call at_access_success or at_access_failure depending on the
outcome of the access check.
This function will call at_access_success or at_access_failure
depending on the outcome of the access check.
"""
if self.dbobj.access(accessing_obj, access_type=access_type, default=default):
@ -373,12 +442,12 @@ class Object(TypeClass):
This explicitly checks the given string against this object's
'permissions' property without involving any locks.
permstring (string) - permission string that need to match a permission on the object.
permstring (string) - permission string that need to match a
permission on the object.
(example: 'Builders')
"""
return self.dbobj.check_permstring(permstring)
def __eq__(self, other):
"""
Checks for equality against an id string or another object or user.
@ -387,24 +456,23 @@ class Object(TypeClass):
parent doesn't work.
"""
try:
return _GA(_GA(self, "dbobj"),"dbid") == _GA(_GA(other,"dbobj"),"dbid")
return _GA(_GA(self, "dbobj"), "dbid") == _GA(_GA(other, "dbobj"), "dbid")
except AttributeError:
# compare players instead
try:
return _GA(_GA(_GA(self, "dbobj"),"player"),"uid") == _GA(_GA(other, "player"),"uid")
return _GA(_GA(_GA(self, "dbobj"), "player"), "uid") == _GA(_GA(other, "player"), "uid")
except AttributeError:
return False
## hooks called by the game engine
def basetype_setup(self):
"""
This sets up the default properties of an Object,
just before the more general at_object_creation.
You normally don't need to change this unless you change some fundamental
things like names of permission groups.
You normally don't need to change this unless you change some
fundamental things like names of permission groups.
"""
# the default security setup fallback for a generic
# object. Overload in child for a custom setup. Also creation
@ -412,22 +480,25 @@ class Object(TypeClass):
# controller, for example)
dbref = self.dbobj.dbref
self.locks.add(";".join(["control:perm(Immortals)", # edit locks/permissions, delete
"examine:perm(Builders)", # examine properties
"view:all()", # look at object (visibility)
"edit:perm(Wizards)", # edit properties/attributes
"delete:perm(Wizards)", # delete object
"get:all()", # pick up object
"call:true()", # allow to call commands on this object
"tell:perm(Wizards)", # allow emits to this object
"puppet:pid(%s) or perm(Immortals) or pperm(Immortals)" % dbref])) # restricts puppeting of this object
self.locks.add(";".join([
"control:perm(Immortals)", # edit locks/permissions, delete
"examine:perm(Builders)", # examine properties
"view:all()", # look at object (visibility)
"edit:perm(Wizards)", # edit properties/attributes
"delete:perm(Wizards)", # delete object
"get:all()", # pick up object
"call:true()", # allow to call commands on this object
"tell:perm(Wizards)", # allow emits to this object
# restricts puppeting of this object
"puppet:pid(%s) or perm(Immortals) or pperm(Immortals)" % dbref]))
def basetype_posthook_setup(self):
"""
Called once, after basetype_setup and at_object_creation. This should generally not be overloaded unless
you are redefining how a room/exit/object works. It allows for basetype-like setup
after the object is created. An example of this is EXITs, who need to know keys, aliases, locks
etc to set up their exit-cmdsets.
Called once, after basetype_setup and at_object_creation. This should
generally not be overloaded unless you are redefining how a
room/exit/object works. It allows for basetype-like setup after the
object is created. An example of this is EXITs, who need to know keys,
aliases, locks etc to set up their exit-cmdsets.
"""
pass
@ -437,7 +508,6 @@ class Object(TypeClass):
"""
pass
def at_object_delete(self):
"""
Called just before the database object is
@ -502,34 +572,34 @@ class Object(TypeClass):
def at_server_reload(self):
"""
This hook is called whenever the server is shutting down for restart/reboot.
If you want to, for example, save non-persistent properties across a restart,
this is the place to do it.
This hook is called whenever the server is shutting down for
restart/reboot. If you want to, for example, save non-persistent
properties across a restart, this is the place to do it.
"""
pass
def at_server_shutdown(self):
"""
This hook is called whenever the server is shutting down fully (i.e. not for
a restart).
This hook is called whenever the server is shutting down fully
(i.e. not for a restart).
"""
pass
def at_access_success(self, accessing_obj, access_type):
"""
This hook is called whenever accessing_obj succeed a lock check of type access_type
on this object, for whatever reason. The return value of this hook is not used,
the lock will still pass regardless of what this hook does (use lockstring/funcs to tweak
the lock result).
This hook is called whenever accessing_obj succeed a lock check of
type access_type on this object, for whatever reason. The return value
of this hook is not used, the lock will still pass regardless of what
this hook does (use lockstring/funcs to tweak the lock result).
"""
pass
def at_access_failure(self, accessing_obj, access_type):
"""
This hook is called whenever accessing_obj fails a lock check of type access_type
on this object, for whatever reason. The return value of this hook is not used, the
lock will still fail regardless of what this hook does (use lockstring/funcs to tweak the
lock result).
This hook is called whenever accessing_obj fails a lock check of type
access_type on this object, for whatever reason. The return value of
this hook is not used, the lock will still fail regardless of what
this hook does (use lockstring/funcs to tweak the lock result).
"""
pass
@ -588,7 +658,6 @@ class Object(TypeClass):
string = "%s arrives to %s from %s."
self.location.msg_contents(string % (name, loc_name, src_name), exclude=self)
def at_after_move(self, source_location):
"""
Called after move has completed, regardless of quiet mode or not.
@ -598,7 +667,6 @@ class Object(TypeClass):
"""
pass
def at_object_leave(self, moved_obj, target_location):
"""
Called just before an object leaves from inside this object
@ -630,9 +698,9 @@ class Object(TypeClass):
"""
This hook is responsible for handling the actual traversal, normally
by calling traversing_object.move_to(target_location). It is normally
only implemented by Exit objects. If it returns False (usually because move_to
returned False), at_after_traverse below should not be called and
instead at_failed_traverse should be called.
only implemented by Exit objects. If it returns False (usually because
move_to returned False), at_after_traverse below should not be called
and instead at_failed_traverse should be called.
"""
pass
@ -687,7 +755,6 @@ class Object(TypeClass):
"""
pass
# hooks called by the default cmdset.
def return_appearance(self, pobject):
@ -698,7 +765,8 @@ class Object(TypeClass):
if not pobject:
return
# get and identify all objects
visible = (con for con in self.contents if con != pobject and con.access(pobject, "view"))
visible = (con for con in self.contents if con != pobject and
con.access(pobject, "view"))
exits, users, things = [], [], []
for con in visible:
key = con.key
@ -744,6 +812,7 @@ class Object(TypeClass):
dropper - the object which just dropped this object.
"""
pass
def at_say(self, speaker, message):
"""
Called on this object if an object inside this object speaks.
@ -797,12 +866,13 @@ class Character(Object):
def at_pre_puppet(self, player, sessid=None):
"""
This recovers the character again after having been "stoved away" at the unpuppet
This recovers the character again after having been "stoved away"
at the unpuppet
"""
if self.db.prelogout_location:
# try to recover
self.location = self.db.prelogout_location
if self.location == None:
if self.location is None:
# make sure location is never None (home should always exist)
self.location = self.home
if self.location:
@ -824,8 +894,9 @@ class Character(Object):
def at_post_unpuppet(self, player, sessid=None):
"""
We stove away the character when the player goes ooc/logs off, otherwise the character object will
remain in the room also after the player logged off ("headless", so to say).
We stove away the character when the player goes ooc/logs off,
otherwise the character object will remain in the room also after the
player logged off ("headless", so to say).
"""
if self.location: # have to check, in case of multiple connections closing
self.location.msg_contents("%s has left the game." % self.name, exclude=[self])
@ -852,6 +923,7 @@ class Room(Object):
"puppet:false()"])) # would be weird to puppet a room ...
self.location = None
#
# Base Exit object
#
@ -905,7 +977,8 @@ class Exit(Object):
# No shorthand error message. Call hook.
self.obj.at_failed_traverse(self.caller)
# create an exit command. We give the properties here, to always trigger metaclass preparations
# create an exit command. We give the properties here,
# to always trigger metaclass preparations
cmd = ExitCommand(key=exidbobj.db_key.strip().lower(),
aliases=exidbobj.aliases.all(),
locks=str(exidbobj.locks),
@ -944,8 +1017,9 @@ class Exit(Object):
def at_cmdset_get(self):
"""
Called when the cmdset is requested from this object, just before the cmdset is
actually extracted. If no Exit-cmdset is cached, create it now.
Called when the cmdset is requested from this object, just before the
cmdset is actually extracted. If no Exit-cmdset is cached, create
it now.
"""
if self.ndb.exit_reset or not self.cmdset.has_cmdset("_exitset", must_be_default=True):
@ -984,8 +1058,9 @@ class Exit(Object):
def at_failed_traverse(self, traversing_object):
"""
This is called if an object fails to traverse this object for some
reason. It will not be called if the attribute "err_traverse" is defined,
that attribute will then be echoed back instead as a convenient shortcut.
reason. It will not be called if the attribute "err_traverse" is
defined, that attribute will then be echoed back instead as a
convenient shortcut.
(See also hooks at_before_traverse and at_after_traverse).
"""

View file

@ -8,10 +8,12 @@ Runs as part of the Evennia's test suite with 'manage.py test"
Please add new tests to this module as needed.
Guidelines:
A 'test case' is testing a specific component and is defined as a class inheriting from unittest.TestCase.
The test case class can have a method setUp() that creates and sets up the testing environment.
All methods inside the test case class whose names start with 'test' are used as test methods by the runner.
Inside the test methods, special member methods assert*() are used to test the behaviour.
A 'test case' is testing a specific component and is defined as a class
inheriting from unittest.TestCase. The test case class can have a method
setUp() that creates and sets up the testing environment.
All methods inside the test case class whose names start with 'test' are
used as test methods by the runner. Inside the test methods, special member
methods assert*() are used to test the behaviour.
"""
import sys
@ -24,12 +26,10 @@ try:
except ImportError:
import unittest
from django.conf import settings
from src.objects import models, objects
from src.utils import create
from src.commands.default import tests as commandtests
from src.locks import tests as locktests
class TestObjAttrs(TestCase):
"""
Test aspects of ObjAttributes
@ -49,6 +49,7 @@ class TestObjAttrs(TestCase):
# self.assertEqual(self.obj2 ,self.obj1.db.testattr)
# self.assertEqual(self.obj2.location, self.obj1.db.testattr.location)
def suite():
"""
This function is called automatically by the django test runner.