Add typeclass kwarg to player.search; make player.search search all playerdb-derived typeclasses by default. Resolves #1057.

This commit is contained in:
Griatch 2016-09-15 13:34:17 +02:00
parent ece023d5ee
commit 22e6cb4f8f
2 changed files with 21 additions and 7 deletions

View file

@ -8,7 +8,7 @@ from django.contrib.auth.models import UserManager
#from functools import update_wrapper #from functools import update_wrapper
from evennia.typeclasses.managers import (returns_typeclass_list, returns_typeclass, from evennia.typeclasses.managers import (returns_typeclass_list, returns_typeclass,
TypedObjectManager, TypeclassManager) TypedObjectManager, TypeclassManager)
#from evennia.utils import logger from evennia.utils.utils import make_iter
__all__ = ("PlayerManager",) __all__ = ("PlayerManager",)
@ -149,7 +149,7 @@ class PlayerDBManager(TypedObjectManager, UserManager):
return None return None
@returns_typeclass_list @returns_typeclass_list
def player_search(self, ostring, exact=True): def player_search(self, ostring, exact=True, typeclass=None):
""" """
Searches for a particular player by name or Searches for a particular player by name or
database id. database id.
@ -160,6 +160,8 @@ class PlayerDBManager(TypedObjectManager, UserManager):
`True`, requires exact (non-case-sensitive) match, `True`, requires exact (non-case-sensitive) match,
otherwise also match also keys containing the `ostring` otherwise also match also keys containing the `ostring`
(non-case-sensitive fuzzy match). (non-case-sensitive fuzzy match).
typeclass (str or Typeclass, optional): Limit the search only to
players of this typeclass.
""" """
dbref = self.dbref(ostring) dbref = self.dbref(ostring)
@ -168,10 +170,18 @@ class PlayerDBManager(TypedObjectManager, UserManager):
matches = self.filter(id=dbref) matches = self.filter(id=dbref)
if matches: if matches:
return matches return matches
if exact: query = {"username__iexact" if exact else "username__icontains": ostring}
return self.filter(username__iexact=ostring) if typeclass:
# we accept both strings and actual typeclasses
if callable(typeclass):
typeclass = u"%s.%s" % (typeclass.__module__, typeclass.__name__)
else: else:
return self.filter(username__icontains=ostring) typeclass = u"%s" % typeclass
query["db_typeclass_path"] = typeclass
if exact:
return self.filter(**query)
else:
return self.filter(**query)
class PlayerManager(PlayerDBManager, TypeclassManager): class PlayerManager(PlayerDBManager, TypeclassManager):

View file

@ -456,7 +456,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
callertype="player", session=session, **kwargs) callertype="player", session=session, **kwargs)
def search(self, searchdata, return_puppet=False, search_object=False, def search(self, searchdata, return_puppet=False, search_object=False,
nofound_string=None, multimatch_string=None, **kwargs): typeclass=None, nofound_string=None, multimatch_string=None, **kwargs):
""" """
This is similar to `DefaultObject.search` but defaults to searching This is similar to `DefaultObject.search` but defaults to searching
for Players only. for Players only.
@ -470,6 +470,10 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
search_object (bool, optional): Search for Objects instead of search_object (bool, optional): Search for Objects instead of
Players. This is used by e.g. the @examine command when Players. This is used by e.g. the @examine command when
wanting to examine Objects while OOC. wanting to examine Objects while OOC.
typeclass (Player typeclass, optional): Limit the search
only to this particular typeclass. This can be used to
limit to specific player typeclasses or to limit the search
to a particular Object typeclass if `search_object` is True.
nofound_string (str, optional): A one-time error message nofound_string (str, optional): A one-time error message
to echo if `searchdata` leads to no matches. If not given, to echo if `searchdata` leads to no matches. If not given,
will fall back to the default handler. will fall back to the default handler.
@ -491,9 +495,9 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
if searchdata.lower() in ("me", "*me", "self", "*self",): if searchdata.lower() in ("me", "*me", "self", "*self",):
return self return self
if search_object: if search_object:
matches = ObjectDB.objects.object_search(searchdata) matches = ObjectDB.objects.object_search(searchdata, typeclass=typeclass)
else: else:
matches = self.__class__.objects.player_search(searchdata) matches = PlayerDB.objects.player_search(searchdata, typeclass=typeclass)
matches = _AT_SEARCH_RESULT(matches, self, query=searchdata, matches = _AT_SEARCH_RESULT(matches, self, query=searchdata,
nofound_string=nofound_string, nofound_string=nofound_string,
multimatch_string=multimatch_string) multimatch_string=multimatch_string)