Add ability to batch-add tags, permissions and aliases along with category in the object/player create functions as well as in the tag handler. This is useful for direct assignment of categories from prototypes.

This commit is contained in:
Griatch 2017-04-02 22:11:54 +02:00
parent a648433db8
commit e34d32bd60
6 changed files with 50 additions and 10 deletions

View file

@ -944,17 +944,17 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
self.save(update_fields=updates) self.save(update_fields=updates)
if cdict.get("permissions"): if cdict.get("permissions"):
self.permissions.add(cdict["permissions"]) self.permissions.batch_add(cdict["permissions"])
if cdict.get("locks"): if cdict.get("locks"):
self.locks.add(cdict["locks"]) self.locks.add(cdict["locks"])
if cdict.get("aliases"): if cdict.get("aliases"):
self.aliases.add(cdict["aliases"]) self.aliases.batch_add(cdict["aliases"])
if cdict.get("location"): if cdict.get("location"):
cdict["location"].at_object_receive(self, None) cdict["location"].at_object_receive(self, None)
self.at_after_move(None) self.at_after_move(None)
if cdict.get("tags"): if cdict.get("tags"):
# this should be a list of tags # this should be a list of tags
self.tags.add(cdict["tags"]) self.tags.batch_add(cdict["tags"])
if cdict.get("attributes"): if cdict.get("attributes"):
# this should be a dict of attrname:value # this should be a dict of attrname:value
keys, values = list(cdict["attributes"]), listvalues(cdict["attributes"]) keys, values = list(cdict["attributes"]), listvalues(cdict["attributes"])

View file

@ -624,7 +624,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)):
permissions = cdict["permissions"] permissions = cdict["permissions"]
del self._createdict del self._createdict
self.permissions.add(permissions) self.permissions.batch_add(permissions)
def at_access(self, result, accessing_obj, access_type, **kwargs): def at_access(self, result, accessing_obj, access_type, **kwargs):
""" """

View file

@ -10,6 +10,7 @@ respective handlers.
""" """
from builtins import object from builtins import object
from collections import defaultdict
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
@ -239,7 +240,7 @@ class TagHandler(object):
category (str, optional): Category of Tag. `None` is the default category. category (str, optional): Category of Tag. `None` is the default category.
data (str, optional): Info text about the tag(s) added. data (str, optional): Info text about the tag(s) added.
This can not be used to store object-unique info but only This can not be used to store object-unique info but only
eventual info about the text itself. eventual info about the tag itself.
Notes: Notes:
If the tag + category combination matches an already If the tag + category combination matches an already
@ -356,6 +357,37 @@ class TagHandler(object):
else: else:
return [to_str(tag.db_key) for tag in tags] return [to_str(tag.db_key) for tag in tags]
def batch_add(self, *tuples):
"""
Batch-add tags from a list of tuples.
Args:
tuples (tuple or str): Any number of `tagstr` keys, `(keystr, category)` or
`(keystr, category, data)` tuples.
Notes:
This will generate a mimimal number of self.add calls,
based on the number of categories involved (including
`None`) (data is not unique and may be overwritten by the content
of a latter tuple with the same category).
"""
keys = defaultdict(list)
data = {}
for tup in tuples:
tup = make_iter(tup)
nlen = len(tup)
if nlen == 1: # just a key
keys[None].append(tup[0])
elif nlen == 2:
keys[tup[1]].append(tup[0])
else:
keys[tup[1]].append(tup[0])
data[tup[1]] = tup[2] # overwrite previous
for category, key in keys.iteritems():
self.add(tag=key, category=category, data=data.get(category, None))
def __str__(self): def __str__(self):
return ",".join(self.all()) return ",".join(self.all())

View file

@ -65,10 +65,10 @@ def create_object(typeclass=None, key=None, location=None, home=None,
#dbref will be set. #dbref will be set.
home (Object or str): Obj or #dbref to use as the object's home (Object or str): Obj or #dbref to use as the object's
home location. home location.
permissions (str): A comma-separated string of permissions. permissions (list): A list of permission strings or tuples (permstring, category).
locks (str): one or more lockstrings, separated by semicolons. locks (str): one or more lockstrings, separated by semicolons.
aliases (list): A list of alternative keys. aliases (list): A list of alternative keys or tuples (aliasstring, category).
tags (list): List of tag keys (using no category). tags (list): List of tag keys or tuples (tagkey, category).
destination (Object or str): Obj or #dbref to use as an Exit's destination (Object or str): Obj or #dbref to use as an Exit's
target. target.
report_to (Object): The object to return error messages to. report_to (Object): The object to return error messages to.

View file

@ -182,9 +182,11 @@ def _batch_create_object(*objparams):
def spawn(*prototypes, **kwargs): def spawn(*prototypes, **kwargs):
""" """
Spawn a number of prototyped objects. Each argument should be a Spawn a number of prototyped objects.
prototype dictionary.
Args:
prototypes (dict): Each argument should be a prototype
dictionary.
Kwargs: Kwargs:
prototype_modules (str or list): A python-path to a prototype prototype_modules (str or list): A python-path to a prototype
module, or a list of such paths. These will be used to build module, or a list of such paths. These will be used to build
@ -196,6 +198,7 @@ def spawn(*prototypes, **kwargs):
prototypes from prototype_modules. prototypes from prototype_modules.
return_prototypes (bool): Only return a list of the return_prototypes (bool): Only return a list of the
prototype-parents (no object creation happens) prototype-parents (no object creation happens)
""" """
protparents = {} protparents = {}
@ -249,6 +252,7 @@ def spawn(*prototypes, **kwargs):
alias_string = aliasval() if callable(aliasval) else aliasval alias_string = aliasval() if callable(aliasval) else aliasval
tagval = prot.pop("tags", "") tagval = prot.pop("tags", "")
tags = tagval() if callable(tagval) else tagval tags = tagval() if callable(tagval) else tagval
exval = prot.pop("exec", "") exval = prot.pop("exec", "")
execs = make_iter(exval() if callable(exval) else exval) execs = make_iter(exval() if callable(exval) else exval)

View file

@ -1834,3 +1834,7 @@ def get_game_dir_path():
else: else:
os.chdir(os.pardir) os.chdir(os.pardir)
raise RuntimeError("server/conf/settings.py not found: Must start from inside game dir.") raise RuntimeError("server/conf/settings.py not found: Must start from inside game dir.")