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)
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 []
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)
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
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 []
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)
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")
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
def match_string(criteria, string): string = make_iter(string) return True if string_partial_matching(string, criteria) else False
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 []