def save_prototype(**kwargs): """ Create/Store a prototype persistently. Kwargs: prototype_key (str): This is required for any storage. All other kwargs are considered part of the new prototype dict. Returns: prototype (dict or None): The prototype stored using the given kwargs, None if deleting. Raises: prototypes.ValidationError: If prototype does not validate. Note: No edit/spawn locks will be checked here - if this function is called the caller is expected to have valid permissions. """ kwargs = homogenize_prototype(kwargs) def _to_batchtuple(inp, *args): "build tuple suitable for batch-creation" if is_iter(inp): # already a tuple/list, use as-is return inp return (inp, ) + args prototype_key = kwargs.get("prototype_key") if not prototype_key: raise ValidationError("Prototype requires a prototype_key") prototype_key = str(prototype_key).lower() # we can't edit a prototype defined in a module if prototype_key in _MODULE_PROTOTYPES: mod = _MODULE_PROTOTYPE_MODULES.get(prototype_key, "N/A") raise PermissionError("{} is a read-only prototype " "(defined as code in {}).".format(prototype_key, mod)) # make sure meta properties are included with defaults stored_prototype = DbPrototype.objects.filter(db_key=prototype_key) prototype = stored_prototype[0].prototype if stored_prototype else {} kwargs['prototype_desc'] = kwargs.get("prototype_desc", prototype.get("prototype_desc", "")) prototype_locks = kwargs.get( "prototype_locks", prototype.get('prototype_locks', "spawn:all();edit:perm(Admin)")) is_valid, err = validate_lockstring(prototype_locks) if not is_valid: raise ValidationError("Lock error: {}".format(err)) kwargs['prototype_locks'] = prototype_locks prototype_tags = [ _to_batchtuple(tag, _PROTOTYPE_TAG_META_CATEGORY) for tag in make_iter(kwargs.get("prototype_tags", prototype.get('prototype_tags', [])))] kwargs["prototype_tags"] = prototype_tags prototype.update(kwargs) if stored_prototype: # edit existing prototype stored_prototype = stored_prototype[0] stored_prototype.desc = prototype['prototype_desc'] if prototype_tags: stored_prototype.tags.clear(category=_PROTOTYPE_TAG_CATEGORY) stored_prototype.tags.batch_add(*prototype['prototype_tags']) stored_prototype.locks.add(prototype['prototype_locks']) stored_prototype.attributes.add('prototype', prototype) else: # create a new prototype stored_prototype = create_script( DbPrototype, key=prototype_key, desc=prototype['prototype_desc'], persistent=True, locks=prototype_locks, tags=prototype['prototype_tags'], attributes=[("prototype", prototype)]) return stored_prototype.prototype
def save_prototype(prototype): """ Create/Store a prototype persistently. Args: prototype (dict): The prototype to save. A `prototype_key` key is required. Returns: prototype (dict or None): The prototype stored using the given kwargs, None if deleting. Raises: prototypes.ValidationError: If prototype does not validate. Note: No edit/spawn locks will be checked here - if this function is called the caller is expected to have valid permissions. """ in_prototype = prototype in_prototype = homogenize_prototype(in_prototype) def _to_batchtuple(inp, *args): "build tuple suitable for batch-creation" if is_iter(inp): # already a tuple/list, use as-is return inp return (inp, ) + args prototype_key = in_prototype.get("prototype_key") if not prototype_key: raise ValidationError("Prototype requires a prototype_key") prototype_key = str(prototype_key).lower() # we can't edit a prototype defined in a module if prototype_key in _MODULE_PROTOTYPES: mod = _MODULE_PROTOTYPE_MODULES.get(prototype_key, "N/A") raise PermissionError("{} is a read-only prototype " "(defined as code in {}).".format( prototype_key, mod)) # make sure meta properties are included with defaults in_prototype["prototype_desc"] = in_prototype.get( "prototype_desc", prototype.get("prototype_desc", "")) prototype_locks = in_prototype.get( "prototype_locks", prototype.get("prototype_locks", _PROTOTYPE_FALLBACK_LOCK)) is_valid, err = validate_lockstring(prototype_locks) if not is_valid: raise ValidationError("Lock error: {}".format(err)) in_prototype["prototype_locks"] = prototype_locks prototype_tags = [ _to_batchtuple(tag, _PROTOTYPE_TAG_META_CATEGORY) for tag in make_iter( in_prototype.get("prototype_tags", prototype.get("prototype_tags", []))) ] in_prototype["prototype_tags"] = prototype_tags stored_prototype = DbPrototype.objects.filter(db_key=prototype_key) if stored_prototype: # edit existing prototype stored_prototype = stored_prototype[0] stored_prototype.desc = in_prototype["prototype_desc"] if prototype_tags: stored_prototype.tags.clear(category=PROTOTYPE_TAG_CATEGORY) stored_prototype.tags.batch_add(*in_prototype["prototype_tags"]) stored_prototype.locks.add(in_prototype["prototype_locks"]) stored_prototype.attributes.add("prototype", in_prototype) else: # create a new prototype stored_prototype = create_script( DbPrototype, key=prototype_key, desc=in_prototype["prototype_desc"], persistent=True, locks=prototype_locks, tags=in_prototype["prototype_tags"], attributes=[("prototype", in_prototype)], ) return stored_prototype.prototype