Ran black on sources
This commit is contained in:
parent
a9aae82092
commit
6929bec4e6
11 changed files with 100 additions and 163 deletions
|
|
@ -35,8 +35,8 @@ extensions = [
|
||||||
"sphinx.ext.githubpages",
|
"sphinx.ext.githubpages",
|
||||||
]
|
]
|
||||||
|
|
||||||
source_suffix = ['.md', '.rst']
|
source_suffix = [".md", ".rst"]
|
||||||
master_doc = 'index'
|
master_doc = "index"
|
||||||
|
|
||||||
# make sure sectionlabel references can be used as path/to/file:heading
|
# make sure sectionlabel references can be used as path/to/file:heading
|
||||||
autosectionlabel_prefix_document = True
|
autosectionlabel_prefix_document = True
|
||||||
|
|
@ -74,9 +74,9 @@ smv_tag_whitelist = r"^$"
|
||||||
# html_theme = 'scrolls'
|
# html_theme = 'scrolls'
|
||||||
# html_theme = 'agogo'
|
# html_theme = 'agogo'
|
||||||
# html_theme = "traditional"
|
# html_theme = "traditional"
|
||||||
html_theme = 'nature'
|
html_theme = "nature"
|
||||||
## html_theme = 'pyramid'
|
## html_theme = 'pyramid'
|
||||||
#html_theme = 'bizstyle'
|
# html_theme = 'bizstyle'
|
||||||
# html_theme = 'epub'
|
# html_theme = 'epub'
|
||||||
|
|
||||||
# Custom extras for sidebar
|
# Custom extras for sidebar
|
||||||
|
|
@ -100,23 +100,23 @@ pygments_style = "sphinx"
|
||||||
# -- Options for LaTeX output ------------------------------------------------
|
# -- Options for LaTeX output ------------------------------------------------
|
||||||
# experimental, not working well atm
|
# experimental, not working well atm
|
||||||
|
|
||||||
latex_engine = 'xelatex'
|
latex_engine = "xelatex"
|
||||||
latex_show_urls = 'footnote'
|
latex_show_urls = "footnote"
|
||||||
latex_elements = {
|
latex_elements = {
|
||||||
'papersize': 'a4paper',
|
"papersize": "a4paper",
|
||||||
'fncychap': r'\usepackage[Bjarne]{fncychap}',
|
"fncychap": r"\usepackage[Bjarne]{fncychap}",
|
||||||
'fontpkg': r'\usepackage{times,amsmath,amsfonts,amssymb,amsthm}',
|
"fontpkg": r"\usepackage{times,amsmath,amsfonts,amssymb,amsthm}",
|
||||||
'preamble': r'''
|
"preamble": r"""
|
||||||
\usepackage[utf8]{fontenc}
|
\usepackage[utf8]{fontenc}
|
||||||
\usepackage{amsmath,amsfonts,amssymb,amsthm}
|
\usepackage{amsmath,amsfonts,amssymb,amsthm}
|
||||||
\usepackage[math-style=literal]{unicode-math}
|
\usepackage[math-style=literal]{unicode-math}
|
||||||
\usepackage{newunicodechar}
|
\usepackage{newunicodechar}
|
||||||
\usepackage{graphicx}
|
\usepackage{graphicx}
|
||||||
'''
|
""",
|
||||||
}
|
}
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
(master_doc, 'main.tex', 'Sphinx format', 'Evennia', 'report'),
|
(master_doc, "main.tex", "Sphinx format", "Evennia", "report"),
|
||||||
("toc", 'toc.tex', 'TOC', 'Evennia', 'report')
|
("toc", "toc.tex", "TOC", "Evennia", "report"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -139,7 +139,7 @@ def url_resolver(url):
|
||||||
return _github_issue_choose
|
return _github_issue_choose
|
||||||
|
|
||||||
elif url.startswith(githubstart):
|
elif url.startswith(githubstart):
|
||||||
urlpath = url[len(githubstart):]
|
urlpath = url[len(githubstart) :]
|
||||||
if not (urlpath.startswith("develop/") or urlpath.startswith("master")):
|
if not (urlpath.startswith("develop/") or urlpath.startswith("master")):
|
||||||
urlpath = "master/" + urlpath
|
urlpath = "master/" + urlpath
|
||||||
return _github_code_root + urlpath
|
return _github_code_root + urlpath
|
||||||
|
|
@ -240,13 +240,15 @@ napoleon_use_rtype = True
|
||||||
# -- Main config setup ------------------------------------------
|
# -- Main config setup ------------------------------------------
|
||||||
# last setup steps for some plugins
|
# last setup steps for some plugins
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
app.connect("autodoc-skip-member", autodoc_skip_member)
|
app.connect("autodoc-skip-member", autodoc_skip_member)
|
||||||
app.add_transform(AutoStructify)
|
app.add_transform(AutoStructify)
|
||||||
|
|
||||||
# build toctree file
|
# build toctree file
|
||||||
sys.path.insert(1, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'docs'))
|
sys.path.insert(1, os.path.join(os.path.dirname(os.path.dirname(__file__)), "docs"))
|
||||||
from docs.pylib import create_toctree
|
from docs.pylib import create_toctree
|
||||||
|
|
||||||
create_toctree.create_toctree()
|
create_toctree.create_toctree()
|
||||||
print("Updated source/toc.md file")
|
print("Updated source/toc.md file")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,9 +92,7 @@ def help_search_with_index(query, candidate_entries, suggestion_maxnum=5):
|
||||||
# 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
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -140,10 +138,7 @@ 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 (
|
if self.session and self.session.protocol_key in ("websocket", "ajax/comet",):
|
||||||
"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"]:
|
||||||
|
|
@ -177,9 +172,7 @@ 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" % (
|
string += " |C(aliases: %s|C)|n" % ("|C,|n ".join("|w%s|n" % ali for ali in aliases))
|
||||||
"|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:
|
||||||
|
|
@ -206,22 +199,15 @@ class CmdHelp(Command):
|
||||||
category_str = f"-- {category.title()} "
|
category_str = f"-- {category.title()} "
|
||||||
grid.append(
|
grid.append(
|
||||||
ANSIString(
|
ANSIString(
|
||||||
category_clr
|
category_clr + category_str + "-" * (width - len(category_str)) + topic_clr
|
||||||
+ category_str
|
|
||||||
+ "-" * (width - len(category_str))
|
|
||||||
+ topic_clr
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
verbatim_elements.append(len(grid) - 1)
|
verbatim_elements.append(len(grid) - 1)
|
||||||
|
|
||||||
entries = sorted(
|
entries = sorted(set(hdict_cmds.get(category, []) + hdict_db.get(category, [])))
|
||||||
set(hdict_cmds.get(category, []) + hdict_db.get(category, []))
|
|
||||||
)
|
|
||||||
grid.extend(entries)
|
grid.extend(entries)
|
||||||
|
|
||||||
gridrows = format_grid(
|
gridrows = format_grid(grid, width, sep=" ", verbatim_elements=verbatim_elements)
|
||||||
grid, width, sep=" ", verbatim_elements=verbatim_elements
|
|
||||||
)
|
|
||||||
gridrows = ANSIString("\n").join(gridrows)
|
gridrows = ANSIString("\n").join(gridrows)
|
||||||
return gridrows
|
return gridrows
|
||||||
|
|
||||||
|
|
@ -293,9 +279,7 @@ 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
|
topic for topic in HelpEntry.objects.all() if topic.access(caller, "view", default=True)
|
||||||
for topic in HelpEntry.objects.all()
|
|
||||||
if topic.access(caller, "view", default=True)
|
|
||||||
]
|
]
|
||||||
all_categories = list(
|
all_categories = list(
|
||||||
set(
|
set(
|
||||||
|
|
@ -320,11 +304,7 @@ class CmdHelp(Command):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Try to access a particular help entry or category
|
# Try to access a particular help entry or category
|
||||||
entries = (
|
entries = [cmd for cmd in all_cmds if cmd] + list(HelpEntry.objects.all()) + all_categories
|
||||||
[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
|
||||||
|
|
@ -459,9 +439,7 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
||||||
# 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(
|
old_entry = HelpEntry.objects.find_topicmatch(querystr) # also search by alias
|
||||||
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
|
||||||
|
|
@ -483,11 +461,7 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
||||||
helpentry = old_entry
|
helpentry = old_entry
|
||||||
else:
|
else:
|
||||||
helpentry = create.create_help_entry(
|
helpentry = create.create_help_entry(
|
||||||
topicstr,
|
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases,
|
||||||
self.rhs,
|
|
||||||
category=category,
|
|
||||||
locks=lockstring,
|
|
||||||
aliases=aliases,
|
|
||||||
)
|
)
|
||||||
self.caller.db._editing_help = helpentry
|
self.caller.db._editing_help = helpentry
|
||||||
|
|
||||||
|
|
@ -504,9 +478,7 @@ 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(
|
self.msg("Could not find topic '%s'. You must give an exact name." % topicstr)
|
||||||
"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.")
|
||||||
|
|
@ -553,9 +525,7 @@ 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(
|
self.msg("Topic '%s'%s was successfully created." % (topicstr, aliastxt))
|
||||||
"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
|
||||||
|
|
@ -570,6 +540,5 @@ class CmdSetHelp(COMMAND_DEFAULT_CLASS):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.msg(
|
self.msg(
|
||||||
"Error when creating topic '%s'%s! Contact an admin."
|
"Error when creating topic '%s'%s! Contact an admin." % (topicstr, aliastxt)
|
||||||
% (topicstr, aliastxt)
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -265,16 +265,17 @@ class TestGeneral(CommandTest):
|
||||||
|
|
||||||
|
|
||||||
class TestHelp(CommandTest):
|
class TestHelp(CommandTest):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
# we need to set up a logger here since lunr takes over the logger otherwise
|
# we need to set up a logger here since lunr takes over the logger otherwise
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logging.basicConfig(level=logging.ERROR)
|
logging.basicConfig(level=logging.ERROR)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logging.disable(level=logging.ERROR)
|
logging.disable(level=logging.ERROR)
|
||||||
|
|
||||||
def test_help(self):
|
def test_help(self):
|
||||||
|
|
|
||||||
|
|
@ -611,7 +611,6 @@ class CmdUsePuzzleParts(MuxCommand):
|
||||||
passed in.
|
passed in.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
key = "use"
|
key = "use"
|
||||||
aliases = "combine"
|
aliases = "combine"
|
||||||
locks = "cmd:pperm(use) or pperm(Player)"
|
locks = "cmd:pperm(use) or pperm(Player)"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from django.utils.unittest import TestCase
|
from django.utils.unittest import TestCase
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|
@ -290,7 +289,7 @@ class TestWebSocket(EvenniaTest):
|
||||||
self.proto.sessionhandler = PORTAL_SESSIONS
|
self.proto.sessionhandler = PORTAL_SESSIONS
|
||||||
self.proto.sessionhandler.portal = Mock()
|
self.proto.sessionhandler.portal = Mock()
|
||||||
self.proto.transport = proto_helpers.StringTransport()
|
self.proto.transport = proto_helpers.StringTransport()
|
||||||
#self.proto.transport = proto_helpers.FakeDatagramTransport()
|
# self.proto.transport = proto_helpers.FakeDatagramTransport()
|
||||||
self.proto.transport.client = ["localhost"]
|
self.proto.transport.client = ["localhost"]
|
||||||
self.proto.transport.setTcpKeepAlive = Mock()
|
self.proto.transport.setTcpKeepAlive = Mock()
|
||||||
self.proto.state = MagicMock()
|
self.proto.state = MagicMock()
|
||||||
|
|
@ -318,4 +317,4 @@ class TestWebSocket(EvenniaTest):
|
||||||
self.proto.sendLine = MagicMock()
|
self.proto.sendLine = MagicMock()
|
||||||
msg = json.dumps(["logged_in", (), {}])
|
msg = json.dumps(["logged_in", (), {}])
|
||||||
self.proto.sessionhandler.data_out(self.proto, text=[["Excepting Alice"], {}])
|
self.proto.sessionhandler.data_out(self.proto, text=[["Excepting Alice"], {}])
|
||||||
self.proto.sendLine.assert_called_with(json.dumps(['text', ['Excepting Alice'], {}]))
|
self.proto.sendLine.assert_called_with(json.dumps(["text", ["Excepting Alice"], {}]))
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ def _server_maintenance():
|
||||||
else:
|
else:
|
||||||
# adjust the runtime not with 60s but with the actual elapsed time
|
# adjust the runtime not with 60s but with the actual elapsed time
|
||||||
# in case this may varies slightly from 60s.
|
# in case this may varies slightly from 60s.
|
||||||
_GAMETIME_MODULE.SERVER_RUNTIME += (now - _LAST_SERVER_TIME_SNAPSHOT)
|
_GAMETIME_MODULE.SERVER_RUNTIME += now - _LAST_SERVER_TIME_SNAPSHOT
|
||||||
_LAST_SERVER_TIME_SNAPSHOT = now
|
_LAST_SERVER_TIME_SNAPSHOT = now
|
||||||
|
|
||||||
# update game time and save it across reloads
|
# update game time and save it across reloads
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ class Attribute(IAttribute, SharedMemoryModel):
|
||||||
"""
|
"""
|
||||||
This attribute is stored via Django. Most Attributes will be using this class.
|
This attribute is stored via Django. Most Attributes will be using this class.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Attribute Database Model setup
|
# Attribute Database Model setup
|
||||||
#
|
#
|
||||||
|
|
@ -269,10 +270,12 @@ class Attribute(IAttribute, SharedMemoryModel):
|
||||||
|
|
||||||
value = property(__value_get, __value_set, __value_del)
|
value = property(__value_get, __value_set, __value_del)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Handlers making use of the Attribute model
|
# Handlers making use of the Attribute model
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class IAttributeBackend:
|
class IAttributeBackend:
|
||||||
"""
|
"""
|
||||||
Abstract interface for the backends used by the Attribute Handler.
|
Abstract interface for the backends used by the Attribute Handler.
|
||||||
|
|
@ -336,8 +339,10 @@ class IAttributeBackend:
|
||||||
if not _TYPECLASS_AGGRESSIVE_CACHE:
|
if not _TYPECLASS_AGGRESSIVE_CACHE:
|
||||||
return
|
return
|
||||||
attrs = self.query_all()
|
attrs = self.query_all()
|
||||||
self._cache = {f"{to_str(attr.key).lower()}-{attr.category.lower() if attr.category else None}": attr
|
self._cache = {
|
||||||
for attr in attrs}
|
f"{to_str(attr.key).lower()}-{attr.category.lower() if attr.category else None}": attr
|
||||||
|
for attr in attrs
|
||||||
|
}
|
||||||
self._cache_complete = True
|
self._cache_complete = True
|
||||||
|
|
||||||
def _get_cache_key(self, key, category):
|
def _get_cache_key(self, key, category):
|
||||||
|
|
@ -623,7 +628,9 @@ class IAttributeBackend:
|
||||||
# update an existing attribute object
|
# update an existing attribute object
|
||||||
self.do_batch_update_attribute(attr_obj, category, lockstring, new_value, strattr)
|
self.do_batch_update_attribute(attr_obj, category, lockstring, new_value, strattr)
|
||||||
else:
|
else:
|
||||||
new_attr = self.do_create_attribute(keystr, category, lockstring, new_value, strvalue=strattr)
|
new_attr = self.do_create_attribute(
|
||||||
|
keystr, category, lockstring, new_value, strvalue=strattr
|
||||||
|
)
|
||||||
new_attrobjs.append(new_attr)
|
new_attrobjs.append(new_attr)
|
||||||
if new_attrobjs:
|
if new_attrobjs:
|
||||||
self.do_batch_finish(new_attrobjs)
|
self.do_batch_finish(new_attrobjs)
|
||||||
|
|
@ -696,8 +703,13 @@ class IAttributeBackend:
|
||||||
attrs = self._cache.values()
|
attrs = self._cache.values()
|
||||||
|
|
||||||
if accessing_obj:
|
if accessing_obj:
|
||||||
self.do_batch_delete([attr for attr in attrs if attr.access(accessing_obj, self._attredit,
|
self.do_batch_delete(
|
||||||
default=default_access)])
|
[
|
||||||
|
attr
|
||||||
|
for attr in attrs
|
||||||
|
if attr.access(accessing_obj, self._attredit, default=default_access)
|
||||||
|
]
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# have to cast the results to a list or we'll get a RuntimeError for removing from the dict we're iterating
|
# have to cast the results to a list or we'll get a RuntimeError for removing from the dict we're iterating
|
||||||
self.do_batch_delete(list(attrs))
|
self.do_batch_delete(list(attrs))
|
||||||
|
|
@ -765,7 +777,9 @@ class InMemoryAttributeBackend(IAttributeBackend):
|
||||||
|
|
||||||
strvalue has no meaning for InMemory attributes.
|
strvalue has no meaning for InMemory attributes.
|
||||||
"""
|
"""
|
||||||
new_attr = self._attrclass(pk=self._next_id(), key=key, category=category, lock_storage=lockstring, value=value)
|
new_attr = self._attrclass(
|
||||||
|
pk=self._next_id(), key=key, category=category, lock_storage=lockstring, value=value
|
||||||
|
)
|
||||||
self._storage[(key, category)] = new_attr
|
self._storage[(key, category)] = new_attr
|
||||||
self._category_storage[category].append(new_attr)
|
self._category_storage[category].append(new_attr)
|
||||||
return new_attr
|
return new_attr
|
||||||
|
|
@ -805,6 +819,7 @@ class ModelAttributeBackend(IAttributeBackend):
|
||||||
"""
|
"""
|
||||||
Uses Django models for storing Attributes.
|
Uses Django models for storing Attributes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_attrclass = Attribute
|
_attrclass = Attribute
|
||||||
_m2m_fieldname = "db_attributes"
|
_m2m_fieldname = "db_attributes"
|
||||||
|
|
||||||
|
|
@ -844,9 +859,7 @@ class ModelAttributeBackend(IAttributeBackend):
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
conn.attribute
|
conn.attribute
|
||||||
for conn in getattr(self.obj, self._m2m_fieldname).through.objects.filter(
|
for conn in getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)
|
||||||
**query
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def do_create_attribute(self, key, category, lockstring, value, strvalue):
|
def do_create_attribute(self, key, category, lockstring, value, strvalue):
|
||||||
|
|
@ -855,7 +868,7 @@ class ModelAttributeBackend(IAttributeBackend):
|
||||||
"db_category": category,
|
"db_category": category,
|
||||||
"db_model": self._model,
|
"db_model": self._model,
|
||||||
"db_lock_storage": lockstring if lockstring else "",
|
"db_lock_storage": lockstring if lockstring else "",
|
||||||
"db_attrtype": self._attrtype
|
"db_attrtype": self._attrtype,
|
||||||
}
|
}
|
||||||
if strvalue:
|
if strvalue:
|
||||||
kwargs["db_value"] = None
|
kwargs["db_value"] = None
|
||||||
|
|
@ -901,6 +914,7 @@ class AttributeHandler:
|
||||||
"""
|
"""
|
||||||
Handler for adding Attributes to the object.
|
Handler for adding Attributes to the object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_attrcreate = "attrcreate"
|
_attrcreate = "attrcreate"
|
||||||
_attredit = "attredit"
|
_attredit = "attredit"
|
||||||
_attrread = "attrread"
|
_attrread = "attrread"
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
|
|
||||||
# Attribute manager methods
|
# Attribute manager methods
|
||||||
def get_attribute(
|
def get_attribute(
|
||||||
self,
|
self, key=None, category=None, value=None, strvalue=None, obj=None, attrtype=None, **kwargs
|
||||||
key=None,
|
|
||||||
category=None,
|
|
||||||
value=None,
|
|
||||||
strvalue=None,
|
|
||||||
obj=None,
|
|
||||||
attrtype=None,
|
|
||||||
**kwargs
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Return Attribute objects by key, by category, by value, by
|
Return Attribute objects by key, by category, by value, by
|
||||||
|
|
@ -82,9 +75,9 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
# no reason to make strvalue/value mutually exclusive at this level
|
# no reason to make strvalue/value mutually exclusive at this level
|
||||||
query.append(("attribute__db_value", value))
|
query.append(("attribute__db_value", value))
|
||||||
return Attribute.objects.filter(
|
return Attribute.objects.filter(
|
||||||
pk__in=self.model.db_attributes.through.objects.filter(
|
pk__in=self.model.db_attributes.through.objects.filter(**dict(query)).values_list(
|
||||||
**dict(query)
|
"attribute_id", flat=True
|
||||||
).values_list("attribute_id", flat=True)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_nick(self, key=None, category=None, value=None, strvalue=None, obj=None):
|
def get_nick(self, key=None, category=None, value=None, strvalue=None, obj=None):
|
||||||
|
|
@ -111,13 +104,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_by_attribute(
|
def get_by_attribute(
|
||||||
self,
|
self, key=None, category=None, value=None, strvalue=None, attrtype=None, **kwargs
|
||||||
key=None,
|
|
||||||
category=None,
|
|
||||||
value=None,
|
|
||||||
strvalue=None,
|
|
||||||
attrtype=None,
|
|
||||||
**kwargs
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Return objects having attributes with the given key, category,
|
Return objects having attributes with the given key, category,
|
||||||
|
|
@ -174,15 +161,11 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
obj (list): Objects having the matching Nicks.
|
obj (list): Objects having the matching Nicks.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get_by_attribute(
|
return self.get_by_attribute(key=key, category=category, strvalue=nick, attrtype="nick")
|
||||||
key=key, category=category, strvalue=nick, attrtype="nick"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Tag manager methods
|
# Tag manager methods
|
||||||
|
|
||||||
def get_tag(
|
def get_tag(self, key=None, category=None, obj=None, tagtype=None, global_search=False):
|
||||||
self, key=None, category=None, obj=None, tagtype=None, global_search=False
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Return Tag objects by key, by category, by object (it is
|
Return Tag objects by key, by category, by object (it is
|
||||||
stored on) or with a combination of those criteria.
|
stored on) or with a combination of those criteria.
|
||||||
|
|
@ -226,9 +209,9 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
if category:
|
if category:
|
||||||
query.append(("tag__db_category", category))
|
query.append(("tag__db_category", category))
|
||||||
return Tag.objects.filter(
|
return Tag.objects.filter(
|
||||||
pk__in=self.model.db_tags.through.objects.filter(
|
pk__in=self.model.db_tags.through.objects.filter(**dict(query)).values_list(
|
||||||
**dict(query)
|
"tag_id", flat=True
|
||||||
).values_list("tag_id", flat=True)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_permission(self, key=None, category=None, obj=None):
|
def get_permission(self, key=None, category=None, obj=None):
|
||||||
|
|
@ -310,9 +293,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
|
|
||||||
dbmodel = self.model.__dbclass__.__name__.lower()
|
dbmodel = self.model.__dbclass__.__name__.lower()
|
||||||
query = (
|
query = (
|
||||||
self.filter(
|
self.filter(db_tags__db_tagtype__iexact=tagtype, db_tags__db_model__iexact=dbmodel)
|
||||||
db_tags__db_tagtype__iexact=tagtype, db_tags__db_model__iexact=dbmodel
|
|
||||||
)
|
|
||||||
.distinct()
|
.distinct()
|
||||||
.order_by("id")
|
.order_by("id")
|
||||||
)
|
)
|
||||||
|
|
@ -332,9 +313,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
clauses = Q()
|
clauses = Q()
|
||||||
for ikey, key in enumerate(keys):
|
for ikey, key in enumerate(keys):
|
||||||
# ANY mode; must match any one of the given tags/categories
|
# ANY mode; must match any one of the given tags/categories
|
||||||
clauses |= Q(
|
clauses |= Q(db_key__iexact=key, db_category__iexact=categories[ikey])
|
||||||
db_key__iexact=key, db_category__iexact=categories[ikey]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# only one or more categories given
|
# only one or more categories given
|
||||||
clauses = Q()
|
clauses = Q()
|
||||||
|
|
@ -344,8 +323,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
|
|
||||||
tags = _Tag.objects.filter(clauses)
|
tags = _Tag.objects.filter(clauses)
|
||||||
query = query.filter(db_tags__in=tags).annotate(
|
query = query.filter(db_tags__in=tags).annotate(
|
||||||
matches=Count("db_tags__pk", filter=Q(db_tags__in=tags),
|
matches=Count("db_tags__pk", filter=Q(db_tags__in=tags), distinct=True)
|
||||||
distinct=True)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if anymatch:
|
if anymatch:
|
||||||
|
|
@ -412,9 +390,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
# try to get old tag
|
# try to get old tag
|
||||||
|
|
||||||
dbmodel = self.model.__dbclass__.__name__.lower()
|
dbmodel = self.model.__dbclass__.__name__.lower()
|
||||||
tag = self.get_tag(
|
tag = self.get_tag(key=key, category=category, tagtype=tagtype, global_search=True)
|
||||||
key=key, category=category, tagtype=tagtype, global_search=True
|
|
||||||
)
|
|
||||||
if tag and data is not None:
|
if tag and data is not None:
|
||||||
# get tag from list returned by get_tag
|
# get tag from list returned by get_tag
|
||||||
tag = tag[0]
|
tag = tag[0]
|
||||||
|
|
@ -428,9 +404,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
from evennia.typeclasses.models import Tag as _Tag
|
from evennia.typeclasses.models import Tag as _Tag
|
||||||
tag = _Tag.objects.create(
|
tag = _Tag.objects.create(
|
||||||
db_key=key.strip().lower() if key is not None else None,
|
db_key=key.strip().lower() if key is not None else None,
|
||||||
db_category=category.strip().lower()
|
db_category=category.strip().lower() if category and key is not None else None,
|
||||||
if category and key is not None
|
|
||||||
else None,
|
|
||||||
db_data=data,
|
db_data=data,
|
||||||
db_model=dbmodel,
|
db_model=dbmodel,
|
||||||
db_tagtype=tagtype.strip().lower() if tagtype is not None else None,
|
db_tagtype=tagtype.strip().lower() if tagtype is not None else None,
|
||||||
|
|
@ -539,8 +513,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
typeclass=F("db_typeclass_path"),
|
typeclass=F("db_typeclass_path"),
|
||||||
# Calculate this class' percentage of total composition
|
# Calculate this class' percentage of total composition
|
||||||
percent=ExpressionWrapper(
|
percent=ExpressionWrapper(
|
||||||
((F("count") / float(self.count())) * 100.0),
|
((F("count") / float(self.count())) * 100.0), output_field=FloatField(),
|
||||||
output_field=FloatField(),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.values("typeclass", "count", "percent")
|
.values("typeclass", "count", "percent")
|
||||||
|
|
@ -560,9 +533,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
|
||||||
stats = self.get_typeclass_totals().order_by("typeclass")
|
stats = self.get_typeclass_totals().order_by("typeclass")
|
||||||
return {x.get("typeclass"): x.get("count") for x in stats}
|
return {x.get("typeclass"): x.get("count") for x in stats}
|
||||||
|
|
||||||
def typeclass_search(
|
def typeclass_search(self, typeclass, include_children=False, include_parents=False):
|
||||||
self, typeclass, include_children=False, include_parents=False
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Searches through all objects returning those which has a
|
Searches through all objects returning those which has a
|
||||||
certain typeclass. If location is set, limit search to objects
|
certain typeclass. If location is set, limit search to objects
|
||||||
|
|
@ -837,8 +808,7 @@ class TypeclassManager(TypedObjectManager):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
paths = [self.model.path] + [
|
paths = [self.model.path] + [
|
||||||
"%s.%s" % (cls.__module__, cls.__name__)
|
"%s.%s" % (cls.__module__, cls.__name__) for cls in self._get_subclasses(self.model)
|
||||||
for cls in self._get_subclasses(self.model)
|
|
||||||
]
|
]
|
||||||
kwargs.update({"db_typeclass_path__in": paths})
|
kwargs.update({"db_typeclass_path__in": paths})
|
||||||
return super().get(**kwargs)
|
return super().get(**kwargs)
|
||||||
|
|
@ -860,8 +830,7 @@ class TypeclassManager(TypedObjectManager):
|
||||||
"""
|
"""
|
||||||
# query, including all subclasses
|
# query, including all subclasses
|
||||||
paths = [self.model.path] + [
|
paths = [self.model.path] + [
|
||||||
"%s.%s" % (cls.__module__, cls.__name__)
|
"%s.%s" % (cls.__module__, cls.__name__) for cls in self._get_subclasses(self.model)
|
||||||
for cls in self._get_subclasses(self.model)
|
|
||||||
]
|
]
|
||||||
kwargs.update({"db_typeclass_path__in": paths})
|
kwargs.update({"db_typeclass_path__in": paths})
|
||||||
return super().filter(*args, **kwargs)
|
return super().filter(*args, **kwargs)
|
||||||
|
|
@ -876,7 +845,6 @@ class TypeclassManager(TypedObjectManager):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
paths = [self.model.path] + [
|
paths = [self.model.path] + [
|
||||||
"%s.%s" % (cls.__module__, cls.__name__)
|
"%s.%s" % (cls.__module__, cls.__name__) for cls in self._get_subclasses(self.model)
|
||||||
for cls in self._get_subclasses(self.model)
|
|
||||||
]
|
]
|
||||||
return super().all().filter(db_typeclass_path__in=paths)
|
return super().all().filter(db_typeclass_path__in=paths)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,12 @@ from django.urls import reverse
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
|
|
||||||
from evennia.typeclasses.attributes import Attribute, AttributeHandler, ModelAttributeBackend, InMemoryAttributeBackend
|
from evennia.typeclasses.attributes import (
|
||||||
|
Attribute,
|
||||||
|
AttributeHandler,
|
||||||
|
ModelAttributeBackend,
|
||||||
|
InMemoryAttributeBackend,
|
||||||
|
)
|
||||||
from evennia.typeclasses.attributes import DbHolder
|
from evennia.typeclasses.attributes import DbHolder
|
||||||
from evennia.typeclasses.tags import Tag, TagHandler, AliasHandler, PermissionHandler
|
from evennia.typeclasses.tags import Tag, TagHandler, AliasHandler, PermissionHandler
|
||||||
|
|
||||||
|
|
@ -122,6 +127,7 @@ class TypeclassBase(SharedMemoryModelBase):
|
||||||
signals.pre_delete.connect(remove_attributes_on_delete, sender=new_class)
|
signals.pre_delete.connect(remove_attributes_on_delete, sender=new_class)
|
||||||
return new_class
|
return new_class
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Main TypedObject abstraction
|
# Main TypedObject abstraction
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -58,16 +58,12 @@ class TestTypedObjectManager(EvenniaTest):
|
||||||
self.obj2.tags.add("tag4")
|
self.obj2.tags.add("tag4")
|
||||||
self.obj2.tags.add("tag2c")
|
self.obj2.tags.add("tag2c")
|
||||||
self.assertEqual(self._manager("get_by_tag", "tag1"), [self.obj1])
|
self.assertEqual(self._manager("get_by_tag", "tag1"), [self.obj1])
|
||||||
self.assertEqual(
|
self.assertEqual(set(self._manager("get_by_tag", "tag2")), set([self.obj1, self.obj2]))
|
||||||
set(self._manager("get_by_tag", "tag2")), set([self.obj1, self.obj2])
|
|
||||||
)
|
|
||||||
self.assertEqual(self._manager("get_by_tag", "tag2a"), [self.obj2])
|
self.assertEqual(self._manager("get_by_tag", "tag2a"), [self.obj2])
|
||||||
self.assertEqual(self._manager("get_by_tag", "tag3 with spaces"), [self.obj2])
|
self.assertEqual(self._manager("get_by_tag", "tag3 with spaces"), [self.obj2])
|
||||||
self.assertEqual(self._manager("get_by_tag", ["tag2a", "tag2b"]), [self.obj2])
|
self.assertEqual(self._manager("get_by_tag", ["tag2a", "tag2b"]), [self.obj2])
|
||||||
self.assertEqual(self._manager("get_by_tag", ["tag2a", "tag1"]), [])
|
self.assertEqual(self._manager("get_by_tag", ["tag2a", "tag1"]), [])
|
||||||
self.assertEqual(
|
self.assertEqual(self._manager("get_by_tag", ["tag2a", "tag4", "tag2c"]), [self.obj2])
|
||||||
self._manager("get_by_tag", ["tag2a", "tag4", "tag2c"]), [self.obj2]
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_get_by_tag_and_category(self):
|
def test_get_by_tag_and_category(self):
|
||||||
self.obj1.tags.add("tag5", "category1")
|
self.obj1.tags.add("tag5", "category1")
|
||||||
|
|
@ -83,24 +79,17 @@ class TestTypedObjectManager(EvenniaTest):
|
||||||
self.obj1.tags.add("tag8", "category6")
|
self.obj1.tags.add("tag8", "category6")
|
||||||
self.obj2.tags.add("tag9", "category6")
|
self.obj2.tags.add("tag9", "category6")
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(self._manager("get_by_tag", "tag5", "category1"), [self.obj1, self.obj2])
|
||||||
self._manager("get_by_tag", "tag5", "category1"), [self.obj1, self.obj2]
|
|
||||||
)
|
|
||||||
self.assertEqual(self._manager("get_by_tag", "tag6", "category1"), [])
|
self.assertEqual(self._manager("get_by_tag", "tag6", "category1"), [])
|
||||||
self.assertEqual(
|
self.assertEqual(self._manager("get_by_tag", "tag6", "category3"), [self.obj1, self.obj2])
|
||||||
self._manager("get_by_tag", "tag6", "category3"), [self.obj1, self.obj2]
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self._manager("get_by_tag", ["tag5", "tag6"], ["category1", "category3"]),
|
self._manager("get_by_tag", ["tag5", "tag6"], ["category1", "category3"]),
|
||||||
[self.obj1, self.obj2],
|
[self.obj1, self.obj2],
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self._manager("get_by_tag", ["tag5", "tag7"], "category1"),
|
self._manager("get_by_tag", ["tag5", "tag7"], "category1"), [self.obj1, self.obj2],
|
||||||
[self.obj1, self.obj2],
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self._manager("get_by_tag", category="category1"), [self.obj1, self.obj2]
|
|
||||||
)
|
)
|
||||||
|
self.assertEqual(self._manager("get_by_tag", category="category1"), [self.obj1, self.obj2])
|
||||||
self.assertEqual(self._manager("get_by_tag", category="category2"), [self.obj2])
|
self.assertEqual(self._manager("get_by_tag", category="category2"), [self.obj2])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self._manager("get_by_tag", category=["category1", "category3"]),
|
self._manager("get_by_tag", category=["category1", "category3"]),
|
||||||
|
|
@ -110,39 +99,27 @@ class TestTypedObjectManager(EvenniaTest):
|
||||||
self._manager("get_by_tag", category=["category1", "category2"]),
|
self._manager("get_by_tag", category=["category1", "category2"]),
|
||||||
[self.obj1, self.obj2],
|
[self.obj1, self.obj2],
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(self._manager("get_by_tag", category=["category5", "category4"]), [])
|
||||||
self._manager("get_by_tag", category=["category5", "category4"]), []
|
self.assertEqual(self._manager("get_by_tag", category="category1"), [self.obj1, self.obj2])
|
||||||
)
|
self.assertEqual(self._manager("get_by_tag", category="category6"), [self.obj1, self.obj2])
|
||||||
self.assertEqual(
|
|
||||||
self._manager("get_by_tag", category="category1"), [self.obj1, self.obj2]
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
self._manager("get_by_tag", category="category6"), [self.obj1, self.obj2]
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_get_tag_with_all(self):
|
def test_get_tag_with_all(self):
|
||||||
self.obj1.tags.add("tagA", "categoryA")
|
self.obj1.tags.add("tagA", "categoryA")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self._manager(
|
self._manager("get_by_tag", ["tagA", "tagB"], ["categoryA", "categoryB"], match="all"),
|
||||||
"get_by_tag", ["tagA", "tagB"], ["categoryA", "categoryB"], match="all"
|
|
||||||
),
|
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_get_tag_with_any(self):
|
def test_get_tag_with_any(self):
|
||||||
self.obj1.tags.add("tagA", "categoryA")
|
self.obj1.tags.add("tagA", "categoryA")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self._manager(
|
self._manager("get_by_tag", ["tagA", "tagB"], ["categoryA", "categoryB"], match="any"),
|
||||||
"get_by_tag", ["tagA", "tagB"], ["categoryA", "categoryB"], match="any"
|
|
||||||
),
|
|
||||||
[self.obj1],
|
[self.obj1],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_get_tag_withnomatch(self):
|
def test_get_tag_withnomatch(self):
|
||||||
self.obj1.tags.add("tagC", "categoryC")
|
self.obj1.tags.add("tagC", "categoryC")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self._manager(
|
self._manager("get_by_tag", ["tagA", "tagB"], ["categoryA", "categoryB"], match="any"),
|
||||||
"get_by_tag", ["tagA", "tagB"], ["categoryA", "categoryB"], match="any"
|
|
||||||
),
|
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -158,11 +158,13 @@ class EvenniaTest(TestCase):
|
||||||
self.account2.delete()
|
self.account2.delete()
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
|
|
||||||
|
|
||||||
class LocalEvenniaTest(EvenniaTest):
|
class LocalEvenniaTest(EvenniaTest):
|
||||||
"""
|
"""
|
||||||
This test class is intended for inheriting in mygame tests.
|
This test class is intended for inheriting in mygame tests.
|
||||||
It helps ensure your tests are run with your own objects.
|
It helps ensure your tests are run with your own objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
account_typeclass = settings.BASE_ACCOUNT_TYPECLASS
|
account_typeclass = settings.BASE_ACCOUNT_TYPECLASS
|
||||||
object_typeclass = settings.BASE_OBJECT_TYPECLASS
|
object_typeclass = settings.BASE_OBJECT_TYPECLASS
|
||||||
character_typeclass = settings.BASE_CHARACTER_TYPECLASS
|
character_typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue