Fix optimized prototype search mechanism. Still no dual db/mod search

This commit is contained in:
Griatch 2020-09-14 19:13:18 +02:00
parent f61c80caf7
commit 7307887185
3 changed files with 29 additions and 25 deletions

View file

@ -38,9 +38,7 @@ without arguments starts a full interactive Python console.
of texts (such as tables). New `justify` bool. Old `justify_kwargs` remains
but is now only used to pass extra kwargs into the justify function.
- EvMore `text` argument can now also be a list or a queryset. Querysets will be
sliced to only return the required data per page. EvMore takes a new kwarg
`page_formatter` which will be called for each page. This allows to customize
the display of queryset data, build a new EvTable per page etc.
sliced to only return the required data per page.
- Improve performance of `find` and `objects` commands on large data sets (strikaco)
- New `CHANNEL_HANDLER_CLASS` setting allows for replacing the ChannelHandler entirely.
- Made `py` interactive mode support regular quit() and more verbose.

View file

@ -410,22 +410,13 @@ def search_prototype(key=None, tags=None, require_single=False, return_iterators
.filter(scriptdb__pk__in=db_ids, db_key="prototype")
.values_list("db_value", flat=True)
)
if key:
matches = list(db_matches) + module_prototypes
nmatches = len(matches)
if nmatches > 1:
key = key.lower()
# avoid duplicates if an exact match exist between the two types
filter_matches = [
mta for mta in matches if mta.get("prototype_key") and mta["prototype_key"] == key
]
if filter_matches and len(filter_matches) < nmatches:
matches = filter_matches
nmatches = len(matches)
if nmatches != 1 and require_single:
raise KeyError("Found {} matching prototypes.".format(nmatches))
return matches
elif return_iterators:
if key and require_single:
nmodules = len(module_prototypes)
ndbprots = db_matches.count()
if nmodules + ndbprots != 1:
raise KeyError(f"Found {nmodules + ndbprots} matching prototypes.")
if return_iterators:
# trying to get the entire set of prototypes - we must paginate
# the result instead of trying to fetch the entire set at once
db_pages = Paginator(db_matches, 20)
@ -479,6 +470,8 @@ class PrototypeEvMore(EvMore):
# get use-permissions of readonly attributes (edit is always False)
display_tuples = []
print("page", page)
for prototype in page:
lock_use = caller.locks.check_lockstring(
caller, prototype.get("prototype_locks", ""), access_type="spawn", default=True
@ -538,16 +531,23 @@ def list_prototypes(caller, key=None, tags=None, show_non_use=False, show_non_ed
show_non_edit (bool, optional): Show also prototypes the caller may not edit.
session (Session, optional): If given, this is used for display formatting.
Returns:
table (EvTable or None): An EvTable representation of the prototypes. None
if no prototypes were found.
PrototypeEvMore: An EvMore subclass optimized for prototype listings.
None: If a `key` was given and no matches was found. In this case the caller
has already been notified.
"""
# this allows us to pass lists of empty strings
tags = [tag for tag in make_iter(tags) if tag]
if key is not None:
matches = search_prototype(key, tags)
if not matches:
caller.msg("No prototypes found.", session=session)
return None
if len(matches) < 2:
matches = [matches]
# get specific prototype (one value or exception)
return PrototypeEvMore(caller, [search_prototype(key, tags)],
return PrototypeEvMore(caller, matches,
session=session,
show_non_use=show_non_use,
show_non_edit=show_non_edit)

View file

@ -248,8 +248,11 @@ class EvMore(object):
"""
Pretty-print the page.
"""
pos = self._npos
text = self.page_formatter(self.paginator(pos))
pos = 0
text = "[no content]"
if self._npages > 0:
pos = self._npos
text = self.page_formatter(self.paginator(pos))
if show_footer:
page = _DISPLAY.format(text=text, pageno=pos + 1, pagemax=self._npages)
else:
@ -447,6 +450,7 @@ class EvMore(object):
if inherits_from(inp, "evennia.utils.evtable.EvTable"):
# an EvTable
self.init_evtable(inp)
self._paginator = self.paginator_index
elif isinstance(inp, QuerySet):
# a queryset
self.init_queryset(inp)
@ -457,13 +461,15 @@ class EvMore(object):
elif not isinstance(inp, str):
# anything else not a str
self.init_iterable(inp)
self._paginator = self.paginator_django
self._paginator = self.paginator_index
elif "\f" in inp:
# string with \f line-break markers in it
self.init_f_str(inp)
self._paginator = self.paginator_index
else:
# a string
self.init_str(inp)
self._paginator = self.paginator_index
def paginator(self, pageno):
"""