Implemented a modified and cleaned objectdb.search and accompanying object.manager.search_object that also searches globally. The default commands have not yet been converted to use the new call.
This commit is contained in:
parent
be22a31ec4
commit
218e4a149c
6 changed files with 131 additions and 118 deletions
|
|
@ -10,7 +10,7 @@ from django.contrib.auth.models import User
|
||||||
from src.players.models import PlayerDB
|
from src.players.models import PlayerDB
|
||||||
from src.server.sessionhandler import SESSIONS
|
from src.server.sessionhandler import SESSIONS
|
||||||
from src.server.models import ServerConfig
|
from src.server.models import ServerConfig
|
||||||
from src.utils import utils, prettytable
|
from src.utils import utils, prettytable, search
|
||||||
from src.commands.default.muxcommand import MuxCommand
|
from src.commands.default.muxcommand import MuxCommand
|
||||||
|
|
||||||
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
||||||
|
|
@ -65,24 +65,22 @@ class CmdBoot(MuxCommand):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# Boot by player object
|
# Boot by player object
|
||||||
pobj = caller.search("*%s" % args.lstrip('*'), global_search=True, player=True)
|
pobj = search.player_search(args)
|
||||||
if not pobj:
|
if not pobj:
|
||||||
|
self.caller("Player %s was not found." % pobj.key)
|
||||||
return
|
return
|
||||||
if pobj.character.has_player:
|
pobj = pobj[0]
|
||||||
if not pobj.access(caller, 'boot'):
|
if not pobj.access(caller, 'boot'):
|
||||||
string = "You don't have the permission to boot %s."
|
string = "You don't have the permission to boot %s."
|
||||||
pobj.msg(string)
|
pobj.msg(string)
|
||||||
return
|
|
||||||
# we have a bootable object with a connected user
|
|
||||||
matches = SESSIONS.sessions_from_player(pobj)
|
|
||||||
for match in matches:
|
|
||||||
boot_list.append(match)
|
|
||||||
else:
|
|
||||||
caller.msg("That object has no connected player.")
|
|
||||||
return
|
return
|
||||||
|
# we have a bootable object with a connected user
|
||||||
|
matches = SESSIONS.sessions_from_player(pobj)
|
||||||
|
for match in matches:
|
||||||
|
boot_list.append(match)
|
||||||
|
|
||||||
if not boot_list:
|
if not boot_list:
|
||||||
caller.msg("No matches found.")
|
caller.msg("No matching sessions found. The Player does not seem to be online.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Carry out the booting of the sessions in the boot list.
|
# Carry out the booting of the sessions in the boot list.
|
||||||
|
|
@ -96,8 +94,7 @@ class CmdBoot(MuxCommand):
|
||||||
for session in boot_list:
|
for session in boot_list:
|
||||||
name = session.uname
|
name = session.uname
|
||||||
session.msg(feedback)
|
session.msg(feedback)
|
||||||
session.disconnect()
|
pobj.disconnect_session_from_player(session.sessid)
|
||||||
caller.msg("You booted %s." % name)
|
|
||||||
|
|
||||||
|
|
||||||
# regex matching IP addresses with wildcards, eg. 233.122.4.*
|
# regex matching IP addresses with wildcards, eg. 233.122.4.*
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ class CmdIC(MuxPlayerCommand):
|
||||||
return
|
return
|
||||||
if not new_character:
|
if not new_character:
|
||||||
# search for a matching character
|
# search for a matching character
|
||||||
new_character = search.objects(self.args, player)
|
new_character = search.object_search(self.args, player)
|
||||||
if new_character:
|
if new_character:
|
||||||
new_character = new_character[0]
|
new_character = new_character[0]
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,16 @@
|
||||||
"""
|
"""
|
||||||
Custom manager for Objects.
|
Custom manager for Objects.
|
||||||
"""
|
"""
|
||||||
try: import cPickle as pickle
|
|
||||||
except ImportError: import pickle
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models.fields import exceptions
|
from django.db.models.fields import exceptions
|
||||||
from src.typeclasses.managers import TypedObjectManager
|
from src.typeclasses.managers import TypedObjectManager
|
||||||
from src.typeclasses.managers import returns_typeclass, returns_typeclass_list
|
from src.typeclasses.managers import returns_typeclass, returns_typeclass_list
|
||||||
from src.utils import utils
|
from src.utils import utils
|
||||||
from src.utils.utils import to_unicode, make_iter, string_partial_matching, to_str
|
from src.utils.utils import to_unicode, make_iter, string_partial_matching
|
||||||
|
|
||||||
__all__ = ("ObjectManager",)
|
__all__ = ("ObjectManager",)
|
||||||
_GA = object.__getattribute__
|
_GA = object.__getattribute__
|
||||||
_DUMPS = lambda inp: to_unicode(pickle.dumps(inp))
|
|
||||||
|
|
||||||
# Try to use a custom way to parse id-tagged multimatches.
|
# Try to use a custom way to parse id-tagged multimatches.
|
||||||
|
|
||||||
|
|
@ -120,21 +117,20 @@ class ObjectManager(TypedObjectManager):
|
||||||
return self.filter(cand_restriction & Q(objattribute__db_key=attribute_name))
|
return self.filter(cand_restriction & Q(objattribute__db_key=attribute_name))
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_objs_with_attr_value(self, attribute_name, attribute_value, candidates=None):
|
def get_objs_with_attr_value(self, attribute_name, attribute_value, candidates=None, typeclasses=None):
|
||||||
"""
|
"""
|
||||||
Returns all objects having the valid
|
Returns all objects having the valid attrname set to the given value.
|
||||||
attrname set to the given value. Note that no conversion is made
|
|
||||||
to attribute_value, and so it can accept also non-strings. For this reason it does
|
candidates - list of candidate objects to search
|
||||||
not make sense to offer an "exact" type matching for this.
|
typeclasses - list of typeclass-path strings to restrict matches with
|
||||||
|
|
||||||
|
This uses the Attribute's PickledField to transparently search the database by matching
|
||||||
|
the internal representation. This is reasonably effective but since Attribute values
|
||||||
|
cannot be indexed, searching by Attribute key is to be preferred whenever possible.
|
||||||
"""
|
"""
|
||||||
cand_restriction = candidates and Q(db_obj__pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
|
cand_restriction = candidates and Q(db_obj__pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
|
||||||
if type(attribute_value) in (basestring, int, float):
|
type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q()
|
||||||
# simple attribute_value - do direct lookup
|
return self.filter(cand_restriction & type_restriction & Q(objattribute__db_key=attribute_name, objattribute__db_value=attribute_value))
|
||||||
return self.filter(cand_restriction & Q(objattribute__db_key=attribute_name, objattribute__db_value=_DUMPS(("simple", attribute_value))))
|
|
||||||
else:
|
|
||||||
# go via attribute conversion
|
|
||||||
attrs= self.model.objattribute_set.related.model.objects.select_related("db_obj").filter(cand_restriction & Q(db_key=attribute_name))
|
|
||||||
return [attr.db_obj for attr in attrs if attribute_value == attr.value]
|
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_objs_with_db_property(self, property_name, candidates=None):
|
def get_objs_with_db_property(self, property_name, candidates=None):
|
||||||
|
|
@ -151,16 +147,19 @@ class ObjectManager(TypedObjectManager):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_objs_with_db_property_value(self, property_name, property_value, candidates=None):
|
def get_objs_with_db_property_value(self, property_name, property_value, candidates=None, typeclasses=None):
|
||||||
"""
|
"""
|
||||||
Returns all objects having a given db field property
|
Returns all objects having a given db field property.
|
||||||
|
candidates - list of objects to search
|
||||||
|
typeclasses - list of typeclass-path strings to restrict matches with
|
||||||
"""
|
"""
|
||||||
if isinstance(property_value, basestring):
|
if isinstance(property_value, basestring):
|
||||||
property_value = to_unicode(property_value)
|
property_value = to_unicode(property_value)
|
||||||
property_name = "db_%s" % property_name.lstrip('db_')
|
property_name = "db_%s" % property_name.lstrip('db_')
|
||||||
cand_restriction = candidates and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
|
cand_restriction = candidates and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
|
||||||
|
type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q()
|
||||||
try:
|
try:
|
||||||
return self.filter(cand_restriction & Q(property_name=property_value))
|
return self.filter(cand_restriction & type_restriction & Q(property_name=property_value))
|
||||||
except exceptions.FieldError:
|
except exceptions.FieldError:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
@ -176,23 +175,26 @@ class ObjectManager(TypedObjectManager):
|
||||||
return self.filter(db_location=location).exclude(exclude_restriction)
|
return self.filter(db_location=location).exclude(exclude_restriction)
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def get_objs_with_key_or_alias(self, ostring, exact=True, candidates=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
|
Returns objects based on key or alias match. Will also do fuzzy matching based on
|
||||||
the utils.string_partial_matching function.
|
the utils.string_partial_matching function.
|
||||||
|
candidates - list of candidate objects to restrict on
|
||||||
|
typeclasses - list of typeclass path strings to restrict on
|
||||||
"""
|
"""
|
||||||
# build query objects
|
# build query objects
|
||||||
candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj]
|
candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj]
|
||||||
cand_restriction = candidates and Q(pk__in=candidates_id) or Q()
|
cand_restriction = candidates and Q(pk__in=make_iter(candidates_id)) or Q()
|
||||||
|
type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q()
|
||||||
if exact:
|
if exact:
|
||||||
# exact match - do direct search
|
# exact match - do direct search
|
||||||
return self.filter(cand_restriction & (Q(db_key__iexact=ostring) | Q(alias__db_key__iexact=ostring))).distinct()
|
return self.filter(cand_restriction & type_restriction & (Q(db_key__iexact=ostring) | Q(alias__db_key__iexact=ostring))).distinct()
|
||||||
elif candidates:
|
elif candidates:
|
||||||
# fuzzy with candidates
|
# fuzzy with candidates
|
||||||
key_candidates = self.filter(cand_restriction)
|
key_candidates = self.filter(cand_restriction & type_restriction)
|
||||||
else:
|
else:
|
||||||
# fuzzy without supplied candidates - we select our own candidates
|
# fuzzy without supplied candidates - we select our own candidates
|
||||||
key_candidates = self.filter(Q(db_key__istartswith=ostring) | Q(alias__db_key__istartswith=ostring)).distinct()
|
key_candidates = self.filter(type_restriction & (Q(db_key__istartswith=ostring) | Q(alias__db_key__istartswith=ostring))).distinct()
|
||||||
candidates_id = [_GA(obj, "id") for obj in key_candidates]
|
candidates_id = [_GA(obj, "id") for obj in key_candidates]
|
||||||
# fuzzy matching
|
# fuzzy matching
|
||||||
key_strings = key_candidates.values_list("db_key", flat=True)
|
key_strings = key_candidates.values_list("db_key", flat=True)
|
||||||
|
|
@ -210,25 +212,25 @@ class ObjectManager(TypedObjectManager):
|
||||||
# main search methods and helper functions
|
# main search methods and helper functions
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
def object_search(self, ostring, caller=None,
|
def object_search(self, ostring=None,
|
||||||
attribute_name=None,
|
attribute_name=None,
|
||||||
|
typeclass=None,
|
||||||
candidates=None,
|
candidates=None,
|
||||||
exact=True):
|
exact=True):
|
||||||
"""
|
"""
|
||||||
Search as an object and return results. The result is always an Object.
|
Search as an object globally or in a list of candidates and return results. The result is always an Object.
|
||||||
If * is appended (player search, a Character controlled by this Player
|
Always returns a list.
|
||||||
is looked for. The Character is returned, not the Player. Use player_search
|
|
||||||
to find Player objects. Always returns a list.
|
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
ostring: (string) The string to compare names against.
|
ostring: (str) The string to compare names against. By default (if not attribute_name
|
||||||
Can be a dbref. If name is prepended by *, a player is searched for.
|
is set), this will search object.key and object.aliases in order. Can also
|
||||||
caller: (Object) The optional object performing the search.
|
be on the form #dbref, which will, if exact=True be matched against primary key.
|
||||||
attribute_name: (string) Which object attribute to match ostring against. If not
|
attribute_name: (str): Use this named ObjectAttribute to match ostring against, instead
|
||||||
set, the "key" and "aliases" properties are searched in order.
|
of the defaults.
|
||||||
candidates (list obj ObjectDBs): If objlist is supplied, global_search keyword is ignored
|
typeclass (str or TypeClass): restrict matches to objects having this typeclass. This will help
|
||||||
and search will only be performed among the candidates in this list. A common list
|
speed up global searches.
|
||||||
of candidates is the contents of the current location searched.
|
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
|
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
|
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
|
multiple matches in names with multiple components (so "bi sw" will match
|
||||||
|
|
@ -240,41 +242,42 @@ class ObjectManager(TypedObjectManager):
|
||||||
A list of matching objects (or a list with one unique match)
|
A list of matching objects (or a list with one unique match)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def _searcher(ostring, exact=False):
|
def _searcher(ostring, candidates, typeclass, exact=False):
|
||||||
"Helper method for searching objects"
|
"Helper method for searching objects. typeclass is only used for global searching (no candidates)"
|
||||||
if attribute_name:
|
if attribute_name and isinstance(attribute_name, basestring):
|
||||||
# attribute/property search (always exact).
|
# attribute/property search (always exact).
|
||||||
matches = self.get_objs_with_db_property_value(attribute_name, ostring, candidates=candidates)
|
matches = self.get_objs_with_db_property_value(attribute_name, ostring, candidates=candidates, typeclasses=typeclass)
|
||||||
if matches:
|
if matches:
|
||||||
return matches
|
return matches
|
||||||
return self.get_objs_with_attr_value(attribute_name, ostring, candidates=candidates)
|
return self.get_objs_with_attr_value(attribute_name, ostring, candidates=candidates, typeclasses=typeclass)
|
||||||
if ostring.startswith("*"):
|
|
||||||
# Player search - try to find obj by its player's name
|
|
||||||
player_match = self.get_object_with_player(ostring, candidates=candidates)
|
|
||||||
if player_match is not None:
|
|
||||||
return [player_match]
|
|
||||||
return []
|
|
||||||
else:
|
else:
|
||||||
# normal key/alias search
|
# normal key/alias search
|
||||||
return self.get_objs_with_key_or_alias(ostring, exact=exact, candidates=candidates)
|
return self.get_objs_with_key_or_alias(ostring, exact=exact, candidates=candidates, typeclasses=typeclass)
|
||||||
|
|
||||||
|
|
||||||
if not ostring and ostring != 0:
|
if not ostring and ostring != 0:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# Convenience check to make sure candidates are really dbobjs
|
if typeclass:
|
||||||
|
# typeclass may also be a list
|
||||||
|
for i, typeclass in enumerate(make_iter(typeclass)):
|
||||||
|
if callable(typeclass):
|
||||||
|
typeclass[i] = u"%s.%s" % (typeclass.__module__, typeclass.__name__)
|
||||||
|
else:
|
||||||
|
typeclass[i] = u"%s" % typeclass
|
||||||
|
|
||||||
if candidates:
|
if candidates:
|
||||||
candidates = [cand.dbobj for cand in make_iter(candidates) if hasattr(cand, "dbobj")]
|
# Convenience check to make sure candidates are really dbobjs
|
||||||
|
candidates = [cand.dbobj for cand in make_iter(candidates) if _GA(cand, "_hasattr")(cand, "dbobj")]
|
||||||
|
if typeclass:
|
||||||
|
candidates = [cand for cand in candidates if _GA(cand, "db_typeclass_path") in typeclass]
|
||||||
|
|
||||||
# If candidates is given as an empty list, don't go any further.
|
dbref = not attribute_name and exact and self.dbref(ostring)
|
||||||
if candidates == []:
|
if dbref != None:
|
||||||
return []
|
|
||||||
|
|
||||||
dbref = not attribute_name and self.dbref(ostring)
|
|
||||||
if dbref or dbref == 0:
|
|
||||||
# Easiest case - dbref matching (always exact)
|
# Easiest case - dbref matching (always exact)
|
||||||
dbref_match = self.dbref_search(dbref)
|
dbref_match = self.dbref_search(dbref)
|
||||||
if dbref_match:
|
if dbref_match:
|
||||||
if candidates == None or dbref_match.dbobj in candidates:
|
if not candidates or dbref_match.dbobj in candidates:
|
||||||
return [dbref_match]
|
return [dbref_match]
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
@ -283,12 +286,12 @@ class ObjectManager(TypedObjectManager):
|
||||||
|
|
||||||
match_number = None
|
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(ostring, exact=True)
|
matches = _searcher(ostring, candidates, typeclass, exact=True)
|
||||||
if not matches:
|
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, ostring = _AT_MULTIMATCH_INPUT(ostring)
|
match_number, ostring = _AT_MULTIMATCH_INPUT(ostring)
|
||||||
# run search again, with the exactness set by caller
|
# run search again, with the exactness set by call
|
||||||
matches = _searcher(ostring, exact=exact)
|
matches = _searcher(ostring, candidates, typeclass, exact=exact)
|
||||||
|
|
||||||
# deal with result
|
# deal with result
|
||||||
if len(matches) > 1 and match_number != None:
|
if len(matches) > 1 and match_number != None:
|
||||||
|
|
|
||||||
|
|
@ -550,7 +550,6 @@ class ObjectDB(TypedObject):
|
||||||
typeclass=None,
|
typeclass=None,
|
||||||
location=None,
|
location=None,
|
||||||
attribute_name=None,
|
attribute_name=None,
|
||||||
attribute_value=None,
|
|
||||||
quiet=False,
|
quiet=False,
|
||||||
exact=False):
|
exact=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -559,26 +558,25 @@ class ObjectDB(TypedObject):
|
||||||
Perform a standard object search in the database, handling
|
Perform a standard object search in the database, handling
|
||||||
multiple results and lack thereof gracefully. By default, only
|
multiple results and lack thereof gracefully. By default, only
|
||||||
objects in self's current location or inventory is searched.
|
objects in self's current location or inventory is searched.
|
||||||
|
Note: to find Players, use eg. ev.player_search.
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
|
|
||||||
ostring: (str) The string to match object.key against. Special strings:
|
ostring (str): Primary search criterion. Will be matched against object.key (with object.aliases second)
|
||||||
*<string> - search only for objects of type settings.CHARACTER_DEFAULT
|
unless the keyword attribute_name specifies otherwise. Special strings:
|
||||||
#<num> - search by unique dbref. This is always a global search.
|
#<num> - search by unique dbref. This is always a global search.
|
||||||
me,self - self-reference to this object
|
me,self - self-reference to this object
|
||||||
<num>-<string> - can be used to differentiate between multiple same-named matches
|
<num>-<string> - can be used to differentiate between multiple same-named matches
|
||||||
global_search: Search all objects globally. This is overruled by "location" keyword.
|
global_search (bool): Search all objects globally. This is overruled by "location" keyword.
|
||||||
use_nicks : Use nickname-replace (nick of type "object") on the search string
|
use_nicks (bool): Use nickname-replace (nicktype "object") on the search string
|
||||||
typeclass : Limit search only to Objects with this typeclass. Overrides the
|
typeclass (str or Typeclass): Limit search only to Objects with this typeclass. May be a list of typeclasses
|
||||||
use of the *-operator at the beginning of the string.
|
for a broader search.
|
||||||
location : Specify a location to search, if different from the self's given location
|
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.
|
plus its contents. This can also be a list of locations.
|
||||||
attribute_name: Match only objects also having Attributes with this name
|
attribute_name (str): Use this named Attribute to match ostring against, instead of object.key.
|
||||||
attribute_value: Match only objects where obj.db.attribute_name also has this value
|
quiet (bool) - don't display default error messages - return multiple matches as a list and
|
||||||
|
|
||||||
quiet - 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.
|
no matches as None. If not set (default), will echo error messages and return None.
|
||||||
exact - if unset (default) - prefers to match to beginning of string rather than not matching
|
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.
|
at all. If set, requires exact mathing of entire string.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
@ -606,9 +604,6 @@ class ObjectDB(TypedObject):
|
||||||
if use_nicks:
|
if use_nicks:
|
||||||
nick = None
|
nick = None
|
||||||
nicktype = "object"
|
nicktype = "object"
|
||||||
if player or ostring.startswith('*'):
|
|
||||||
ostring = ostring.lstrip("*")
|
|
||||||
nicktype = "player"
|
|
||||||
# look up nicks
|
# look up nicks
|
||||||
nicks = ObjectNick.objects.filter(db_obj=self, db_type=nicktype)
|
nicks = ObjectNick.objects.filter(db_obj=self, db_type=nicktype)
|
||||||
if self.has_player:
|
if self.has_player:
|
||||||
|
|
@ -619,8 +614,8 @@ class ObjectDB(TypedObject):
|
||||||
break
|
break
|
||||||
|
|
||||||
candidates=None
|
candidates=None
|
||||||
if global_search or (global_dbref and ostring.startswith("#")):
|
if global_search or (ostring.startswith("#") and len(ostring) > 1 and ostring[1:].isdigit()):
|
||||||
# only allow exact matching if searching the entire database
|
# only allow exact matching if searching the entire database or unique #dbrefs
|
||||||
exact = True
|
exact = True
|
||||||
elif location:
|
elif location:
|
||||||
# location(s) were given
|
# location(s) were given
|
||||||
|
|
@ -638,16 +633,14 @@ class ObjectDB(TypedObject):
|
||||||
# db manager expects database objects
|
# db manager expects database objects
|
||||||
candidates = [obj.dbobj for obj in candidates]
|
candidates = [obj.dbobj for obj in candidates]
|
||||||
|
|
||||||
results = ObjectDB.objects.object_search(ostring, caller=self,
|
results = ObjectDB.objects.object_search(ostring=ostring,
|
||||||
|
typeclass=typeclass,
|
||||||
attribute_name=attribute_name,
|
attribute_name=attribute_name,
|
||||||
candidates=candidates,
|
candidates=candidates,
|
||||||
exact=exact)
|
exact=exact)
|
||||||
if ignore_errors:
|
if quiet:
|
||||||
return results
|
return results
|
||||||
result = _AT_SEARCH_RESULT(self, ostring, results, global_search)
|
return _AT_SEARCH_RESULT(self, ostring, results, global_search)
|
||||||
if player and result:
|
|
||||||
return result.player
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -822,6 +822,7 @@ class TypedObject(SharedMemoryModel):
|
||||||
return any((cls for cls in self.typeclass.__class__.mro()
|
return any((cls for cls in self.typeclass.__class__.mro()
|
||||||
if any(("%s.%s" % (_GA(cls,"__module__"), _GA(cls,"__name__")) == typec for typec in typeclasses))))
|
if any(("%s.%s" % (_GA(cls,"__module__"), _GA(cls,"__name__")) == typec for typec in typeclasses))))
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Object manipulation methods
|
# Object manipulation methods
|
||||||
#
|
#
|
||||||
|
|
@ -874,7 +875,6 @@ class TypedObject(SharedMemoryModel):
|
||||||
# this will automatically use a default class if
|
# this will automatically use a default class if
|
||||||
# there is an error with the given typeclass.
|
# there is an error with the given typeclass.
|
||||||
new_typeclass = self.typeclass
|
new_typeclass = self.typeclass
|
||||||
print new_typeclass
|
|
||||||
if self.typeclass_path != new_typeclass.path and no_default:
|
if self.typeclass_path != new_typeclass.path and no_default:
|
||||||
# something went wrong; the default was loaded instead,
|
# something went wrong; the default was loaded instead,
|
||||||
# and we don't allow that; instead we return to previous.
|
# and we don't allow that; instead we return to previous.
|
||||||
|
|
|
||||||
|
|
@ -48,31 +48,46 @@ HelpEntry = ContentType.objects.get(app_label="help", model="helpentry").model_c
|
||||||
# is reachable from within each command class
|
# is reachable from within each command class
|
||||||
# by using self.caller.search()!
|
# by using self.caller.search()!
|
||||||
#
|
#
|
||||||
|
# def object_search(self, ostring=None,
|
||||||
|
# attribute_name=None,
|
||||||
|
# typeclass=None,
|
||||||
|
# candidates=None,
|
||||||
|
# exact=True):
|
||||||
|
#
|
||||||
|
# Search globally or in a list of candidates and return results. The result is always an Object.
|
||||||
|
# Always returns a list.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# ostring: (str) The string to compare names against. 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 ostring against, instead
|
||||||
|
# of the defaults.
|
||||||
|
# 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 object_search(self, ostring, caller=None,
|
# def object_search(self, ostring, caller=None,
|
||||||
# candidates=None,
|
# candidates=None,
|
||||||
# attribute_name=None):
|
# attribute_name=None):
|
||||||
# """
|
|
||||||
# Search as an object and return results.
|
|
||||||
#
|
#
|
||||||
# ostring: (string) The string to compare names against.
|
|
||||||
# Can be a dbref. If name is appended by *, a player is searched for.
|
|
||||||
# caller: (Object) The object performing the search.
|
|
||||||
# candidates (list of Objects): restrict search only to those objects
|
|
||||||
# attribute_name: (string) Which attribute to search in each object.
|
|
||||||
# If None, the default 'name' attribute is used.
|
|
||||||
# """
|
|
||||||
|
|
||||||
search_object = ObjectDB.objects.object_search
|
search_object = ObjectDB.objects.object_search
|
||||||
search_objects = search_object
|
search_objects = search_object
|
||||||
|
object_search = search_object
|
||||||
objects = search_objects
|
objects = search_objects
|
||||||
|
|
||||||
#
|
#
|
||||||
# Search for players
|
# Search for players
|
||||||
#
|
#
|
||||||
# NOTE: Most usually you would do such searches from
|
|
||||||
# from inseide command definitions using
|
|
||||||
# self.caller.search() by appending an '*' to the
|
|
||||||
# beginning of the search criterion.
|
|
||||||
#
|
|
||||||
# def player_search(self, ostring):
|
# def player_search(self, ostring):
|
||||||
# """
|
# """
|
||||||
# Searches for a particular player by name or
|
# Searches for a particular player by name or
|
||||||
|
|
@ -83,6 +98,7 @@ objects = search_objects
|
||||||
|
|
||||||
search_player = PlayerDB.objects.player_search
|
search_player = PlayerDB.objects.player_search
|
||||||
search_players = search_player
|
search_players = search_player
|
||||||
|
player_search = search_player
|
||||||
players = search_players
|
players = search_players
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
@ -100,6 +116,7 @@ players = search_players
|
||||||
|
|
||||||
search_script = ScriptDB.objects.script_search
|
search_script = ScriptDB.objects.script_search
|
||||||
search_scripts = search_script
|
search_scripts = search_script
|
||||||
|
script_search = search_script
|
||||||
scripts = search_scripts
|
scripts = search_scripts
|
||||||
#
|
#
|
||||||
# Searching for communication messages
|
# Searching for communication messages
|
||||||
|
|
@ -120,6 +137,7 @@ scripts = search_scripts
|
||||||
|
|
||||||
search_message = Msg.objects.message_search
|
search_message = Msg.objects.message_search
|
||||||
search_messages = search_message
|
search_messages = search_message
|
||||||
|
message_search = search_message
|
||||||
messages = search_messages
|
messages = search_messages
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
@ -134,6 +152,7 @@ messages = search_messages
|
||||||
|
|
||||||
search_channel = Channel.objects.channel_search
|
search_channel = Channel.objects.channel_search
|
||||||
search_channels = search_channel
|
search_channels = search_channel
|
||||||
|
channel_search = search_channel
|
||||||
channels = search_channels
|
channels = search_channels
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
@ -149,4 +168,5 @@ channels = search_channels
|
||||||
|
|
||||||
search_help_entry = HelpEntry.objects.search_help
|
search_help_entry = HelpEntry.objects.search_help
|
||||||
search_help_entries = search_help_entry
|
search_help_entries = search_help_entry
|
||||||
|
help_entry_search = search_help_entry
|
||||||
help_entries = search_help_entries
|
help_entries = search_help_entries
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue