Esempio n. 1
0
    def get_object_with_player(self, ostring, exact=True, candidates=None):
        """
        Search for an object based on its player's name or dbref.

        Args:
            ostring (str or int): Search criterion or dbref. Searching
                for a player is sometimes initiated by appending an `*` to
                the beginning of the search criterion (e.g. in
                local_and_global_search). This is stripped here.
            exact (bool, optional): Require an exact player match.
            candidates (list, optional): Only search among this list of possible
                object candidates.

        Return:
            match (Object or list): One or more matching results.

        """
        ostring = to_unicode(ostring).lstrip('*')
        # simplest case - search by dbref
        dbref = self.dbref(ostring)
        if dbref:
            return dbref
        # not a dbref. Search by name.
        cand_restriction = candidates != None and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
        if exact:
            return self.filter(cand_restriction & Q(db_player__username__iexact=ostring))
        else: # fuzzy matching
            ply_cands = self.filter(cand_restriction & Q(playerdb__username__istartswith=ostring)).values_list("db_key", flat=True)
            if candidates:
                index_matches = string_partial_matching(ply_cands, ostring, ret_index=True)
                return [obj for ind, obj in enumerate(make_iter(candidates)) if ind in index_matches]
            else:
                return string_partial_matching(ply_cands, ostring, ret_index=False)
Esempio n. 2
0
    def get_objs_with_key_or_alias(self, ostring, exact=True,
                                         candidates=None, typeclasses=None):
        """
        Args:
            ostring (str): A search criterion.
            exact (bool, optional): Require exact match of ostring
                (still case-insensitive). If `False`, will do fuzzy matching
                using `evennia.utils.utils.string_partial_matching` algorithm.
            candidates (list): Only match among these candidates.
            typeclasses (list): Only match objects with typeclasses having thess path strings.

        Returns:
            matches (list): A list of matches of length 0, 1 or more.
        """
        if not isinstance(ostring, basestring):
            if hasattr(ostring, "key"):
                ostring = ostring.key
            else:
                return []
        if is_iter(candidates) and not len(candidates):
            # if candidates is an empty iterable there can be no matches
            # Exit early.
            return []

        # build query objects
        candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj]
        cand_restriction = candidates != None and Q(pk__in=candidates_id) or Q()
        type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q()
        if exact:
            # exact match - do direct search
            return self.filter(cand_restriction & type_restriction & (Q(db_key__iexact=ostring) |
                               Q(db_tags__db_key__iexact=ostring) & Q(db_tags__db_tagtype__iexact="alias"))).distinct()
        elif candidates:
            # fuzzy with candidates
            search_candidates = self.filter(cand_restriction & type_restriction)
        else:
            # fuzzy without supplied candidates - we select our own candidates
            search_candidates = self.filter(type_restriction & (Q(db_key__istartswith=ostring) | Q(db_tags__db_key__istartswith=ostring))).distinct()
        # fuzzy matching
        key_strings = search_candidates.values_list("db_key", flat=True).order_by("id")

        index_matches = string_partial_matching(key_strings, ostring, ret_index=True)
        if index_matches:
            # a match by key
            return [obj for ind, obj in enumerate(search_candidates) if ind in index_matches]
        else:
            # match by alias rather than by key
            search_candidates = search_candidates.filter(db_tags__db_tagtype__iexact="alias",
                                                        db_tags__db_key__icontains=ostring)
            alias_strings = []
            alias_candidates = []
            #TODO create the alias_strings and alias_candidates lists more effiently?
            for candidate in search_candidates:
                for alias in candidate.aliases.all():
                    alias_strings.append(alias)
                    alias_candidates.append(candidate)
            index_matches = string_partial_matching(alias_strings, ostring, ret_index=True)
            if index_matches:
                return [alias_candidates[ind] for ind in index_matches]
            return []
