mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Merge pull request #3550 from InspectorCaracal/rpsystem-search-fix
Fix rpsystem contrib searching issues
This commit is contained in:
commit
4558237247
2 changed files with 63 additions and 22 deletions
|
|
@ -392,7 +392,7 @@ def parse_sdescs_and_recogs(
|
|||
# if no sdesc, include key plus aliases instead
|
||||
else:
|
||||
candidate_map.append((obj, obj.key))
|
||||
candidate_map.extend([(obj, alias) for alias in obj.aliases.all()])
|
||||
candidate_map.extend([(obj, alias) for alias in obj.aliases.all()])
|
||||
|
||||
# escape mapping syntax on the form {#id} if it exists already in emote,
|
||||
# if so it is replaced with just "id".
|
||||
|
|
@ -422,7 +422,10 @@ def parse_sdescs_and_recogs(
|
|||
|
||||
# first see if there is a number given (e.g. 1-tall)
|
||||
num_identifier, _ = marker_match.groups("") # return "" if no match, rather than None
|
||||
# get the beginning of the actual text, minus the numeric identifier
|
||||
match_index = marker_match.start()
|
||||
if num_identifier:
|
||||
match_index += len(num_identifier) + 1
|
||||
# split the emote string at the reference marker, to process everything after it
|
||||
head = string[:match_index]
|
||||
tail = string[match_index + 1 :]
|
||||
|
|
@ -439,7 +442,7 @@ def parse_sdescs_and_recogs(
|
|||
(re.search(rquery, text, _RE_FLAGS), obj, text) for obj, text in candidate_map
|
||||
)
|
||||
# filter out any non-matching candidates
|
||||
bestmatches = [(obj, match.group()) for match, obj, text in matches if match]
|
||||
bestmatches = [(obj, mtch.group()) for mtch, obj, text in matches if mtch]
|
||||
|
||||
else:
|
||||
# to find the longest match, we start from the marker and lengthen the
|
||||
|
|
@ -1333,30 +1336,30 @@ class ContribRPObject(DefaultObject):
|
|||
"""
|
||||
# we also want to use the default search method
|
||||
search_obj = super().get_search_result
|
||||
is_builder = self.locks.check_lockstring(self, "perm(Builder)")
|
||||
is_builder = self.permissions.check("Builder")
|
||||
results = []
|
||||
|
||||
if candidates:
|
||||
candidates = parse_sdescs_and_recogs(
|
||||
if candidates is not None:
|
||||
searched_results = parse_sdescs_and_recogs(
|
||||
self, candidates, _PREFIX + searchdata, search_mode=True
|
||||
)
|
||||
results = []
|
||||
for candidate in candidates:
|
||||
# we search by candidate keys here; this allows full error
|
||||
# management and use of all kwargs - we will use searchdata
|
||||
# in eventual error reporting later (not their keys). Doing
|
||||
# it like this e.g. allows for use of the typeclass kwarg
|
||||
# limiter.
|
||||
results.extend(
|
||||
[obj for obj in search_obj(candidate.key, **kwargs) if obj not in results]
|
||||
)
|
||||
|
||||
if not results and is_builder:
|
||||
# builders get to do a global search by key+alias
|
||||
results = search_obj(searchdata, **kwargs)
|
||||
if not searched_results and is_builder:
|
||||
# builders get to do a search by key
|
||||
results = search_obj(searchdata, candidates=candidates, **kwargs)
|
||||
else:
|
||||
# we do a default search on each result by key, here, to apply extra filtering kwargs
|
||||
for searched_obj in searched_results:
|
||||
results.extend(
|
||||
[
|
||||
obj
|
||||
for obj in search_obj(
|
||||
searched_obj.key, candidates=[searched_obj], **kwargs
|
||||
)
|
||||
if obj not in results
|
||||
]
|
||||
)
|
||||
else:
|
||||
# global searches with #drefs end up here. Global searches are
|
||||
# only done in code, so is controlled, #dbrefs are turned off
|
||||
# for non-Builders.
|
||||
# no candidates means it's a global search, so we pass it back to the default
|
||||
results = search_obj(searchdata, **kwargs)
|
||||
return results
|
||||
|
||||
|
|
|
|||
|
|
@ -346,6 +346,44 @@ class TestRPSystem(BaseEvenniaTest):
|
|||
self.assertEqual(self.speaker.search("receiver of emotes"), self.receiver1)
|
||||
self.assertEqual(self.speaker.search("colliding"), self.receiver2)
|
||||
|
||||
def test_get_search_result(self):
|
||||
self.obj1 = create_object(rpsystem.ContribRPObject, key="Obj1", location=self.room)
|
||||
self.obj1.sdesc.add("something")
|
||||
self.obj2 = create_object(rpsystem.ContribRPCharacter, key="Obj2", location=self.room)
|
||||
self.obj2.sdesc.add("something")
|
||||
candidates = [self.obj1, self.obj2]
|
||||
|
||||
# search candidates by sdesc: both objects should be found
|
||||
result = self.speaker.get_search_result("something", candidates)
|
||||
self.assertEqual(list(result), candidates)
|
||||
|
||||
# search by sdesc with 2-disambiguator: only second object should be found
|
||||
result = self.speaker.get_search_result("2-something", candidates)
|
||||
self.assertEqual(list(result), [self.obj2])
|
||||
|
||||
# search empty candidates: no objects should be found
|
||||
result = self.speaker.get_search_result("something", candidates=[])
|
||||
self.assertEqual(list(result), [])
|
||||
|
||||
# typeclass was given: only matching object should be found
|
||||
result = self.speaker.get_search_result(
|
||||
"something", candidates=candidates, typeclass=rpsystem.ContribRPCharacter
|
||||
)
|
||||
self.assertEqual(list(result), [self.obj2])
|
||||
|
||||
# search by key with player permissions: no objects should be found
|
||||
result = self.speaker.get_search_result("obj1", candidates)
|
||||
self.assertEqual(list(result), [])
|
||||
|
||||
# search by key with builder permissions: object should be found
|
||||
self.speaker.permissions.add("builder")
|
||||
result = self.speaker.get_search_result("obj1", candidates)
|
||||
self.assertEqual(list(result), [self.obj1])
|
||||
|
||||
# search by key with builder permissions when NOT IN candidates: object should NOT be found
|
||||
result = self.speaker.get_search_result("obj1", [self.obj2])
|
||||
self.assertEqual(list(result), [])
|
||||
|
||||
|
||||
class TestRPSystemCommands(BaseEvenniaCommandTest):
|
||||
def setUp(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue