Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Fix auto-fill in the text client when clicking on a hint suggestion #3267

Merged
merged 8 commits into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions MultiServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

import NetUtils
import Utils
from Utils import version_tuple, restricted_loads, Version, async_start
from Utils import version_tuple, restricted_loads, Version, async_start, get_intended_text
from NetUtils import Endpoint, ClientStatus, NetworkItem, decode, encode, NetworkPlayer, Permission, NetworkSlot, \
SlotType, LocationStore

Expand Down Expand Up @@ -1071,28 +1071,6 @@ def json_format_send_event(net_item: NetworkItem, receiving_player: int):
"item": net_item}


def get_intended_text(input_text: str, possible_answers) -> typing.Tuple[str, bool, str]:
picks = Utils.get_fuzzy_results(input_text, possible_answers, limit=2)
if len(picks) > 1:
dif = picks[0][1] - picks[1][1]
if picks[0][1] == 100:
return picks[0][0], True, "Perfect Match"
elif picks[0][1] < 75:
return picks[0][0], False, f"Didn't find something that closely matches '{input_text}', " \
f"did you mean '{picks[0][0]}'? ({picks[0][1]}% sure)"
elif dif > 5:
return picks[0][0], True, "Close Match"
else:
return picks[0][0], False, f"Too many close matches for '{input_text}', " \
f"did you mean '{picks[0][0]}'? ({picks[0][1]}% sure)"
else:
if picks[0][1] > 90:
return picks[0][0], True, "Only Option Match"
else:
return picks[0][0], False, f"Didn't find something that closely matches '{input_text}', " \
f"did you mean '{picks[0][0]}'? ({picks[0][1]}% sure)"


class CommandMeta(type):
def __new__(cls, name, bases, attrs):
commands = attrs["commands"] = {}
Expand Down
34 changes: 34 additions & 0 deletions Utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,40 @@ def get_fuzzy_ratio(word1: str, word2: str) -> float:
)
)

def get_intended_text(input_text: str, possible_answers) -> typing.Tuple[str, bool, str]:
Ishigh1 marked this conversation as resolved.
Show resolved Hide resolved
picks = get_fuzzy_results(input_text, possible_answers, limit=2)
if len(picks) > 1:
dif = picks[0][1] - picks[1][1]
if picks[0][1] == 100:
return picks[0][0], True, "Perfect Match"
elif picks[0][1] < 75:
return picks[0][0], False, f"Didn't find something that closely matches '{input_text}', " \
f"did you mean '{picks[0][0]}'? ({picks[0][1]}% sure)"
elif dif > 5:
return picks[0][0], True, "Close Match"
else:
return picks[0][0], False, f"Too many close matches for '{input_text}', " \
f"did you mean '{picks[0][0]}'? ({picks[0][1]}% sure)"
else:
if picks[0][1] > 90:
return picks[0][0], True, "Only Option Match"
else:
return picks[0][0], False, f"Didn't find something that closely matches '{input_text}', " \
f"did you mean '{picks[0][0]}'? ({picks[0][1]}% sure)"


def get_input_text_from_response(text: str, command: str) -> typing.Optional[str]:
if "did you mean " in text:
for question in ("Didn't find something that closely matches",
"Too many close matches"):
if text.startswith(question):
name = get_text_between(text, "did you mean '",
"'? (")
return f"!{command} {name}"
break
Ishigh1 marked this conversation as resolved.
Show resolved Hide resolved
elif text.startswith("Missing: "):
return text.replace("Missing: ", "!hint_location ")
return None

def open_filename(title: str, filetypes: typing.Sequence[typing.Tuple[str, typing.Sequence[str]]], suggest: str = "") \
Ishigh1 marked this conversation as resolved.
Show resolved Hide resolved
-> typing.Optional[str]:
Expand Down
16 changes: 5 additions & 11 deletions kvui.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
fade_in_animation = Animation(opacity=0, duration=0) + Animation(opacity=1, duration=0.25)

from NetUtils import JSONtoTextParser, JSONMessagePart, SlotType
from Utils import async_start
from Utils import async_start, get_input_text_from_response

if typing.TYPE_CHECKING:
import CommonClient
Expand Down Expand Up @@ -285,16 +285,10 @@ def on_touch_down(self, touch):
temp = MarkupLabel(text=self.text).markup
text = "".join(part for part in temp if not part.startswith(("[color", "[/color]", "[ref=", "[/ref]")))
cmdinput = App.get_running_app().textinput
if not cmdinput.text and " did you mean " in text:
for question in ("Didn't find something that closely matches, did you mean ",
"Too many close matches, did you mean "):
if text.startswith(question):
name = Utils.get_text_between(text, question,
"? (")
cmdinput.text = f"!{App.get_running_app().last_autofillable_command} {name}"
break
elif not cmdinput.text and text.startswith("Missing: "):
cmdinput.text = text.replace("Missing: ", "!hint_location ")
if not cmdinput.text:
input_text = get_input_text_from_response(text, App.get_running_app().last_autofillable_command)
if input_text is not None:
cmdinput.text = input_text

Clipboard.copy(text.replace("&amp;", "&").replace("&bl;", "[").replace("&br;", "]"))
return self.parent.select_with_touch(self.index, touch)
Expand Down
21 changes: 21 additions & 0 deletions test/general/test_client_server_interaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import unittest

from Utils import get_intended_text, get_input_text_from_response


class TestClient(unittest.TestCase):
def test_autofill_hint_from_fuzzy_hint(self) -> None:
tests = (
("item", ["item1", "item2"]), # Multiple close matches
("itm", ["item1", "item21"]), # No close match, multiple option
("item", ["item1"]), # No close match, single option
("item", ["\"item\" 'item' (item)"]), # Testing different special characters
)

for input_text, possible_answers in tests:
item_name, usable, response = get_intended_text(input_text, possible_answers)
self.assertFalse(usable, "This test must be updated, it seems get_fuzzy_results behavior changed")

hint_command = get_input_text_from_response(response, "hint")
self.assertIsNotNone(hint_command, "The response to fuzzy hints is no longer recognized by the hint autofill")
self.assertEqual(hint_command, f"!hint {item_name}", "The hint command autofilled by the response is not correct")
Ishigh1 marked this conversation as resolved.
Show resolved Hide resolved
Loading