Fix unittest warnings caused by lunr

This commit is contained in:
Griatch 2020-05-16 22:07:58 +02:00
parent 537948561a
commit a96332e9c3
2 changed files with 92 additions and 24 deletions

View file

@ -6,8 +6,6 @@ set. The normal, database-tied help system is used for collaborative
creation of other help topics such as RP help or game-world aides. creation of other help topics such as RP help or game-world aides.
""" """
from lunr import lunr
from lunr.exceptions import QueryParseError
from django.conf import settings from django.conf import settings
from collections import defaultdict from collections import defaultdict
from evennia.utils.utils import fill, dedent from evennia.utils.utils import fill, dedent
@ -16,7 +14,12 @@ from evennia.help.models import HelpEntry
from evennia.utils import create, evmore from evennia.utils import create, evmore
from evennia.utils.ansi import ANSIString from evennia.utils.ansi import ANSIString
from evennia.utils.eveditor import EvEditor from evennia.utils.eveditor import EvEditor
from evennia.utils.utils import string_suggestions, class_from_module, inherits_from, format_grid from evennia.utils.utils import (
string_suggestions,
class_from_module,
inherits_from,
format_grid,
)
COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS) COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
HELP_MORE = settings.HELP_MORE HELP_MORE = settings.HELP_MORE
@ -27,6 +30,9 @@ __all__ = ("CmdHelp", "CmdSetHelp")
_DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH _DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH
_SEP = "|C" + "-" * _DEFAULT_WIDTH + "|n" _SEP = "|C" + "-" * _DEFAULT_WIDTH + "|n"
_LUNR = None
_LUNR_EXCEPTION = None
class HelpCategory: class HelpCategory:
def __init__(self, key): def __init__(self, key):
@ -34,7 +40,13 @@ class HelpCategory:
@property @property
def search_index_entry(self): def search_index_entry(self):
return {"key": str(self), "aliases": "", "category": self.key, "tags": "", "text": ""} return {
"key": str(self),
"aliases": "",
"category": self.key,
"tags": "",
"text": "",
}
def __str__(self): def __str__(self):
return f"Category: {self.key}" return f"Category: {self.key}"
@ -47,30 +59,42 @@ class HelpCategory:
def help_search_with_index(query, candidate_entries, suggestion_maxnum=5): def help_search_with_index(query, candidate_entries, suggestion_maxnum=5):
"""
Lunr-powered fast index search and suggestion wrapper
"""
global _LUNR, _LUNR_EXCEPTION
if not _LUNR:
# we have to delay-load lunr because it messes with logging if it's imported
# before twisted's logging has been set up
from lunr import lunr as _LUNR
from lunr.exceptions import QueryParseError as _LUNR_EXCEPTION
indx = [cnd.search_index_entry for cnd in candidate_entries] indx = [cnd.search_index_entry for cnd in candidate_entries]
mapping = {indx[ix]["key"]: cand for ix, cand in enumerate(candidate_entries)} mapping = {indx[ix]["key"]: cand for ix, cand in enumerate(candidate_entries)}
search_index = lunr( search_index = _LUNR(
ref="key", ref="key",
fields=[ fields=[
{"field_name": "key", "boost": 10,}, {"field_name": "key", "boost": 10},
{"field_name": "aliases", "boost": 9,}, {"field_name": "aliases", "boost": 9},
{"field_name": "category", "boost": 8,}, {"field_name": "category", "boost": 8},
{"field_name": "tags", "boost": 5}, {"field_name": "tags", "boost": 5},
{"field_name": "text", "boost": 1,}, {"field_name": "text", "boost": 1},
], ],
documents=indx, documents=indx,
) )
try: try:
matches = search_index.search(query)[:suggestion_maxnum] matches = search_index.search(query)[:suggestion_maxnum]
except QueryParseError: except _LUNR_EXCEPTION:
# this is a user-input problem # this is a user-input problem
matches = [] matches = []
# matches (objs), suggestions (strs) # matches (objs), suggestions (strs)
return ( return (
[mapping[match["ref"]] for match in matches], [mapping[match["ref"]] for match in matches],
[str(match["ref"]) for match in matches], # + f" (score {match['score']})") # good debug [
str(match["ref"]) for match in matches
], # + f" (score {match['score']})") # good debug
) )
@ -116,7 +140,10 @@ class CmdHelp(Command):
if type(self).help_more: if type(self).help_more:
usemore = True usemore = True
if self.session and self.session.protocol_key in ("websocket", "ajax/comet"): if self.session and self.session.protocol_key in (
"websocket",
"ajax/comet",
):
try: try:
options = self.account.db._saved_webclient_options options = self.account.db._saved_webclient_options
if options and options["helppopup"]: if options and options["helppopup"]:
@ -150,7 +177,9 @@ class CmdHelp(Command):
if title: if title:
string += "|CHelp for |w%s|n" % title string += "|CHelp for |w%s|n" % title
if aliases: if aliases:
string += " |C(aliases: %s|C)|n" % ("|C,|n ".join("|w%s|n" % ali for ali in aliases)) string += " |C(aliases: %s|C)|n" % (
"|C,|n ".join("|w%s|n" % ali for ali in aliases)
)
if help_text: if help_text:
string += "\n%s" % dedent(help_text.rstrip()) string += "\n%s" % dedent(help_text.rstrip())
if suggested: if suggested:
@ -177,15 +206,22 @@ class CmdHelp(Command):
category_str = f"-- {category.title()} " category_str = f"-- {category.title()} "
grid.append( grid.append(
ANSIString( ANSIString(
category_clr + category_str + "-" * (width - len(category_str)) + topic_clr category_clr
+ category_str
+ "-" * (width - len(category_str))
+ topic_clr
) )
) )
verbatim_elements.append(len(grid) - 1) verbatim_elements.append(len(grid) - 1)
entries = sorted(set(hdict_cmds.get(category, []) + hdict_db.get(category, []))) entries = sorted(
set(hdict_cmds.get(category, []) + hdict_db.get(category, []))
)
grid.extend(entries) grid.extend(entries)
gridrows = format_grid(grid, width, sep=" ", verbatim_elements=verbatim_elements) gridrows = format_grid(
grid, width, sep=" ", verbatim_elements=verbatim_elements
)
gridrows = ANSIString("\n").join(gridrows) gridrows = ANSIString("\n").join(gridrows)
return gridrows return gridrows
@ -257,7 +293,9 @@ class CmdHelp(Command):
# retrieve all available commands and database topics # retrieve all available commands and database topics
all_cmds = [cmd for cmd in cmdset if self.check_show_help(cmd, caller)] all_cmds = [cmd for cmd in cmdset if self.check_show_help(cmd, caller)]
all_topics = [ all_topics = [
topic for topic in HelpEntry.objects.all() if topic.access(caller, "view", default=True) topic
for topic in HelpEntry.objects.all()
if topic.access(caller, "view", default=True)
] ]
all_categories = list( all_categories = list(
set( set(
@ -282,7 +320,11 @@ class CmdHelp(Command):
return return
# Try to access a particular help entry or category # Try to access a particular help entry or category
entries = [cmd for cmd in all_cmds if cmd] + list(HelpEntry.objects.all()) + all_categories entries = (
[cmd for cmd in all_cmds if cmd]
+ list(HelpEntry.objects.all())
+ all_categories
)
for match_query in [f"{query}~1", f"{query}*"]: for match_query in [f"{query}~1", f"{query}*"]:
# We first do an exact word-match followed by a start-by query # We first do an exact word-match followed by a start-by query
@ -407,14 +449,19 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
self.msg("You have to define a topic!") self.msg("You have to define a topic!")
return return
topicstrlist = topicstr.split(";") topicstrlist = topicstr.split(";")
topicstr, aliases = (topicstrlist[0], topicstrlist[1:] if len(topicstr) > 1 else []) topicstr, aliases = (
topicstrlist[0],
topicstrlist[1:] if len(topicstr) > 1 else [],
)
aliastxt = ("(aliases: %s)" % ", ".join(aliases)) if aliases else "" aliastxt = ("(aliases: %s)" % ", ".join(aliases)) if aliases else ""
old_entry = None old_entry = None
# check if we have an old entry with the same name # check if we have an old entry with the same name
try: try:
for querystr in topicstrlist: for querystr in topicstrlist:
old_entry = HelpEntry.objects.find_topicmatch(querystr) # also search by alias old_entry = HelpEntry.objects.find_topicmatch(
querystr
) # also search by alias
if old_entry: if old_entry:
old_entry = list(old_entry)[0] old_entry = list(old_entry)[0]
break break
@ -436,7 +483,11 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
helpentry = old_entry helpentry = old_entry
else: else:
helpentry = create.create_help_entry( helpentry = create.create_help_entry(
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases topicstr,
self.rhs,
category=category,
locks=lockstring,
aliases=aliases,
) )
self.caller.db._editing_help = helpentry self.caller.db._editing_help = helpentry
@ -453,7 +504,9 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
if "append" in switches or "merge" in switches or "extend" in switches: if "append" in switches or "merge" in switches or "extend" in switches:
# merge/append operations # merge/append operations
if not old_entry: if not old_entry:
self.msg("Could not find topic '%s'. You must give an exact name." % topicstr) self.msg(
"Could not find topic '%s'. You must give an exact name." % topicstr
)
return return
if not self.rhs: if not self.rhs:
self.msg("You must supply text to append/merge.") self.msg("You must supply text to append/merge.")
@ -500,7 +553,9 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases
) )
if new_entry: if new_entry:
self.msg("Topic '%s'%s was successfully created." % (topicstr, aliastxt)) self.msg(
"Topic '%s'%s was successfully created." % (topicstr, aliastxt)
)
if "edit" in switches: if "edit" in switches:
# open the line editor to edit the helptext # open the line editor to edit the helptext
self.caller.db._editing_help = new_entry self.caller.db._editing_help = new_entry
@ -515,5 +570,6 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
return return
else: else:
self.msg( self.msg(
"Error when creating topic '%s'%s! Contact an admin." % (topicstr, aliastxt) "Error when creating topic '%s'%s! Contact an admin."
% (topicstr, aliastxt)
) )

View file

@ -265,6 +265,18 @@ class TestGeneral(CommandTest):
class TestHelp(CommandTest): class TestHelp(CommandTest):
def setUp(self):
super().setUp()
# we need to set up a logger here since lunr takes over the logger otherwise
import logging
logging.basicConfig(level=logging.ERROR)
def tearDown(self):
super().tearDown()
import logging
logging.disable(level=logging.ERROR)
def test_help(self): def test_help(self):
self.call(help.CmdHelp(), "", "Admin", cmdset=CharacterCmdSet()) self.call(help.CmdHelp(), "", "Admin", cmdset=CharacterCmdSet())