diff --git a/src/objects/managers/object.py b/src/objects/managers/object.py index 6713680409..3e35a39e07 100644 --- a/src/objects/managers/object.py +++ b/src/objects/managers/object.py @@ -154,20 +154,22 @@ class ObjectManager(models.Manager): defines_global.OTYPE_GOING]) def list_search_object_namestr(self, searchlist, ostring, dbref_only=False, - limit_types=False, match_type="fuzzy"): + limit_types=False, match_type="fuzzy", + attribute_name=None): """ Iterates through a list of objects and returns a list of name matches. - This version handles search criteria of the type keyword-N, this is used - to differentiate several objects of the exact same name, e.g. box-1, box-2 etc. + This version handles search criteria of the type N-keyword, this is used + to differentiate several objects of the exact same name, e.g. 1-box, 2-box etc. searchlist: (List of Objects) The objects to perform name comparisons on. ostring: (string) The string to match against. dbref_only: (bool) Only compare dbrefs. limit_types: (list of int) A list of Object type numbers to filter by. match_type: (string) 'exact' or 'fuzzy' matching. + attribute_name: (string) attribute name to search, if None, 'name' is used. Note that the fuzzy matching gives precedence to exact matches; so if your search query matches an object in the list exactly, it will be the only result. @@ -189,19 +191,25 @@ class ObjectManager(models.Manager): #search by name - this may return multiple matches. results = self._list_search_helper1(searchlist,ostring,dbref_only, - limit_types, match_type) + limit_types, match_type, + attribute_name=attribute_name) match_number = None if not results: #if we have no match, check if we are dealing - #with a "keyword-N" query - if so, strip it and run again. + #with a "N-keyword" query - if so, strip it and run again. match_number, ostring = self._list_search_helper2(ostring) if match_number != None and ostring: results = self._list_search_helper1(searchlist,ostring,dbref_only, - limit_types, match_type) + limit_types, match_type, + attribute_name=attribute_name) if match_type == "fuzzy": #fuzzy matching; run second sweep to catch exact matches - exact_results = [prospect for prospect in results - if prospect.name_match(ostring, match_type="exact")] + if attribute_name: + exact_results = [prospect for prospect in results + if ostring == prospect.get_attribute_value(attribute_name)] + else: + exact_results = [prospect for prospect in results + if prospect.name_match(ostring, match_type="exact")] if exact_results: results = exact_results if len(results) > 1 and match_number != None: @@ -212,19 +220,41 @@ class ObjectManager(models.Manager): pass return results - def _list_search_helper1(self,searchlist,ostring,dbref_only, - limit_types,match_type): + def _list_search_helper1(self, searchlist, ostring, dbref_only, + limit_types, match_type, + attribute_name=None): """ Helper function for list_search_object_namestr - - does name matching through a list of objects. + does name/attribute matching through a list of objects. """ - if limit_types: - return [prospect for prospect in searchlist - if prospect.name_match(ostring, match_type=match_type) - and prospect.type in limit_types] + if attribute_name: + #search an arbitrary attribute name. + if limit_types: + if match_type == "exact": + return [prospect for prospect in searchlist + if prospect.type in limit_types and + ostring == prospect.get_attribute_value(attribute_name)] + else: + return [prospect for prospect in searchlist + if prospect.type in limit_types and + ostring in str(prospect.get_attribute_value(attribute_name))] + else: + if match_type == "exact": + return [prospect for prospect in searchlist + if ostring == str(prospect.get_attribute_value(attribute_name))] + else: + print [type(p) for p in searchlist] + return [prospect for prospect in searchlist + if ostring in str(prospect.get_attribute_value(attribute_name))] else: - return [prospect for prospect in searchlist - if prospect.name_match(ostring, match_type=match_type)] + #search the default "name" attribute + if limit_types: + return [prospect for prospect in searchlist + if prospect.type in limit_types and + prospect.name_match(ostring, match_type=match_type)] + else: + return [prospect for prospect in searchlist + if prospect.name_match(ostring, match_type=match_type)] def _list_search_helper2(self, ostring): """ @@ -242,6 +272,7 @@ class ObjectManager(models.Manager): return None, ostring except IndexError: return None, ostring + def player_alias_search(self, searcher, ostring): """ @@ -286,7 +317,7 @@ class ObjectManager(models.Manager): def local_and_global_search(self, searcher, ostring, search_contents=True, search_location=True, dbref_only=False, - limit_types=False): + limit_types=False, attribute_name=None): """ Searches an object's location then globally for a dbref or name match. @@ -296,6 +327,8 @@ class ObjectManager(models.Manager): search_location: (bool) While true, check the searcher's surroundings. dbref_only: (bool) Only compare dbrefs. limit_types: (list of int) A list of Object type numbers to filter by. + attribute_name: (string) Which attribute to search in each object. + If None, the default 'name' attribute is used. """ search_query = str(ostring).strip() @@ -329,7 +362,8 @@ class ObjectManager(models.Manager): if search_location: local_objs.extend(searcher.get_location().get_contents()) return self.list_search_object_namestr(local_objs, search_query, - limit_types=limit_types) + limit_types=limit_types, + attribute_name=attribute_name) # # ObjectManager Create methods diff --git a/src/objects/models.py b/src/objects/models.py index 6770dd1c13..cae7ccae6e 100755 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -153,16 +153,23 @@ class Object(models.Model): """ def search_for_object(self, ostring, emit_to_obj=None, search_contents=True, search_location=True, dbref_only=False, - limit_types=False, search_aliases=False): + limit_types=False, search_aliases=False, + attribute_name=None): """ Perform a standard object search, handling multiple results and lack thereof gracefully. - source_object: (Object) The Object doing the searching ostring: (str) The string to match object names against. - Obs - To find a player - append * to the start of ostring. + Obs - To find a player, append * to the start of ostring. + emit_to_obj: (obj) An object (instead of caller) to receive search feedback + search_contents: (bool) Search the caller's inventory + search_location: (bool) Search the caller's location + dbref_only: (bool) Requires ostring to be a #dbref + limit_types: (list) Object identifiers from defines_global.OTYPE:s + search_aliases: (bool) Search player aliases first + attribute_name: (string) Which attribute to match (if None, uses default 'name') """ + # This is the object that gets the duplicate/no match emits. if not emit_to_obj: emit_to_obj = self @@ -177,12 +184,14 @@ class Object(models.Model): search_contents=search_contents, search_location=search_location, dbref_only=dbref_only, - limit_types=limit_types) + limit_types=limit_types, + attribute_name=attribute_name) if len(results) > 1: - emit_to_obj.emit_to("More than one match for '%s' (please narrow target):" % ostring) + s = "More than one match for '%s' (please narrow target):" % ostring for num, result in enumerate(results): - emit_to_obj.emit_to(" %i-%s" % (num+1,result.get_name(show_dbref=False))) + s += "\n %i-%s" % (num+1, result.get_name(show_dbref=False)) + emit_to_obj.emit_to(s) return False elif len(results) == 0: emit_to_obj.emit_to("I don't see that here.") @@ -416,35 +425,6 @@ class Object(models.Model): else: return "%s%s" % (parse_ansi(name_string.split(';')[0], strip_ansi=no_ansi), dbref_string) - -## def set_description(self, new_desc=''): -## """ -## Set an objects description -## """ -## if not new_desc: -## self.set_attribute('desc', 'Nothing special') -## #self.description = None -## else: -## self.set_attribute('desc', new_desc) -## #self.description = new_desc -## self.save() - -## def get_description(self, no_parsing=False, wrap_text=False): -## """ -## Returns an object's ANSI'd description or None if description is not -## set. -## """ -## desc = self.get_attribute_value('desc') -## if desc: -## if not no_parsing: -## desc = parse_ansi(desc) -## if wrap_text: -## return functions_general.word_wrap(desc) -## else: -## return desc -## else: -## # No description attribute present, return empty string. -## return "" def get_flags(self): """