예제 #1
0
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
예제 #2
0
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