Esempio n. 3
0
    def get_objs_with_key_or_alias(self, ostring, exact=True,
                                         candidates=None, typeclasses=None):
        """
        Args:
            ostring (str): A search criterion.
            exact (bool, optional): Require exact match of ostring
                (still case-insensitive). If `False`, will do fuzzy matching
                using `evennia.utils.utils.string_partial_matching` algorithm.
            candidates (list): Only match among these candidates.
            typeclasses (list): Only match objects with typeclasses having thess path strings.

        Returns:
            matches (list): A list of matches of length 0, 1 or more.
        """
        if not isinstance(ostring, basestring):
            if hasattr(ostring, "key"):
                ostring = ostring.key
            else:
                return []
        if is_iter(candidates) and not len(candidates):
            # if candidates is an empty iterable there can be no matches
            # Exit early.
            return []

        # build query objects
        candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj]
        cand_restriction = candidates != None and Q(pk__in=candidates_id) or Q()
        type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q()
        if exact:
            # exact match - do direct search
            return self.filter(cand_restriction & type_restriction & (Q(db_key__iexact=ostring) |
                               Q(db_tags__db_key__iexact=ostring) & Q(db_tags__db_tagtype__iexact="alias"))).distinct()
        elif candidates:
            # fuzzy with candidates
            search_candidates = self.filter(cand_restriction & type_restriction)
        else:
            # fuzzy without supplied candidates - we select our own candidates
            search_candidates = self.filter(type_restriction & (Q(db_key__istartswith=ostring) | Q(db_tags__db_key__istartswith=ostring))).distinct()
        # fuzzy matching
        key_strings = search_candidates.values_list("db_key", flat=True).order_by("id")

        index_matches = string_partial_matching(key_strings, ostring, ret_index=True)
        if index_matches:
            # a match by key
            return [obj for ind, obj in enumerate(search_candidates) if ind in index_matches]
        else:
            # match by alias rather than by key
            search_candidates = search_candidates.filter(db_tags__db_tagtype__iexact="alias",
                                                        db_tags__db_key__icontains=ostring)
            alias_strings = []
            alias_candidates = []
            #TODO create the alias_strings and alias_candidates lists more effiently?
            for candidate in search_candidates:
                for alias in candidate.aliases.all():
                    alias_strings.append(alias)
                    alias_candidates.append(candidate)
            index_matches = string_partial_matching(alias_strings, ostring, ret_index=True)
            if index_matches:
                return [alias_candidates[ind] for ind in index_matches]
            return []
Esempio n. 4
0
    def get_object_with_player(self, ostring, exact=True, candidates=None):
        """
        Search for an object based on its player's name or dbref.

        Args:
            ostring (str or int): Search criterion or dbref. Searching
                for a player is sometimes initiated by appending an `*` to
                the beginning of the search criterion (e.g. in
                local_and_global_search). This is stripped here.
            exact (bool, optional): Require an exact player match.
            candidates (list, optional): Only search among this list of possible
                object candidates.

        Return:
            match (Object or list): One or more matching results.

        """
        ostring = to_unicode(ostring).lstrip('*')
        # simplest case - search by dbref
        dbref = self.dbref(ostring)
        if dbref:
            return dbref
        # not a dbref. Search by name.
        cand_restriction = candidates != None and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
        if exact:
            return self.filter(cand_restriction & Q(db_player__username__iexact=ostring))
        else: # fuzzy matching
            ply_cands = self.filter(cand_restriction & Q(playerdb__username__istartswith=ostring)).values_list("db_key", flat=True)
            if candidates:
                index_matches = string_partial_matching(ply_cands, ostring, ret_index=True)
                return [obj for ind, obj in enumerate(make_iter(candidates)) if ind in index_matches]
            else:
                return string_partial_matching(ply_cands, ostring, ret_index=False)
Esempio n. 5
0
 def get_object_with_player(self, ostring, exact=True, candidates=None):
     """
     Search for an object based on its player's name or dbref.
     This search is sometimes initiated by appending an `*` to the
     beginning of the search criterion (e.g. in local_and_global_search).
     search_string:  (string) The name or dbref to search for.
     """
     ostring = to_unicode(ostring).lstrip('*')
     # simplest case - search by dbref
     dbref = self.dbref(ostring)
     if dbref:
         return dbref
     # not a dbref. Search by name.
     cand_restriction = candidates != None and Q(
         pk__in=[_GA(obj, "id")
                 for obj in make_iter(candidates) if obj]) or Q()
     if exact:
         return self.filter(cand_restriction
                            & Q(db_player__username__iexact=ostring))
     else:  # fuzzy matching
         ply_cands = self.filter(cand_restriction & Q(
             playerdb__username__istartswith=ostring)).values_list(
                 "db_key", flat=True)
         if candidates:
             index_matches = string_partial_matching(ply_cands,
                                                     ostring,
                                                     ret_index=True)
             return [
                 obj for ind, obj in enumerate(make_iter(candidates))
                 if ind in index_matches
             ]
         else:
             return string_partial_matching(ply_cands,
                                            ostring,
                                            ret_index=False)
