From 22e6cb4f8fe347ebce169577b056cbffac7af1c8 Mon Sep 17 00:00:00 2001 From: Griatch Date: Thu, 15 Sep 2016 13:34:17 +0200 Subject: [PATCH] Add typeclass kwarg to player.search; make player.search search all playerdb-derived typeclasses by default. Resolves #1057. --- evennia/players/manager.py | 18 ++++++++++++++---- evennia/players/players.py | 10 +++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/evennia/players/manager.py b/evennia/players/manager.py index eedb858caa..e7389e7b82 100644 --- a/evennia/players/manager.py +++ b/evennia/players/manager.py @@ -8,7 +8,7 @@ from django.contrib.auth.models import UserManager #from functools import update_wrapper from evennia.typeclasses.managers import (returns_typeclass_list, returns_typeclass, TypedObjectManager, TypeclassManager) -#from evennia.utils import logger +from evennia.utils.utils import make_iter __all__ = ("PlayerManager",) @@ -149,7 +149,7 @@ class PlayerDBManager(TypedObjectManager, UserManager): return None @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 database id. @@ -160,6 +160,8 @@ class PlayerDBManager(TypedObjectManager, UserManager): `True`, requires exact (non-case-sensitive) match, otherwise also match also keys containing the `ostring` (non-case-sensitive fuzzy match). + typeclass (str or Typeclass, optional): Limit the search only to + players of this typeclass. """ dbref = self.dbref(ostring) @@ -168,10 +170,18 @@ class PlayerDBManager(TypedObjectManager, UserManager): matches = self.filter(id=dbref) if matches: return matches + query = {"username__iexact" if exact else "username__icontains": ostring} + if typeclass: + # we accept both strings and actual typeclasses + if callable(typeclass): + typeclass = u"%s.%s" % (typeclass.__module__, typeclass.__name__) + else: + typeclass = u"%s" % typeclass + query["db_typeclass_path"] = typeclass if exact: - return self.filter(username__iexact=ostring) + return self.filter(**query) else: - return self.filter(username__icontains=ostring) + return self.filter(**query) class PlayerManager(PlayerDBManager, TypeclassManager): diff --git a/evennia/players/players.py b/evennia/players/players.py index b6e8f31c11..28b6ba1bc4 100644 --- a/evennia/players/players.py +++ b/evennia/players/players.py @@ -456,7 +456,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)): callertype="player", session=session, **kwargs) 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 for Players only. @@ -470,6 +470,10 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)): search_object (bool, optional): Search for Objects instead of Players. This is used by e.g. the @examine command when 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 to echo if `searchdata` leads to no matches. If not given, 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",): return self if search_object: - matches = ObjectDB.objects.object_search(searchdata) + matches = ObjectDB.objects.object_search(searchdata, typeclass=typeclass) else: - matches = self.__class__.objects.player_search(searchdata) + matches = PlayerDB.objects.player_search(searchdata, typeclass=typeclass) matches = _AT_SEARCH_RESULT(matches, self, query=searchdata, nofound_string=nofound_string, multimatch_string=multimatch_string)