Cleaner implementation of the fuzzy matching fix I did; this also handels "true" multiple matches (such that there really are

>1 thing named "box" in the room); the previous implementation just picked the first occurence instead of giving a
multiple match error.
/Griatch
This commit is contained in:
Griatch 2009-09-02 17:57:54 +00:00
parent 68217072a6
commit 2aae4a0105
2 changed files with 32 additions and 32 deletions

View file

@ -15,15 +15,9 @@ from src.objects.exceptions import ObjectNotExist
from src.objects.util import object as util_object from src.objects.util import object as util_object
from src import defines_global from src import defines_global
from src import logger from src import logger
class UniqueMatch(Exception):
"""
This allows a fuzzy match to give precedence to a perfect match.
"""
def __init__(self,matchobj):
self.matchobj = matchobj
class ObjectManager(models.Manager): class ObjectManager(models.Manager):
def num_total_players(self): def num_total_players(self):
""" """
Returns the total number of registered players. Returns the total number of registered players.
@ -112,18 +106,30 @@ class ObjectManager(models.Manager):
""" """
if dbref_only: if dbref_only:
if limit_types: if limit_types:
return [prospect for prospect in searchlist if prospect.dbref_match(ostring) and prospect.type in limit_types] return [prospect for prospect in searchlist if prospect.dbref_match(ostring)
and prospect.type in limit_types]
else: else:
return [prospect for prospect in searchlist if prospect.dbref_match(ostring)] return [prospect for prospect in searchlist if prospect.dbref_match(ostring)]
else: else:
try: if limit_types:
if limit_types: results = [prospect for prospect in searchlist
return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type) and prospect.type in limit_types] if prospect.name_match(ostring, match_type=match_type)
and prospect.type in limit_types]
else:
results = [prospect for prospect in searchlist
if prospect.name_match(ostring, match_type=match_type)]
if match_type == "exact":
return results
else:
#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 exact_results:
return exact_results
else: else:
return [prospect for prospect in searchlist if prospect.name_match(ostring, match_type=match_type)] return results
except UniqueMatch, e:
return [e.matchobj]
def object_totals(self): def object_totals(self):
""" """

View file

@ -11,7 +11,6 @@ from django.contrib.auth.models import User, Group
from django.conf import settings from django.conf import settings
from src.objects.util import object as util_object from src.objects.util import object as util_object
from src.objects.managers.object import ObjectManager from src.objects.managers.object import ObjectManager
from src.objects.managers.object import UniqueMatch
from src.objects.managers.attribute import AttributeManager from src.objects.managers.attribute import AttributeManager
from src.config.models import ConfigValue from src.config.models import ConfigValue
from src.ansi import ANSITable, parse_ansi from src.ansi import ANSITable, parse_ansi
@ -961,22 +960,17 @@ class Object(models.Model):
if util_object.is_dbref(oname): if util_object.is_dbref(oname):
# First character is a pound sign, looks to be a dbref. # First character is a pound sign, looks to be a dbref.
return self.dbref_match(oname) return self.dbref_match(oname)
else:
# Check if this is an exact match oname = oname.lower()
oname = oname.lower() if match_type == "exact":
#exact matching
name_chunks = self.name.lower().split(';') name_chunks = self.name.lower().split(';')
# True=1, False=0, so if any hit, sum(result)>0. #False=0 and True=1 in python, so if sum>0, we
exact_match = sum(map(lambda o: oname == o, name_chunks)) > 0 #have at least one exact match.
if match_type == "exact": return sum(map(lambda o: oname == o, name_chunks)) > 0
#return result outright else:
return exact_match #fuzzy matching
if match_type == "fuzzy": return oname in self.name.lower()
if exact_match:
#even if a fuzzy match, an exact match is worth more
raise UniqueMatch(self)
else:
#not an exact match; use fuzzy matching
return oname in self.name.lower()
def filter_contents_from_str(self, oname): def filter_contents_from_str(self, oname):
""" """