Esempio n. 6
0
    def set(self, key, value, **kwargs):
        """
        Change an individual option.

        Args:
            key (str): The key of an option that can be changed. Allows partial matching.
            value (str): The value that should be checked, coerced, and stored.:
            kwargs (any, optional): These are passed into the Option's validation function,
                save function and display function and allows to customize either.

        Returns:
            value (any): Value stored in option, after validation.

        """
        if not key:
            raise ValueError("Option field blank!")
        match = string_partial_matching(list(self.options_dict.keys()),
                                        key,
                                        ret_index=False)
        if not match:
            raise ValueError("Option not found!")
        if len(match) > 1:
            raise ValueError(
                f"Multiple matches: {', '.join(match)}. Please be more specific."
            )
        match = match[0]
        op = self.get(match, return_obj=True)
        op.set(value, **kwargs)
        return op.value
Esempio n. 7
0
    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.
        candidates - list of candidate objects to restrict on
        typeclasses - list of typeclass path strings to restrict on
        """
        if not isinstance(ostring, basestring):
            if hasattr(ostring, "key"):
                ostring = ostring.key
            else:
                return []
        if is_iter(candidates) and not len(candidates):
            # if candidates is an empty iterable there can be no matches
            # Exit early.
            return []

        # build query objects
        candidates_id = [_GA(obj, "id") for obj in make_iter(candidates) if obj]
        cand_restriction = candidates != None 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:
            # exact match - do direct search
            return self.filter(cand_restriction & type_restriction & (Q(db_key__iexact=ostring) |
                               Q(db_tags__db_key__iexact=ostring) & Q(db_tags__db_tagtype__iexact="alias"))).distinct()
        elif candidates:
            # fuzzy with candidates
            key_candidates = self.filter(cand_restriction & type_restriction)
        else:
            # fuzzy without supplied candidates - we select our own candidates
            key_candidates = self.filter(type_restriction & (Q(db_key__istartswith=ostring) | Q(db_tags__db_key__istartswith=ostring))).distinct()
            candidates_id = [_GA(obj, "id") for obj in key_candidates]
        # fuzzy matching
        key_strings = key_candidates.values_list("db_key", flat=True).order_by("id")

        index_matches = string_partial_matching(key_strings, ostring, ret_index=True)
        if index_matches:
            return [obj for ind, obj in enumerate(key_candidates) if ind in index_matches]
        else:
            alias_candidates = self.filter(id__in=candidates_id, db_tags__db_tagtype__iexact="alias")
            alias_strings = alias_candidates.values_list("db_key", flat=True)
            index_matches = string_partial_matching(alias_strings, ostring, ret_index=True)
            if index_matches:
                return [alias.db_obj for ind, alias in enumerate(alias_candidates) if ind in index_matches]
            return []
Esempio n. 8
0
 def get_object_with_player(self, ostring, exact=True, candidates=None):
     """
     Search for an object based on its player's name or dbref.
     This search is sometimes initiated by appending an `*` to the
     beginning of the search criterion (e.g. in local_and_global_search).
     search_string:  (string) The name or dbref to search for.
     """
     ostring = to_unicode(ostring).lstrip('*')
     # simplest case - search by dbref
     dbref = self.dbref(ostring)
     if dbref:
         return dbref
     # not a dbref. Search by name.
     cand_restriction = candidates != None and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
     if exact:
         return self.filter(cand_restriction & Q(db_player__username__iexact=ostring))
     else: # fuzzy matching
         ply_cands = self.filter(cand_restriction & Q(playerdb__username__istartswith=ostring)).values_list("db_key", flat=True)
         if candidates:
             index_matches = string_partial_matching(ply_cands, ostring, ret_index=True)
             return [obj for ind, obj in enumerate(make_iter(candidates)) if ind in index_matches]
         else:
             return string_partial_matching(ply_cands, ostring, ret_index=False)
Esempio n. 9
0
    def get_object_with_account(self, ostring, exact=True, candidates=None):
        """
        Search for an object based on its account's name or dbref.

        Args:
            ostring (str or int): Search criterion or dbref. Searching
                for an account is sometimes initiated by appending an `*` to
                the beginning of the search criterion (e.g. in
                local_and_global_search). This is stripped here.
            exact (bool, optional): Require an exact account match.
            candidates (list, optional): Only search among this list of possible
                object candidates.

        Return:
            match (query): Matching query.

        """
        ostring = str(ostring).lstrip("*")
        # simplest case - search by dbref
        dbref = self.dbref(ostring)
        if dbref:
            try:
                return self.get(db_account__id=dbref)
            except self.model.DoesNotExist:
                pass

        # not a dbref. Search by name.
        cand_restriction = (
            candidates is not None
            and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj])
            or Q()
        )
        if exact:
            return self.filter(cand_restriction & Q(db_account__username__iexact=ostring)).order_by(
                "id"
            )
        else:  # fuzzy matching
            obj_cands = self.select_related().filter(
                cand_restriction & Q(db_account__username__istartswith=ostring)
            )
            acct_cands = [obj.account for obj in obj_cands]

            if obj_cands:
                index_matches = string_partial_matching(
                    [acct.key for acct in acct_cands], ostring, ret_index=True
                )
                acct_cands = [acct_cands[i].id for i in index_matches]
                return obj_cands.filter(db_account__id__in=acct_cands).order_by("id")
Esempio n. 10
0
def match_name(name, obj):
    if not is_obj(obj):
        raise ValueError("obj must be object type")
    return True if string_partial_matching(obj.db.name, name) else False
Esempio n. 11
0
def match_string(criteria, string):
    string = make_iter(string)
    return True if string_partial_matching(string, criteria) else False
Esempio n. 12
0
    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.
        candidates - list of candidate objects to restrict on
        typeclasses - list of typeclass path strings to restrict on
        """
        if not isinstance(ostring, basestring):
            if hasattr(ostring, "key"):
                ostring = ostring.key
            else:
                return []
        if is_iter(candidates) and not len(candidates):
            # if candidates is an empty iterable there can be no matches
            # Exit early.
            return []

        # build query objects
        candidates_id = [
            _GA(obj, "id") for obj in make_iter(candidates) if obj
        ]
        cand_restriction = candidates != None 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:
            # exact match - do direct search
            return self.filter(cand_restriction & type_restriction & (
                Q(db_key__iexact=ostring) | Q(db_tags__db_key__iexact=ostring)
                & Q(db_tags__db_tagtype__iexact="alias"))).distinct()
        elif candidates:
            # fuzzy with candidates
            key_candidates = self.filter(cand_restriction & type_restriction)
        else:
            # fuzzy without supplied candidates - we select our own candidates
            key_candidates = self.filter(type_restriction & (
                Q(db_key__istartswith=ostring)
                | Q(db_tags__db_key__istartswith=ostring))).distinct()
            candidates_id = [_GA(obj, "id") for obj in key_candidates]
        # fuzzy matching
        key_strings = key_candidates.values_list("db_key",
                                                 flat=True).order_by("id")

        index_matches = string_partial_matching(key_strings,
                                                ostring,
                                                ret_index=True)
        if index_matches:
            return [
                obj for ind, obj in enumerate(key_candidates)
                if ind in index_matches
            ]
        else:
            alias_candidates = self.filter(id__in=candidates_id,
                                           db_tags__db_tagtype__iexact="alias")
            alias_strings = alias_candidates.values_list("db_key", flat=True)
            index_matches = string_partial_matching(alias_strings,
                                                    ostring,
                                                    ret_index=True)
            if index_matches:
                return [
                    alias.db_obj for ind, alias in enumerate(alias_candidates)
                    if ind in index_matches
                ]
            return []