Handle going from location=None to unset and back in prototype, as per #2005
This commit is contained in:
parent
bea61b289e
commit
8c44766c0a
5 changed files with 59 additions and 34 deletions
|
|
@ -54,7 +54,8 @@ without arguments starts a full interactive Python console.
|
||||||
bugfixes.
|
bugfixes.
|
||||||
- Remove `dummy@example.com` as a default account email when unset, a string is no longer
|
- Remove `dummy@example.com` as a default account email when unset, a string is no longer
|
||||||
required by Django.
|
required by Django.
|
||||||
- Fixes to `spawn`, make updating an existing prototype/object work better.
|
- Fixes to `spawn`, make updating an existing prototype/object work better. Add `/raw` switch
|
||||||
|
to `spawn` command to extract the raw prototype dict for manual editing.
|
||||||
|
|
||||||
|
|
||||||
## Evennia 0.9 (2018-2019)
|
## Evennia 0.9 (2018-2019)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ from evennia.utils.utils import (
|
||||||
class_from_module,
|
class_from_module,
|
||||||
get_all_typeclasses,
|
get_all_typeclasses,
|
||||||
variable_from_module,
|
variable_from_module,
|
||||||
dbref, interactive
|
dbref, interactive,
|
||||||
|
list_to_string
|
||||||
)
|
)
|
||||||
from evennia.utils.eveditor import EvEditor
|
from evennia.utils.eveditor import EvEditor
|
||||||
from evennia.utils.evmore import EvMore
|
from evennia.utils.evmore import EvMore
|
||||||
|
|
@ -3253,6 +3254,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
search - search prototype by name or tags.
|
search - search prototype by name or tags.
|
||||||
list - list available prototypes, optionally limit by tags.
|
list - list available prototypes, optionally limit by tags.
|
||||||
show, examine - inspect prototype by key. If not given, acts like list.
|
show, examine - inspect prototype by key. If not given, acts like list.
|
||||||
|
raw - show the raw dict of the prototype as a one-line string for manual editing.
|
||||||
save - save a prototype to the database. It will be listable by /list.
|
save - save a prototype to the database. It will be listable by /list.
|
||||||
delete - remove a prototype from database, if allowed to.
|
delete - remove a prototype from database, if allowed to.
|
||||||
update - find existing objects with the same prototype_key and update
|
update - find existing objects with the same prototype_key and update
|
||||||
|
|
@ -3301,6 +3303,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
"search",
|
"search",
|
||||||
"list",
|
"list",
|
||||||
"show",
|
"show",
|
||||||
|
"raw",
|
||||||
"examine",
|
"examine",
|
||||||
"save",
|
"save",
|
||||||
"delete",
|
"delete",
|
||||||
|
|
@ -3433,9 +3436,12 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
def _list_prototypes(self, key=None, tags=None):
|
def _list_prototypes(self, key=None, tags=None):
|
||||||
"""Display prototypes as a list, optionally limited by key/tags. """
|
"""Display prototypes as a list, optionally limited by key/tags. """
|
||||||
|
table = protlib.list_prototypes(self.caller, key=key, tags=tags)
|
||||||
|
if not table:
|
||||||
|
return True
|
||||||
EvMore(
|
EvMore(
|
||||||
self.caller,
|
self.caller,
|
||||||
str(protlib.list_prototypes(self.caller, key=key, tags=tags)),
|
str(table),
|
||||||
exit_on_lastpage=True,
|
exit_on_lastpage=True,
|
||||||
justify_kwargs=False,
|
justify_kwargs=False,
|
||||||
)
|
)
|
||||||
|
|
@ -3492,8 +3498,8 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
Parse ;-separated input list.
|
Parse ;-separated input list.
|
||||||
"""
|
"""
|
||||||
key, desc, tags = "", "", []
|
key, desc, tags = "", "", []
|
||||||
if ";" in self.args:
|
if ";" in argstring:
|
||||||
parts = (part.strip().lower() for part in self.args.split(";"))
|
parts = [part.strip().lower() for part in argstring.split(";")]
|
||||||
if len(parts) > 1 and desc:
|
if len(parts) > 1 and desc:
|
||||||
key = parts[0]
|
key = parts[0]
|
||||||
desc = parts[1]
|
desc = parts[1]
|
||||||
|
|
@ -3537,10 +3543,20 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
return
|
return
|
||||||
|
|
||||||
# search for key;tag combinations
|
# search for key;tag combinations
|
||||||
key, _, tags = self._parse_key_desc_tags(self.args, desc=False)
|
key, _, tags = self._parse_key_desc_tags(self.args, desc=False)
|
||||||
self._list_prototypes(key, tags)
|
self._list_prototypes(key, tags)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if "raw" in self.switches:
|
||||||
|
# query for key match and return the prototype as a safe one-liner string.
|
||||||
|
if not self.args:
|
||||||
|
caller.msg("You need to specify a prototype-key to get the raw data for.")
|
||||||
|
prototype = self._search_prototype(self.args)
|
||||||
|
if not prototype:
|
||||||
|
return
|
||||||
|
caller.msg(str(prototype))
|
||||||
|
return
|
||||||
|
|
||||||
if "show" in self.switches or "examine" in self.switches:
|
if "show" in self.switches or "examine" in self.switches:
|
||||||
# show a specific prot detail. The argument is a search query or empty.
|
# show a specific prot detail. The argument is a search query or empty.
|
||||||
if not self.args:
|
if not self.args:
|
||||||
|
|
@ -3556,7 +3572,11 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||||
|
|
||||||
if "list" in self.switches:
|
if "list" in self.switches:
|
||||||
# for list, all optional arguments are tags.
|
# for list, all optional arguments are tags.
|
||||||
self._list_prototypes(tags=self.lhslist)
|
tags = self.lhslist
|
||||||
|
err = self._list_prototypes(tags=tags)
|
||||||
|
if err:
|
||||||
|
caller.msg("No prototypes found with prototype-tag(s): {}".format(
|
||||||
|
list_to_string(tags, "or")))
|
||||||
return
|
return
|
||||||
|
|
||||||
if "save" in self.switches:
|
if "save" in self.switches:
|
||||||
|
|
|
||||||
|
|
@ -2294,7 +2294,8 @@ def node_apply_diff(caller, **kwargs):
|
||||||
if not custom_location:
|
if not custom_location:
|
||||||
diff.pop("location", None)
|
diff.pop("location", None)
|
||||||
|
|
||||||
txt, options = _format_diff_text_and_options(diff, objects=update_objects, base_obj=base_obj)
|
txt, options = _format_diff_text_and_options(diff, objects=update_objects,
|
||||||
|
base_obj=base_obj, prototype=prototype)
|
||||||
|
|
||||||
if options:
|
if options:
|
||||||
text = [
|
text = [
|
||||||
|
|
|
||||||
|
|
@ -272,10 +272,10 @@ def save_prototype(prototype):
|
||||||
stored_prototype = create_script(
|
stored_prototype = create_script(
|
||||||
DbPrototype,
|
DbPrototype,
|
||||||
key=prototype_key,
|
key=prototype_key,
|
||||||
desc=prototype["prototype_desc"],
|
desc=in_prototype["prototype_desc"],
|
||||||
persistent=True,
|
persistent=True,
|
||||||
locks=prototype_locks,
|
locks=prototype_locks,
|
||||||
tags=prototype["prototype_tags"],
|
tags=in_prototype["prototype_tags"],
|
||||||
attributes=[("prototype", in_prototype)],
|
attributes=[("prototype", in_prototype)],
|
||||||
)
|
)
|
||||||
return stored_prototype.prototype
|
return stored_prototype.prototype
|
||||||
|
|
@ -724,15 +724,15 @@ def prototype_to_str(prototype):
|
||||||
prototype_desc=prototype.get("prototype_desc", "|wNone|n"),
|
prototype_desc=prototype.get("prototype_desc", "|wNone|n"),
|
||||||
prototype_parent=prototype.get("prototype_parent", "|wNone|n"),
|
prototype_parent=prototype.get("prototype_parent", "|wNone|n"),
|
||||||
)
|
)
|
||||||
|
key = aliases = attrs = tags = locks = permissions = location = home = destination = ""
|
||||||
key = prototype.get("key", "")
|
if "key" in prototype:
|
||||||
if key:
|
key = prototype["key"]
|
||||||
key = "|ckey:|n {key}".format(key=key)
|
key = "|ckey:|n {key}".format(key=key)
|
||||||
aliases = prototype.get("aliases", "")
|
if "aliases" in prototype:
|
||||||
if aliases:
|
aliases = prototype["aliases"]
|
||||||
aliases = "|caliases:|n {aliases}".format(aliases=", ".join(aliases))
|
aliases = "|caliases:|n {aliases}".format(aliases=", ".join(aliases))
|
||||||
attrs = prototype.get("attrs", "")
|
if "attrs" in prototype:
|
||||||
if attrs:
|
attrs = prototype["attrs"]
|
||||||
out = []
|
out = []
|
||||||
for (attrkey, value, category, locks) in attrs:
|
for (attrkey, value, category, locks) in attrs:
|
||||||
locks = ", ".join(lock for lock in locks if lock)
|
locks = ", ".join(lock for lock in locks if lock)
|
||||||
|
|
@ -751,8 +751,8 @@ def prototype_to_str(prototype):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
attrs = "|cattrs:|n\n {attrs}".format(attrs="\n ".join(out))
|
attrs = "|cattrs:|n\n {attrs}".format(attrs="\n ".join(out))
|
||||||
tags = prototype.get("tags", "")
|
if "tags" in prototype:
|
||||||
if tags:
|
tags = prototype['tags']
|
||||||
out = []
|
out = []
|
||||||
for (tagkey, category, data) in tags:
|
for (tagkey, category, data) in tags:
|
||||||
out.append(
|
out.append(
|
||||||
|
|
@ -761,20 +761,20 @@ def prototype_to_str(prototype):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
tags = "|ctags:|n\n {tags}".format(tags=", ".join(out))
|
tags = "|ctags:|n\n {tags}".format(tags=", ".join(out))
|
||||||
locks = prototype.get("locks", "")
|
if "locks" in prototype:
|
||||||
if locks:
|
locks = prototype["locks"]
|
||||||
locks = "|clocks:|n\n {locks}".format(locks=locks)
|
locks = "|clocks:|n\n {locks}".format(locks=locks)
|
||||||
permissions = prototype.get("permissions", "")
|
if "permissions" in prototype:
|
||||||
if permissions:
|
permissions = prototype["permissions"]
|
||||||
permissions = "|cpermissions:|n {perms}".format(perms=", ".join(permissions))
|
permissions = "|cpermissions:|n {perms}".format(perms=", ".join(permissions))
|
||||||
location = prototype.get("location", "")
|
if "location" in prototype:
|
||||||
if location:
|
location = prototype["location"]
|
||||||
location = "|clocation:|n {location}".format(location=location)
|
location = "|clocation:|n {location}".format(location=location)
|
||||||
home = prototype.get("home", "")
|
if "home" in prototype:
|
||||||
if home:
|
home = prototype["home"]
|
||||||
home = "|chome:|n {home}".format(home=home)
|
home = "|chome:|n {home}".format(home=home)
|
||||||
destination = prototype.get("destination", "")
|
if "destination" in prototype:
|
||||||
if destination:
|
destination = prototype["destination"]
|
||||||
destination = "|cdestination:|n {destination}".format(destination=destination)
|
destination = "|cdestination:|n {destination}".format(destination=destination)
|
||||||
|
|
||||||
body = "\n".join(
|
body = "\n".join(
|
||||||
|
|
|
||||||
|
|
@ -354,6 +354,9 @@ def prototype_diff(prototype1, prototype2, maxdepth=2, homogenize=False, implici
|
||||||
class Unset:
|
class Unset:
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return False
|
return False
|
||||||
|
def __str__(self):
|
||||||
|
return "<Unset>"
|
||||||
|
|
||||||
_unset = Unset()
|
_unset = Unset()
|
||||||
|
|
||||||
def _recursive_diff(old, new, depth=0):
|
def _recursive_diff(old, new, depth=0):
|
||||||
|
|
@ -361,10 +364,10 @@ def prototype_diff(prototype1, prototype2, maxdepth=2, homogenize=False, implici
|
||||||
old_type = type(old)
|
old_type = type(old)
|
||||||
new_type = type(new)
|
new_type = type(new)
|
||||||
|
|
||||||
if old_type == new_type and not (old and new):
|
if old_type == new_type and not (old or new):
|
||||||
# both old and new are unset, like [] or None
|
# both old and new are unset, like [] or None
|
||||||
return (old, new, "KEEP")
|
return (None, None, "KEEP")
|
||||||
elif old_type != new_type:
|
if old_type != new_type:
|
||||||
if old and not new:
|
if old and not new:
|
||||||
if depth < maxdepth and old_type == dict:
|
if depth < maxdepth and old_type == dict:
|
||||||
return {key: (part, None, "REMOVE") for key, part in old.items()}
|
return {key: (part, None, "REMOVE") for key, part in old.items()}
|
||||||
|
|
@ -388,7 +391,7 @@ def prototype_diff(prototype1, prototype2, maxdepth=2, homogenize=False, implici
|
||||||
elif depth < maxdepth and new_type == dict:
|
elif depth < maxdepth and new_type == dict:
|
||||||
all_keys = set(list(old.keys()) + list(new.keys()))
|
all_keys = set(list(old.keys()) + list(new.keys()))
|
||||||
return {
|
return {
|
||||||
key: _recursive_diff(old.get(key), new.get(key, _unset), depth=depth + 1)
|
key: _recursive_diff(old.get(key, _unset), new.get(key, _unset), depth=depth + 1)
|
||||||
for key in all_keys
|
for key in all_keys
|
||||||
}
|
}
|
||||||
elif depth < maxdepth and is_iter(new):
|
elif depth < maxdepth and is_iter(new):
|
||||||
|
|
@ -396,7 +399,7 @@ def prototype_diff(prototype1, prototype2, maxdepth=2, homogenize=False, implici
|
||||||
new_map = {part[0] if is_iter(part) else part: part for part in new}
|
new_map = {part[0] if is_iter(part) else part: part for part in new}
|
||||||
all_keys = set(list(old_map.keys()) + list(new_map.keys()))
|
all_keys = set(list(old_map.keys()) + list(new_map.keys()))
|
||||||
return {
|
return {
|
||||||
key: _recursive_diff(old_map.get(key), new_map.get(key, _unset), depth=depth + 1)
|
key: _recursive_diff(old_map.get(key, _unset), new_map.get(key, _unset), depth=depth + 1)
|
||||||
for key in all_keys
|
for key in all_keys
|
||||||
}
|
}
|
||||||
elif old != new:
|
elif old != new:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue